[Core, Creature] Implement Creature/Pet Interrupts
This commit is contained in:
@@ -110,6 +110,10 @@ void CombatAI::UpdateAI(const uint32 diff)
|
||||
else
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
void CombatAI::SpellInterrupted(uint32 spellId, uint32 unTimeMs)
|
||||
{
|
||||
events.RescheduleEvent(spellId, msTime);
|
||||
}
|
||||
|
||||
/////////////////
|
||||
//CasterAI
|
||||
|
||||
@@ -46,6 +46,7 @@ class CombatAI : public CreatureAI
|
||||
void EnterCombat(Unit* who);
|
||||
void JustDied(Unit* killer);
|
||||
void UpdateAI(const uint32 diff);
|
||||
void SpellInterrupted(uint32 spellId, uint32 unTimeMs);
|
||||
static int Permissible(const Creature*);
|
||||
protected:
|
||||
EventMap events;
|
||||
|
||||
@@ -242,6 +242,10 @@ class UnitAI
|
||||
// Called when the unit heals
|
||||
virtual void HealDone(Unit* /*done_to*/, uint32& /*addhealth*/) {}
|
||||
|
||||
// Called when a spell is interrupted by Spell::EffectInterruptCast
|
||||
// Use to reschedule next planned cast of spell.
|
||||
virtual void SpellInterrupted(uint32 /*spellId*/, uint32 /*unTimeMs*/) {}
|
||||
|
||||
void AttackStartCaster(Unit* victim, float dist);
|
||||
|
||||
void DoAddAuraToAllHostilePlayers(uint32 spellid);
|
||||
|
||||
@@ -1317,6 +1317,10 @@ bool CreatureEventAI::CanCast(Unit* target, SpellInfo const* spell, bool trigger
|
||||
if (!me->IsInRange(target, spell->GetMinRange(false), spell->GetMaxRange(false)))
|
||||
return false;
|
||||
|
||||
//Spell is on cooldown
|
||||
if (me->HasSpellCooldown(spell->Id))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -2231,6 +2231,39 @@ bool Creature::HasSpellCooldown(uint32 spell_id) const
|
||||
return (itr != m_CreatureSpellCooldowns.end() && itr->second > time(NULL)) || HasCategoryCooldown(spell_id);
|
||||
}
|
||||
|
||||
void Creature::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
|
||||
{
|
||||
time_t curTime = time(NULL);
|
||||
for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
|
||||
{
|
||||
if (m_spells[i] == 0)
|
||||
continue;
|
||||
|
||||
uint32 unSpellId = m_spells[i];
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(unSpellId);
|
||||
if (!spellInfo)
|
||||
{
|
||||
ASSERT(spellInfo);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Not send cooldown for this spells
|
||||
if (spellInfo->Attributes & SPELL_ATTR0_DISABLED_WHILE_ACTIVE)
|
||||
continue;
|
||||
|
||||
if (spellInfo->PreventionType != SPELL_PREVENTION_TYPE_SILENCE)
|
||||
continue;
|
||||
|
||||
if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetCreatureSpellCooldownDelay(unSpellId) < unTimeMs)
|
||||
{
|
||||
_AddCreatureSpellCooldown(unSpellId, curTime + unTimeMs/IN_MILLISECONDS);
|
||||
if(UnitAI *ai = GetAI())
|
||||
ai->SpellInterrupted(unSpellId, unTimeMs);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool Creature::HasSpell(uint32 spellID) const
|
||||
{
|
||||
uint8 i;
|
||||
|
||||
@@ -540,6 +540,13 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
|
||||
void AddCreatureSpellCooldown(uint32 spellid);
|
||||
bool HasSpellCooldown(uint32 spell_id) const;
|
||||
bool HasCategoryCooldown(uint32 spell_id) const;
|
||||
uint32 GetCreatureSpellCooldownDelay(uint32 spell_id) const
|
||||
{
|
||||
CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spell_id);
|
||||
time_t t = time(NULL);
|
||||
return uint32(itr != m_CreatureSpellCooldowns.end() && itr->second > t ? itr->second - t : 0);
|
||||
}
|
||||
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32);
|
||||
|
||||
bool HasSpell(uint32 spellID) const;
|
||||
|
||||
|
||||
@@ -2033,3 +2033,40 @@ void Pet::SynchronizeLevelWithOwner()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Pet::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
|
||||
{
|
||||
WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+m_spells.size()*8);
|
||||
data << uint64(GetGUID());
|
||||
data << uint8(0x0); // flags (0x1, 0x2)
|
||||
time_t curTime = time(NULL);
|
||||
for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
|
||||
{
|
||||
if (itr->second.state == PETSPELL_REMOVED)
|
||||
continue;
|
||||
uint32 unSpellId = itr->first;
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(unSpellId);
|
||||
if (!spellInfo)
|
||||
{
|
||||
ASSERT(spellInfo);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Not send cooldown for this spells
|
||||
if (spellInfo->Attributes & SPELL_ATTR0_DISABLED_WHILE_ACTIVE)
|
||||
continue;
|
||||
|
||||
if (spellInfo->PreventionType != SPELL_PREVENTION_TYPE_SILENCE)
|
||||
continue;
|
||||
|
||||
if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetCreatureSpellCooldownDelay(unSpellId) < unTimeMs)
|
||||
{
|
||||
data << uint32(unSpellId);
|
||||
data << uint32(unTimeMs); // in m.secs
|
||||
_AddCreatureSpellCooldown(unSpellId, curTime + unTimeMs/IN_MILLISECONDS);
|
||||
}
|
||||
}
|
||||
if(Player *owner = GetOwner())
|
||||
owner->GetSession()->SendPacket(&data);
|
||||
|
||||
}
|
||||
@@ -200,6 +200,7 @@ class Pet : public Guardian
|
||||
bool unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true);
|
||||
bool removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true);
|
||||
void CleanupActionBar();
|
||||
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32);
|
||||
|
||||
PetSpellMap m_spells;
|
||||
AutoSpellList m_autospells;
|
||||
|
||||
Reference in New Issue
Block a user