Core/Units: moved stats modifiers and multipliers into a struct for future ports of the remaining secondary stats
This commit is contained in:
1 parent
38784337a2
commit
0f6a99bd85
6 files changed
+96
-83
No files matched your search
@@ -773,7 +773,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
|
||||
if (pInfo->armor > 0)
|
||||
SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor));
|
||||
|
||||
for (StatType stat : AllStats)
|
||||
for (StatType stat : AllPrimaryStats)
|
||||
GetStats().SetBaseStatValue(stat, pInfo->stats[AsUnderlyingType(stat)]);
|
||||
}
|
||||
else // not exist in DB, use some default fake data
|
||||
|
||||
@@ -2230,7 +2230,7 @@ void Player::GiveLevel(uint8 level)
|
||||
packet.PowerDelta[4] = 0;
|
||||
packet.PowerDelta[5] = 0;
|
||||
|
||||
for (StatType stat : AllStats)
|
||||
for (StatType stat : AllPrimaryStats)
|
||||
packet.StatDelta[AsUnderlyingType(stat)] = int32(info.stats[AsUnderlyingType(stat)]) - GetStats().GetBaseStatValue(stat);
|
||||
|
||||
SendDirectMessage(packet.Write());
|
||||
@@ -2250,7 +2250,7 @@ void Player::GiveLevel(uint8 level)
|
||||
SetCreateMana(basemana);
|
||||
|
||||
// save base values (bonuses already included in stored stats)
|
||||
for (StatType stat : AllStats)
|
||||
for (StatType stat : AllPrimaryStats)
|
||||
GetStats().SetBaseStatValue(stat, info.stats[AsUnderlyingType(stat)]);
|
||||
|
||||
InitTalentForLevel();
|
||||
@@ -2380,7 +2380,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
|
||||
SetCreateMana(basemana);
|
||||
|
||||
// save base values (bonuses already included in stored stats
|
||||
for (StatType stat : AllStats)
|
||||
for (StatType stat : AllPrimaryStats)
|
||||
GetStats().SetBaseStatValue(stat, info.stats[AsUnderlyingType(stat)]);
|
||||
|
||||
//reset rating fields values
|
||||
@@ -20030,7 +20030,7 @@ void Player::_SaveStats(CharacterDatabaseTransaction& trans) const
|
||||
for (uint8 i = 0; i < MAX_POWERS_PER_CLASS; ++i)
|
||||
stmt->setUInt32(index++, GetMaxPower(PowerType(i)));
|
||||
|
||||
for (StatType stat : AllStats)
|
||||
for (StatType stat : AllPrimaryStats)
|
||||
stmt->setUInt32(index++, GetStat(stat));
|
||||
|
||||
for (int i = 0; i < MAX_SPELL_SCHOOL; ++i)
|
||||
|
||||
@@ -23,11 +23,8 @@
|
||||
|
||||
Stats::~Stats() = default;
|
||||
|
||||
Stats::Stats(Unit* owner) : _owner(owner), _baseStats({ }), _baseStatModifiers({ }), _basePctMultipliers({ }),
|
||||
_totalModifiers({ }), _totalPctMultipliers({ })
|
||||
Stats::Stats(Unit* owner) : _owner(owner), _primaryStatData({ })
|
||||
{
|
||||
_basePctMultipliers.fill(1.0);
|
||||
_totalPctMultipliers.fill(1.0);
|
||||
}
|
||||
|
||||
/// Returns the unmodified base value of the specified stat.
|
||||
@@ -36,7 +33,7 @@ Stats::Stats(Unit* owner) : _owner(owner), _baseStats({ }), _baseStatModifiers({
|
||||
/// @return returns the base value fo the specified stat
|
||||
int32 Stats::GetBaseStatValue(StatType statType) const
|
||||
{
|
||||
return _baseStats[AsUnderlyingType(statType)];
|
||||
return _primaryStatData[AsUnderlyingType(statType)].BaseStat;
|
||||
}
|
||||
|
||||
/// Sets the unmodified base value of the specified stat and
|
||||
@@ -46,7 +43,7 @@ int32 Stats::GetBaseStatValue(StatType statType) const
|
||||
/// @param value The new base value that will be set
|
||||
void Stats::SetBaseStatValue(StatType statType, int32 value)
|
||||
{
|
||||
_baseStats[AsUnderlyingType(statType)] = value;
|
||||
_primaryStatData[AsUnderlyingType(statType)].BaseStat= value;
|
||||
updateStat(statType);
|
||||
}
|
||||
|
||||
@@ -56,7 +53,7 @@ void Stats::SetBaseStatValue(StatType statType, int32 value)
|
||||
/// @param value The amount of the modifier that will be applied
|
||||
void Stats::AddBaseStatModifier(StatType statType, int32 value)
|
||||
{
|
||||
_baseStatModifiers[AsUnderlyingType(statType)] += value;
|
||||
_primaryStatData[AsUnderlyingType(statType)].BaseStatModifier += value;
|
||||
updateStat(statType);
|
||||
}
|
||||
|
||||
@@ -66,7 +63,7 @@ void Stats::AddBaseStatModifier(StatType statType, int32 value)
|
||||
/// @param value The amount of the modifier that will be removed
|
||||
void Stats::RemoveBaseStatModifier(StatType statType, int32 value)
|
||||
{
|
||||
_baseStatModifiers[AsUnderlyingType(statType)] -= value;
|
||||
_primaryStatData[AsUnderlyingType(statType)].BaseStatModifier -= value;
|
||||
updateStat(statType);
|
||||
}
|
||||
|
||||
@@ -75,19 +72,19 @@ void Stats::RemoveBaseStatModifier(StatType statType, int32 value)
|
||||
/// @param statType The stat which multiplier value will be updated
|
||||
void Stats::UpdateBaseStatMultiplier(StatType statType)
|
||||
{
|
||||
if (statType == StatType::AllStats || statType == StatType::AllStats2)
|
||||
if (statType == StatType::AllPrimaryStats || statType == StatType::AllPrimaryStats2)
|
||||
{
|
||||
for (StatType stat : AllStats)
|
||||
for (StatType stat : AllPrimaryStats)
|
||||
{
|
||||
float multiplier = getAuraMultiplierForStatType(SPELL_AURA_MOD_PERCENT_STAT, stat);
|
||||
_basePctMultipliers[AsUnderlyingType(stat)] = multiplier;
|
||||
_primaryStatData[AsUnderlyingType(stat)].BasePctMultiplier = multiplier;
|
||||
updateStat(stat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float multiplier = getAuraMultiplierForStatType(SPELL_AURA_MOD_PERCENT_STAT, statType);
|
||||
_basePctMultipliers[AsUnderlyingType(statType)] = multiplier;
|
||||
_primaryStatData[AsUnderlyingType(statType)].BasePctMultiplier = multiplier;
|
||||
updateStat(statType);
|
||||
}
|
||||
}
|
||||
@@ -97,19 +94,19 @@ void Stats::UpdateBaseStatMultiplier(StatType statType)
|
||||
/// @param statType The stat which modifier value will be updated
|
||||
void Stats::UpdateTotalStatModifier(StatType statType)
|
||||
{
|
||||
if (statType == StatType::AllStats || statType == StatType::AllStats2)
|
||||
if (statType == StatType::AllPrimaryStats || statType == StatType::AllPrimaryStats2)
|
||||
{
|
||||
for (StatType stat : AllStats)
|
||||
for (StatType stat : AllPrimaryStats)
|
||||
{
|
||||
int32 modifier = getAuraModifierForStatType(SPELL_AURA_MOD_STAT, stat);
|
||||
_totalModifiers[AsUnderlyingType(stat)] = modifier;
|
||||
_primaryStatData[AsUnderlyingType(stat)].TotalModifier = modifier;
|
||||
updateStat(stat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int32 modifier = getAuraModifierForStatType(SPELL_AURA_MOD_STAT, statType);
|
||||
_totalModifiers[AsUnderlyingType(statType)] = modifier;
|
||||
_primaryStatData[AsUnderlyingType(statType)].TotalModifier = modifier;
|
||||
updateStat(statType);
|
||||
}
|
||||
}
|
||||
@@ -119,19 +116,19 @@ void Stats::UpdateTotalStatModifier(StatType statType)
|
||||
/// @param statType The stat which multiplier value will be updated
|
||||
void Stats::UpdateTotalStatMultiplier(StatType statType)
|
||||
{
|
||||
if (statType == StatType::AllStats || statType == StatType::AllStats2)
|
||||
if (statType == StatType::AllPrimaryStats || statType == StatType::AllPrimaryStats2)
|
||||
{
|
||||
for (StatType stat : AllStats)
|
||||
for (StatType stat : AllPrimaryStats)
|
||||
{
|
||||
float multiplier = getAuraMultiplierForStatType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, stat);
|
||||
_totalPctMultipliers[AsUnderlyingType(stat)] = multiplier;
|
||||
_primaryStatData[AsUnderlyingType(stat)].TotalPctMultiplier = multiplier;
|
||||
updateStat(stat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float multiplier = getAuraMultiplierForStatType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, statType);
|
||||
_totalPctMultipliers[AsUnderlyingType(statType)] = multiplier;
|
||||
_primaryStatData[AsUnderlyingType(statType)].TotalPctMultiplier = multiplier;
|
||||
updateStat(statType);
|
||||
}
|
||||
}
|
||||
@@ -200,41 +197,9 @@ void Stats::updateStat(StatType statType)
|
||||
{
|
||||
int32 negStatValue = 0;
|
||||
int32 posStatValue = 0;
|
||||
int32 statValue = 0;
|
||||
|
||||
// ==== Calculate the base flat value (Level stats and item/enchantment mods)
|
||||
int32 baseStatValue = _baseStats[AsUnderlyingType(statType)];
|
||||
int32 baseModifier = _baseStatModifiers[AsUnderlyingType(statType)];
|
||||
if (baseModifier > 0)
|
||||
posStatValue += baseModifier;
|
||||
else
|
||||
negStatValue += baseModifier;
|
||||
|
||||
int32 flatStatValue = baseStatValue + baseModifier;
|
||||
|
||||
// ==== Calculate the total base value (Base pct multiplier auras)
|
||||
double basePctMultiplier = _basePctMultipliers[AsUnderlyingType(statType)];
|
||||
int32 baseTotalValue = static_cast<int32>(std::round(flatStatValue * basePctMultiplier));
|
||||
if (flatStatValue < baseTotalValue)
|
||||
posStatValue += baseTotalValue - flatStatValue;
|
||||
else
|
||||
negStatValue += baseTotalValue - flatStatValue;
|
||||
|
||||
// ==== Calculate the total value (Total value buff auras)
|
||||
int32 totalModifier = _totalModifiers[AsUnderlyingType(statType)];
|
||||
if (totalModifier > 0)
|
||||
posStatValue += totalModifier;
|
||||
else
|
||||
negStatValue += totalModifier;
|
||||
|
||||
int32 totalValue = baseTotalValue + totalModifier;
|
||||
|
||||
// ==== Calculate the total value (Total pct multipliers)
|
||||
double totalPctMultiplier = _totalPctMultipliers[AsUnderlyingType(statType)];
|
||||
int32 statValue = static_cast<int32>(std::round(totalValue * totalPctMultiplier));
|
||||
if (totalValue < statValue)
|
||||
posStatValue += statValue - totalValue;
|
||||
else
|
||||
negStatValue += statValue - totalValue;
|
||||
calculateStatValues(_primaryStatData[AsUnderlyingType(statType)], statValue, posStatValue, negStatValue);
|
||||
|
||||
// ==== Apply the stats
|
||||
_owner->SetInt32Value(UNIT_FIELD_STAT0 + AsUnderlyingType(statType), statValue);
|
||||
@@ -286,22 +251,63 @@ void Stats::updateStat(StatType statType)
|
||||
combatRatingMask |= aurEff->GetMiscValue();
|
||||
}
|
||||
|
||||
Player* player = Object::ToPlayer(_owner);
|
||||
if (combatRatingMask)
|
||||
{
|
||||
Player* player = Object::ToPlayer(_owner);
|
||||
for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
|
||||
if ((combatRatingMask & (1 << rating)) != 0)
|
||||
player->ApplyRatingMod(CombatRating(rating), 0, true);
|
||||
player->ApplyRatingMod(static_cast<CombatRating>(rating), 0, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Stats::calculateStatValues(StatData const& statData, int32& statValue, int32& posStatValue, int32& negStatValue)
|
||||
{
|
||||
negStatValue = 0;
|
||||
posStatValue = 0;
|
||||
|
||||
// ==== Calculate the base flat value (Level stats and item/enchantment mods)
|
||||
int32 baseStatValue = statData.BaseStat;
|
||||
int32 baseModifier = statData.BaseStatModifier;
|
||||
if (baseModifier > 0)
|
||||
posStatValue += baseModifier;
|
||||
else
|
||||
negStatValue += baseModifier;
|
||||
|
||||
int32 flatStatValue = baseStatValue + baseModifier;
|
||||
|
||||
// ==== Calculate the total base value (Base pct multiplier auras)
|
||||
double basePctMultiplier = statData.BasePctMultiplier;
|
||||
int32 baseTotalValue = static_cast<int32>(std::round(flatStatValue * basePctMultiplier));
|
||||
if (flatStatValue < baseTotalValue)
|
||||
posStatValue += baseTotalValue - flatStatValue;
|
||||
else
|
||||
negStatValue += baseTotalValue - flatStatValue;
|
||||
|
||||
// ==== Calculate the total value (Total value buff auras)
|
||||
int32 totalModifier = statData.TotalModifier;
|
||||
if (totalModifier > 0)
|
||||
posStatValue += totalModifier;
|
||||
else
|
||||
negStatValue += totalModifier;
|
||||
|
||||
int32 totalValue = baseTotalValue + totalModifier;
|
||||
|
||||
// ==== Calculate the total value (Total pct multipliers)
|
||||
double totalPctMultiplier = statData.TotalPctMultiplier;
|
||||
statValue = static_cast<int32>(std::round(totalValue * totalPctMultiplier));
|
||||
if (totalValue < statValue)
|
||||
posStatValue += statValue - totalValue;
|
||||
else
|
||||
negStatValue += statValue - totalValue;
|
||||
}
|
||||
|
||||
float Stats::getAuraMultiplierForStatType(AuraType auraType, StatType statType) const
|
||||
{
|
||||
float multiplier = _owner->GetTotalAuraMultiplier(auraType, [&](AuraEffect const* aurEff)
|
||||
{
|
||||
StatType auraStatType = static_cast<StatType>(aurEff->GetMiscValue());
|
||||
if (auraStatType == StatType::AllStats || auraStatType == StatType::AllStats2 || auraStatType == statType)
|
||||
if (auraStatType == StatType::AllPrimaryStats || auraStatType == StatType::AllPrimaryStats2 || auraStatType == statType)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -315,7 +321,7 @@ int32 Stats::getAuraModifierForStatType(AuraType auraType, StatType statType) co
|
||||
int32 modifier = _owner->GetTotalAuraModifier(auraType, [&](AuraEffect const* aurEff)
|
||||
{
|
||||
StatType auraStatType = static_cast<StatType>(aurEff->GetMiscValue());
|
||||
if (auraStatType == StatType::AllStats || auraStatType == StatType::AllStats2 || auraStatType == statType)
|
||||
if (auraStatType == StatType::AllPrimaryStats || auraStatType == StatType::AllPrimaryStats2 || auraStatType == statType)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
@@ -27,17 +27,18 @@ enum AuraType : uint32;
|
||||
|
||||
enum class StatType : int8
|
||||
{
|
||||
AllStats2 = -2, // There is only one spell using this and it also states that it increases all stats
|
||||
AllStats = -1,
|
||||
Strength = 0,
|
||||
Agility = 1,
|
||||
Stamina = 2,
|
||||
Intellect = 3,
|
||||
Spirit = 4,
|
||||
Max
|
||||
// Primary Stats
|
||||
AllPrimaryStats2 = -2, // There is only one spell using this and it also states that it increases all stats
|
||||
AllPrimaryStats = -1,
|
||||
Strength = 0,
|
||||
Agility = 1,
|
||||
Stamina = 2,
|
||||
Intellect = 3,
|
||||
Spirit = 4,
|
||||
Max,
|
||||
};
|
||||
|
||||
static constexpr std::array<StatType, AsUnderlyingType(StatType::Max)> AllStats =
|
||||
static constexpr std::array<StatType, AsUnderlyingType(StatType::Max)> AllPrimaryStats =
|
||||
{
|
||||
StatType::Strength,
|
||||
StatType::Agility,
|
||||
@@ -46,6 +47,15 @@ static constexpr std::array<StatType, AsUnderlyingType(StatType::Max)> AllStats
|
||||
StatType::Spirit
|
||||
};
|
||||
|
||||
struct StatData
|
||||
{
|
||||
int32 BaseStat = 0;
|
||||
int32 BaseStatModifier = 0;
|
||||
int32 TotalModifier = 0;
|
||||
double BasePctMultiplier = 1.0;
|
||||
double TotalPctMultiplier = 1.0;
|
||||
};
|
||||
|
||||
class TC_GAME_API Stats
|
||||
{
|
||||
public:
|
||||
@@ -70,13 +80,10 @@ public:
|
||||
|
||||
private:
|
||||
Unit* _owner;
|
||||
std::array<int32, AsUnderlyingType(StatType::Max)> _baseStats;
|
||||
std::array<int32, AsUnderlyingType(StatType::Max)> _baseStatModifiers;
|
||||
std::array<double, AsUnderlyingType(StatType::Max)> _basePctMultipliers;
|
||||
std::array<int32, AsUnderlyingType(StatType::Max)> _totalModifiers;
|
||||
std::array<double, AsUnderlyingType(StatType::Max)> _totalPctMultipliers;
|
||||
std::array<StatData, AsUnderlyingType(StatType::Max)> _primaryStatData;
|
||||
|
||||
void updateStat(StatType statType);
|
||||
void calculateStatValues(StatData const& statData, int32& statValue, int32& posStatValue, int32& negStatValue);
|
||||
float getAuraMultiplierForStatType(AuraType auraType, StatType statType) const;
|
||||
int32 getAuraModifierForStatType(AuraType auraType, StatType statType) const;
|
||||
|
||||
|
||||
@@ -3284,7 +3284,7 @@ void ObjectMgr::LoadPetLevelInfo()
|
||||
pLevelInfo->armor = fields[9].GetUInt32();
|
||||
|
||||
|
||||
for (StatType stat : AllStats)
|
||||
for (StatType stat : AllPrimaryStats)
|
||||
pLevelInfo->stats[AsUnderlyingType(stat)] = fields[AsUnderlyingType(stat) + 4].GetUInt16();
|
||||
|
||||
++count;
|
||||
@@ -3732,7 +3732,7 @@ void ObjectMgr::LoadPlayerInfo()
|
||||
continue;
|
||||
}
|
||||
|
||||
for (StatType stat : AllStats)
|
||||
for (StatType stat : AllPrimaryStats)
|
||||
raceStatModifiers[current_race].StatModifier[AsUnderlyingType(stat)] = fields[AsUnderlyingType(stat) + 1].GetInt16();
|
||||
|
||||
} while (raceStatsResult->NextRow());
|
||||
@@ -3781,7 +3781,7 @@ void ObjectMgr::LoadPlayerInfo()
|
||||
playerInfo->levelInfo = std::make_unique<PlayerLevelInfo[]>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
|
||||
|
||||
PlayerLevelInfo& levelInfo = playerInfo->levelInfo[current_level - 1];
|
||||
for (StatType stat : AllStats)
|
||||
for (StatType stat : AllPrimaryStats)
|
||||
levelInfo.stats[AsUnderlyingType(stat)] = fields[AsUnderlyingType(stat) + 2].GetUInt16() + raceStatModifiers[race].StatModifier[AsUnderlyingType(stat)];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3570,7 +3570,7 @@ void AuraEffect::HandleAuraModStat(AuraApplication const* aurApp, uint8 mode, bo
|
||||
return;
|
||||
|
||||
StatType stat = static_cast<StatType>(GetMiscValue());
|
||||
if (stat < StatType::AllStats2 || stat >= StatType::Max)
|
||||
if (stat < StatType::AllPrimaryStats2 || stat >= StatType::Max)
|
||||
{
|
||||
TC_LOG_ERROR("spells", "WARNING: Spell %u effect %u has an unsupported misc value (%i) for SPELL_AURA_MOD_STAT ", GetId(), GetEffIndex(), GetMiscValue());
|
||||
return;
|
||||
@@ -3586,7 +3586,7 @@ void AuraEffect::HandleModPercentStat(AuraApplication const* aurApp, uint8 mode,
|
||||
return;
|
||||
|
||||
StatType stat = static_cast<StatType>(GetMiscValue());
|
||||
if (stat < StatType::AllStats2 || stat >= StatType::Max)
|
||||
if (stat < StatType::AllPrimaryStats2 || stat >= StatType::Max)
|
||||
{
|
||||
TC_LOG_ERROR("spells", "WARNING: Spell %u effect %u has an unsupported misc value (%i) for SPELL_AURA_MOD_PERCENT_STAT ", GetId(), GetEffIndex(), GetMiscValue());
|
||||
return;
|
||||
@@ -3676,7 +3676,7 @@ void AuraEffect::HandleModTotalPercentStat(AuraApplication const* aurApp, uint8
|
||||
return;
|
||||
|
||||
StatType stat = static_cast<StatType>(GetMiscValue());
|
||||
if (stat < StatType::AllStats2 || stat >= StatType::Max)
|
||||
if (stat < StatType::AllPrimaryStats2 || stat >= StatType::Max)
|
||||
{
|
||||
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());
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user