diff options
author | e <e@encyclopediadramatica.se> | 2012-09-04 23:04:59 -0400 |
---|---|---|
committer | e <e@encyclopediadramatica.se> | 2012-09-04 23:04:59 -0400 |
commit | 98f5d4ef4a16f13e0c47cc68c934c53dae188257 (patch) | |
tree | 6cecaacb28e48e8c606c271a9a4af7cbc61f3006 /src | |
parent | f9a1fabc7b37a439d4ee9b9f1b7b79881de5c44f (diff) |
[Core, Creature] Implement Creature/Pet Interrupts
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/AI/CoreAI/CombatAI.cpp | 4 | ||||
-rwxr-xr-x | src/server/game/AI/CoreAI/CombatAI.h | 1 | ||||
-rwxr-xr-x | src/server/game/AI/CoreAI/UnitAI.h | 4 | ||||
-rwxr-xr-x | src/server/game/AI/EventAI/CreatureEventAI.cpp | 6 | ||||
-rwxr-xr-x | src/server/game/Entities/Creature/Creature.cpp | 33 | ||||
-rwxr-xr-x | src/server/game/Entities/Creature/Creature.h | 7 | ||||
-rwxr-xr-x | src/server/game/Entities/Pet/Pet.cpp | 37 | ||||
-rwxr-xr-x | src/server/game/Entities/Pet/Pet.h | 1 |
8 files changed, 92 insertions, 1 deletions
diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp index 7d7a27fce13..d8c0bff0d4e 100755 --- a/src/server/game/AI/CoreAI/CombatAI.cpp +++ b/src/server/game/AI/CoreAI/CombatAI.cpp @@ -110,6 +110,10 @@ void CombatAI::UpdateAI(const uint32 diff) else DoMeleeAttackIfReady(); } +void CombatAI::SpellInterrupted(uint32 spellId, uint32 unTimeMs) +{ + events.RescheduleEvent(spellId, msTime); +} ///////////////// //CasterAI diff --git a/src/server/game/AI/CoreAI/CombatAI.h b/src/server/game/AI/CoreAI/CombatAI.h index ad98cec0779..fa31e57d780 100755 --- a/src/server/game/AI/CoreAI/CombatAI.h +++ b/src/server/game/AI/CoreAI/CombatAI.h @@ -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; diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h index 593f0d15e18..bd3b9fa6ee9 100755 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -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); diff --git a/src/server/game/AI/EventAI/CreatureEventAI.cpp b/src/server/game/AI/EventAI/CreatureEventAI.cpp index aa14bc1b56e..7bb1a2c8116 100755 --- a/src/server/game/AI/EventAI/CreatureEventAI.cpp +++ b/src/server/game/AI/EventAI/CreatureEventAI.cpp @@ -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; } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index afa4b62d8b0..5b0c2c871e7 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -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; diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 4dd080f8b15..d1142620bd2 100755 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -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; diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 17b214857db..cb5922a03c0 100755 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -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); + +}
\ No newline at end of file diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 3475817816d..14888e1a513 100755 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -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; |