Core/Players: unified the updating of power regeneration into a single function and corrected the way the update fields are being set

* this adds support for all power types for SPELL_AURA_MOD_POWER_REGEN and SPELL_AURA_MOD_POWER_REGEN_PERCENT
This commit is contained in:
Ovahlord
2024-06-29 00:11:40 +02:00
parent 686f10cb0f
commit 6df40875a2
4 changed files with 86 additions and 49 deletions

View File

@@ -1665,7 +1665,7 @@ void Player::Regenerate(Powers power)
return;
/// @todo possible use of miscvalueb instead of amount
if (HasAuraTypeWithValue(SPELL_AURA_PREVENT_REGENERATE_POWER, power))
if (HasAuraTypeWithValue(SPELL_AURA_PREVENT_REGENERATE_POWER, power) || HasAuraType(SPELL_AURA_INTERRUPT_REGEN))
return;
int32 curValue = GetPower(power);
@@ -1719,14 +1719,6 @@ void Player::Regenerate(Powers power)
if (RatesForPower[power] != MAX_RATES)
addvalue *= sWorld->getRate(RatesForPower[power]);
// Mana regen calculated in Player::UpdateManaRegen()
if (power != POWER_MANA)
{
addvalue *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, power);
addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, power) * ((power != POWER_ENERGY) ? m_regenTimerCount : m_regenTimer) / (5 * IN_MILLISECONDS);
}
int32 minPower = powerType->MinPower;
int32 maxPower = GetMaxPower(power);

View File

@@ -2084,7 +2084,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void UpdateExpertise(WeaponAttackType attType);
void ApplyManaRegenBonus(int32 amount, bool apply);
void ApplyHealthRegenBonus(int32 amount, bool apply);
void UpdateManaRegen();
void UpdatePowerRegen(Powers powerType);
void UpdateAllRunesRegen();
void SetPetSpellPower(uint32 spellPower) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::PetSpellPower), spellPower); }

View File

@@ -145,7 +145,7 @@ bool Player::UpdateStats(Stats stat)
UpdateArmor();
UpdateSpellDamageAndHealingBonus();
UpdateManaRegen();
UpdatePowerRegen(POWER_MANA);
return true;
}
@@ -219,12 +219,14 @@ bool Player::UpdateAllStats()
UpdateParryPercentage();
UpdateDodgePercentage();
UpdateSpellDamageAndHealingBonus();
UpdateManaRegen();
UpdateExpertise(BASE_ATTACK);
UpdateExpertise(OFF_ATTACK);
RecalculateRating(CR_ARMOR_PENETRATION);
UpdateAllResistances();
for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i)
UpdatePowerRegen(Powers(i));
return true;
}
@@ -785,7 +787,7 @@ void Player::UpdateExpertise(WeaponAttackType attack)
void Player::ApplyManaRegenBonus(int32 amount, bool apply)
{
_ModifyUInt32(apply, m_baseManaRegen, amount);
UpdateManaRegen();
UpdatePowerRegen(POWER_MANA);
}
void Player::ApplyHealthRegenBonus(int32 amount, bool apply)
@@ -793,42 +795,90 @@ void Player::ApplyHealthRegenBonus(int32 amount, bool apply)
_ModifyUInt32(apply, m_baseHealthRegen, amount);
}
void Player::UpdateManaRegen()
void Player::UpdatePowerRegen(Powers powerType)
{
uint32 manaIndex = GetPowerIndex(POWER_MANA);
if (manaIndex == MAX_POWERS)
uint32 powerIndex = GetPowerIndex(powerType);
if (powerIndex == MAX_POWERS && powerType != POWER_RUNES)
return;
// Get base of Mana Pool in sBaseMPGameTable
uint32 basemana = 0;
sObjectMgr->GetPlayerClassLevelInfo(GetClass(), GetLevel(), basemana);
float powerRegenMod = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, powerType) / 5.f;
float powerRegenModPct = GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, powerType);
float powerRegenModPct = GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, POWER_MANA);
float manaRegenModPct = GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_MANA_REGEN_PCT, POWER_MANA);
switch (powerType)
{
case POWER_MANA:
{
// Get base of Mana Pool in sBaseMPGameTable
uint32 basemana = 0;
sObjectMgr->GetPlayerClassLevelInfo(GetClass(), GetLevel(), basemana);
// BaseRegen = 5% of Base Mana per five seconds
float baseRegen = basemana / 100.f;
// SPELL_AURA_MOD_POWER_REGEN flat bonus
baseRegen += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) / 5.0f;
float manaRegenModPct = GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_MANA_REGEN_PCT, POWER_MANA);
// SpiritRegen = Spirit * GTRegenMpPerSpt * Sqrt(INT) * 5
float spiritRegen = GetStat(STAT_SPIRIT) * GetGameTableColumnForClass(sRegenMpPerSptTable.GetRow(GetLevel()), GetClass()) * 5.0f;
if (GetStat(STAT_INTELLECT) > 0.0f)
spiritRegen *= std::sqrt(GetStat(STAT_INTELLECT));
// BaseRegen = 5% of Base Mana per five seconds
float baseRegen = basemana / 100.f;
// SPELL_AURA_MOD_POWER_REGEN flat bonus
baseRegen += powerRegenMod;
// SPELL_AURA_MOD_POWER_REGEN_PERCENT pct bonus
baseRegen *= powerRegenModPct;
spiritRegen *= powerRegenModPct;
// SpiritRegen = Spirit * GTRegenMpPerSpt * Sqrt(INT) * 5
float spiritRegen = GetStat(STAT_SPIRIT) * GetGameTableColumnForClass(sRegenMpPerSptTable.GetRow(GetLevel()), GetClass()) * 5.0f;
if (GetStat(STAT_INTELLECT) > 0.0f)
spiritRegen *= std::sqrt(GetStat(STAT_INTELLECT));
// SPELL_AURA_MOD_MANA_REGEN_PCT pct bonus
baseRegen *= manaRegenModPct;
spiritRegen *= manaRegenModPct;
// SPELL_AURA_MOD_POWER_REGEN_PERCENT pct bonus
baseRegen *= powerRegenModPct;
spiritRegen *= powerRegenModPct;
// SPELL_AURA_MOD_MANA_REGEN_INTERRUPT allow some of the spirit regeneration to bypass the combat restriction
int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT);
// SPELL_AURA_MOD_MANA_REGEN_PCT pct bonus
baseRegen *= manaRegenModPct;
spiritRegen *= manaRegenModPct;
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PowerRegenFlatModifier, manaIndex), baseRegen + spiritRegen);
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PowerRegenInterruptedFlatModifier, manaIndex), baseRegen + CalculatePct(spiritRegen, modManaRegenInterrupt));
// SPELL_AURA_MOD_MANA_REGEN_INTERRUPT allow some of the spirit regeneration to bypass the combat restriction
int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT);
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PowerRegenFlatModifier, powerIndex), baseRegen + spiritRegen);
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PowerRegenInterruptedFlatModifier, powerIndex), baseRegen + CalculatePct(spiritRegen, modManaRegenInterrupt));
break;
}
case POWER_FOCUS:
case POWER_ENERGY:
{
PowerTypeEntry const* powerTypeEntry = sDB2Manager.GetPowerTypeEntry(powerType);
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PowerRegenFlatModifier, powerIndex), powerTypeEntry->RegenPeace * powerRegenModPct - powerTypeEntry->RegenPeace + powerRegenMod);
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PowerRegenInterruptedFlatModifier, powerIndex), powerTypeEntry->RegenCombat * powerRegenModPct - powerTypeEntry->RegenCombat + powerRegenMod);
break;
}
case POWER_RUNIC_POWER:
case POWER_RAGE:
// Butchery and Anger Management
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PowerRegenInterruptedFlatModifier, powerIndex), powerRegenMod);
break;
case POWER_RUNES:
{
UpdateAllRunesRegen(); // @todo: replace this with the code below once runes have been downgraded for Cataclysm Classic
break;
/*
// Formular: base cooldown / (1 - haste)
float regeneration = 0.1f;
float haste = m_unitData->ModHasteRegen;
if (haste != 0.f)
regeneration /= haste;
for (int8 i = 0; i < NUM_RUNE_TYPES; i++)
{
float mod = 0.f;
for (AuraEffect const* effect : GetAuraEffectsByType(SPELL_AURA_MOD_POWER_REGEN))
if (effect->GetMiscValue() == int32(powerType) && effect->GetMiscValueB() == i)
mod += effect->GetAmount();
SetFloatValue(PLAYER_RUNE_REGEN_1 + i, regeneration + mod);
}
break;
*/
}
default:
break;
}
}
void Player::UpdateAllRunesRegen()

View File

@@ -154,7 +154,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleWaterBreathing, // 82 SPELL_AURA_WATER_BREATHING
&AuraEffect::HandleModBaseResistance, // 83 SPELL_AURA_MOD_BASE_RESISTANCE
&AuraEffect::HandleNoImmediateEffect, // 84 SPELL_AURA_MOD_REGEN implemented in Player::RegenerateHealth
&AuraEffect::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN implemented in Player::Regenerate
&AuraEffect::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN
&AuraEffect::HandleChannelDeathItem, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM
&AuraEffect::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
&AuraEffect::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT implemented in Player::RegenerateHealth
@@ -179,7 +179,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNoImmediateEffect, //107 SPELL_AURA_ADD_FLAT_MODIFIER implemented in AuraEffect::CalculateSpellMod()
&AuraEffect::HandleNoImmediateEffect, //108 SPELL_AURA_ADD_PCT_MODIFIER implemented in AuraEffect::CalculateSpellMod()
&AuraEffect::HandleNoImmediateEffect, //109 SPELL_AURA_ADD_TARGET_TRIGGER
&AuraEffect::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT implemented in Player::Regenerate, Creature::Regenerate
&AuraEffect::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT implemented in Player::UpdatePowerRegen, Creature::Regenerate
&AuraEffect::HandleNoImmediateEffect, //111 SPELL_AURA_INTERCEPT_MELEE_RANGED_ATTACKS implemented in Unit::GetMeleeHitRedirectTarget
&AuraEffect::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
&AuraEffect::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
@@ -3933,12 +3933,7 @@ void AuraEffect::HandleModPowerRegen(AuraApplication const* aurApp, uint8 mode,
if (target->GetTypeId() != TYPEID_PLAYER)
return;
// Update manaregen value
if (GetMiscValue() == POWER_MANA)
target->ToPlayer()->UpdateManaRegen();
else if (GetMiscValue() == POWER_RUNES)
target->ToPlayer()->UpdateAllRunesRegen();
// other powers are not immediate effects - implemented in Player::Regenerate, Creature::Regenerate
target->ToPlayer()->UpdatePowerRegen(static_cast<Powers>(GetMiscValue()));
}
void AuraEffect::HandleModPowerRegenPCT(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -3956,7 +3951,7 @@ void AuraEffect::HandleModManaRegenPct(AuraApplication const* aurApp, uint8 mode
if (!target->IsPlayer())
return;
target->ToPlayer()->UpdateManaRegen();
target->ToPlayer()->UpdatePowerRegen(POWER_MANA);
}
void AuraEffect::HandleAuraModIncreaseHealth(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -4270,7 +4265,7 @@ void AuraEffect::HandleAuraModRegenInterrupt(AuraApplication const* aurApp, uint
if (!target->IsPlayer())
return;
target->ToPlayer()->UpdateManaRegen();
target->ToPlayer()->UpdatePowerRegen(POWER_MANA);
}
void AuraEffect::HandleAuraModWeaponCritPercent(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const