aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authore <e@encyclopediadramatica.se>2012-09-04 23:04:59 -0400
committere <e@encyclopediadramatica.se>2012-09-04 23:04:59 -0400
commit98f5d4ef4a16f13e0c47cc68c934c53dae188257 (patch)
tree6cecaacb28e48e8c606c271a9a4af7cbc61f3006 /src
parentf9a1fabc7b37a439d4ee9b9f1b7b79881de5c44f (diff)
[Core, Creature] Implement Creature/Pet Interrupts
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/AI/CoreAI/CombatAI.cpp4
-rwxr-xr-xsrc/server/game/AI/CoreAI/CombatAI.h1
-rwxr-xr-xsrc/server/game/AI/CoreAI/UnitAI.h4
-rwxr-xr-xsrc/server/game/AI/EventAI/CreatureEventAI.cpp6
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp33
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.h7
-rwxr-xr-xsrc/server/game/Entities/Pet/Pet.cpp37
-rwxr-xr-xsrc/server/game/Entities/Pet/Pet.h1
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;