Merge pull request #14454 from ariel-/cd

Port Core/Spells: Cooldown updates (6.x branch)
This commit is contained in:
Duarte Duarte committed 2015-05-19 18:52:05 +01:00
commit f4c1a8fb2d
35 files changed
+1043 -1093

No files matched your search

+60 -101
View File
@@ -51,6 +51,7 @@
#include "SpellAuras.h"
#include "Spell.h"
#include "SpellInfo.h"
#include "SpellHistory.h"
#include "SpellMgr.h"
#include "TemporarySummon.h"
#include "Totem.h"
@@ -163,7 +164,7 @@ Unit::Unit(bool isWorldObject) :
i_AI(NULL), i_disabledAI(NULL), m_AutoRepeatFirstCast(false), m_procDeep(0),
m_removedAurasCount(0), i_motionMaster(new MotionMaster(this)), m_regenTimer(0), m_ThreatManager(this),
m_vehicle(NULL), m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE),
m_HostileRefManager(this), _lastDamagedTime(0)
m_HostileRefManager(this), _lastDamagedTime(0), m_spellHistory(new SpellHistory(this))
{
m_objectType |= TYPEMASK_UNIT;
m_objectTypeId = TYPEID_UNIT;
@@ -256,24 +257,6 @@ Unit::Unit(bool isWorldObject) :
_isWalkingBeforeCharm = false;
}
////////////////////////////////////////////////////////////
// Methods of class GlobalCooldownMgr
bool GlobalCooldownMgr::HasGlobalCooldown(SpellInfo const* spellInfo) const
{
GlobalCooldownList::const_iterator itr = m_GlobalCooldowns.find(spellInfo->StartRecoveryCategory);
return itr != m_GlobalCooldowns.end() && itr->second.duration && getMSTimeDiff(itr->second.cast_time, getMSTime()) < itr->second.duration;
}
void GlobalCooldownMgr::AddGlobalCooldown(SpellInfo const* spellInfo, uint32 gcd)
{
m_GlobalCooldowns[spellInfo->StartRecoveryCategory] = GlobalCooldown(gcd, getMSTime());
}
void GlobalCooldownMgr::CancelGlobalCooldown(SpellInfo const* spellInfo)
{
m_GlobalCooldowns[spellInfo->StartRecoveryCategory].duration = 0;
}
////////////////////////////////////////////////////////////
// Methods of class Unit
Unit::~Unit()
@@ -291,6 +274,7 @@ Unit::~Unit()
delete i_motionMaster;
delete m_charmInfo;
delete movespline;
delete m_spellHistory;
ASSERT(!m_duringRemoveFromWorld);
ASSERT(!m_attacking);
@@ -2925,6 +2909,8 @@ void Unit::_UpdateSpells(uint32 time)
++itr;
}
}
m_spellHistory->Update();
}
void Unit::_UpdateAutoRepeatSpell()
@@ -4860,13 +4846,13 @@ void Unit::AddGameObject(GameObject* gameObj)
m_gameObj.push_back(gameObj);
gameObj->SetOwnerGUID(GetGUID());
if (GetTypeId() == TYPEID_PLAYER && gameObj->GetSpellId())
if (gameObj->GetSpellId())
{
SpellInfo const* createBySpell = sSpellMgr->GetSpellInfo(gameObj->GetSpellId());
// Need disable spell use for owner
if (createBySpell && createBySpell->IsCooldownStartedOnEvent())
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases)
ToPlayer()->AddSpellAndCategoryCooldowns(createBySpell, 0, NULL, true);
GetSpellHistory()->StartCooldown(createBySpell, 0, nullptr, true);
}
}
@@ -4891,14 +4877,11 @@ void Unit::RemoveGameObject(GameObject* gameObj, bool del)
{
RemoveAurasDueToSpell(spellid);
if (GetTypeId() == TYPEID_PLAYER)
{
SpellInfo const* createBySpell = sSpellMgr->GetSpellInfo(spellid);
// Need activate spell use for owner
if (createBySpell && createBySpell->IsCooldownStartedOnEvent())
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases)
ToPlayer()->SendCooldownEvent(createBySpell);
}
SpellInfo const* createBySpell = sSpellMgr->GetSpellInfo(spellid);
// Need activate spell use for owner
if (createBySpell && createBySpell->IsCooldownStartedOnEvent())
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existing cases)
GetSpellHistory()->SendCooldownEvent(createBySpell);
}
m_gameObj.remove(gameObj);
@@ -5488,8 +5471,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
CastSpell(target, RandomSpells[rand_spell], true, castItem, triggeredByAura, originalCaster);
for (std::vector<uint32>::iterator itr = RandomSpells.begin(); itr != RandomSpells.end(); ++itr)
{
if (!ToPlayer()->HasSpellCooldown(*itr))
ToPlayer()->AddSpellCooldown(*itr, 0, time(NULL) + cooldown);
if (!GetSpellHistory()->HasCooldown(*itr))
GetSpellHistory()->AddCooldown(*itr, 0, std::chrono::seconds(cooldown));
}
break;
}
@@ -5534,8 +5517,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
CastSpell(target, RandomSpells[rand_spell], true, castItem, triggeredByAura, originalCaster);
for (std::vector<uint32>::iterator itr = RandomSpells.begin(); itr != RandomSpells.end(); ++itr)
{
if (!ToPlayer()->HasSpellCooldown(*itr))
ToPlayer()->AddSpellCooldown(*itr, 0, time(NULL) + cooldown);
if (!GetSpellHistory()->HasCooldown(*itr))
GetSpellHistory()->AddCooldown(*itr, 0, std::chrono::seconds(cooldown));
}
break;
}
@@ -5639,20 +5622,17 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
// Glyph of Ice Block
case 56372:
{
Player* player = ToPlayer();
if (!player)
if (GetTypeId() != TYPEID_PLAYER)
return false;
SpellCooldowns const cooldowns = player->GetSpellCooldowns();
// remove cooldowns on all ranks of Frost Nova
for (SpellCooldowns::const_iterator itr = cooldowns.begin(); itr != cooldowns.end(); ++itr)
GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool
{
SpellInfo const* cdSpell = sSpellMgr->GetSpellInfo(itr->first);
// Frost Nova
if (cdSpell && cdSpell->SpellFamilyName == SPELLFAMILY_MAGE
&& cdSpell->SpellFamilyFlags[0] & 0x00000040)
player->RemoveSpellCooldown(cdSpell->Id, true);
}
if (!cdSpell || cdSpell->SpellFamilyName != SPELLFAMILY_MAGE
|| !(cdSpell->SpellFamilyFlags[0] & 0x00000040))
return false;
return true;
}, true);
break;
}
case 47020: // Enter vehicle XT-002 (Scrapbot)
@@ -6061,7 +6041,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
int32 basepoints1 = CalculatePct(GetMaxPower(Powers(POWER_MANA)), triggerAmount * 2);
// Improved Leader of the Pack
// Check cooldown of heal spell cooldown
if (GetTypeId() == TYPEID_PLAYER && !ToPlayer()->HasSpellCooldown(34299))
if (!GetSpellHistory()->HasCooldown(34299))
CastCustomSpell(this, 68285, &basepoints1, 0, 0, true, 0, triggeredByAura);
break;
}
@@ -6732,7 +6712,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
return false;
// custom cooldown processing case
if (cooldown && player->HasSpellCooldown(dummySpell->Id))
if (cooldown && GetSpellHistory()->HasCooldown(dummySpell->Id))
return false;
if (triggeredByAura->GetBase() && castItem->GetGUID() != triggeredByAura->GetBase()->GetCastItemGUID())
@@ -6798,7 +6778,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
// apply cooldown before cast to prevent processing itself
if (cooldown)
player->AddSpellCooldown(dummySpell->Id, 0, time(NULL) + cooldown);
player->GetSpellHistory()->AddCooldown(dummySpell->Id, 0, std::chrono::seconds(cooldown));
// Attack Twice
for (uint32 i = 0; i < 2; ++i)
@@ -7040,7 +7020,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
return false;
// custom cooldown processing case
if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(dummySpell->Id))
if (cooldown && GetTypeId() == TYPEID_PLAYER && GetSpellHistory()->HasCooldown(dummySpell->Id))
return false;
uint32 spellId = 0;
@@ -7087,13 +7067,13 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
return false;
// Remove cooldown (Chain Lightning - has Category Recovery time)
ToPlayer()->RemoveSpellCooldown(spellId);
GetSpellHistory()->ResetCooldown(spellId);
}
CastSpell(victim, spellId, true, castItem, triggeredByAura);
if (cooldown && GetTypeId() == TYPEID_PLAYER)
ToPlayer()->AddSpellCooldown(dummySpell->Id, 0, time(NULL) + cooldown);
GetSpellHistory()->AddCooldown(dummySpell->Id, 0, std::chrono::seconds(cooldown));
return true;
}
@@ -7106,8 +7086,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
uint32 spell = sSpellMgr->GetSpellWithRank(26364, aurEff->GetSpellInfo()->GetRank());
// custom cooldown processing case
if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(spell))
ToPlayer()->RemoveSpellCooldown(spell);
if (GetTypeId() == TYPEID_PLAYER && GetSpellHistory()->HasCooldown(spell))
GetSpellHistory()->ResetCooldown(spell);
CastSpell(target, spell, true, castItem, triggeredByAura);
aurEff->GetBase()->DropCharge();
@@ -7399,7 +7379,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
if (cooldown_spell_id == 0)
cooldown_spell_id = triggered_spell_id;
if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(cooldown_spell_id))
if (cooldown && GetTypeId() == TYPEID_PLAYER && GetSpellHistory()->HasCooldown(cooldown_spell_id))
return false;
if (basepoints0)
@@ -7408,7 +7388,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura, originalCaster);
if (cooldown && GetTypeId() == TYPEID_PLAYER)
ToPlayer()->AddSpellCooldown(cooldown_spell_id, 0, time(NULL) + cooldown);
GetSpellHistory()->AddCooldown(cooldown_spell_id, 0, std::chrono::seconds(cooldown));
return true;
}
@@ -7629,9 +7609,9 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, Sp
*handled = true;
if (cooldown && GetTypeId() == TYPEID_PLAYER)
{
if (ToPlayer()->HasSpellCooldown(100000))
if (GetSpellHistory()->HasCooldown(100000))
return false;
ToPlayer()->AddSpellCooldown(100000, 0, time(NULL) + cooldown);
GetSpellHistory()->AddCooldown(100000, 0, std::chrono::seconds(cooldown));
}
return true;
}
@@ -8300,7 +8280,11 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
return false;
// Howling Blast
ToPlayer()->RemoveSpellCategoryCooldown(1248, true);
GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
return spellInfo && spellInfo->GetCategory() == 1248;
}, true);
}
// Custom basepoints/target for exist spell
@@ -8319,13 +8303,13 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
if (!target)
return false;
if (cooldown && target->GetTypeId() == TYPEID_PLAYER && target->ToPlayer()->HasSpellCooldown(trigger_spell_id))
if (cooldown && target->GetTypeId() == TYPEID_PLAYER && target->GetSpellHistory()->HasCooldown(trigger_spell_id))
return false;
target->CastSpell(target, trigger_spell_id, true, castItem, triggeredByAura);
if (cooldown && GetTypeId() == TYPEID_PLAYER)
ToPlayer()->AddSpellCooldown(trigger_spell_id, 0, time(NULL) + cooldown);
GetSpellHistory()->AddCooldown(trigger_spell_id, 0, std::chrono::seconds(cooldown));
return true;
}
// Cast positive spell on enemy target
@@ -8408,8 +8392,11 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
case 50227:
{
// Remove cooldown on Shield Slam
if (GetTypeId() == TYPEID_PLAYER)
ToPlayer()->RemoveSpellCategoryCooldown(1209, true);
GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) -> bool
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
return spellInfo && spellInfo->GetCategory() == 1209;
}, true);
break;
}
// Maelstrom Weapon
@@ -8469,8 +8456,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
case 58628:
{
// remove cooldown of Death Grip
if (GetTypeId() == TYPEID_PLAYER)
ToPlayer()->RemoveSpellCooldown(49576, true);
GetSpellHistory()->ResetCooldown(49576, true);
return true;
}
// Savage Defense
@@ -8501,7 +8487,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
}
}
if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(trigger_spell_id))
if (cooldown && GetTypeId() == TYPEID_PLAYER && GetSpellHistory()->HasCooldown(trigger_spell_id))
return false;
// extra attack should hit same target
@@ -8518,7 +8504,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
CastSpell(target, trigger_spell_id, true, castItem, triggeredByAura);
if (cooldown && GetTypeId() == TYPEID_PLAYER)
ToPlayer()->AddSpellCooldown(trigger_spell_id, 0, time(NULL) + cooldown);
GetSpellHistory()->AddCooldown(trigger_spell_id, 0, std::chrono::seconds(cooldown));
return true;
}
@@ -8614,13 +8600,13 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit* victim, uint32 /*damage*/, Au
return false;
}
if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(triggered_spell_id))
if (cooldown && GetTypeId() == TYPEID_PLAYER && GetSpellHistory()->HasCooldown(triggered_spell_id))
return false;
CastSpell(victim, triggered_spell_id, true, castItem, triggeredByAura);
if (cooldown && GetTypeId() == TYPEID_PLAYER)
ToPlayer()->AddSpellCooldown(triggered_spell_id, 0, time(NULL) + cooldown);
GetSpellHistory()->AddCooldown(triggered_spell_id, 0, std::chrono::seconds(cooldown));
return true;
}
@@ -9355,14 +9341,11 @@ void Unit::SetMinion(Minion *minion, bool apply)
if (minion->IsPetGhoul())
minion->setPowerType(POWER_ENERGY);
if (GetTypeId() == TYPEID_PLAYER)
{
// Send infinity cooldown - client does that automatically but after relog cooldown needs to be set again
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(minion->GetUInt32Value(UNIT_CREATED_BY_SPELL));
// Send infinity cooldown - client does that automatically but after relog cooldown needs to be set again
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(minion->GetUInt32Value(UNIT_CREATED_BY_SPELL));
if (spellInfo && (spellInfo->IsCooldownStartedOnEvent()))
ToPlayer()->AddSpellAndCategoryCooldowns(spellInfo, 0, NULL, true);
}
if (spellInfo && (spellInfo->IsCooldownStartedOnEvent()))
GetSpellHistory()->StartCooldown(spellInfo, 0, nullptr, true);
}
else
{
@@ -9396,13 +9379,10 @@ void Unit::SetMinion(Minion *minion, bool apply)
}
}
if (GetTypeId() == TYPEID_PLAYER)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(minion->GetUInt32Value(UNIT_CREATED_BY_SPELL));
// Remove infinity cooldown
if (spellInfo && (spellInfo->IsCooldownStartedOnEvent()))
ToPlayer()->SendCooldownEvent(spellInfo);
}
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(minion->GetUInt32Value(UNIT_CREATED_BY_SPELL));
// Remove infinity cooldown
if (spellInfo && (spellInfo->IsCooldownStartedOnEvent()))
GetSpellHistory()->SendCooldownEvent(spellInfo);
//if (minion->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
{
@@ -17778,27 +17758,6 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target)
data->append(fieldBuffer);
}
void Unit::BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 spellId, uint32 cooldown)
{
data.Initialize(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
data << uint64(GetGUID());
data << uint8(flags);
data << uint32(spellId);
data << uint32(cooldown);
}
void Unit::BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCooldowns const& cooldowns)
{
data.Initialize(SMSG_SPELL_COOLDOWN, 8 + 1 + (4 + 4) * cooldowns.size());
data << uint64(GetGUID());
data << uint8(flags);
for (std::unordered_map<uint32, uint32>::const_iterator itr = cooldowns.begin(); itr != cooldowns.end(); ++itr)
{
data << uint32(itr->first);
data << uint32(itr->second);
}
}
int32 Unit::GetHighestExclusiveSameEffectSpellGroupValue(AuraEffect const* aurEff, AuraType auraType, bool checkMiscValue /*= false*/, int32 miscValue /*= 0*/) const
{
int32 val = 0;