Updated Copyright year to 2013
[getmangos.git] / src / game / CreatureAI.cpp
blob58e07f33a15fbdeb2290fed3a552e1357caeb868
1 /*
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 #include "CreatureAI.h"
20 #include "Creature.h"
21 #include "DBCStores.h"
22 #include "Spell.h"
24 CreatureAI::~CreatureAI()
28 void CreatureAI::AttackedBy(Unit* attacker)
30 if (!m_creature->getVictim())
31 AttackStart(attacker);
34 CanCastResult CreatureAI::CanCastSpell(Unit* pTarget, const SpellEntry* pSpell, bool isTriggered)
36 // If not triggered, we check
37 if (!isTriggered)
39 // State does not allow
40 if (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL))
41 return CAST_FAIL_STATE;
43 if (pSpell->GetPreventionType() == SPELL_PREVENTION_TYPE_SILENCE && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
44 return CAST_FAIL_STATE;
46 if (pSpell->GetPreventionType() == SPELL_PREVENTION_TYPE_PACIFY && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
47 return CAST_FAIL_STATE;
49 // Check for power (also done by Spell::CheckCast())
50 if (m_creature->GetPower((Powers)pSpell->powerType) < Spell::CalculatePowerCost(pSpell, m_creature))
51 return CAST_FAIL_POWER;
54 if (const SpellRangeEntry* pSpellRange = sSpellRangeStore.LookupEntry(pSpell->rangeIndex))
56 if (pTarget != m_creature)
58 // pTarget is out of range of this spell (also done by Spell::CheckCast())
59 float fDistance = m_creature->GetCombatDistance(pTarget);
61 if (fDistance > (m_creature->IsHostileTo(pTarget) ? pSpellRange->maxRange : pSpellRange->maxRangeFriendly))
62 return CAST_FAIL_TOO_FAR;
64 float fMinRange = m_creature->IsHostileTo(pTarget) ? pSpellRange->minRange : pSpellRange->minRangeFriendly;
66 if (fMinRange && fDistance < fMinRange)
67 return CAST_FAIL_TOO_CLOSE;
70 return CAST_OK;
72 else
73 return CAST_FAIL_OTHER;
76 CanCastResult CreatureAI::DoCastSpellIfCan(Unit* pTarget, uint32 uiSpell, uint32 uiCastFlags, ObjectGuid uiOriginalCasterGUID)
78 Unit* pCaster = m_creature;
80 if (uiCastFlags & CAST_FORCE_TARGET_SELF)
81 pCaster = pTarget;
83 // Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered
84 if (!pCaster->IsNonMeleeSpellCasted(false) || (uiCastFlags & (CAST_TRIGGERED | CAST_INTERRUPT_PREVIOUS)))
86 if (const SpellEntry* pSpell = sSpellStore.LookupEntry(uiSpell))
88 // If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them
89 if (uiCastFlags & CAST_AURA_NOT_PRESENT)
91 if (pTarget->HasAura(uiSpell))
92 return CAST_FAIL_TARGET_AURA;
95 // Check if cannot cast spell
96 if (!(uiCastFlags & (CAST_FORCE_TARGET_SELF | CAST_FORCE_CAST)))
98 CanCastResult castResult = CanCastSpell(pTarget, pSpell, uiCastFlags & CAST_TRIGGERED);
100 if (castResult != CAST_OK)
101 return castResult;
104 // Interrupt any previous spell
105 if (uiCastFlags & CAST_INTERRUPT_PREVIOUS && pCaster->IsNonMeleeSpellCasted(false))
106 pCaster->InterruptNonMeleeSpells(false);
108 pCaster->CastSpell(pTarget, pSpell, uiCastFlags & CAST_TRIGGERED, NULL, NULL, uiOriginalCasterGUID);
109 return CAST_OK;
111 else
113 sLog.outErrorDb("DoCastSpellIfCan by creature entry %u attempt to cast spell %u but spell does not exist.", m_creature->GetEntry(), uiSpell);
114 return CAST_FAIL_OTHER;
117 else
118 return CAST_FAIL_IS_CASTING;
121 bool CreatureAI::DoMeleeAttackIfReady()
123 return m_creature->UpdateMeleeAttackingState();