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())
|
||||
{
|
||||
// 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)
|
||||
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"
|
||||
printField(val);
|
||||
out << "\tSubtype: " << bonus.subtype.toString() << "\n";
|
||||
printField(duration.to_ulong());
|
||||
printField(duration);
|
||||
printField(source);
|
||||
out << "\tSource ID: " << bonus.sid.toString() << "\n";
|
||||
if(bonus.additionalInfo != CAddInfo::NONE)
|
||||
|
@ -58,21 +58,22 @@ public:
|
||||
/// 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
|
||||
{
|
||||
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
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
BonusValueType valType = BonusValueType::ADDITIVE_VALUE;
|
||||
std::string stacking; // bonuses with the same stacking value don't stack (e.g. Angel/Archangel morale bonus)
|
||||
|
||||
CAddInfo additionalInfo;
|
||||
BonusLimitEffect effectRange = BonusLimitEffect::NO_LIMIT;
|
||||
|
||||
TLimiterPtr limiter;
|
||||
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)
|
||||
{
|
||||
auto set = hb->duration & BonusDuration::N_DAYS;
|
||||
return set.any();
|
||||
return set != 0;
|
||||
}
|
||||
static bool NTurns(const Bonus *hb)
|
||||
{
|
||||
auto set = hb->duration & BonusDuration::N_TURNS;
|
||||
return set.any();
|
||||
return set != 0;
|
||||
}
|
||||
static bool OneDay(const Bonus *hb)
|
||||
{
|
||||
auto set = hb->duration & BonusDuration::ONE_DAY;
|
||||
return set.any();
|
||||
return set != 0;
|
||||
}
|
||||
static bool OneWeek(const Bonus *hb)
|
||||
{
|
||||
auto set = hb->duration & BonusDuration::ONE_WEEK;
|
||||
return set.any();
|
||||
return set != 0;
|
||||
}
|
||||
static bool OneBattle(const Bonus *hb)
|
||||
{
|
||||
auto set = hb->duration & BonusDuration::ONE_BATTLE;
|
||||
return set.any();
|
||||
return set != 0;
|
||||
}
|
||||
static bool Permanent(const Bonus *hb)
|
||||
{
|
||||
auto set = hb->duration & BonusDuration::PERMANENT;
|
||||
return set.any();
|
||||
return set != 0;
|
||||
}
|
||||
static bool UntilGetsTurn(const Bonus *hb)
|
||||
{
|
||||
auto set = hb->duration & BonusDuration::STACK_GETS_TURN;
|
||||
return set.any();
|
||||
return set != 0;
|
||||
}
|
||||
static bool UntilAttack(const Bonus *hb)
|
||||
{
|
||||
auto set = hb->duration & BonusDuration::UNTIL_ATTACK;
|
||||
return set.any();
|
||||
return set != 0;
|
||||
}
|
||||
static bool UntilBeingAttacked(const Bonus *hb)
|
||||
{
|
||||
auto set = hb->duration & BonusDuration::UNTIL_BEING_ATTACKED;
|
||||
return set.any();
|
||||
return set != 0;
|
||||
}
|
||||
static bool UntilCommanderKilled(const Bonus *hb)
|
||||
{
|
||||
auto set = hb->duration & BonusDuration::COMMANDER_KILLED;
|
||||
return set.any();
|
||||
return set != 0;
|
||||
}
|
||||
static bool UntilOwnAttack(const Bonus *hb)
|
||||
{
|
||||
auto set = hb->duration & BonusDuration::UNTIL_OWN_ATTACK;
|
||||
return set.any();
|
||||
return set != 0;
|
||||
}
|
||||
inline bool operator == (const BonusType & cf) const
|
||||
{
|
||||
|
@ -60,10 +60,11 @@ namespace BonusDuration
|
||||
JsonNode toJson(const Type & duration)
|
||||
{
|
||||
std::vector<std::string> durationNames;
|
||||
for(auto durBit = 0; durBit < duration.size(); durBit++)
|
||||
for(size_t durBit = 0; durBit < Size; durBit++)
|
||||
{
|
||||
if(duration[durBit])
|
||||
durationNames.push_back(vstd::findKey(bonusDurationMap, duration & Type().set(durBit)));
|
||||
Type value = duration & (1 << durBit);
|
||||
if(value)
|
||||
durationNames.push_back(vstd::findKey(bonusDurationMap, value));
|
||||
}
|
||||
if(durationNames.size() == 1)
|
||||
{
|
||||
|
@ -212,7 +212,7 @@ class JsonNode;
|
||||
BONUS_VALUE(INDEPENDENT_MIN) //used for SECONDARY_SKILL_PREMY bonus
|
||||
|
||||
|
||||
enum class BonusType
|
||||
enum class BonusType : uint8_t
|
||||
{
|
||||
#define BONUS_NAME(x) x,
|
||||
BONUS_LIST
|
||||
@ -220,21 +220,27 @@ enum class BonusType
|
||||
};
|
||||
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);
|
||||
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,
|
||||
BONUS_SOURCE_LIST
|
||||
@ -242,13 +248,13 @@ enum class BonusSource
|
||||
NUM_BONUS_SOURCE /*This is a dummy value, which will be always last*/
|
||||
};
|
||||
|
||||
enum class BonusLimitEffect
|
||||
enum class BonusLimitEffect : uint8_t
|
||||
{
|
||||
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)
|
||||
};
|
||||
|
||||
enum class BonusValueType
|
||||
enum class BonusValueType : uint8_t
|
||||
{
|
||||
#define BONUS_VALUE(x) x,
|
||||
BONUS_VALUE_LIST
|
||||
|
@ -19,7 +19,7 @@ class CBattleInfoCallback;
|
||||
struct BattleHex;
|
||||
class CStack;
|
||||
class PlayerColor;
|
||||
enum class BonusType;
|
||||
enum class BonusType : uint8_t;
|
||||
|
||||
namespace battle
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user