aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/Unit
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2015-02-17 01:01:44 +0100
committerShauren <shauren.trinity@gmail.com>2015-02-17 01:01:44 +0100
commit56186319bdd41dd26b6cc14f84e6e41eef5d953b (patch)
tree7b531cdf71b59170f9fa65120c09935ce51f3307 /src/server/game/Entities/Unit
parent7829412416c9709991fd686030ab77908c27922b (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.cpp124
-rw-r--r--src/server/game/Entities/Unit/Unit.h47
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