mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
Reduce size of Bonus struct from 320 bytes to 296 bytes.
- Internal enums were resized to occupy single byte. - Duration bitmask uses 16 bit integer directly instead of std::bitset<11> which consumed 8 bytes. - Fields shuffled to minimise padding and keep the most useful data on first 2 cache lines.
This commit is contained in:
parent
6f5710e809
commit
c1e6bbddfe
@ -119,7 +119,7 @@ std::string Bonus::Description(std::optional<si32> customValue) const
|
|||||||
if(descriptionHelper.empty())
|
if(descriptionHelper.empty())
|
||||||
{
|
{
|
||||||
// still no description - try to generate one based on duration
|
// still no description - try to generate one based on duration
|
||||||
if ((duration & BonusDuration::ONE_BATTLE).any())
|
if ((duration & BonusDuration::ONE_BATTLE) != 0)
|
||||||
{
|
{
|
||||||
if (val > 0)
|
if (val > 0)
|
||||||
descriptionHelper.appendTextID("core.arraytxt.110"); //+%d Temporary until next battle"
|
descriptionHelper.appendTextID("core.arraytxt.110"); //+%d Temporary until next battle"
|
||||||
@ -248,7 +248,7 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus)
|
|||||||
#define printField(field) out << "\t" #field ": " << (int)bonus.field << "\n"
|
#define printField(field) out << "\t" #field ": " << (int)bonus.field << "\n"
|
||||||
printField(val);
|
printField(val);
|
||||||
out << "\tSubtype: " << bonus.subtype.toString() << "\n";
|
out << "\tSubtype: " << bonus.subtype.toString() << "\n";
|
||||||
printField(duration.to_ulong());
|
printField(duration);
|
||||||
printField(source);
|
printField(source);
|
||||||
out << "\tSource ID: " << bonus.sid.toString() << "\n";
|
out << "\tSource ID: " << bonus.sid.toString() << "\n";
|
||||||
if(bonus.additionalInfo != CAddInfo::NONE)
|
if(bonus.additionalInfo != CAddInfo::NONE)
|
||||||
|
@ -58,21 +58,22 @@ public:
|
|||||||
/// Struct for handling bonuses of several types. Can be transferred to any hero
|
/// Struct for handling bonuses of several types. Can be transferred to any hero
|
||||||
struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>, public Serializeable
|
struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>, public Serializeable
|
||||||
{
|
{
|
||||||
BonusDuration::Type duration = BonusDuration::PERMANENT; //uses BonusDuration values
|
BonusDuration::Type duration = BonusDuration::PERMANENT; //uses BonusDuration values - 2 bytes
|
||||||
si16 turnsRemain = 0; //used if duration is N_TURNS, N_DAYS or ONE_WEEK
|
si16 turnsRemain = 0; //used if duration is N_TURNS, N_DAYS or ONE_WEEK
|
||||||
|
|
||||||
BonusType type = BonusType::NONE; //uses BonusType values - says to what is this bonus - 1 byte
|
|
||||||
BonusSubtypeID subtype;
|
|
||||||
|
|
||||||
BonusSource source = BonusSource::OTHER; //source type" uses BonusSource values - what gave that bonus
|
|
||||||
BonusSource targetSourceType = BonusSource::OTHER;//Bonuses of what origin this amplifies, uses BonusSource values. Needed for PERCENT_TO_TARGET_TYPE.
|
|
||||||
si32 val = 0;
|
si32 val = 0;
|
||||||
|
|
||||||
|
BonusValueType valType = BonusValueType::ADDITIVE_VALUE; // 1 byte
|
||||||
|
BonusSource source = BonusSource::OTHER; //source type" uses BonusSource values - what gave that bonus - 1 byte
|
||||||
|
BonusSource targetSourceType = BonusSource::OTHER;//Bonuses of what origin this amplifies, uses BonusSource values. Needed for PERCENT_TO_TARGET_TYPE. - 1 byte
|
||||||
|
BonusType type = BonusType::NONE; //uses BonusType values - says to what is this bonus - 1 byte
|
||||||
|
BonusLimitEffect effectRange = BonusLimitEffect::NO_LIMIT; // 1 byte
|
||||||
|
// 3 bytes padding
|
||||||
|
|
||||||
|
BonusSubtypeID subtype;
|
||||||
BonusSourceID sid; //source id: id of object/artifact/spell
|
BonusSourceID sid; //source id: id of object/artifact/spell
|
||||||
BonusValueType valType = BonusValueType::ADDITIVE_VALUE;
|
|
||||||
std::string stacking; // bonuses with the same stacking value don't stack (e.g. Angel/Archangel morale bonus)
|
std::string stacking; // bonuses with the same stacking value don't stack (e.g. Angel/Archangel morale bonus)
|
||||||
|
|
||||||
CAddInfo additionalInfo;
|
CAddInfo additionalInfo;
|
||||||
BonusLimitEffect effectRange = BonusLimitEffect::NO_LIMIT;
|
|
||||||
|
|
||||||
TLimiterPtr limiter;
|
TLimiterPtr limiter;
|
||||||
TPropagatorPtr propagator;
|
TPropagatorPtr propagator;
|
||||||
@ -128,57 +129,57 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>, public Se
|
|||||||
static bool NDays(const Bonus *hb)
|
static bool NDays(const Bonus *hb)
|
||||||
{
|
{
|
||||||
auto set = hb->duration & BonusDuration::N_DAYS;
|
auto set = hb->duration & BonusDuration::N_DAYS;
|
||||||
return set.any();
|
return set != 0;
|
||||||
}
|
}
|
||||||
static bool NTurns(const Bonus *hb)
|
static bool NTurns(const Bonus *hb)
|
||||||
{
|
{
|
||||||
auto set = hb->duration & BonusDuration::N_TURNS;
|
auto set = hb->duration & BonusDuration::N_TURNS;
|
||||||
return set.any();
|
return set != 0;
|
||||||
}
|
}
|
||||||
static bool OneDay(const Bonus *hb)
|
static bool OneDay(const Bonus *hb)
|
||||||
{
|
{
|
||||||
auto set = hb->duration & BonusDuration::ONE_DAY;
|
auto set = hb->duration & BonusDuration::ONE_DAY;
|
||||||
return set.any();
|
return set != 0;
|
||||||
}
|
}
|
||||||
static bool OneWeek(const Bonus *hb)
|
static bool OneWeek(const Bonus *hb)
|
||||||
{
|
{
|
||||||
auto set = hb->duration & BonusDuration::ONE_WEEK;
|
auto set = hb->duration & BonusDuration::ONE_WEEK;
|
||||||
return set.any();
|
return set != 0;
|
||||||
}
|
}
|
||||||
static bool OneBattle(const Bonus *hb)
|
static bool OneBattle(const Bonus *hb)
|
||||||
{
|
{
|
||||||
auto set = hb->duration & BonusDuration::ONE_BATTLE;
|
auto set = hb->duration & BonusDuration::ONE_BATTLE;
|
||||||
return set.any();
|
return set != 0;
|
||||||
}
|
}
|
||||||
static bool Permanent(const Bonus *hb)
|
static bool Permanent(const Bonus *hb)
|
||||||
{
|
{
|
||||||
auto set = hb->duration & BonusDuration::PERMANENT;
|
auto set = hb->duration & BonusDuration::PERMANENT;
|
||||||
return set.any();
|
return set != 0;
|
||||||
}
|
}
|
||||||
static bool UntilGetsTurn(const Bonus *hb)
|
static bool UntilGetsTurn(const Bonus *hb)
|
||||||
{
|
{
|
||||||
auto set = hb->duration & BonusDuration::STACK_GETS_TURN;
|
auto set = hb->duration & BonusDuration::STACK_GETS_TURN;
|
||||||
return set.any();
|
return set != 0;
|
||||||
}
|
}
|
||||||
static bool UntilAttack(const Bonus *hb)
|
static bool UntilAttack(const Bonus *hb)
|
||||||
{
|
{
|
||||||
auto set = hb->duration & BonusDuration::UNTIL_ATTACK;
|
auto set = hb->duration & BonusDuration::UNTIL_ATTACK;
|
||||||
return set.any();
|
return set != 0;
|
||||||
}
|
}
|
||||||
static bool UntilBeingAttacked(const Bonus *hb)
|
static bool UntilBeingAttacked(const Bonus *hb)
|
||||||
{
|
{
|
||||||
auto set = hb->duration & BonusDuration::UNTIL_BEING_ATTACKED;
|
auto set = hb->duration & BonusDuration::UNTIL_BEING_ATTACKED;
|
||||||
return set.any();
|
return set != 0;
|
||||||
}
|
}
|
||||||
static bool UntilCommanderKilled(const Bonus *hb)
|
static bool UntilCommanderKilled(const Bonus *hb)
|
||||||
{
|
{
|
||||||
auto set = hb->duration & BonusDuration::COMMANDER_KILLED;
|
auto set = hb->duration & BonusDuration::COMMANDER_KILLED;
|
||||||
return set.any();
|
return set != 0;
|
||||||
}
|
}
|
||||||
static bool UntilOwnAttack(const Bonus *hb)
|
static bool UntilOwnAttack(const Bonus *hb)
|
||||||
{
|
{
|
||||||
auto set = hb->duration & BonusDuration::UNTIL_OWN_ATTACK;
|
auto set = hb->duration & BonusDuration::UNTIL_OWN_ATTACK;
|
||||||
return set.any();
|
return set != 0;
|
||||||
}
|
}
|
||||||
inline bool operator == (const BonusType & cf) const
|
inline bool operator == (const BonusType & cf) const
|
||||||
{
|
{
|
||||||
|
@ -60,10 +60,11 @@ namespace BonusDuration
|
|||||||
JsonNode toJson(const Type & duration)
|
JsonNode toJson(const Type & duration)
|
||||||
{
|
{
|
||||||
std::vector<std::string> durationNames;
|
std::vector<std::string> durationNames;
|
||||||
for(auto durBit = 0; durBit < duration.size(); durBit++)
|
for(size_t durBit = 0; durBit < Size; durBit++)
|
||||||
{
|
{
|
||||||
if(duration[durBit])
|
Type value = duration & (1 << durBit);
|
||||||
durationNames.push_back(vstd::findKey(bonusDurationMap, duration & Type().set(durBit)));
|
if(value)
|
||||||
|
durationNames.push_back(vstd::findKey(bonusDurationMap, value));
|
||||||
}
|
}
|
||||||
if(durationNames.size() == 1)
|
if(durationNames.size() == 1)
|
||||||
{
|
{
|
||||||
|
@ -212,7 +212,7 @@ class JsonNode;
|
|||||||
BONUS_VALUE(INDEPENDENT_MIN) //used for SECONDARY_SKILL_PREMY bonus
|
BONUS_VALUE(INDEPENDENT_MIN) //used for SECONDARY_SKILL_PREMY bonus
|
||||||
|
|
||||||
|
|
||||||
enum class BonusType
|
enum class BonusType : uint8_t
|
||||||
{
|
{
|
||||||
#define BONUS_NAME(x) x,
|
#define BONUS_NAME(x) x,
|
||||||
BONUS_LIST
|
BONUS_LIST
|
||||||
@ -220,21 +220,27 @@ enum class BonusType
|
|||||||
};
|
};
|
||||||
namespace BonusDuration //when bonus is automatically removed
|
namespace BonusDuration //when bonus is automatically removed
|
||||||
{
|
{
|
||||||
using Type = std::bitset<11>;
|
// We use uint16_t directly because std::bitset<11> eats whole 8 byte word.
|
||||||
|
using Type = uint16_t;
|
||||||
|
constexpr static size_t Size = 11;
|
||||||
|
|
||||||
|
enum BonusDuration : Type {
|
||||||
|
PERMANENT = 1 << 0,
|
||||||
|
ONE_BATTLE = 1 << 1, //at the end of battle
|
||||||
|
ONE_DAY = 1 << 2, //at the end of day
|
||||||
|
ONE_WEEK = 1 << 3, //at the end of week (bonus lasts till the end of week, thats NOT 7 days
|
||||||
|
N_TURNS = 1 << 4, //used during battles, after battle bonus is always removed
|
||||||
|
N_DAYS = 1 << 5,
|
||||||
|
UNTIL_BEING_ATTACKED = 1 << 6, /*removed after attack and counterattacks are performed*/
|
||||||
|
UNTIL_ATTACK = 1 << 7, /*removed after attack and counterattacks are performed*/
|
||||||
|
STACK_GETS_TURN = 1 << 8, /*removed when stack gets its turn - used for defensive stance*/
|
||||||
|
COMMANDER_KILLED = 1 << 9,
|
||||||
|
UNTIL_OWN_ATTACK = 1 << 10 /*removed after attack is performed (not counterattack)*/,
|
||||||
|
};
|
||||||
|
|
||||||
extern JsonNode toJson(const Type & duration);
|
extern JsonNode toJson(const Type & duration);
|
||||||
constexpr Type PERMANENT = 1 << 0;
|
|
||||||
constexpr Type ONE_BATTLE = 1 << 1; //at the end of battle
|
|
||||||
constexpr Type ONE_DAY = 1 << 2; //at the end of day
|
|
||||||
constexpr Type ONE_WEEK = 1 << 3; //at the end of week (bonus lasts till the end of week, thats NOT 7 days
|
|
||||||
constexpr Type N_TURNS = 1 << 4; //used during battles, after battle bonus is always removed
|
|
||||||
constexpr Type N_DAYS = 1 << 5;
|
|
||||||
constexpr Type UNTIL_BEING_ATTACKED = 1 << 6; /*removed after attack and counterattacks are performed*/
|
|
||||||
constexpr Type UNTIL_ATTACK = 1 << 7; /*removed after attack and counterattacks are performed*/
|
|
||||||
constexpr Type STACK_GETS_TURN = 1 << 8; /*removed when stack gets its turn - used for defensive stance*/
|
|
||||||
constexpr Type COMMANDER_KILLED = 1 << 9;
|
|
||||||
constexpr Type UNTIL_OWN_ATTACK = 1 << 10; /*removed after attack is performed (not counterattack)*/;
|
|
||||||
};
|
};
|
||||||
enum class BonusSource
|
enum class BonusSource : uint8_t
|
||||||
{
|
{
|
||||||
#define BONUS_SOURCE(x) x,
|
#define BONUS_SOURCE(x) x,
|
||||||
BONUS_SOURCE_LIST
|
BONUS_SOURCE_LIST
|
||||||
@ -242,13 +248,13 @@ enum class BonusSource
|
|||||||
NUM_BONUS_SOURCE /*This is a dummy value, which will be always last*/
|
NUM_BONUS_SOURCE /*This is a dummy value, which will be always last*/
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class BonusLimitEffect
|
enum class BonusLimitEffect : uint8_t
|
||||||
{
|
{
|
||||||
NO_LIMIT = 0,
|
NO_LIMIT = 0,
|
||||||
ONLY_DISTANCE_FIGHT=1, ONLY_MELEE_FIGHT, //used to mark bonuses for attack/defense primary skills from spells like Precision (distance only)
|
ONLY_DISTANCE_FIGHT=1, ONLY_MELEE_FIGHT, //used to mark bonuses for attack/defense primary skills from spells like Precision (distance only)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class BonusValueType
|
enum class BonusValueType : uint8_t
|
||||||
{
|
{
|
||||||
#define BONUS_VALUE(x) x,
|
#define BONUS_VALUE(x) x,
|
||||||
BONUS_VALUE_LIST
|
BONUS_VALUE_LIST
|
||||||
|
@ -19,7 +19,7 @@ class CBattleInfoCallback;
|
|||||||
struct BattleHex;
|
struct BattleHex;
|
||||||
class CStack;
|
class CStack;
|
||||||
class PlayerColor;
|
class PlayerColor;
|
||||||
enum class BonusType;
|
enum class BonusType : uint8_t;
|
||||||
|
|
||||||
namespace battle
|
namespace battle
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user