aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bindings/scripts/include/sc_creature.cpp24
-rw-r--r--src/bindings/scripts/include/sc_creature.h3
-rw-r--r--src/game/Creature.cpp14
-rw-r--r--src/game/Creature.h4
-rw-r--r--src/game/CreatureAI.cpp25
-rw-r--r--src/game/CreatureAI.h3
-rw-r--r--src/game/NullCreatureAI.cpp25
-rw-r--r--src/game/NullCreatureAI.h12
-rw-r--r--src/game/PetAI.cpp97
-rw-r--r--src/game/PetAI.h2
-rw-r--r--src/game/PetHandler.cpp4
-rw-r--r--src/game/PossessedAI.cpp102
-rw-r--r--src/game/PossessedAI.h28
-rw-r--r--src/game/Unit.cpp31
-rw-r--r--src/game/Unit.h3
15 files changed, 118 insertions, 259 deletions
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp
index 47bc01f183c..be37c66c740 100644
--- a/src/bindings/scripts/include/sc_creature.cpp
+++ b/src/bindings/scripts/include/sc_creature.cpp
@@ -169,30 +169,6 @@ void ScriptedAI::DoStartNoMovement(Unit* victim)
m_creature->StopMoving();
}
-
-void ScriptedAI::DoMeleeAttackIfReady()
-{
- //Make sure our attack is ready and we aren't currently casting before checking distance
- if (m_creature->isAttackReady() && !m_creature->hasUnitState(UNIT_STAT_CASTING))
- {
- //If we are within range melee the target
- if (m_creature->IsWithinMeleeRange(m_creature->getVictim()))
- {
- m_creature->AttackerStateUpdate(m_creature->getVictim());
- m_creature->resetAttackTimer();
- }
- }
- if (m_creature->haveOffhandWeapon() && m_creature->isAttackReady(OFF_ATTACK) && !m_creature->hasUnitState(UNIT_STAT_CASTING))
- {
- //If we are within range melee the target
- if (m_creature->IsWithinMeleeRange(m_creature->getVictim()))
- {
- m_creature->AttackerStateUpdate(m_creature->getVictim(), OFF_ATTACK);
- m_creature->resetAttackTimer(OFF_ATTACK);
- }
- }
-}
-
void ScriptedAI::DoStopAttack()
{
if (m_creature->getVictim() != NULL)
diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h
index f9eb8c716d5..5e0e185a9dd 100644
--- a/src/bindings/scripts/include/sc_creature.h
+++ b/src/bindings/scripts/include/sc_creature.h
@@ -113,9 +113,6 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI
//Start no movement on victim
void DoStartNoMovement(Unit* victim);
- //Do melee swing of current victim if in rnage and ready and not casting
- void DoMeleeAttackIfReady();
-
//Stop attack of current victim
void DoStopAttack();
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 00e826404e6..ed2f3f2ee54 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -46,7 +46,6 @@
#include "CellImpl.h"
#include "OutdoorPvPMgr.h"
#include "GameEvent.h"
-#include "PossessedAI.h"
#include "CreatureGroups.h"
// apply implementation of the singletons
#include "Policies/SingletonImp.h"
@@ -141,7 +140,7 @@ bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
}
Creature::Creature() :
-Unit(), i_AI(NULL),
+Unit(),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
m_lootMoney(0), m_lootRecipient(0),
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),
@@ -424,7 +423,7 @@ void Creature::Update(uint32 diff)
setDeathState( JUST_ALIVED );
//Call AI respawn virtual function
- i_AI->JustRespawned();
+ AI()->JustRespawned();
GetMap()->Add(this);
}
@@ -484,6 +483,9 @@ void Creature::Update(uint32 diff)
if(!isAlive())
break;
+ // if creature is charmed, switch to charmed AI
+ UpdateCharmAI();
+
if(!IsInEvadeMode() && IsAIEnabled)
{
// do not allow the AI to be changed during update
@@ -596,11 +598,9 @@ bool Creature::AIM_Initialize(CreatureAI* ai)
return false;
}
- CreatureAI * oldAI = i_AI;
- i_motionMaster.Initialize();
+ if(i_AI) delete i_AI;
i_AI = ai ? ai : FactorySelector::selectAI(this);
- if (oldAI)
- delete oldAI;
+ i_motionMaster.Initialize();
IsAIEnabled = true;
return true;
}
diff --git a/src/game/Creature.h b/src/game/Creature.h
index fc5318c1cdb..b477ea00f1d 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -401,8 +401,6 @@ typedef std::map<uint32,time_t> CreatureSpellCooldowns;
class TRINITY_DLL_SPEC Creature : public Unit
{
- CreatureAI *i_AI;
-
public:
explicit Creature();
@@ -468,7 +466,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool AIM_Initialize(CreatureAI* ai = NULL);
void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type);
- CreatureAI* AI() { return i_AI; }
+ CreatureAI* AI() { return (CreatureAI*)i_AI; }
uint32 GetShieldBlockValue() const //dunno mob block value
{
diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
index fa512fce726..2d7eeeb18ff 100644
--- a/src/game/CreatureAI.cpp
+++ b/src/game/CreatureAI.cpp
@@ -36,11 +36,34 @@ void UnitAI::AttackStart(Unit *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) { me->IsAIEnabled = !apply; }
+void CreatureAI::OnCharmed(bool apply) { /*me->IsAIEnabled = !apply;*/ }
void CreatureAI::MoveInLineOfSight(Unit *who)
{
diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h
index fbfb8605866..1cfeb6555f2 100644
--- a/src/game/CreatureAI.h
+++ b/src/game/CreatureAI.h
@@ -81,6 +81,9 @@ class TRINITY_DLL_SPEC UnitAI
// Called when unit is charmed
virtual void OnCharmed(bool apply) = 0;
+
+ //Do melee swing of current victim if in rnage and ready and not casting
+ void DoMeleeAttackIfReady();
};
class TRINITY_DLL_SPEC PlayerAI : public UnitAI
diff --git a/src/game/NullCreatureAI.cpp b/src/game/NullCreatureAI.cpp
index 0814e348a80..1bb787b25c3 100644
--- a/src/game/NullCreatureAI.cpp
+++ b/src/game/NullCreatureAI.cpp
@@ -27,6 +27,30 @@ void PassiveAI::UpdateAI(const uint32)
EnterEvadeMode();
}
+void PossessedAI::UpdateAI(const uint32 diff)
+{
+ if(me->getVictim())
+ {
+ if(!me->canAttack(me->getVictim()))
+ me->AttackStop();
+ else
+ DoMeleeAttackIfReady();
+ }
+}
+
+void PossessedAI::JustDied(Unit *u)
+{
+ // We died while possessed, disable our loot
+ me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+}
+
+void PossessedAI::KilledUnit(Unit* victim)
+{
+ // We killed a creature, disable victim's loot
+ if (victim->GetTypeId() == TYPEID_UNIT)
+ victim->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+}
+
void CritterAI::DamageTaken(Unit *done_by, uint32 &)
{
if(!me->hasUnitState(UNIT_STAT_FLEEING))
@@ -39,4 +63,3 @@ void CritterAI::EnterEvadeMode()
me->SetControlled(false, UNIT_STAT_FLEEING);
CreatureAI::EnterEvadeMode();
}
-
diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h
index 3c9c35cdc9d..b64bf43ce5f 100644
--- a/src/game/NullCreatureAI.h
+++ b/src/game/NullCreatureAI.h
@@ -36,6 +36,18 @@ class TRINITY_DLL_DECL PassiveAI : public CreatureAI
static int Permissible(const Creature *) { return PERMIT_BASE_IDLE; }
};
+class TRINITY_DLL_DECL PossessedAI : public PassiveAI
+{
+ public:
+ PossessedAI(Creature *c) : PassiveAI(c) {}
+
+ void UpdateAI(const uint32);
+ void EnterEvadeMode() {}
+
+ void JustDied(Unit*);
+ void KilledUnit(Unit* victim);
+};
+
class TRINITY_DLL_DECL NullCreatureAI : public PassiveAI
{
public:
diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp
index cf639f84db5..72c8c1e760b 100644
--- a/src/game/PetAI.cpp
+++ b/src/game/PetAI.cpp
@@ -44,44 +44,6 @@ PetAI::PetAI(Creature *c) : CreatureAI(c), i_pet(*c), i_tracker(TIME_INTERVAL_LO
UpdateAllies();
}
-void PetAI::MoveInLineOfSight(Unit *u)
-{
- if( !i_pet.getVictim() && i_pet.GetCharmInfo() &&
- i_pet.IsHostileTo( u ) && i_pet.canAttack(u) &&
- u->isInAccessiblePlaceFor(&i_pet))
- {
- float attackRadius = i_pet.GetAttackDistance(u);
- if(i_pet.IsWithinDistInMap(u, attackRadius) && i_pet.GetDistanceZ(u) <= CREATURE_Z_ATTACK_RANGE)
- {
- if(i_pet.IsWithinLOSInMap(u))
- {
- AttackStart(u);
- //u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
- }
- }
- }
-}
-
-void PetAI::AttackStart(Unit *u)
-{
- if( !u || (i_pet.isPet() && ((Pet&)i_pet).getPetType() == MINI_PET) )
- return;
-
- if (inCombat && i_pet.getVictim() && u != i_pet.getVictim())
- i_pet.AttackStop();
-
- if(i_pet.Attack(u,true))
- {
- i_pet.clearUnitState(UNIT_STAT_FOLLOW);
- // TMGs call CreatureRelocation which via MoveInLineOfSight can call this function
- // thus with the following clear the original TMG gets invalidated and crash, doh
- // hope it doesn't start to leak memory without this :-/
- //i_pet->Clear();
- i_pet.GetMotionMaster()->MoveChase(u);
- inCombat = true;
- }
-}
-
void PetAI::EnterEvadeMode()
{
}
@@ -138,11 +100,8 @@ void PetAI::UpdateAI(const uint32 diff)
else
m_updateAlliesTimer -= diff;
- if (inCombat && i_pet.getVictim() == NULL)
- _stopAttack();
-
// i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
- if( i_pet.getVictim() != NULL )
+ if( i_pet.getVictim() )
{
if( _needToStop() )
{
@@ -150,50 +109,23 @@ void PetAI::UpdateAI(const uint32 diff)
_stopAttack();
return;
}
- else if( i_pet.IsStopped() || i_pet.IsWithinMeleeRange(i_pet.getVictim()))
- {
- // required to be stopped cases
- if ( i_pet.IsStopped() && i_pet.IsNonMeleeSpellCasted(false) )
- {
- if( i_pet.hasUnitState(UNIT_STAT_FOLLOW) )
- i_pet.InterruptNonMeleeSpells(false);
- else
- return;
- }
- // not required to be stopped case
- else if( i_pet.isAttackReady() && i_pet.IsWithinMeleeRange(i_pet.getVictim()) )
- {
- i_pet.AttackerStateUpdate(i_pet.getVictim());
- i_pet.resetAttackTimer();
-
- if ( !i_pet.getVictim() )
- return;
-
- //if pet misses its target, it will also be the first in threat list
- i_pet.getVictim()->AddThreat(&i_pet,0.0f);
-
- if( _needToStop() )
- _stopAttack();
- }
- }
+ DoMeleeAttackIfReady();
}
- else if(owner && i_pet.GetCharmInfo())
+ else
{
- if(owner->isInCombat() && !(i_pet.HasReactState(REACT_PASSIVE) || i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY)))
+ if(me->isInCombat())
+ _stopAttack();
+ else if(owner && i_pet.GetCharmInfo()) //no victim
{
- AttackStart(owner->getAttackerForHelper());
- }
- else if(i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
- {
- if (!i_pet.hasUnitState(UNIT_STAT_FOLLOW) )
- {
+ if(owner->isInCombat() && !(i_pet.HasReactState(REACT_PASSIVE) || i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY)))
+ AttackStart(owner->getAttackerForHelper());
+ else if(i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW) && !i_pet.hasUnitState(UNIT_STAT_FOLLOW))
i_pet.GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
- }
}
}
- if (i_pet.GetGlobalCooldown() == 0 && !i_pet.IsNonMeleeSpellCasted(false))
+ if (i_pet.GetGlobalCooldown() == 0 && !i_pet.hasUnitState(UNIT_STAT_CASTING))
{
//Autocast
for (uint8 i = 0; i < i_pet.GetPetAutoSpellSize(); i++)
@@ -323,12 +255,3 @@ void PetAI::UpdateAllies()
else //remove group
m_AllySet.insert(owner->GetGUID());
}
-
-/*void PetAI::AttackedBy(Unit *attacker)
-{
- //when attacked, fight back in case 1)no victim already AND 2)not set to passive AND 3)not set to stay, unless can it can reach attacker with melee attack anyway
- if(!i_pet.getVictim() && i_pet.GetCharmInfo() && !i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE) &&
- (!i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY) || i_pet.IsWithinMeleeRange(attacker)))
- AttackStart(attacker);
-}*/
-
diff --git a/src/game/PetAI.h b/src/game/PetAI.h
index 017627d73f0..eebd1e27a67 100644
--- a/src/game/PetAI.h
+++ b/src/game/PetAI.h
@@ -33,8 +33,6 @@ class TRINITY_DLL_DECL PetAI : public CreatureAI
PetAI(Creature *c);
- void MoveInLineOfSight(Unit *);
- void AttackStart(Unit *);
void EnterEvadeMode();
void JustDied(Unit* who) { _stopAttack(); }
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
index b87193b7e9f..49a3bb95cb7 100644
--- a/src/game/PetHandler.cpp
+++ b/src/game/PetHandler.cpp
@@ -85,13 +85,15 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
switch(spellid)
{
case COMMAND_STAY: //flat=1792 //STAY
+ pet->AttackStop();
+ pet->InterruptNonMeleeSpells(false);
pet->StopMoving();
- pet->GetMotionMaster()->Clear();
pet->GetMotionMaster()->MoveIdle();
charmInfo->SetCommandState( COMMAND_STAY );
break;
case COMMAND_FOLLOW: //spellid=1792 //FOLLOW
pet->AttackStop();
+ pet->InterruptNonMeleeSpells(false);
pet->GetMotionMaster()->MoveFollow(_player,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
charmInfo->SetCommandState( COMMAND_FOLLOW );
break;
diff --git a/src/game/PossessedAI.cpp b/src/game/PossessedAI.cpp
index 23ac5fae43e..bda0de88882 100644
--- a/src/game/PossessedAI.cpp
+++ b/src/game/PossessedAI.cpp
@@ -18,105 +18,3 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "PossessedAI.h"
-#include "Creature.h"
-#include "World.h"
-
-void PossessedAI::AttackStart(Unit *u)
-{
- if( !u || i_pet.GetCharmer()->HasAuraType(SPELL_AURA_MOD_PACIFY))
- return;
-
- if (i_pet.getVictim() && u != i_pet.getVictim())
- i_pet.AttackStop();
-
- if(i_pet.Attack(u, true))
- i_victimGuid = u->GetGUID();
-
- // Do not autochase our target, and also make sure our current movement generator
- // is removed since the motion master is reset before this function is called
- i_pet.GetMotionMaster()->Clear(false);
- i_pet.GetMotionMaster()->MoveIdle();
-}
-
-bool PossessedAI::_needToStop() const
-{
- if(!i_pet.getVictim() || !i_pet.isAlive())
- return true;
-
- // This is needed for charmed creatures, as once their target was reset other effects can trigger threat
- if(i_pet.getVictim() == i_pet.GetCharmer())
- return true;
-
- return !i_pet.canAttack(i_pet.getVictim());
-}
-
-void PossessedAI::_stopAttack()
-{
- if( !i_victimGuid )
- return;
-
- Unit* victim = Unit::GetUnit(i_pet, i_victimGuid );
-
- if ( !victim )
- return;
-
- assert(!i_pet.getVictim() || i_pet.getVictim() == victim);
-
- if( !i_pet.isAlive() )
- {
- i_pet.StopMoving();
- i_pet.GetMotionMaster()->Clear(false);
- i_pet.GetMotionMaster()->MoveIdle();
- i_victimGuid = 0;
- i_pet.CombatStop();
- i_pet.getHostilRefManager().deleteReferences();
-
- return;
- }
-
- i_pet.GetMotionMaster()->Clear(false);
- i_pet.GetMotionMaster()->MoveIdle();
- i_victimGuid = 0;
- i_pet.AttackStop();
-}
-
-void PossessedAI::UpdateAI(const uint32 diff)
-{
- // update i_victimGuid if i_pet.getVictim() !=0 and changed
- if(i_pet.getVictim())
- i_victimGuid = i_pet.getVictim()->GetGUID();
-
- // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
- if( i_victimGuid )
- {
- if( _needToStop() )
- {
- _stopAttack(); // i_victimGuid == 0 && i_pet.getVictim() == NULL now
- return;
- }
- else if(i_pet.IsWithinMeleeRange(i_pet.getVictim()) && i_pet.isAttackReady() && !i_pet.GetCharmer()->HasAuraType(SPELL_AURA_MOD_PACIFY))
- {
- i_pet.AttackerStateUpdate(i_pet.getVictim());
-
- i_pet.resetAttackTimer();
-
- if( _needToStop() )
- _stopAttack();
- }
- }
-}
-
-void PossessedAI::JustDied(Unit *u)
-{
- // We died while possessed, disable our loot
- i_pet.RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
-}
-
-void PossessedAI::KilledUnit(Unit* victim)
-{
- // We killed a creature, disable victim's loot
- if (victim->GetTypeId() == TYPEID_UNIT)
- victim->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
-}
-
diff --git a/src/game/PossessedAI.h b/src/game/PossessedAI.h
index c9ad643eea1..bbfacb6454c 100644
--- a/src/game/PossessedAI.h
+++ b/src/game/PossessedAI.h
@@ -21,33 +21,5 @@
#ifndef MANGOS_POSSESSEDAI_H
#define MANGOS_POSSESSEDAI_H
-#include "CreatureAI.h"
-class Creature;
-
-class TRINITY_DLL_DECL PossessedAI : public CreatureAI
-{
- public:
- PossessedAI(Creature *c) : CreatureAI(c), i_pet(*c), i_victimGuid(0) {}
-
- // Possessed creatures shouldn't aggro by themselves
- void MoveInLineOfSight(Unit *) {}
- void AttackStart(Unit *);
- void EnterEvadeMode() {}
- void JustDied(Unit*);
- void KilledUnit(Unit* victim);
-
- void UpdateAI(const uint32);
- // Never permit this to be used, it must always be initialized with Creature::InitPossessedAI()
- static int Permissible(const Creature *) { return PERMIT_BASE_NO; }
-
- private:
- bool _isVisible(Unit *) const;
- bool _needToStop(void) const;
- void _stopAttack(void);
-
- Creature &i_pet;
- uint64 i_victimGuid;
-};
#endif
-
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index d7b3305c55d..e3e11c2e840 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -47,6 +47,8 @@
#include "CellImpl.h"
#include "Path.h"
#include "CreatureGroups.h"
+#include "PetAI.h"
+#include "NullCreatureAI.h"
#include <math.h>
@@ -150,6 +152,7 @@ bool IsPassiveStackableSpell( uint32 spellId )
Unit::Unit()
: WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostilRefManager(this)
, m_IsInNotifyList(false), m_Notified(false), IsAIEnabled(false)
+, i_AI(NULL), i_disabledAI(NULL)
{
m_objectType |= TYPEMASK_UNIT;
m_objectTypeId = TYPEID_UNIT;
@@ -11250,10 +11253,38 @@ void Unit::CleanupsBeforeDelete()
RemoveFromWorld();
}
+void Unit::UpdateCharmAI()
+{
+ if(GetTypeId() == TYPEID_PLAYER)
+ return;
+
+ if(i_disabledAI) // disabled AI must be primary AI
+ {
+ if(!isCharmed())
+ {
+ if(i_AI) delete i_AI;
+ i_AI = i_disabledAI;
+ i_disabledAI = NULL;
+ }
+ }
+ else
+ {
+ if(isCharmed())
+ {
+ i_disabledAI = i_AI;
+ if(isPossessed())
+ i_AI = new PossessedAI((Creature*)this);
+ else
+ i_AI = new PetAI((Creature*)this);
+ }
+ }
+}
+
CharmInfo* Unit::InitCharmInfo()
{
if(!m_charmInfo)
m_charmInfo = new CharmInfo(this);
+
return m_charmInfo;
}
diff --git a/src/game/Unit.h b/src/game/Unit.h
index d103525208c..f73a5386aef 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1109,6 +1109,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
CharmInfo* GetCharmInfo() { return m_charmInfo; }
CharmInfo* InitCharmInfo();
void DeleteCharmInfo();
+ void UpdateCharmAI();
SharedVisionList const& GetSharedVisionList() { return m_sharedVision; }
void AddPlayerToVision(Player* plr);
void RemovePlayerFromVision(Player* plr);
@@ -1424,6 +1425,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
protected:
explicit Unit ();
+ UnitAI *i_AI, *i_disabledAI;
+
void _UpdateSpells(uint32 time);
void _UpdateAutoRepeatSpell();