diff options
author | megamage <none@none> | 2009-05-10 16:07:49 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-05-10 16:07:49 -0500 |
commit | dcf41256ddaa341b532bd7c565c3d18a7c3b6757 (patch) | |
tree | 088ca8f6a5bc4847d9499d4502d8d782bc6977db /src | |
parent | 518ac83fbf51eb60d02d619e7c2a176272768c97 (diff) |
*Move some AI functions to core. No real change.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/bindings/scripts/include/sc_creature.cpp | 1 | ||||
-rw-r--r-- | src/bindings/scripts/include/sc_creature.h | 76 | ||||
-rw-r--r-- | src/game/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/game/CreatureAI.cpp | 64 | ||||
-rw-r--r-- | src/game/CreatureAI.h | 166 | ||||
-rw-r--r-- | src/game/CreatureAIFactory.h | 53 | ||||
-rw-r--r-- | src/game/CreatureAIImpl.h | 153 | ||||
-rw-r--r-- | src/game/CreatureAIRegistry.cpp | 3 | ||||
-rw-r--r-- | src/game/CreatureAISelector.cpp | 2 | ||||
-rw-r--r-- | src/game/InstanceSaveMgr.cpp | 2 | ||||
-rw-r--r-- | src/game/NullCreatureAI.h | 1 | ||||
-rw-r--r-- | src/game/PossessedAI.cpp | 20 | ||||
-rw-r--r-- | src/game/PossessedAI.h | 25 | ||||
-rw-r--r-- | src/game/UnitAI.cpp | 84 | ||||
-rw-r--r-- | src/game/UnitAI.h | 68 |
15 files changed, 378 insertions, 345 deletions
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 4a9f8ec61e8..42ee15074ed 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -375,7 +375,6 @@ bool ScriptedAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered) return true; } - float GetSpellMaxRangeForHostile(uint32 id) { SpellEntry const *spellInfo = GetSpellStore()->LookupEntry(id); diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 44caf063162..8336df545b6 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -8,75 +8,25 @@ #ifndef SC_CREATURE_H #define SC_CREATURE_H -#include "CreatureAI.h" #include "Creature.h" - -#define HEROIC(n,h) (HeroicMode ? h : n) - -template<class T> -inline -const T& RAND(const T& v1, const T& v2) -{ - return rand()%2 ? v1 : v2; -} - -template<class T> -inline -const T& RAND(const T& v1, const T& v2, const T& v3) -{ - switch(rand()%3) - { - default: - case 0: return v1; - case 1: return v2; - case 2: return v3; - } -} - -template<class T> -inline -const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4) -{ - switch(rand()%4) - { - default: - case 0: return v1; - case 1: return v2; - case 2: return v3; - case 3: return v4; - } -} - -template<class T> -inline -const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) -{ - switch(rand()%4) - { - default: - case 0: return v1; - case 1: return v2; - case 2: return v3; - case 3: return v4; - case 4: return v5; - } -} - -float GetSpellMaxRangeForHostile(uint32 id); +#include "CreatureAI.h" +#include "CreatureAIImpl.h" class SummonList : private std::list<uint64> { -public: - explicit SummonList(Creature* creature) : m_creature(creature) {} - void Summon(Creature *summon) { push_back(summon->GetGUID()); } - void Despawn(Creature *summon) { remove(summon->GetGUID()); } - void DespawnEntry(uint32 entry); - void DespawnAll(); - void DoAction(uint32 entry, uint32 info); -private: - Creature *m_creature; + public: + explicit SummonList(Creature* creature) : m_creature(creature) {} + void Summon(Creature *summon) { push_back(summon->GetGUID()); } + void Despawn(Creature *summon) { remove(summon->GetGUID()); } + void DespawnEntry(uint32 entry); + void DespawnAll(); + void DoAction(uint32 entry, uint32 info); + private: + Creature *m_creature; }; +float GetSpellMaxRangeForHostile(uint32 id); + //Get a single creature of given entry Unit* FindCreature(uint32 entry, float range, Unit* Finder); diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt index 081d9669696..89a9e460968 100644 --- a/src/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -68,6 +68,7 @@ SET(game_STAT_SRCS Corpse.h CreatureAI.cpp CreatureAI.h + CreatureAIFactory.h CreatureAIImpl.h CreatureAIRegistry.cpp CreatureAIRegistry.h @@ -208,8 +209,6 @@ SET(game_STAT_SRCS PointMovementGenerator.h PoolHandler.cpp PoolHandler.h - PossessedAI.cpp - PossessedAI.h QueryHandler.cpp QuestDef.cpp QuestDef.h @@ -262,6 +261,8 @@ SET(game_STAT_SRCS Traveller.h Unit.cpp Unit.h + UnitAI.cpp + UnitAI.h UnitEvents.h UpdateData.cpp UpdateData.h diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 0713ef592d3..2390b359731 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -19,50 +19,12 @@ */ #include "CreatureAI.h" +#include "CreatureAIImpl.h" #include "Creature.h" #include "Player.h" #include "Pet.h" -#include "SpellAuras.h" #include "World.h" -void UnitAI::AttackStart(Unit *victim) -{ - if(!victim) - return; - - if(me->Attack(victim, true)) - { - //DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", me->GetName(), victim->GetGUIDLow()); - me->GetMotionMaster()->MoveChase(victim); - } -} - -void UnitAI::DoMeleeAttackIfReady() -{ - //Make sure our attack is ready and we aren't currently casting before checking distance - if (me->isAttackReady() && !me->hasUnitState(UNIT_STAT_CASTING)) - { - //If we are within range melee the target - if (me->IsWithinMeleeRange(me->getVictim())) - { - me->AttackerStateUpdate(me->getVictim()); - me->resetAttackTimer(); - } - } - if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK) && !me->hasUnitState(UNIT_STAT_CASTING)) - { - //If we are within range melee the target - if (me->IsWithinMeleeRange(me->getVictim())) - { - me->AttackerStateUpdate(me->getVictim(), OFF_ATTACK); - me->resetAttackTimer(OFF_ATTACK); - } - } -} - -//Enable PlayerAI when charmed -void PlayerAI::OnCharmed(bool apply) { me->IsAIEnabled = apply; } - //Disable CreatureAI when charmed void CreatureAI::OnCharmed(bool apply) { @@ -295,30 +257,6 @@ void CreatureAI::SelectTargetList(std::list<Unit*> &targetList, uint32 num, Sele } } -void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) -{ - Creature *charmer = (Creature*)me->GetCharmer(); - - //kill self if charm aura has infinite duration - if(charmer->IsInEvadeMode()) - { - Unit::AuraEffectList const& auras = me->GetAurasByType(SPELL_AURA_MOD_CHARM); - for(Unit::AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) - if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetParentAura()->IsPermanent()) - { - charmer->Kill(me); - return; - } - } - - if(!charmer->isInCombat()) - me->GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - - Unit *target = me->getVictim(); - if(!target || !charmer->canAttack(target)) - AttackStart(charmer->SelectNearestTarget()); -} - /*void CreatureAI::AttackedBy( Unit* attacker ) { if(!m_creature->getVictim()) diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index 16271775728..6df7dcfbe95 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -23,9 +23,7 @@ #include "Common.h" #include "Platform/Define.h" -#include "Policies/Singleton.h" -#include "Dynamic/ObjectRegistry.h" -#include "Dynamic/FactoryHolder.h" +#include "UnitAI.h" class WorldObject; class Unit; @@ -77,149 +75,11 @@ enum SCEquip EQUIP_UNEQUIP = 0 }; -enum AITarget -{ - AITARGET_SELF, - AITARGET_VICTIM, - AITARGET_ENEMY, - AITARGET_ALLY, - AITARGET_BUFF, - AITARGET_DEBUFF, -}; - -enum AICondition -{ - AICOND_AGGRO, - AICOND_COMBAT, - AICOND_DIE, -}; - -#define AI_DEFAULT_COOLDOWN 5000 - -struct AISpellInfoType -{ - AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT), cooldown(AI_DEFAULT_COOLDOWN) {} - AITarget target; - AICondition condition; - uint32 cooldown; -}; - -extern AISpellInfoType *AISpellInfo; - -class EventMap : private std::map<uint32, uint32> -{ - private: - uint32 m_time, m_phase; - public: - explicit EventMap() : m_phase(0), m_time(0) {} - - void Reset() { clear(); m_time = 0; m_phase = 0; } - - void Update(uint32 time) { m_time += time; } - - void SetPhase(uint32 phase) - { - if(phase && phase < 9) - m_phase = (1 << (phase + 24)); - } - - void ScheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0) - { - time += m_time; - if(gcd && gcd < 9) - eventId |= (1 << (gcd + 16)); - if(phase && phase < 9) - eventId |= (1 << (phase + 24)); - iterator itr = find(time); - while(itr != end()) - { - ++time; - itr = find(time); - } - insert(std::make_pair(time, eventId)); - } - - uint32 ExecuteEvent() - { - while(!empty()) - { - if(begin()->first > m_time) - return 0; - else if(m_phase && (begin()->second & 0xFF000000) && !(begin()->second & m_phase)) - erase(begin()); - else - { - uint32 eventId = (begin()->second & 0x0000FFFF); - erase(begin()); - return eventId; - } - } - return 0; - } - - void DelayEvents(uint32 time, uint32 gcd) - { - time += m_time; - gcd = (1 << (gcd + 16)); - for(iterator itr = begin(); itr != end();) - { - if(itr->first >= time) - break; - if(itr->second & gcd) - { - ScheduleEvent(time, itr->second); - erase(itr++); - } - else - ++itr; - } - } -}; - -class TRINITY_DLL_SPEC UnitAI -{ - protected: - Unit* const me; - public: - explicit UnitAI(Unit *u) : me(u) {} - virtual void AttackStart(Unit *); - virtual void UpdateAI(const uint32 diff) = 0; - - virtual void InitializeAI() { Reset(); } - - virtual void Reset() {}; - - // Called when unit is charmed - virtual void OnCharmed(bool apply) = 0; - - // Pass parameters between AI - virtual void DoAction(const int32 param) {} - - //Do melee swing of current victim if in rnage and ready and not casting - void DoMeleeAttackIfReady(); -}; - -class TRINITY_DLL_SPEC PlayerAI : public UnitAI -{ - protected: - Player* const me; - public: - explicit PlayerAI(Player *p) : UnitAI((Unit*)p), me(p) {} - - void OnCharmed(bool apply); -}; - -class TRINITY_DLL_SPEC SimpleCharmedAI : public PlayerAI -{ - public: - void UpdateAI(const uint32 diff); -}; - class TRINITY_DLL_SPEC CreatureAI : public UnitAI { protected: - Creature* const me; - Creature* const m_creature; + Creature * const me; + Creature * const m_creature; bool UpdateVictim(); public: @@ -307,22 +167,6 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI void SelectTargetList(std::list<Unit*> &targetList, uint32 num, SelectAggroTarget target, float dist = 0, bool playerOnly = false, int32 aura = 0); }; -struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature> -{ - - SelectableAI(const char *id) : FactoryHolder<CreatureAI>(id) {} -}; - -template<class REAL_AI> -struct CreatureAIFactory : public SelectableAI -{ - CreatureAIFactory(const char *name) : SelectableAI(name) {} - - CreatureAI* Create(void *) const; - - int Permit(const Creature *c) const { return REAL_AI::Permissible(c); } -}; - enum Permitions { PERMIT_BASE_NO = -1, @@ -333,8 +177,4 @@ enum Permitions PERMIT_BASE_SPECIAL = 800 }; -typedef FactoryHolder<CreatureAI> CreatureAICreator; -typedef FactoryHolder<CreatureAI>::FactoryHolderRegistry CreatureAIRegistry; -typedef FactoryHolder<CreatureAI>::FactoryHolderRepository CreatureAIRepository; #endif - diff --git a/src/game/CreatureAIFactory.h b/src/game/CreatureAIFactory.h new file mode 100644 index 00000000000..d546c2b1720 --- /dev/null +++ b/src/game/CreatureAIFactory.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef TRINITY_CREATUREAIFACTORY_H +#define TRINITY_CREATUREAIFACTORY_H + +//#include "Policies/Singleton.h" +#include "Dynamic/ObjectRegistry.h" +#include "Dynamic/FactoryHolder.h" + +struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature> +{ + SelectableAI(const char *id) : FactoryHolder<CreatureAI>(id) {} +}; + +template<class REAL_AI> +struct CreatureAIFactory : public SelectableAI +{ + CreatureAIFactory(const char *name) : SelectableAI(name) {} + + CreatureAI* Create(void *) const; + + int Permit(const Creature *c) const { return REAL_AI::Permissible(c); } +}; + +template<class REAL_AI> +inline CreatureAI* +CreatureAIFactory<REAL_AI>::Create(void *data) const +{ + Creature* creature = reinterpret_cast<Creature *>(data); + return (new REAL_AI(creature)); +} + +typedef FactoryHolder<CreatureAI> CreatureAICreator; +typedef FactoryHolder<CreatureAI>::FactoryHolderRegistry CreatureAIRegistry; +typedef FactoryHolder<CreatureAI>::FactoryHolderRepository CreatureAIRepository; +#endif diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h index a8b8271c5ff..823f4cbcca6 100644 --- a/src/game/CreatureAIImpl.h +++ b/src/game/CreatureAIImpl.h @@ -20,14 +20,155 @@ #ifndef CREATUREAIIMPL_H #define CREATUREAIIMPL_H -#include "CreatureAI.h" +#define HEROIC(n,h) (HeroicMode ? h : n) -template<class REAL_AI> -inline CreatureAI* -CreatureAIFactory<REAL_AI>::Create(void *data) const +template<class T> +inline +const T& RAND(const T& v1, const T& v2) { - Creature* creature = reinterpret_cast<Creature *>(data); - return (new REAL_AI(creature)); + return rand()%2 ? v1 : v2; } + +template<class T> +inline +const T& RAND(const T& v1, const T& v2, const T& v3) +{ + switch(rand()%3) + { + default: + case 0: return v1; + case 1: return v2; + case 2: return v3; + } +} + +template<class T> +inline +const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4) +{ + switch(rand()%4) + { + default: + case 0: return v1; + case 1: return v2; + case 2: return v3; + case 3: return v4; + } +} + +template<class T> +inline +const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) +{ + switch(rand()%4) + { + default: + case 0: return v1; + case 1: return v2; + case 2: return v3; + case 3: return v4; + case 4: return v5; + } +} + +class EventMap : private std::map<uint32, uint32> +{ + private: + uint32 m_time, m_phase; + public: + explicit EventMap() : m_phase(0), m_time(0) {} + + void Reset() { clear(); m_time = 0; m_phase = 0; } + + void Update(uint32 time) { m_time += time; } + + void SetPhase(uint32 phase) + { + if(phase && phase < 9) + m_phase = (1 << (phase + 24)); + } + + void ScheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0) + { + time += m_time; + if(gcd && gcd < 9) + eventId |= (1 << (gcd + 16)); + if(phase && phase < 9) + eventId |= (1 << (phase + 24)); + iterator itr = find(time); + while(itr != end()) + { + ++time; + itr = find(time); + } + insert(std::make_pair(time, eventId)); + } + + uint32 ExecuteEvent() + { + while(!empty()) + { + if(begin()->first > m_time) + return 0; + else if(m_phase && (begin()->second & 0xFF000000) && !(begin()->second & m_phase)) + erase(begin()); + else + { + uint32 eventId = (begin()->second & 0x0000FFFF); + erase(begin()); + return eventId; + } + } + return 0; + } + + void DelayEvents(uint32 time, uint32 gcd) + { + time += m_time; + gcd = (1 << (gcd + 16)); + for(iterator itr = begin(); itr != end();) + { + if(itr->first >= time) + break; + if(itr->second & gcd) + { + ScheduleEvent(time, itr->second); + erase(itr++); + } + else + ++itr; + } + } +}; + +enum AITarget +{ + AITARGET_SELF, + AITARGET_VICTIM, + AITARGET_ENEMY, + AITARGET_ALLY, + AITARGET_BUFF, + AITARGET_DEBUFF, +}; + +enum AICondition +{ + AICOND_AGGRO, + AICOND_COMBAT, + AICOND_DIE, +}; + +#define AI_DEFAULT_COOLDOWN 5000 + +struct AISpellInfoType +{ + AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT), cooldown(AI_DEFAULT_COOLDOWN) {} + AITarget target; + AICondition condition; + uint32 cooldown; +}; + +extern AISpellInfoType *AISpellInfo; + #endif diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp index 6253c06b8bc..36f49d28521 100644 --- a/src/game/CreatureAIRegistry.cpp +++ b/src/game/CreatureAIRegistry.cpp @@ -28,11 +28,12 @@ #include "OutdoorPvPObjectiveAI.h" #include "CreatureEventAI.h" #include "RandomMovementGenerator.h" -#include "CreatureAIImpl.h" #include "MovementGeneratorImpl.h" #include "CreatureAIRegistry.h" #include "WaypointMovementGenerator.h" +#include "CreatureAIFactory.h" +#include "CreatureAIImpl.h" namespace AIRegistry { void Initialize() diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp index a698d094e18..b270de289c7 100644 --- a/src/game/CreatureAISelector.cpp +++ b/src/game/CreatureAISelector.cpp @@ -19,7 +19,6 @@ */ #include "Creature.h" -#include "CreatureAIImpl.h" #include "CreatureAISelector.h" #include "NullCreatureAI.h" #include "Policies/SingletonImp.h" @@ -27,6 +26,7 @@ #include "ScriptCalls.h" #include "Pet.h" #include "TemporarySummon.h" +#include "CreatureAIFactory.h" INSTANTIATE_SINGLETON_1(CreatureAIRegistry); INSTANTIATE_SINGLETON_1(MovementGeneratorRegistry); diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp index 9332f4b8f0a..131d26e90f7 100644 --- a/src/game/InstanceSaveMgr.cpp +++ b/src/game/InstanceSaveMgr.cpp @@ -40,6 +40,8 @@ #include "Group.h" #include "InstanceData.h" #include "ProgressBar.h" +#include "Policies/Singleton.h" +#include "Policies/SingletonImp.h" INSTANTIATE_SINGLETON_1( InstanceSaveManager ); diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h index d5c12d8c9a0..f8a5d8480f0 100644 --- a/src/game/NullCreatureAI.h +++ b/src/game/NullCreatureAI.h @@ -22,6 +22,7 @@ #define TRINITY_NULLCREATUREAI_H #include "CreatureAI.h" +#include "CreatureAIImpl.h" class TRINITY_DLL_DECL PassiveAI : public CreatureAI { diff --git a/src/game/PossessedAI.cpp b/src/game/PossessedAI.cpp deleted file mode 100644 index 8fd2e5ca014..00000000000 --- a/src/game/PossessedAI.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/> - * - * Thanks to the original authors: MaNGOS <http://getmangos.com/> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - diff --git a/src/game/PossessedAI.h b/src/game/PossessedAI.h deleted file mode 100644 index bef7853246e..00000000000 --- a/src/game/PossessedAI.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/> - * - * Thanks to the original authors: MaNGOS <http://getmangos.com/> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef MANGOS_POSSESSEDAI_H -#define MANGOS_POSSESSEDAI_H - - -#endif diff --git a/src/game/UnitAI.cpp b/src/game/UnitAI.cpp new file mode 100644 index 00000000000..4914bd36b7c --- /dev/null +++ b/src/game/UnitAI.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "UnitAI.h" +#include "SpellAuras.h" + +void UnitAI::AttackStart(Unit *victim) +{ + if(!victim) + return; + + if(me->Attack(victim, true)) + { + //DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", me->GetName(), victim->GetGUIDLow()); + me->GetMotionMaster()->MoveChase(victim); + } +} + +void UnitAI::DoMeleeAttackIfReady() +{ + //Make sure our attack is ready and we aren't currently casting before checking distance + if (me->isAttackReady() && !me->hasUnitState(UNIT_STAT_CASTING)) + { + //If we are within range melee the target + if (me->IsWithinMeleeRange(me->getVictim())) + { + me->AttackerStateUpdate(me->getVictim()); + me->resetAttackTimer(); + } + } + if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK) && !me->hasUnitState(UNIT_STAT_CASTING)) + { + //If we are within range melee the target + if (me->IsWithinMeleeRange(me->getVictim())) + { + me->AttackerStateUpdate(me->getVictim(), OFF_ATTACK); + me->resetAttackTimer(OFF_ATTACK); + } + } +} + +//Enable PlayerAI when charmed +void PlayerAI::OnCharmed(bool apply) { me->IsAIEnabled = apply; } + +void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) +{ + Creature *charmer = (Creature*)me->GetCharmer(); + + //kill self if charm aura has infinite duration + if(charmer->IsInEvadeMode()) + { + Unit::AuraEffectList const& auras = me->GetAurasByType(SPELL_AURA_MOD_CHARM); + for(Unit::AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) + if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetParentAura()->IsPermanent()) + { + charmer->Kill(me); + return; + } + } + + if(!charmer->isInCombat()) + me->GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + + Unit *target = me->getVictim(); + if(!target || !charmer->canAttack(target)) + AttackStart(charmer->SelectNearestTarget()); +} diff --git a/src/game/UnitAI.h b/src/game/UnitAI.h new file mode 100644 index 00000000000..04de74f480e --- /dev/null +++ b/src/game/UnitAI.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef TRINITY_UNITAI_H +#define TRINITY_UNITAI_H + +#include "Platform/Define.h" + +class Unit; +class Player; + +class TRINITY_DLL_SPEC UnitAI +{ + protected: + Unit * const me; + public: + explicit UnitAI(Unit *u) : me(u) {} + virtual void AttackStart(Unit *); + virtual void UpdateAI(const uint32 diff) = 0; + + virtual void InitializeAI() { Reset(); } + + virtual void Reset() {}; + + // Called when unit is charmed + virtual void OnCharmed(bool apply) = 0; + + // Pass parameters between AI + virtual void DoAction(const int32 param) {} + + //Do melee swing of current victim if in rnage and ready and not casting + void DoMeleeAttackIfReady(); +}; + +class TRINITY_DLL_SPEC PlayerAI : public UnitAI +{ + protected: + Player* const me; + public: + explicit PlayerAI(Player *p) : UnitAI((Unit*)p), me(p) {} + + void OnCharmed(bool apply); +}; + +class TRINITY_DLL_SPEC SimpleCharmedAI : public PlayerAI +{ + public: + void UpdateAI(const uint32 diff); +}; + +#endif |