diff options
| author | Shauren <shauren.trinity@gmail.com> | 2015-02-17 01:01:44 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2015-02-17 01:01:44 +0100 |
| commit | 56186319bdd41dd26b6cc14f84e6e41eef5d953b (patch) | |
| tree | 7b531cdf71b59170f9fa65120c09935ce51f3307 /src/server/game/Entities/Unit | |
| parent | 7829412416c9709991fd686030ab77908c27922b (diff) | |
Core/Spells: Cooldown updates
* Refactored cooldown handling to separate class shared by creatures and players
* Updated and enabled cooldown packets
* Implemented creature school lockouts
* Implemented spell charges
* Fixed AuraUpdate structure
* Fixed aura flag AFLAG_NOCASTER handling
* Implemented spell charge related auras
Diffstat (limited to 'src/server/game/Entities/Unit')
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 124 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 47 |
2 files changed, 45 insertions, 126 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index fe16759ff98..76ff57361ea 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -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" @@ -193,7 +194,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), _spellHistory(new SpellHistory(this)) { m_objectType |= TYPEMASK_UNIT; m_objectTypeId = TYPEID_UNIT; @@ -290,24 +291,6 @@ Unit::Unit(bool isWorldObject) : } //////////////////////////////////////////////////////////// -// 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() { @@ -324,6 +307,7 @@ Unit::~Unit() delete i_motionMaster; delete m_charmInfo; delete movespline; + delete _spellHistory; ASSERT(!m_duringRemoveFromWorld); ASSERT(!m_attacking); @@ -2708,6 +2692,8 @@ void Unit::_UpdateSpells(uint32 time) ++itr; } } + + _spellHistory->Update(); } void Unit::_UpdateAutoRepeatSpell() @@ -4647,13 +4633,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); } } @@ -4678,14 +4664,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); @@ -5223,8 +5206,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; } @@ -5269,8 +5252,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; } @@ -5850,7 +5833,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()) @@ -5897,7 +5880,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) @@ -6036,10 +6019,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere { uint32 spell = 26364; - // custom cooldown processing case - if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(spell)) - ToPlayer()->RemoveSpellCooldown(spell); - + GetSpellHistory()->ResetCooldown(spell); CastSpell(target, spell, true, castItem, triggeredByAura); return true; } @@ -6138,7 +6118,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) @@ -6146,8 +6126,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere else CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura, originalCaster); - if (cooldown && GetTypeId() == TYPEID_PLAYER) - ToPlayer()->AddSpellCooldown(cooldown_spell_id, 0, time(NULL) + cooldown); + if (cooldown) + GetSpellHistory()->AddCooldown(cooldown_spell_id, 0, std::chrono::seconds(cooldown)); return true; } @@ -6294,9 +6274,10 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura *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; } @@ -6810,7 +6791,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 @@ -6826,8 +6807,8 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg else CastSpell(target, trigger_spell_id, true, castItem, triggeredByAura); - if (cooldown && GetTypeId() == TYPEID_PLAYER) - ToPlayer()->AddSpellCooldown(trigger_spell_id, 0, time(NULL) + cooldown); + if (cooldown) + GetSpellHistory()->AddCooldown(trigger_spell_id, 0, std::chrono::seconds(cooldown)); return true; } @@ -6882,13 +6863,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 && ToPlayer()->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); + if (cooldown) + GetSpellHistory()->AddCooldown(triggered_spell_id, 0, std::chrono::seconds(cooldown)); return true; } @@ -7621,14 +7602,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 { @@ -7662,13 +7640,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)) { @@ -16404,27 +16379,6 @@ void Unit::DestroyForPlayer(Player* target) const WorldObject::DestroyForPlayer(target); } -void Unit::BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 spellId, uint32 cooldown) -{ - data.Initialize(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4); - data << 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 << 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; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 82f7240bc76..3f9570b548f 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -397,6 +397,7 @@ class Creature; class Spell; class SpellInfo; class SpellEffectInfo; +class SpellHistory; class DynamicObject; class GameObject; class Item; @@ -1105,30 +1106,6 @@ enum CurrentSpellTypes #define CURRENT_FIRST_NON_MELEE_SPELL 1 #define CURRENT_MAX_SPELL 4 -struct GlobalCooldown -{ - explicit GlobalCooldown(uint32 _dur = 0, uint32 _time = 0) : duration(_dur), cast_time(_time) { } - - uint32 duration; - uint32 cast_time; -}; - -typedef std::unordered_map<uint32 /*category*/, GlobalCooldown> GlobalCooldownList; - -class GlobalCooldownMgr // Shared by Player and CharmInfo -{ -public: - GlobalCooldownMgr() { } - -public: - bool HasGlobalCooldown(SpellInfo const* spellInfo) const; - void AddGlobalCooldown(SpellInfo const* spellInfo, uint32 gcd); - void CancelGlobalCooldown(SpellInfo const* spellInfo); - -private: - GlobalCooldownList m_GlobalCooldowns; -}; - enum ActiveStates { ACT_PASSIVE = 0x01, // 0x01 - passive @@ -1246,8 +1223,6 @@ struct CharmInfo CharmSpellInfo* GetCharmSpell(uint8 index) { return &(_charmspells[index]); } - GlobalCooldownMgr& GetGlobalCooldownMgr() { return m_GlobalCooldownMgr; } - void SetIsCommandAttack(bool val); bool IsCommandAttack(); void SetIsCommandFollow(bool val); @@ -1280,8 +1255,6 @@ struct CharmInfo float _stayX; float _stayY; float _stayZ; - - GlobalCooldownMgr m_GlobalCooldownMgr; }; // for clearing special attacks @@ -1312,16 +1285,6 @@ enum PlayerTotemType SUMMON_TYPE_TOTEM_AIR = 83 }; -/// Spell cooldown flags sent in SMSG_SPELL_COOLDOWN -enum SpellCooldownFlags -{ - SPELL_COOLDOWN_FLAG_NONE = 0x0, - SPELL_COOLDOWN_FLAG_INCLUDE_GCD = 0x1, ///< Starts GCD in addition to normal cooldown specified in the packet - SPELL_COOLDOWN_FLAG_INCLUDE_EVENT_COOLDOWNS = 0x2 ///< Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUDE_GCD set -}; - -typedef std::unordered_map<uint32, uint32> PacketCooldowns; - // delay time next attack to prevent client attack animation problems #define ATTACK_DISPLAY_DELAY 200 #define MAX_PLAYER_STEALTH_DETECT_RANGE 30.0f // max distance for detection targets by player @@ -1658,8 +1621,6 @@ class Unit : public WorldObject Aura* AddAura(SpellInfo const* spellInfo, uint32 effMask, Unit* target); void SetAuraStack(uint32 spellId, Unit* target, uint32 stack); void SendPlaySpellVisualKit(uint32 id, uint32 unkParam); - void BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 spellId, uint32 cooldown); - void BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCooldowns const& cooldowns); void DeMorph(); @@ -1920,7 +1881,6 @@ class Unit : public WorldObject void SetChannelObjectGuid(ObjectGuid guid) { SetGuidValue(UNIT_FIELD_CHANNEL_OBJECT, guid); } void SetCurrentCastSpell(Spell* pSpell); - virtual void ProhibitSpellSchool(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/) { } void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed = true, bool withInstant = true); void FinishSpell(CurrentSpellTypes spellType, bool ok = true); @@ -1939,6 +1899,9 @@ class Unit : public WorldObject int32 GetCurrentSpellCastTime(uint32 spell_id) const; virtual SpellInfo const* GetCastSpellInfo(SpellInfo const* spellInfo) const; + SpellHistory* GetSpellHistory() { return _spellHistory; } + SpellHistory const* GetSpellHistory() const { return _spellHistory; } + ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]; ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]; @@ -2374,6 +2337,8 @@ class Unit : public WorldObject uint16 _aiAnimKitId; uint16 _movementAnimKitId; uint16 _meleeAnimKitId; + + SpellHistory* _spellHistory; }; namespace Trinity |
