Skip to content

Commit 0f6a99b

Browse files
committed
Core/Units: moved stats modifiers and multipliers into a struct for future ports of the remaining secondary stats
1 parent 3878433 commit 0f6a99b

6 files changed

Lines changed: 96 additions & 83 deletions

File tree

src/server/game/Entities/Pet/Pet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
773773
if (pInfo->armor > 0)
774774
SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor));
775775

776-
for (StatType stat : AllStats)
776+
for (StatType stat : AllPrimaryStats)
777777
GetStats().SetBaseStatValue(stat, pInfo->stats[AsUnderlyingType(stat)]);
778778
}
779779
else // not exist in DB, use some default fake data

src/server/game/Entities/Player/Player.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2230,7 +2230,7 @@ void Player::GiveLevel(uint8 level)
22302230
packet.PowerDelta[4] = 0;
22312231
packet.PowerDelta[5] = 0;
22322232

2233-
for (StatType stat : AllStats)
2233+
for (StatType stat : AllPrimaryStats)
22342234
packet.StatDelta[AsUnderlyingType(stat)] = int32(info.stats[AsUnderlyingType(stat)]) - GetStats().GetBaseStatValue(stat);
22352235

22362236
SendDirectMessage(packet.Write());
@@ -2250,7 +2250,7 @@ void Player::GiveLevel(uint8 level)
22502250
SetCreateMana(basemana);
22512251

22522252
// save base values (bonuses already included in stored stats)
2253-
for (StatType stat : AllStats)
2253+
for (StatType stat : AllPrimaryStats)
22542254
GetStats().SetBaseStatValue(stat, info.stats[AsUnderlyingType(stat)]);
22552255

22562256
InitTalentForLevel();
@@ -2380,7 +2380,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
23802380
SetCreateMana(basemana);
23812381

23822382
// save base values (bonuses already included in stored stats
2383-
for (StatType stat : AllStats)
2383+
for (StatType stat : AllPrimaryStats)
23842384
GetStats().SetBaseStatValue(stat, info.stats[AsUnderlyingType(stat)]);
23852385

23862386
//reset rating fields values
@@ -20030,7 +20030,7 @@ void Player::_SaveStats(CharacterDatabaseTransaction& trans) const
2003020030
for (uint8 i = 0; i < MAX_POWERS_PER_CLASS; ++i)
2003120031
stmt->setUInt32(index++, GetMaxPower(PowerType(i)));
2003220032

20033-
for (StatType stat : AllStats)
20033+
for (StatType stat : AllPrimaryStats)
2003420034
stmt->setUInt32(index++, GetStat(stat));
2003520035

2003620036
for (int i = 0; i < MAX_SPELL_SCHOOL; ++i)

src/server/game/Entities/Unit/Stats.cpp

Lines changed: 64 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,8 @@
2323

2424
Stats::~Stats() = default;
2525

26-
Stats::Stats(Unit* owner) : _owner(owner), _baseStats({ }), _baseStatModifiers({ }), _basePctMultipliers({ }),
27-
_totalModifiers({ }), _totalPctMultipliers({ })
26+
Stats::Stats(Unit* owner) : _owner(owner), _primaryStatData({ })
2827
{
29-
_basePctMultipliers.fill(1.0);
30-
_totalPctMultipliers.fill(1.0);
3128
}
3229

3330
/// Returns the unmodified base value of the specified stat.
@@ -36,7 +33,7 @@ Stats::Stats(Unit* owner) : _owner(owner), _baseStats({ }), _baseStatModifiers({
3633
/// @return returns the base value fo the specified stat
3734
int32 Stats::GetBaseStatValue(StatType statType) const
3835
{
39-
return _baseStats[AsUnderlyingType(statType)];
36+
return _primaryStatData[AsUnderlyingType(statType)].BaseStat;
4037
}
4138

4239
/// Sets the unmodified base value of the specified stat and
@@ -46,7 +43,7 @@ int32 Stats::GetBaseStatValue(StatType statType) const
4643
/// @param value The new base value that will be set
4744
void Stats::SetBaseStatValue(StatType statType, int32 value)
4845
{
49-
_baseStats[AsUnderlyingType(statType)] = value;
46+
_primaryStatData[AsUnderlyingType(statType)].BaseStat= value;
5047
updateStat(statType);
5148
}
5249

@@ -56,7 +53,7 @@ void Stats::SetBaseStatValue(StatType statType, int32 value)
5653
/// @param value The amount of the modifier that will be applied
5754
void Stats::AddBaseStatModifier(StatType statType, int32 value)
5855
{
59-
_baseStatModifiers[AsUnderlyingType(statType)] += value;
56+
_primaryStatData[AsUnderlyingType(statType)].BaseStatModifier += value;
6057
updateStat(statType);
6158
}
6259

@@ -66,7 +63,7 @@ void Stats::AddBaseStatModifier(StatType statType, int32 value)
6663
/// @param value The amount of the modifier that will be removed
6764
void Stats::RemoveBaseStatModifier(StatType statType, int32 value)
6865
{
69-
_baseStatModifiers[AsUnderlyingType(statType)] -= value;
66+
_primaryStatData[AsUnderlyingType(statType)].BaseStatModifier -= value;
7067
updateStat(statType);
7168
}
7269

@@ -75,19 +72,19 @@ void Stats::RemoveBaseStatModifier(StatType statType, int32 value)
7572
/// @param statType The stat which multiplier value will be updated
7673
void Stats::UpdateBaseStatMultiplier(StatType statType)
7774
{
78-
if (statType == StatType::AllStats || statType == StatType::AllStats2)
75+
if (statType == StatType::AllPrimaryStats || statType == StatType::AllPrimaryStats2)
7976
{
80-
for (StatType stat : AllStats)
77+
for (StatType stat : AllPrimaryStats)
8178
{
8279
float multiplier = getAuraMultiplierForStatType(SPELL_AURA_MOD_PERCENT_STAT, stat);
83-
_basePctMultipliers[AsUnderlyingType(stat)] = multiplier;
80+
_primaryStatData[AsUnderlyingType(stat)].BasePctMultiplier = multiplier;
8481
updateStat(stat);
8582
}
8683
}
8784
else
8885
{
8986
float multiplier = getAuraMultiplierForStatType(SPELL_AURA_MOD_PERCENT_STAT, statType);
90-
_basePctMultipliers[AsUnderlyingType(statType)] = multiplier;
87+
_primaryStatData[AsUnderlyingType(statType)].BasePctMultiplier = multiplier;
9188
updateStat(statType);
9289
}
9390
}
@@ -97,19 +94,19 @@ void Stats::UpdateBaseStatMultiplier(StatType statType)
9794
/// @param statType The stat which modifier value will be updated
9895
void Stats::UpdateTotalStatModifier(StatType statType)
9996
{
100-
if (statType == StatType::AllStats || statType == StatType::AllStats2)
97+
if (statType == StatType::AllPrimaryStats || statType == StatType::AllPrimaryStats2)
10198
{
102-
for (StatType stat : AllStats)
99+
for (StatType stat : AllPrimaryStats)
103100
{
104101
int32 modifier = getAuraModifierForStatType(SPELL_AURA_MOD_STAT, stat);
105-
_totalModifiers[AsUnderlyingType(stat)] = modifier;
102+
_primaryStatData[AsUnderlyingType(stat)].TotalModifier = modifier;
106103
updateStat(stat);
107104
}
108105
}
109106
else
110107
{
111108
int32 modifier = getAuraModifierForStatType(SPELL_AURA_MOD_STAT, statType);
112-
_totalModifiers[AsUnderlyingType(statType)] = modifier;
109+
_primaryStatData[AsUnderlyingType(statType)].TotalModifier = modifier;
113110
updateStat(statType);
114111
}
115112
}
@@ -119,19 +116,19 @@ void Stats::UpdateTotalStatModifier(StatType statType)
119116
/// @param statType The stat which multiplier value will be updated
120117
void Stats::UpdateTotalStatMultiplier(StatType statType)
121118
{
122-
if (statType == StatType::AllStats || statType == StatType::AllStats2)
119+
if (statType == StatType::AllPrimaryStats || statType == StatType::AllPrimaryStats2)
123120
{
124-
for (StatType stat : AllStats)
121+
for (StatType stat : AllPrimaryStats)
125122
{
126123
float multiplier = getAuraMultiplierForStatType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, stat);
127-
_totalPctMultipliers[AsUnderlyingType(stat)] = multiplier;
124+
_primaryStatData[AsUnderlyingType(stat)].TotalPctMultiplier = multiplier;
128125
updateStat(stat);
129126
}
130127
}
131128
else
132129
{
133130
float multiplier = getAuraMultiplierForStatType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, statType);
134-
_totalPctMultipliers[AsUnderlyingType(statType)] = multiplier;
131+
_primaryStatData[AsUnderlyingType(statType)].TotalPctMultiplier = multiplier;
135132
updateStat(statType);
136133
}
137134
}
@@ -200,41 +197,9 @@ void Stats::updateStat(StatType statType)
200197
{
201198
int32 negStatValue = 0;
202199
int32 posStatValue = 0;
200+
int32 statValue = 0;
203201

204-
// ==== Calculate the base flat value (Level stats and item/enchantment mods)
205-
int32 baseStatValue = _baseStats[AsUnderlyingType(statType)];
206-
int32 baseModifier = _baseStatModifiers[AsUnderlyingType(statType)];
207-
if (baseModifier > 0)
208-
posStatValue += baseModifier;
209-
else
210-
negStatValue += baseModifier;
211-
212-
int32 flatStatValue = baseStatValue + baseModifier;
213-
214-
// ==== Calculate the total base value (Base pct multiplier auras)
215-
double basePctMultiplier = _basePctMultipliers[AsUnderlyingType(statType)];
216-
int32 baseTotalValue = static_cast<int32>(std::round(flatStatValue * basePctMultiplier));
217-
if (flatStatValue < baseTotalValue)
218-
posStatValue += baseTotalValue - flatStatValue;
219-
else
220-
negStatValue += baseTotalValue - flatStatValue;
221-
222-
// ==== Calculate the total value (Total value buff auras)
223-
int32 totalModifier = _totalModifiers[AsUnderlyingType(statType)];
224-
if (totalModifier > 0)
225-
posStatValue += totalModifier;
226-
else
227-
negStatValue += totalModifier;
228-
229-
int32 totalValue = baseTotalValue + totalModifier;
230-
231-
// ==== Calculate the total value (Total pct multipliers)
232-
double totalPctMultiplier = _totalPctMultipliers[AsUnderlyingType(statType)];
233-
int32 statValue = static_cast<int32>(std::round(totalValue * totalPctMultiplier));
234-
if (totalValue < statValue)
235-
posStatValue += statValue - totalValue;
236-
else
237-
negStatValue += statValue - totalValue;
202+
calculateStatValues(_primaryStatData[AsUnderlyingType(statType)], statValue, posStatValue, negStatValue);
238203

239204
// ==== Apply the stats
240205
_owner->SetInt32Value(UNIT_FIELD_STAT0 + AsUnderlyingType(statType), statValue);
@@ -286,22 +251,63 @@ void Stats::updateStat(StatType statType)
286251
combatRatingMask |= aurEff->GetMiscValue();
287252
}
288253

289-
Player* player = Object::ToPlayer(_owner);
290254
if (combatRatingMask)
291255
{
256+
Player* player = Object::ToPlayer(_owner);
292257
for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
293258
if ((combatRatingMask & (1 << rating)) != 0)
294-
player->ApplyRatingMod(CombatRating(rating), 0, true);
259+
player->ApplyRatingMod(static_cast<CombatRating>(rating), 0, true);
295260
}
296261
}
297262
}
298263

264+
void Stats::calculateStatValues(StatData const& statData, int32& statValue, int32& posStatValue, int32& negStatValue)
265+
{
266+
negStatValue = 0;
267+
posStatValue = 0;
268+
269+
// ==== Calculate the base flat value (Level stats and item/enchantment mods)
270+
int32 baseStatValue = statData.BaseStat;
271+
int32 baseModifier = statData.BaseStatModifier;
272+
if (baseModifier > 0)
273+
posStatValue += baseModifier;
274+
else
275+
negStatValue += baseModifier;
276+
277+
int32 flatStatValue = baseStatValue + baseModifier;
278+
279+
// ==== Calculate the total base value (Base pct multiplier auras)
280+
double basePctMultiplier = statData.BasePctMultiplier;
281+
int32 baseTotalValue = static_cast<int32>(std::round(flatStatValue * basePctMultiplier));
282+
if (flatStatValue < baseTotalValue)
283+
posStatValue += baseTotalValue - flatStatValue;
284+
else
285+
negStatValue += baseTotalValue - flatStatValue;
286+
287+
// ==== Calculate the total value (Total value buff auras)
288+
int32 totalModifier = statData.TotalModifier;
289+
if (totalModifier > 0)
290+
posStatValue += totalModifier;
291+
else
292+
negStatValue += totalModifier;
293+
294+
int32 totalValue = baseTotalValue + totalModifier;
295+
296+
// ==== Calculate the total value (Total pct multipliers)
297+
double totalPctMultiplier = statData.TotalPctMultiplier;
298+
statValue = static_cast<int32>(std::round(totalValue * totalPctMultiplier));
299+
if (totalValue < statValue)
300+
posStatValue += statValue - totalValue;
301+
else
302+
negStatValue += statValue - totalValue;
303+
}
304+
299305
float Stats::getAuraMultiplierForStatType(AuraType auraType, StatType statType) const
300306
{
301307
float multiplier = _owner->GetTotalAuraMultiplier(auraType, [&](AuraEffect const* aurEff)
302308
{
303309
StatType auraStatType = static_cast<StatType>(aurEff->GetMiscValue());
304-
if (auraStatType == StatType::AllStats || auraStatType == StatType::AllStats2 || auraStatType == statType)
310+
if (auraStatType == StatType::AllPrimaryStats || auraStatType == StatType::AllPrimaryStats2 || auraStatType == statType)
305311
return true;
306312

307313
return false;
@@ -315,7 +321,7 @@ int32 Stats::getAuraModifierForStatType(AuraType auraType, StatType statType) co
315321
int32 modifier = _owner->GetTotalAuraModifier(auraType, [&](AuraEffect const* aurEff)
316322
{
317323
StatType auraStatType = static_cast<StatType>(aurEff->GetMiscValue());
318-
if (auraStatType == StatType::AllStats || auraStatType == StatType::AllStats2 || auraStatType == statType)
324+
if (auraStatType == StatType::AllPrimaryStats || auraStatType == StatType::AllPrimaryStats2 || auraStatType == statType)
319325
return true;
320326

321327
return false;

src/server/game/Entities/Unit/Stats.h

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,18 @@ enum AuraType : uint32;
2727

2828
enum class StatType : int8
2929
{
30-
AllStats2 = -2, // There is only one spell using this and it also states that it increases all stats
31-
AllStats = -1,
32-
Strength = 0,
33-
Agility = 1,
34-
Stamina = 2,
35-
Intellect = 3,
36-
Spirit = 4,
37-
Max
30+
// Primary Stats
31+
AllPrimaryStats2 = -2, // There is only one spell using this and it also states that it increases all stats
32+
AllPrimaryStats = -1,
33+
Strength = 0,
34+
Agility = 1,
35+
Stamina = 2,
36+
Intellect = 3,
37+
Spirit = 4,
38+
Max,
3839
};
3940

40-
static constexpr std::array<StatType, AsUnderlyingType(StatType::Max)> AllStats =
41+
static constexpr std::array<StatType, AsUnderlyingType(StatType::Max)> AllPrimaryStats =
4142
{
4243
StatType::Strength,
4344
StatType::Agility,
@@ -46,6 +47,15 @@ static constexpr std::array<StatType, AsUnderlyingType(StatType::Max)> AllStats
4647
StatType::Spirit
4748
};
4849

50+
struct StatData
51+
{
52+
int32 BaseStat = 0;
53+
int32 BaseStatModifier = 0;
54+
int32 TotalModifier = 0;
55+
double BasePctMultiplier = 1.0;
56+
double TotalPctMultiplier = 1.0;
57+
};
58+
4959
class TC_GAME_API Stats
5060
{
5161
public:
@@ -70,13 +80,10 @@ class TC_GAME_API Stats
7080

7181
private:
7282
Unit* _owner;
73-
std::array<int32, AsUnderlyingType(StatType::Max)> _baseStats;
74-
std::array<int32, AsUnderlyingType(StatType::Max)> _baseStatModifiers;
75-
std::array<double, AsUnderlyingType(StatType::Max)> _basePctMultipliers;
76-
std::array<int32, AsUnderlyingType(StatType::Max)> _totalModifiers;
77-
std::array<double, AsUnderlyingType(StatType::Max)> _totalPctMultipliers;
83+
std::array<StatData, AsUnderlyingType(StatType::Max)> _primaryStatData;
7884

7985
void updateStat(StatType statType);
86+
void calculateStatValues(StatData const& statData, int32& statValue, int32& posStatValue, int32& negStatValue);
8087
float getAuraMultiplierForStatType(AuraType auraType, StatType statType) const;
8188
int32 getAuraModifierForStatType(AuraType auraType, StatType statType) const;
8289

src/server/game/Globals/ObjectMgr.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3284,7 +3284,7 @@ void ObjectMgr::LoadPetLevelInfo()
32843284
pLevelInfo->armor = fields[9].GetUInt32();
32853285

32863286

3287-
for (StatType stat : AllStats)
3287+
for (StatType stat : AllPrimaryStats)
32883288
pLevelInfo->stats[AsUnderlyingType(stat)] = fields[AsUnderlyingType(stat) + 4].GetUInt16();
32893289

32903290
++count;
@@ -3732,7 +3732,7 @@ void ObjectMgr::LoadPlayerInfo()
37323732
continue;
37333733
}
37343734

3735-
for (StatType stat : AllStats)
3735+
for (StatType stat : AllPrimaryStats)
37363736
raceStatModifiers[current_race].StatModifier[AsUnderlyingType(stat)] = fields[AsUnderlyingType(stat) + 1].GetInt16();
37373737

37383738
} while (raceStatsResult->NextRow());
@@ -3781,7 +3781,7 @@ void ObjectMgr::LoadPlayerInfo()
37813781
playerInfo->levelInfo = std::make_unique<PlayerLevelInfo[]>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
37823782

37833783
PlayerLevelInfo& levelInfo = playerInfo->levelInfo[current_level - 1];
3784-
for (StatType stat : AllStats)
3784+
for (StatType stat : AllPrimaryStats)
37853785
levelInfo.stats[AsUnderlyingType(stat)] = fields[AsUnderlyingType(stat) + 2].GetUInt16() + raceStatModifiers[race].StatModifier[AsUnderlyingType(stat)];
37863786
}
37873787
}

src/server/game/Spells/Auras/SpellAuraEffects.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3570,7 +3570,7 @@ void AuraEffect::HandleAuraModStat(AuraApplication const* aurApp, uint8 mode, bo
35703570
return;
35713571

35723572
StatType stat = static_cast<StatType>(GetMiscValue());
3573-
if (stat < StatType::AllStats2 || stat >= StatType::Max)
3573+
if (stat < StatType::AllPrimaryStats2 || stat >= StatType::Max)
35743574
{
35753575
TC_LOG_ERROR("spells", "WARNING: Spell %u effect %u has an unsupported misc value (%i) for SPELL_AURA_MOD_STAT ", GetId(), GetEffIndex(), GetMiscValue());
35763576
return;
@@ -3586,7 +3586,7 @@ void AuraEffect::HandleModPercentStat(AuraApplication const* aurApp, uint8 mode,
35863586
return;
35873587

35883588
StatType stat = static_cast<StatType>(GetMiscValue());
3589-
if (stat < StatType::AllStats2 || stat >= StatType::Max)
3589+
if (stat < StatType::AllPrimaryStats2 || stat >= StatType::Max)
35903590
{
35913591
TC_LOG_ERROR("spells", "WARNING: Spell %u effect %u has an unsupported misc value (%i) for SPELL_AURA_MOD_PERCENT_STAT ", GetId(), GetEffIndex(), GetMiscValue());
35923592
return;
@@ -3676,7 +3676,7 @@ void AuraEffect::HandleModTotalPercentStat(AuraApplication const* aurApp, uint8
36763676
return;
36773677

36783678
StatType stat = static_cast<StatType>(GetMiscValue());
3679-
if (stat < StatType::AllStats2 || stat >= StatType::Max)
3679+
if (stat < StatType::AllPrimaryStats2 || stat >= StatType::Max)
36803680
{
36813681
TC_LOG_ERROR("spells", "WARNING: Spell %u effect %u has an unsupported misc value (%i) for SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE ", GetId(), GetEffIndex(), GetMiscValue());
36823682
return;

0 commit comments

Comments
 (0)