2 * Copyright (C) 2005-2013 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #ifndef MANGOS_CREATUREAI_H
20 #define MANGOS_CREATUREAI_H
23 #include "Platform/Define.h"
24 #include "Policies/Singleton.h"
25 #include "Dynamic/ObjectRegistry.h"
26 #include "Dynamic/FactoryHolder.h"
27 #include "ObjectGuid.h"
37 #define TIME_INTERVAL_LOOK 5000
38 #define VISIBILITY_RANGE 10000
43 CAST_FAIL_IS_CASTING
= 1,
45 CAST_FAIL_TOO_FAR
= 3,
46 CAST_FAIL_TOO_CLOSE
= 4,
49 CAST_FAIL_TARGET_AURA
= 7
54 CAST_INTERRUPT_PREVIOUS
= 0x01, // Interrupt any spell casting
55 CAST_TRIGGERED
= 0x02, // Triggered (this makes spell cost zero mana and have no cast time)
56 CAST_FORCE_CAST
= 0x04, // Forces cast even if creature is out of mana or out of range
57 CAST_NO_MELEE_IF_OOM
= 0x08, // Prevents creature from entering melee if out of mana or out of range
58 CAST_FORCE_TARGET_SELF
= 0x10, // Forces the target to cast this spell on itself
59 CAST_AURA_NOT_PRESENT
= 0x20, // Only casts the spell if the target does not have an aura from the spell
62 class MANGOS_DLL_SPEC CreatureAI
65 explicit CreatureAI(Creature
* creature
) : m_creature(creature
) {}
67 virtual ~CreatureAI();
69 ///== Information about AI ========================
71 * This funcion is used to display information about the AI.
72 * It is called when the .npc aiinfo command is used.
73 * Use this for on-the-fly debugging
74 * @param reader is a ChatHandler to send messages to.
76 virtual void GetAIInformation(ChatHandler
& /*reader*/) {}
78 ///== Reactions At =================================
81 * Called if IsVisible(Unit* pWho) is true at each (relative) override pWho move, reaction at visibility zone enter
82 * Note: The Unit* pWho can be out of Line of Sight, usually this is only visibiliy (by state) and range dependendend
83 * Note: This function is not called for creatures who are in evade mode
84 * @param pWho Unit* who moved in the visibility range and is visisble
86 virtual void MoveInLineOfSight(Unit
* /*pWho*/) {}
89 * Called for reaction at enter to combat if not in combat yet
90 * @param pEnemy Unit* of whom the Creature enters combat with, can be NULL
92 virtual void EnterCombat(Unit
* /*pEnemy*/) {}
95 * Called for reaction at stopping attack at no attackers or targets
96 * This is called usually in Unit::SelectHostileTarget, if no more target exists
98 virtual void EnterEvadeMode() {}
101 * Called at reaching home after MoveTargetedHome
103 virtual void JustReachedHome() {}
105 // Called at any heal cast/item used (call non implemented)
106 // virtual void HealBy(Unit * /*healer*/, uint32 /*amount_healed*/) {}
109 * Called at any Damage to any victim (before damage apply)
110 * @param pDoneTo Unit* to whom Damage of amount uiDamage will be dealt
111 * @param uiDamage Amount of Damage that will be dealt, can be changed here
113 virtual void DamageDeal(Unit
* /*pDoneTo*/, uint32
& /*uiDamage*/) {}
116 * Called at any Damage from any attacker (before damage apply)
117 * Note: Use for recalculation damage or special reaction at damage
118 * for attack reaction use AttackedBy called for not DOT damage in Unit::DealDamage also
119 * @param pDealer Unit* who will deal Damage to the creature
120 * @param uiDamage Amount of Damage that will be dealt, can be changed here
122 virtual void DamageTaken(Unit
* /*pDealer*/, uint32
& /*uiDamage*/) {}
125 * Called when the creature is killed
126 * @param pKiller Unit* who killed the creature
128 virtual void JustDied(Unit
* /*pKiller*/) {}
131 * Called when the corpse of this creature gets removed
132 * @param uiRespawnDelay Delay (in seconds). If != 0, then this is the time after which the creature will respawn, if = 0 the default respawn-delay will be used
134 virtual void CorpseRemoved(uint32
& /*uiRespawnDelay*/) {}
137 * Called when a summoned creature is killed
138 * @param pSummoned Summoned Creature* that got killed
140 virtual void SummonedCreatureJustDied(Creature
* /*pSummoned*/) {}
143 * Called when the creature kills a unit
144 * @param pVictim Victim that got killed
146 virtual void KilledUnit(Unit
* /*pVictim*/) {}
149 * Called when owner of m_creature (if m_creature is PROTECTOR_PET) kills a unit
150 * @param pVictim Victim that got killed (by owner of creature)
152 virtual void OwnerKilledUnit(Unit
* /*pVictim*/) {}
155 * Called when the creature summon successfully other creature
156 * @param pSummoned Creature that got summoned
158 virtual void JustSummoned(Creature
* /*pSummoned*/) {}
161 * Called when the creature summon successfully a gameobject
162 * @param pGo GameObject that was summoned
164 virtual void JustSummoned(GameObject
* /*pGo*/) {}
167 * Called when a summoned creature gets TemporarySummon::UnSummon ed
168 * @param pSummoned Summoned creature that despawned
170 virtual void SummonedCreatureDespawn(Creature
* /*pSummoned*/) {}
173 * Called when hit by a spell
174 * @param pCaster Caster who casted the spell
175 * @param pSpell The spell that hit the creature
177 virtual void SpellHit(Unit
* /*pCaster*/, const SpellEntry
* /*pSpell*/) {}
180 * Called when spell hits creature's target
181 * @param pTarget Target that we hit with the spell
182 * @param pSpell Spell with which we hit pTarget
184 virtual void SpellHitTarget(Unit
* /*pTarget*/, const SpellEntry
* /*pSpell*/) {}
187 * Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc)
188 * @param pAttacker Unit* who attacked the creature
190 virtual void AttackedBy(Unit
* pAttacker
);
193 * Called when creature is respawned (for reseting variables)
195 virtual void JustRespawned() {}
198 * Called at waypoint reached or point movement finished
199 * @param uiMovementType Type of the movement (enum MovementGeneratorType)
200 * @param uiData Data related to the finished movement (ie point-id)
202 virtual void MovementInform(uint32
/*uiMovementType*/, uint32
/*uiData*/) {}
205 * Called if a temporary summoned of m_creature reach a move point
206 * @param pSummoned Summoned Creature that finished some movement
207 * @param uiMotionType Type of the movement (enum MovementGeneratorType)
208 * @param uiData Data related to the finished movement (ie point-id)
210 virtual void SummonedMovementInform(Creature
* /*pSummoned*/, uint32
/*uiMotionType*/, uint32
/*uiData*/) {}
213 * Called at text emote receive from player
214 * @param pPlayer Player* who sent the emote
215 * @param uiEmote ID of the emote the player used with the creature as target
217 virtual void ReceiveEmote(Player
* /*pPlayer*/, uint32
/*uiEmote*/) {}
219 ///== Triggered Actions Requested ==================
222 * Called when creature attack expected (if creature can and no have current victim)
223 * Note: for reaction at hostile action must be called AttackedBy function.
224 * Note: Usually called by MoveInLineOfSight, in Unit::SelectHostileTarget or when the AI is forced to attack an enemy
225 * @param pWho Unit* who is possible target
227 virtual void AttackStart(Unit
* /*pWho*/) {}
230 * Called at World update tick, by default every 100ms
231 * This setting is dependend on CONFIG_UINT32_INTERVAL_MAPUPDATE
232 * Note: Use this function to handle Timers, Threat-Management and MeleeAttacking
233 * @param uiDiff Passed time since last call
235 virtual void UpdateAI(const uint32
/*uiDiff*/) {}
237 ///== State checks =================================
240 * Check if unit is visible for MoveInLineOfSight
241 * Note: This check is by default only the state-depending (visibility, range), NOT LineOfSight
242 * @param pWho Unit* who is checked if it is visisble for the creature
244 virtual bool IsVisible(Unit
* /*pWho*/) const { return false; }
246 // Called when victim entered water and creature can not enter water
247 // TODO: rather unused
248 virtual bool canReachByRangeAttack(Unit
*) { return false; }
250 ///== Helper functions =============================
252 /// This function is used to do the actual melee damage (if possible)
253 bool DoMeleeAttackIfReady();
255 /// Internal helper function, to check if a spell can be cast
256 CanCastResult
CanCastSpell(Unit
* pTarget
, const SpellEntry
* pSpell
, bool isTriggered
);
259 * Function to cast a spell if possible
260 * @param pTarget Unit* onto whom the spell should be cast
261 * @param uiSpell ID of the spell that the creature will try to cast
262 * @param uiCastFlags Some flags to define how to cast, see enum CastFlags
263 * @param OriginalCasterGuid the original caster of the spell if required, empty by default
265 CanCastResult
DoCastSpellIfCan(Unit
* pTarget
, uint32 uiSpell
, uint32 uiCastFlags
= 0, ObjectGuid OriginalCasterGuid
= ObjectGuid());
267 ///== Fields =======================================
269 /// Pointer to the Creature controlled by this AI
270 Creature
* const m_creature
;
273 struct SelectableAI
: public FactoryHolder
<CreatureAI
>, public Permissible
<Creature
>
275 SelectableAI(const char* id
) : FactoryHolder
<CreatureAI
>(id
) {}
278 template<class REAL_AI
>
279 struct CreatureAIFactory
: public SelectableAI
281 CreatureAIFactory(const char* name
) : SelectableAI(name
) {}
283 CreatureAI
* Create(void*) const override
;
285 int Permit(const Creature
* c
) const { return REAL_AI::Permissible(c
); }
291 PERMIT_BASE_IDLE
= 1,
292 PERMIT_BASE_REACTIVE
= 100,
293 PERMIT_BASE_PROACTIVE
= 200,
294 PERMIT_BASE_FACTION_SPECIFIC
= 400,
295 PERMIT_BASE_SPECIAL
= 800
298 typedef FactoryHolder
<CreatureAI
> CreatureAICreator
;
299 typedef FactoryHolder
<CreatureAI
>::FactoryHolderRegistry CreatureAIRegistry
;
300 typedef FactoryHolder
<CreatureAI
>::FactoryHolderRepository CreatureAIRepository
;