aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp159
-rw-r--r--src/server/game/Entities/Player/Player.h3
2 files changed, 52 insertions, 110 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 7193c459c2b..b082d2672f6 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -136,10 +136,9 @@ Player::Player(WorldSession* session) : Unit(true)
if (!GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS))
SetAcceptWhispers(true);
+ m_combatExitTime = 0;
m_regenTimer = 0;
m_regenTimerCount = 0;
- m_holyPowerRegenTimerCount = 0;
- m_focusRegenTimerCount = 0;
m_weaponChangeTimer = 0;
m_zoneUpdateId = uint32(-1);
@@ -1794,19 +1793,11 @@ bool Player::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) co
void Player::RegenerateAll()
{
- //if (m_regenTimer <= 500)
- // return;
-
m_regenTimerCount += m_regenTimer;
- if (getClass() == CLASS_PALADIN)
- m_holyPowerRegenTimerCount += m_regenTimer;
-
- if (getClass() == CLASS_HUNTER)
- m_focusRegenTimerCount += m_regenTimer;
-
- Regenerate(POWER_ENERGY);
- Regenerate(POWER_MANA);
+ for (Powers power = POWER_MANA; power < MAX_POWERS; power = Powers(power + 1))
+ if (power != POWER_RUNES)
+ Regenerate(power);
// Runes act as cooldowns, and they don't need to send any data
if (getClass() == CLASS_DEATH_KNIGHT)
@@ -1829,111 +1820,46 @@ void Player::RegenerateAll()
}
}
- if (m_focusRegenTimerCount >= 1000 && getClass() == CLASS_HUNTER)
- {
- Regenerate(POWER_FOCUS);
- m_focusRegenTimerCount -= 1000;
- }
-
if (m_regenTimerCount >= 2000)
{
// Not in combat or they have regeneration
- if (!IsInCombat() || IsPolymorphed() || m_baseHealthRegen ||
- HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT) ||
- HasAuraType(SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT))
- {
+ if (!IsInCombat() || IsPolymorphed() || m_baseHealthRegen || HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT) || HasAuraType(SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT))
RegenerateHealth();
- }
-
- Regenerate(POWER_RAGE);
- if (getClass() == CLASS_DEATH_KNIGHT)
- Regenerate(POWER_RUNIC_POWER);
m_regenTimerCount -= 2000;
}
- if (m_holyPowerRegenTimerCount >= 10000 && getClass() == CLASS_PALADIN)
- {
- Regenerate(POWER_HOLY_POWER);
- m_holyPowerRegenTimerCount -= 10000;
- }
-
m_regenTimer = 0;
}
void Player::Regenerate(Powers power)
{
- uint32 maxValue = GetMaxPower(power);
- if (!maxValue)
+ // Skip regeneration for power type we cannot have
+ uint32 powerIndex = GetPowerIndex(power);
+ if (powerIndex == MAX_POWERS || powerIndex >= MAX_POWERS_PER_CLASS)
return;
- uint32 curValue = GetPower(power);
-
/// @todo possible use of miscvalueb instead of amount
if (HasAuraTypeWithValue(SPELL_AURA_PREVENT_REGENERATE_POWER, power))
return;
- // Skip regeneration for power type we cannot have
- uint32 powerIndex = GetPowerIndex(power);
- if (powerIndex == MAX_POWERS || powerIndex >= MAX_POWERS_PER_CLASS)
+ uint32 curValue = GetPower(power);
+
+ // TODO: updating haste should update UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER for certain power types
+ PowerTypeEntry const* powerType = sDB2Manager.GetPowerTypeEntry(power);
+ if (!powerType)
return;
float addvalue = 0.0f;
-
- // Powers now benefit from haste.
- float rangedHaste = GetFloatValue(UNIT_FIELD_MOD_RANGED_HASTE);
- float meleeHaste = GetFloatValue(UNIT_FIELD_MOD_HASTE);
- float spellHaste = GetFloatValue(UNIT_MOD_CAST_SPEED);
-
- switch (power)
+ if (!IsInCombat())
{
- case POWER_MANA:
- {
- float ManaIncreaseRate = sWorld->getRate(RATE_POWER_MANA);
-
- if (IsInCombat()) // Trinity Updates Mana in intervals of 2s, which is correct
- addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * ((0.001f * m_regenTimer) + CalculatePct(0.001f, spellHaste));
- else
- addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * ((0.001f * m_regenTimer) + CalculatePct(0.001f, spellHaste));
- }
- break;
- case POWER_RAGE: // Regenerate rage
- {
- if (!IsInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN))
- {
- float RageDecreaseRate = sWorld->getRate(RATE_POWER_RAGE_LOSS);
- addvalue += -25 * RageDecreaseRate / meleeHaste; // 2.5 rage by tick (= 2 seconds => 1.25 rage/sec)
- }
- }
- break;
- case POWER_FOCUS:
- addvalue += (6.0f + CalculatePct(6.0f, rangedHaste)) * sWorld->getRate(RATE_POWER_FOCUS);
- break;
- case POWER_ENERGY: // Regenerate energy (rogue)
- addvalue += ((0.01f * m_regenTimer) + CalculatePct(0.01f, meleeHaste)) * sWorld->getRate(RATE_POWER_ENERGY);
- break;
- case POWER_RUNIC_POWER:
- {
- if (!IsInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN))
- {
- float RunicPowerDecreaseRate = sWorld->getRate(RATE_POWER_RUNICPOWER_LOSS);
- addvalue += -30 * RunicPowerDecreaseRate; // 3 RunicPower by tick
- }
- }
- break;
- case POWER_HOLY_POWER: // Regenerate holy power
- {
- if (!IsInCombat())
- addvalue += -1.0f; // remove 1 every 10 sec, first one removed 20s after leaving combat
- }
- break;
- case POWER_RUNES:
- break;
- case POWER_HEALTH:
+ if (powerType->RegenerationDelay && GetMSTimeDiffToNow(m_combatExitTime) < powerType->RegenerationDelay)
return;
- default:
- break;
+
+ addvalue = (powerType->RegenerationPeace + GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER + powerIndex)) * 0.001f * m_regenTimer;
}
+ else
+ addvalue = (powerType->RegenerationCombat + GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER + powerIndex)) * 0.001f * m_regenTimer;
// Mana regen calculated in Player::UpdateManaRegen()
if (power != POWER_MANA)
@@ -1943,19 +1869,20 @@ void Player::Regenerate(Powers power)
if (Powers((*i)->GetMiscValue()) == power)
AddPct(addvalue, (*i)->GetAmount());
- // Butchery requires combat for this effect
- if (power != POWER_RUNIC_POWER || IsInCombat())
- addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, power) * ((power != POWER_ENERGY) ? m_regenTimerCount : m_regenTimer) / (5 * IN_MILLISECONDS);
+ addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, power) * ((power != POWER_ENERGY) ? m_regenTimerCount : m_regenTimer) / (5 * IN_MILLISECONDS);
}
+ int32 minPower = powerType->RegenerationMin;
+ int32 maxPower = GetMaxPower(power);
+
if (addvalue < 0.0f)
{
- if (curValue == 0)
+ if (curValue <= minPower)
return;
}
else if (addvalue > 0.0f)
{
- if (curValue == maxValue)
+ if (curValue >= maxPower)
return;
}
else
@@ -1964,30 +1891,47 @@ void Player::Regenerate(Powers power)
addvalue += m_powerFraction[powerIndex];
uint32 integerValue = uint32(std::fabs(addvalue));
+ if (powerType->RegenerationCenter)
+ {
+ if (curValue > powerType->RegenerationCenter)
+ {
+ addvalue = -std::abs(addvalue);
+ minPower = powerType->RegenerationCenter;
+ }
+ else if (curValue < powerType->RegenerationCenter)
+ {
+ addvalue = std::abs(addvalue);
+ maxPower = powerType->RegenerationCenter;
+ }
+ else
+ return;
+ }
+
if (addvalue < 0.0f)
{
- if (curValue > integerValue)
+ if (curValue > integerValue + minPower)
{
curValue -= integerValue;
m_powerFraction[powerIndex] = addvalue + integerValue;
}
else
{
- curValue = 0;
+ curValue = minPower;
m_powerFraction[powerIndex] = 0;
}
}
else
{
- curValue += integerValue;
-
- if (curValue > maxValue)
+ if (curValue + integerValue <= maxPower)
{
- curValue = maxValue;
- m_powerFraction[powerIndex] = 0;
+ curValue += integerValue;
+ m_powerFraction[powerIndex] = addvalue - integerValue;
}
else
- m_powerFraction[powerIndex] = addvalue - integerValue;
+ {
+ curValue = maxPower;
+ m_powerFraction[powerIndex] = 0;
+ }
}
if (m_regenTimerCount >= 2000)
@@ -26568,8 +26512,7 @@ VoidStorageItem* Player::GetVoidStorageItem(uint64 id, uint8& slot) const
void Player::OnCombatExit()
{
UpdatePotionCooldown();
- if (getClass() == CLASS_PALADIN)
- m_holyPowerRegenTimerCount = 20000; // first charge of holy power decays 20 seconds after leaving combat
+ m_combatExitTime = getMSTime();
}
void Player::CreateGarrison(uint32 garrSiteId)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 1a6481d296a..b51fdfccd47 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2479,9 +2479,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
protected:
// Gamemaster whisper whitelist
GuidList WhisperList;
+ uint32 m_combatExitTime;
uint32 m_regenTimerCount;
- uint32 m_holyPowerRegenTimerCount;
- uint32 m_focusRegenTimerCount;
float m_powerFraction[MAX_POWERS_PER_CLASS];
uint32 m_contestedPvPTimer;