[Core, Creature] Implement Creature/Pet Interrupts

This commit is contained in:
e
2012-09-04 23:04:59 -04:00
parent f9a1fabc7b
commit 98f5d4ef4a
8 changed files with 92 additions and 1 deletions
+4
View File
@@ -110,6 +110,10 @@ void CombatAI::UpdateAI(const uint32 diff)
else
DoMeleeAttackIfReady();
}
void CombatAI::SpellInterrupted(uint32 spellId, uint32 unTimeMs)
{
events.RescheduleEvent(spellId, msTime);
}
/////////////////
//CasterAI
+1
View File
@@ -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;
+4
View File
@@ -241,6 +241,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);
@@ -1308,7 +1308,7 @@ bool CreatureEventAI::CanCast(Unit* target, SpellInfo const* spell, bool trigger
//Silenced so we can't cast
if (!triggered && me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
return false;
//Check for power
if (!triggered && me->GetPower((Powers)spell->PowerType) < spell->CalcPowerCost(me, spell->GetSchoolMask()))
return false;
@@ -1316,6 +1316,10 @@ bool CreatureEventAI::CanCast(Unit* target, SpellInfo const* spell, bool trigger
//Unit is out of range of this spell
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;
+37
View File
@@ -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);
}
+1
View File
@@ -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;