*Move some AI functions to core. No real change.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-05-10 16:07:49 -05:00
parent 518ac83fbf
commit dcf41256dd
17 changed files with 775 additions and 725 deletions
+3 -2
View File
@@ -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
+1 -63
View File
@@ -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())
+3 -163
View File
@@ -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
+53
View File
@@ -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
+147 -6
View File
@@ -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
+2 -1
View File
@@ -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()
+1 -1
View File
@@ -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);
+2
View File
@@ -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 );
+1
View File
@@ -22,6 +22,7 @@
#define TRINITY_NULLCREATUREAI_H
#include "CreatureAI.h"
#include "CreatureAIImpl.h"
class TRINITY_DLL_DECL PassiveAI : public CreatureAI
{
-20
View File
@@ -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
*/
-25
View File
@@ -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
+84
View File
@@ -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());
}
+68
View File
@@ -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