Skip to content

Commit

Permalink
Creature: Partly reconcile stat calculations with pet
Browse files Browse the repository at this point in the history
  • Loading branch information
killerwife committed May 10, 2024
1 parent a493b3c commit e073f1d
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 120 deletions.
1 change: 1 addition & 0 deletions src/game/Entities/Creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,7 @@ class Creature : public Unit
void UpdateArmor() override;
void UpdateAttackPowerAndDamage(bool ranged = false) override;
void UpdateDamagePhysical(WeaponAttackType attType) override;
virtual float GetConditionalTotalPhysicalDamageModifier(WeaponAttackType type) const;
uint32 GetCurrentEquipmentId() const { return m_equipmentId; }

static float _GetHealthMod(int32 Rank); ///< Get custom factor to scale health (default 1, CONFIG_FLOAT_RATE_CREATURE_*_HP)
Expand Down
5 changes: 1 addition & 4 deletions src/game/Entities/Pet.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,10 @@ class Pet : public Creature
int32 GetDuration() const { return m_duration; }

bool UpdateStats(Stats stat) override;
bool UpdateAllStats() override;
void UpdateResistances(uint32 school) override;
void UpdateArmor() override;
void UpdateMaxHealth() override;
void UpdateMaxPower(Powers power) override;
void UpdateAttackPowerAndDamage(bool ranged = false) override;
void UpdateDamagePhysical(WeaponAttackType attType) override;
float GetConditionalTotalPhysicalDamageModifier(WeaponAttackType type) const override;

bool CanTakeMoreActiveSpells(uint32 spellid) const;
void ToggleAutocast(uint32 spellid, bool apply);
Expand Down
176 changes: 60 additions & 116 deletions src/game/Entities/StatSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ void Unit::UpdateMaxHealth()
value += GetModifierValue(unitMod, TOTAL_VALUE) + GetHealthBonusFromStamina();
value *= GetModifierValue(unitMod, TOTAL_PCT);

SetMaxHealth((uint32)value);
SetMaxHealth((uint32)std::max(value, 1.f));
}

void Unit::UpdateMaxPower(Powers power)
Expand Down Expand Up @@ -740,23 +740,35 @@ void Player::_RemoveAllStatBonuses()
######## ########
#######################################*/

bool Creature::UpdateStats(Stats /*stat*/)
bool Creature::UpdateStats(Stats stat)
{
if (stat > STAT_SPIRIT)
return false;

// value = ((base_value * base_pct) + total_value) * total_pct
float value = GetTotalStatValue(stat);

float oldValue = GetStat(stat);
SetStat(stat, int32(value));

switch (stat)
{
case STAT_STRENGTH: UpdateAttackPowerAndDamage(); break;
case STAT_AGILITY: UpdateArmor(); UpdateAttackPowerAndDamage(true); break;
case STAT_STAMINA: UpdateMaxHealth(); break;
case STAT_INTELLECT: UpdateMaxPower(POWER_MANA); break;
case STAT_SPIRIT:
default:
break;
}

return true;
}

bool Creature::UpdateAllStats()
{
for (int i = STAT_STRENGTH; i < MAX_STATS; ++i)
{
float value = GetTotalStatValue(Stats(i));
SetStat(Stats(i), (int32)value);
}

UpdateArmor();
UpdateMaxHealth();
UpdateAttackPowerAndDamage();
UpdateAttackPowerAndDamage(true);
UpdateStats(Stats(i));

for (int i = POWER_MANA; i < MAX_POWERS; ++i)
UpdateMaxPower(Powers(i));
Expand Down Expand Up @@ -866,8 +878,7 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
break;
}

float att_pwr = (GetModifierValue(attPower, BASE_VALUE) * GetModifierValue(attPower, BASE_PCT) + GetModifierValue(attPower, TOTAL_VALUE)) * GetModifierValue(attPower, TOTAL_PCT);
float base_value = GetModifierValue(unitMod, BASE_VALUE) + (att_pwr * GetAPMultiplier(attType, false) / 14.0f);
float base_value = GetModifierValue(unitMod, BASE_VALUE) + (GetTotalAttackPowerValue(attType) * GetAPMultiplier(attType, false) / 14.0f);
float base_pct = GetModifierValue(unitMod, BASE_PCT);
float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
float total_pct = GetModifierValue(unitMod, TOTAL_PCT);
Expand All @@ -878,12 +889,9 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct;
float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct;

// Disarm for creatures
if (hasWeapon(attType) && !hasWeaponForAttack(attType))
{
mindamage *= 0.5f;
maxdamage *= 0.5f;
}
float conditionalMod = GetConditionalTotalPhysicalDamageModifier(attType);
mindamage *= conditionalMod;
maxdamage *= conditionalMod;

uint16 fieldmin, fieldmax;

Expand All @@ -909,6 +917,14 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType)
SetStatFloatValue(fieldmax, maxdamage);
}

float Creature::GetConditionalTotalPhysicalDamageModifier(WeaponAttackType attType) const
{
float result = 1.f;
if (hasWeapon(attType) && !hasWeaponForAttack(attType))
result *= 0.5f;
return result;
}

/*#######################################
######## ########
######## PETS STAT SYSTEM ########
Expand All @@ -929,7 +945,7 @@ bool Pet::UpdateStats(Stats stat)
switch (stat)
{
case STAT_STRENGTH: UpdateAttackPowerAndDamage(); break;
case STAT_AGILITY: UpdateArmor(); break;
case STAT_AGILITY: UpdateArmor(); UpdateAttackPowerAndDamage(true); break;
case STAT_STAMINA: UpdateMaxHealth(); break;
case STAT_INTELLECT: UpdateMaxPower(POWER_MANA); break;
case STAT_SPIRIT:
Expand All @@ -952,52 +968,16 @@ bool Pet::UpdateStats(Stats stat)
return true;
}

bool Pet::UpdateAllStats()
{
for (int i = STAT_STRENGTH; i < MAX_STATS; ++i)
UpdateStats(Stats(i));

for (int i = POWER_MANA; i < MAX_POWERS; ++i)
UpdateMaxPower(Powers(i));

for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
UpdateResistances(i);

return true;
}

void Pet::UpdateResistances(uint32 school)
{
// This override contains current hardcoded implementation for pet scaling (spells since 2.x):
// 34903 - Hunter Pet Scaling 02
// 34904 - Hunter Pet Scaling 03
// 34956 - Warlock Pet Scaling 02
// 34957 - Warlock Pet Scaling 03
// 34958 - Warlock Pet Scaling 04

if (school > SPELL_SCHOOL_NORMAL)
return Creature::UpdateResistances(school);
else
UpdateArmor();
}

void Pet::UpdateArmor()
{
float amount = (GetStat(STAT_AGILITY) * 2.0f);

// This override contains current hardcoded implementation for pet scaling (spells since 2.x):
// 34903 - Hunter Pet Scaling 02
// 34956 - Warlock Pet Scaling 02

m_auraModifiersGroup[UNIT_MOD_ARMOR][TOTAL_VALUE] += amount;
Creature::UpdateArmor();
m_auraModifiersGroup[UNIT_MOD_ARMOR][TOTAL_VALUE] -= amount;
}

void Pet::UpdateMaxHealth()
{
if (getPetType() == GUARDIAN_PET) // handled by regular cls
{
Creature::UpdateMaxHealth();
return;
}

UnitMods unitMod = UNIT_MOD_HEALTH;
float stamina = GetStat(STAT_STAMINA) - GetCreateStat(STAT_STAMINA);
float stamina = GetStat(STAT_STAMINA) - GetCreateStat(STAT_STAMINA); // TODO: Remove create stat usage like this

float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreateHealth();
value *= GetModifierValue(unitMod, BASE_PCT);
Expand All @@ -1009,6 +989,12 @@ void Pet::UpdateMaxHealth()

void Pet::UpdateMaxPower(Powers power)
{
if (getPetType() == GUARDIAN_PET) // handled by regular cls
{
Creature::UpdateMaxPower(power);
return;
}

UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power);

float addValue = (power == POWER_MANA) ? GetStat(STAT_INTELLECT) - GetCreateStat(STAT_INTELLECT) : 0.0f;
Expand All @@ -1023,6 +1009,12 @@ void Pet::UpdateMaxPower(Powers power)

void Pet::UpdateAttackPowerAndDamage(bool ranged)
{
if (getPetType() == GUARDIAN_PET) // handled by regular cls
{
Creature::UpdateAttackPowerAndDamage(ranged);
return;
}

if (ranged)
return;

Expand Down Expand Up @@ -1050,74 +1042,26 @@ void Pet::UpdateAttackPowerAndDamage(bool ranged)
UpdateDamagePhysical(OFF_ATTACK);
}

void Pet::UpdateDamagePhysical(WeaponAttackType attType)
float Pet::GetConditionalTotalPhysicalDamageModifier(WeaponAttackType attType) const
{
if (attType > OFF_ATTACK)
return;

UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND;

float att_speed = float(GetAttackTime(attType)) / 1000.0f;

float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 14.0f * att_speed;
float base_pct = GetModifierValue(unitMod, BASE_PCT);
float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
float total_pct = GetModifierValue(unitMod, TOTAL_PCT);

float weapon_mindamage = GetBaseWeaponDamage(attType, MINDAMAGE);
float weapon_maxdamage = GetBaseWeaponDamage(attType, MAXDAMAGE);

float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct;
float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct;

float result = Creature::GetConditionalTotalPhysicalDamageModifier(attType);
// Pet's base damage changes depending on happiness
if (getPetType() == HUNTER_PET && attType == BASE_ATTACK)
{
switch (GetHappinessState())
{
case HAPPY:
// 125% of normal damage
mindamage = mindamage * 1.25f;
maxdamage = maxdamage * 1.25f;
result *= 1.25f;
break;
case CONTENT:
// 100% of normal damage, nothing to modify
break;
case UNHAPPY:
// 75% of normal damage
mindamage = mindamage * 0.75f;
maxdamage = maxdamage * 0.75f;
result *= 0.75f;
break;
}
}

// Disarm for creatures
if (hasWeapon(attType) && !hasWeaponForAttack(attType))
{
mindamage *= 0.5f;
maxdamage *= 0.5f;
}

uint16 fieldmin, fieldmax;

switch (attType)
{
case RANGED_ATTACK:
fieldmin = UNIT_FIELD_MINRANGEDDAMAGE;
fieldmax = UNIT_FIELD_MAXRANGEDDAMAGE;
break;
case BASE_ATTACK:
fieldmin = UNIT_FIELD_MINDAMAGE;
fieldmax = UNIT_FIELD_MAXDAMAGE;
break;
case OFF_ATTACK:
fieldmin = UNIT_FIELD_MINOFFHANDDAMAGE;
fieldmax = UNIT_FIELD_MAXOFFHANDDAMAGE;
break;
default:
return;
}

SetStatFloatValue(fieldmin, mindamage);
SetStatFloatValue(fieldmax, maxdamage);
return result;
}

0 comments on commit e073f1d

Please sign in to comment.