Index: Player.cpp =================================================================== --- Player.cpp (revision 5515) +++ Player.cpp (working copy) @@ -110,7 +110,9 @@ m_usedTalentCount = 0; - m_regenTimer = 0; + m_healthRegenTimer = 0; + for (uint32 i = 0; i < MAX_POWERS; i++) + m_powerRegenTimers[i] = 0; m_weaponChangeTimer = 0; m_zoneUpdateId = 0; @@ -163,8 +165,6 @@ m_DailyQuestChanged = false; m_lastDailyQuestTime = 0; - m_regenTimer = 0; - m_weaponChangeTimer = 0; m_breathTimer = 0; m_isunderwater = 0; m_isInWater = false; @@ -939,14 +939,6 @@ } } - if(m_regenTimer > 0) - { - if(p_time >= m_regenTimer) - m_regenTimer = 0; - else - m_regenTimer -= p_time; - } - if (m_weaponChangeTimer > 0) { if(p_time >= m_weaponChangeTimer) @@ -979,6 +971,9 @@ if (isAlive()) { + m_healthRegenTimer -= p_time; + for (uint32 i = 0; i < MAX_POWERS; i++) + m_powerRegenTimers[i] -= p_time; RegenerateAll(); } @@ -1726,51 +1721,76 @@ void Player::RegenerateAll() { - if (m_regenTimer != 0) - return; - uint32 regenDelay = 2000; + static const int32 PLAYER_POWER_REGEN_TIMERS[MAX_POWERS] = + { + 2000, // POWER_MANA + 3000, // POWER_RAGE + 0, // POWER_FOCUS + 2000, // POWER_ENERGY + 0 // POWER_HAPPINESS + }; // Not in combat or they have regeneration if( !isInCombat() || HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT) || HasAuraType(SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT) || IsPolymorphed() ) { - RegenerateHealth(); - if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN)) - Regenerate(POWER_RAGE); + uint32 nTimes = 0; + for (; m_healthRegenTimer <= 0; ++nTimes) + m_healthRegenTimer += 2000; + + RegenerateHealth(nTimes); } - Regenerate( POWER_ENERGY ); + for (uint32 power = 0; power < MAX_POWERS; ++power) + { + if (PLAYER_POWER_REGEN_TIMERS[power] == 0) + { + // power not used -> don't regenerate + m_powerRegenTimers[power] = 0; + continue; + } - Regenerate( POWER_MANA ); + uint32 nTimes = 0; + for (; m_powerRegenTimers[power] <= 0; ++nTimes) + m_powerRegenTimers[power] += PLAYER_POWER_REGEN_TIMERS[power]; - m_regenTimer = regenDelay; + Regenerate(static_cast(power), nTimes); + } } -void Player::Regenerate(Powers power) +void Player::Regenerate(Powers power, uint32 nTimes) { - uint32 curValue = GetPower(power); - uint32 maxValue = GetMaxPower(power); + if (nTimes == 0) + return; // do nothing + const uint32 curValue = GetPower(power); + const uint32 maxValue = GetMaxPower(power); + float addvalue = 0.0f; - uint32 msecSinceLastCast = (uint32)getMSTime() - m_lastManaUse; + const uint32 msecSinceLastCast = (uint32)getMSTime() - m_lastManaUse; switch (power) { case POWER_MANA: { - float ManaIncreaseRate = sWorld.getRate(RATE_POWER_MANA); + const float ManaIncreaseRate = sWorld.getRate(RATE_POWER_MANA); if (msecSinceLastCast < 5000) // Mangos Updates Mana in intervals of 2s, which is correct addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT) * ManaIncreaseRate * 2.00f; else - { addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN)* ManaIncreaseRate * 2.00f; - } } break; case POWER_RAGE: // Regenerate rage { - float RageDecreaseRate = sWorld.getRate(RATE_POWER_RAGE_LOSS); - addvalue = 30 * RageDecreaseRate; // 3 rage by tick + int32 amount = 0; + AuraList const& ModPowerRegenAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN); + for(AuraList::const_iterator i = ModPowerRegenAuras.begin();i != ModPowerRegenAuras.end(); ++i) + if ((*i)->GetModifier()->m_miscvalue == POWER_RAGE) + amount += (*i)->GetModifier()->m_amount; + addvalue = floor(float(3 * amount) / 5.0f); // stored as rage*10 per 5s, convert to rage*10 per 3s + addvalue *= sWorld.getRate(RATE_POWER_RAGE_INCOME); + if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN)) + addvalue -= (30.0f * sWorld.getRate(RATE_POWER_RAGE_LOSS)); // loss of 3 rage per tick } break; case POWER_ENERGY: // Regenerate energy (rogue) addvalue = 20; @@ -1788,24 +1808,22 @@ addvalue *= ((*i)->GetModifier()->m_amount + 100) / 100.0; } - if (power != POWER_RAGE) - { - curValue += uint32(addvalue); - if (curValue > maxValue) - curValue = maxValue; - } - else - { - if(curValue <= uint32(addvalue)) - curValue = 0; - else - curValue -= uint32(addvalue); - } - SetPower(power, curValue); + addvalue *= nTimes; + + int32 newValue = int32(curValue) + int32(addvalue); + if (newValue < 0) + newValue = 0; + if (newValue > maxValue) + newValue = maxValue; + + SetPower(power, uint32(newValue)); } -void Player::RegenerateHealth() +void Player::RegenerateHealth(uint32 nTimes) { + if (nTimes == 0) + return; // do nothing + uint32 curValue = GetHealth(); uint32 maxValue = GetMaxHealth(); @@ -1841,6 +1859,8 @@ if(addvalue < 0) addvalue = 0; + addvalue *= nTimes; + ModifyHealth(int32(addvalue)); } Index: Player.h =================================================================== --- Player.h (revision 5515) +++ Player.h (working copy) @@ -1230,9 +1230,10 @@ void SendPetSkillWipeConfirm(); void CalcRage( uint32 damage,bool attacker ); void RegenerateAll(); - void Regenerate(Powers power); - void RegenerateHealth(); - void setRegenTimer(uint32 time) {m_regenTimer = time;} + void Regenerate(Powers power, uint32 nTimes = 1); + void RegenerateHealth(uint32 nTimes = 1); + void setHealthRegenTimer(uint32 time) {m_healthRegenTimer = (int32)time;} + void setPowerRegenTimer(Powers power, uint32 time) { if (power < MAX_POWERS) m_powerRegenTimers[power] = (int32)time; }; void setWeaponChangeTimer(uint32 time) {m_weaponChangeTimer = time;} uint32 GetMoney() { return GetUInt32Value (PLAYER_FIELD_COINAGE); } @@ -2063,7 +2064,8 @@ bool m_DailyQuestChanged; time_t m_lastDailyQuestTime; - uint32 m_regenTimer; + int32 m_healthRegenTimer; + int32 m_powerRegenTimers[MAX_POWERS]; uint32 m_breathTimer; uint32 m_drunkTimer; uint16 m_drunk; Index: SpellAuras.cpp =================================================================== --- SpellAuras.cpp (revision 5515) +++ SpellAuras.cpp (working copy) @@ -1898,7 +1898,7 @@ // for players, start regeneration after 1s (in polymorph fast regeneration case) if(m_target->GetTypeId() == TYPEID_PLAYER) if (m_target->IsPolymorphed()) - ((Player*)m_target)->setRegenTimer(1000); + ((Player*)m_target)->setHealthRegenTimer(1000); Unit* caster = GetCaster(); @@ -3703,12 +3703,9 @@ m_target->HandleEmoteCommand(398); } - // Prevent rage regeneration in combat with rage loss slowdown warrior talent and 0<->1 switching range out combat. - if( !(pt == POWER_RAGE && (m_target->isInCombat() || m_target->GetPower(POWER_RAGE) == 0)) ) - { - if(pt != POWER_MANA) - m_target->ModifyPower(pt, m_modifier.m_amount*2/5); - } + // rage & mana are handled elsewhere + if ((pt != POWER_RAGE) && (pt != POWER_MANA)) + m_target->ModifyPower(pt, m_modifier.m_amount*2/5); } m_isPeriodic = apply; }