refactor(Core/AI): factory functions cleanup (#11779)
This commit is contained in:
committed by
GitHub
parent
02fa20b638
commit
cc52712ac1
@@ -19,33 +19,29 @@
|
|||||||
#define ACORE_FACTORY_HOLDER
|
#define ACORE_FACTORY_HOLDER
|
||||||
|
|
||||||
#include "Define.h"
|
#include "Define.h"
|
||||||
#include "Dynamic/TypeList.h"
|
|
||||||
#include "ObjectRegistry.h"
|
#include "ObjectRegistry.h"
|
||||||
|
#include "TypeList.h"
|
||||||
|
|
||||||
/*
|
/** FactoryHolder holds a factory object of a specific type
|
||||||
* FactoryHolder holds a factory object of a specific type
|
|
||||||
*/
|
*/
|
||||||
template<class T, class Key = std::string>
|
template<class T, class O, class Key = std::string>
|
||||||
class FactoryHolder
|
class FactoryHolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef ObjectRegistry<FactoryHolder<T, Key >, Key > FactoryHolderRegistry;
|
typedef ObjectRegistry<FactoryHolder<T, O, Key>, Key> FactoryHolderRegistry;
|
||||||
|
|
||||||
FactoryHolder(Key k) : i_key(k) { }
|
explicit FactoryHolder(Key const& k) : _key(k) { }
|
||||||
virtual ~FactoryHolder() { }
|
virtual ~FactoryHolder() { }
|
||||||
inline Key key() const { return i_key; }
|
|
||||||
|
|
||||||
void RegisterSelf(void) { FactoryHolderRegistry::instance()->InsertItem(this, i_key); }
|
void RegisterSelf() { FactoryHolderRegistry::instance()->InsertItem(this, _key); }
|
||||||
void DeregisterSelf(void) { FactoryHolderRegistry::instance()->RemoveItem(this, false); }
|
|
||||||
|
|
||||||
/// Abstract Factory create method
|
/// Abstract Factory create method
|
||||||
virtual T* Create(void* data = nullptr) const = 0;
|
virtual T* Create(O* object = nullptr) const = 0;
|
||||||
private:
|
private:
|
||||||
Key i_key;
|
Key const _key;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/** Permissible is a classic way of letting the object decide
|
||||||
* Permissible is a classic way of letting the object decide
|
|
||||||
* whether how good they handle things. This is not retricted
|
* whether how good they handle things. This is not retricted
|
||||||
* to factory selectors.
|
* to factory selectors.
|
||||||
*/
|
*/
|
||||||
@@ -54,7 +50,6 @@ class Permissible
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Permissible() { }
|
virtual ~Permissible() { }
|
||||||
virtual int Permit(const T*) const = 0;
|
virtual int32 Permit(T const*) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -23,20 +23,23 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
/** ObjectRegistry holds all registry item of the same type
|
/** ObjectRegistry holds all registry item of the same type
|
||||||
*/
|
*/
|
||||||
template<class T, class Key = std::string>
|
template<class T, class Key = std::string>
|
||||||
class ObjectRegistry
|
class ObjectRegistry final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::map<Key, T*> RegistryMapType;
|
typedef std::map<Key, std::unique_ptr<T>> RegistryMapType;
|
||||||
|
|
||||||
/// Returns a registry item
|
/// Returns a registry item
|
||||||
const T* GetRegistryItem(Key key) const
|
T const* GetRegistryItem(Key const& key) const
|
||||||
{
|
{
|
||||||
typename RegistryMapType::const_iterator iter = i_registeredObjects.find(key);
|
auto itr = _registeredObjects.find(key);
|
||||||
return ( iter == i_registeredObjects.end() ? nullptr : iter->second );
|
if (itr == _registeredObjects.end())
|
||||||
|
return nullptr;
|
||||||
|
return itr->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ObjectRegistry<T, Key>* instance()
|
static ObjectRegistry<T, Key>* instance()
|
||||||
@@ -46,72 +49,34 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Inserts a registry item
|
/// Inserts a registry item
|
||||||
bool InsertItem(T* obj, Key key, bool override = false)
|
bool InsertItem(T* obj, Key const& key, bool force = false)
|
||||||
{
|
{
|
||||||
typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
|
auto itr = _registeredObjects.find(key);
|
||||||
if ( iter != i_registeredObjects.end() )
|
if (itr != _registeredObjects.end())
|
||||||
{
|
{
|
||||||
if ( !override )
|
if (!force)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
delete iter->second;
|
_registeredObjects.erase(itr);
|
||||||
i_registeredObjects.erase(iter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i_registeredObjects[key] = obj;
|
_registeredObjects.emplace(std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(obj));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes a registry item
|
|
||||||
void RemoveItem(Key key, bool delete_object = true)
|
|
||||||
{
|
|
||||||
typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
|
|
||||||
if ( iter != i_registeredObjects.end() )
|
|
||||||
{
|
|
||||||
if ( delete_object )
|
|
||||||
{
|
|
||||||
delete iter->second;
|
|
||||||
}
|
|
||||||
i_registeredObjects.erase(iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if registry contains an item
|
|
||||||
bool HasItem(Key key) const
|
|
||||||
{
|
|
||||||
return (i_registeredObjects.find(key) != i_registeredObjects.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inefficiently return a vector of registered items
|
|
||||||
unsigned int GetRegisteredItems(std::vector<Key>& l) const
|
|
||||||
{
|
|
||||||
unsigned int sz = l.size();
|
|
||||||
l.resize(sz + i_registeredObjects.size());
|
|
||||||
for (typename RegistryMapType::const_iterator iter = i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
|
|
||||||
{
|
|
||||||
l[sz++] = iter->first;
|
|
||||||
}
|
|
||||||
return i_registeredObjects.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the map of registered items
|
/// Return the map of registered items
|
||||||
RegistryMapType const& GetRegisteredItems() const
|
RegistryMapType const& GetRegisteredItems() const
|
||||||
{
|
{
|
||||||
return i_registeredObjects;
|
return _registeredObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectRegistry() { }
|
|
||||||
~ObjectRegistry()
|
|
||||||
{
|
|
||||||
for (typename RegistryMapType::iterator iter = i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
|
|
||||||
{
|
|
||||||
delete iter->second;
|
|
||||||
}
|
|
||||||
i_registeredObjects.clear();
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
RegistryMapType i_registeredObjects;
|
RegistryMapType _registeredObjects;
|
||||||
|
|
||||||
|
// non instanceable, only static
|
||||||
|
ObjectRegistry() { }
|
||||||
|
~ObjectRegistry() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
// AggressorAI
|
// AggressorAI
|
||||||
/////////////////
|
/////////////////
|
||||||
|
|
||||||
int AggressorAI::Permissible(Creature const* creature)
|
int32 AggressorAI::Permissible(Creature const* creature)
|
||||||
{
|
{
|
||||||
// have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight
|
// have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight
|
||||||
if (!creature->IsCivilian() && !creature->IsNeutralToAll())
|
if (!creature->IsCivilian() && !creature->IsNeutralToAll())
|
||||||
@@ -320,3 +320,11 @@ void VehicleAI::CheckConditions(uint32 diff)
|
|||||||
else
|
else
|
||||||
m_ConditionsTimer -= diff;
|
m_ConditionsTimer -= diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 VehicleAI::Permissible(Creature const* creature)
|
||||||
|
{
|
||||||
|
if (creature->IsVehicle())
|
||||||
|
return PERMIT_BASE_SPECIAL;
|
||||||
|
|
||||||
|
return PERMIT_BASE_NO;
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public:
|
|||||||
explicit AggressorAI(Creature* c) : CreatureAI(c) {}
|
explicit AggressorAI(Creature* c) : CreatureAI(c) {}
|
||||||
|
|
||||||
void UpdateAI(uint32) override;
|
void UpdateAI(uint32) override;
|
||||||
static int Permissible(Creature const*);
|
static int32 Permissible(Creature const* creature);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<uint32> SpellVct;
|
typedef std::vector<uint32> SpellVct;
|
||||||
@@ -47,7 +47,7 @@ public:
|
|||||||
void JustDied(Unit* killer) override;
|
void JustDied(Unit* killer) override;
|
||||||
void UpdateAI(uint32 diff) override;
|
void UpdateAI(uint32 diff) override;
|
||||||
|
|
||||||
static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EventMap events;
|
EventMap events;
|
||||||
@@ -73,7 +73,7 @@ public:
|
|||||||
void AttackStart(Unit* who) override;
|
void AttackStart(Unit* who) override;
|
||||||
void UpdateAI(uint32 diff) override;
|
void UpdateAI(uint32 diff) override;
|
||||||
|
|
||||||
static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float m_minRange;
|
float m_minRange;
|
||||||
@@ -87,7 +87,7 @@ public:
|
|||||||
void AttackStart(Unit* who) override;
|
void AttackStart(Unit* who) override;
|
||||||
void UpdateAI(uint32 diff) override;
|
void UpdateAI(uint32 diff) override;
|
||||||
|
|
||||||
static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float m_minRange;
|
float m_minRange;
|
||||||
@@ -105,7 +105,7 @@ public:
|
|||||||
void AttackStart(Unit*) override {}
|
void AttackStart(Unit*) override {}
|
||||||
void OnCharmed(bool apply) override;
|
void OnCharmed(bool apply) override;
|
||||||
|
|
||||||
static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
static int32 Permissible(Creature const* creature);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadConditions();
|
void LoadConditions();
|
||||||
|
|||||||
@@ -17,12 +17,15 @@
|
|||||||
|
|
||||||
#include "GameObjectAI.h"
|
#include "GameObjectAI.h"
|
||||||
|
|
||||||
//GameObjectAI::GameObjectAI(GameObject* g) : go(g) {}
|
int32 GameObjectAI::Permissible(GameObject const* /*go*/)
|
||||||
int GameObjectAI::Permissible(GameObject const* go)
|
|
||||||
{
|
{
|
||||||
if (go->GetAIName() == "GameObjectAI")
|
|
||||||
return PERMIT_BASE_SPECIAL;
|
|
||||||
return PERMIT_BASE_NO;
|
return PERMIT_BASE_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
NullGameObjectAI::NullGameObjectAI(GameObject* g) : GameObjectAI(g) {}
|
NullGameObjectAI::NullGameObjectAI(GameObject* go) : GameObjectAI(go) { }
|
||||||
|
|
||||||
|
int32 NullGameObjectAI::Permissible(GameObject const* /*go*/)
|
||||||
|
{
|
||||||
|
return PERMIT_BASE_IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public:
|
|||||||
virtual void SetGUID(ObjectGuid /*guid*/, int32 /*id = 0 */) {}
|
virtual void SetGUID(ObjectGuid /*guid*/, int32 /*id = 0 */) {}
|
||||||
virtual ObjectGuid GetGUID(int32 /*id = 0 */) const { return ObjectGuid::Empty; }
|
virtual ObjectGuid GetGUID(int32 /*id = 0 */) const { return ObjectGuid::Empty; }
|
||||||
|
|
||||||
static int Permissible(GameObject const* go);
|
static int32 Permissible(GameObject const* go);
|
||||||
|
|
||||||
virtual bool GossipHello(Player* /*player*/, bool /*reportUse*/) { return false; }
|
virtual bool GossipHello(Player* /*player*/, bool /*reportUse*/) { return false; }
|
||||||
virtual bool GossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) { return false; }
|
virtual bool GossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) { return false; }
|
||||||
@@ -76,6 +76,6 @@ public:
|
|||||||
|
|
||||||
void UpdateAI(uint32 /*diff*/) override {}
|
void UpdateAI(uint32 /*diff*/) override {}
|
||||||
|
|
||||||
static int Permissible(GameObject const* /*go*/) { return PERMIT_BASE_IDLE; }
|
static int32 Permissible(GameObject const* go);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -19,10 +19,10 @@
|
|||||||
#include "CreatureAIImpl.h"
|
#include "CreatureAIImpl.h"
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
|
|
||||||
int GuardAI::Permissible(Creature const* creature)
|
int32 GuardAI::Permissible(Creature const* creature)
|
||||||
{
|
{
|
||||||
if (creature->IsGuard())
|
if (creature->IsGuard())
|
||||||
return PERMIT_BASE_SPECIAL;
|
return PERMIT_BASE_PROACTIVE;
|
||||||
|
|
||||||
return PERMIT_BASE_NO;
|
return PERMIT_BASE_NO;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class GuardAI : public ScriptedAI
|
|||||||
public:
|
public:
|
||||||
explicit GuardAI(Creature* creature);
|
explicit GuardAI(Creature* creature);
|
||||||
|
|
||||||
static int Permissible(Creature const* creature);
|
static int32 Permissible(Creature const* creature);
|
||||||
|
|
||||||
void Reset() override;
|
void Reset() override;
|
||||||
void EnterEvadeMode(EvadeReason /*why*/) override;
|
void EnterEvadeMode(EvadeReason /*why*/) override;
|
||||||
|
|||||||
@@ -23,6 +23,17 @@ PassiveAI::PassiveAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASS
|
|||||||
PossessedAI::PossessedAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASSIVE); }
|
PossessedAI::PossessedAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASSIVE); }
|
||||||
NullCreatureAI::NullCreatureAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASSIVE); }
|
NullCreatureAI::NullCreatureAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASSIVE); }
|
||||||
|
|
||||||
|
int32 NullCreatureAI::Permissible(Creature const* creature)
|
||||||
|
{
|
||||||
|
if (creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK))
|
||||||
|
return PERMIT_BASE_PROACTIVE + 50;
|
||||||
|
|
||||||
|
if (creature->IsTrigger())
|
||||||
|
return PERMIT_BASE_REACTIVE;
|
||||||
|
|
||||||
|
return PERMIT_BASE_IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
void PassiveAI::UpdateAI(uint32)
|
void PassiveAI::UpdateAI(uint32)
|
||||||
{
|
{
|
||||||
if (me->IsInCombat() && me->getAttackers().empty())
|
if (me->IsInCombat() && me->getAttackers().empty())
|
||||||
@@ -84,8 +95,24 @@ void CritterAI::UpdateAI(uint32 diff)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 CritterAI::Permissible(Creature const* creature)
|
||||||
|
{
|
||||||
|
if (creature->IsCritter() && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
|
||||||
|
return PERMIT_BASE_PROACTIVE;
|
||||||
|
|
||||||
|
return PERMIT_BASE_NO;
|
||||||
|
}
|
||||||
|
|
||||||
void TriggerAI::IsSummonedBy(Unit* summoner)
|
void TriggerAI::IsSummonedBy(Unit* summoner)
|
||||||
{
|
{
|
||||||
if (me->m_spells[0])
|
if (me->m_spells[0])
|
||||||
me->CastSpell(me, me->m_spells[0], false, 0, 0, summoner ? summoner->GetGUID() : ObjectGuid::Empty);
|
me->CastSpell(me, me->m_spells[0], false, 0, 0, summoner ? summoner->GetGUID() : ObjectGuid::Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 TriggerAI::Permissible(Creature const* creature)
|
||||||
|
{
|
||||||
|
if (creature->IsTrigger() && creature->m_spells[0])
|
||||||
|
return PERMIT_BASE_SPECIAL;
|
||||||
|
|
||||||
|
return PERMIT_BASE_NO;
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public:
|
|||||||
void AttackStart(Unit*) override {}
|
void AttackStart(Unit*) override {}
|
||||||
void UpdateAI(uint32) override;
|
void UpdateAI(uint32) override;
|
||||||
|
|
||||||
static int Permissible(Creature const*) { return PERMIT_BASE_IDLE; }
|
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class PossessedAI : public CreatureAI
|
class PossessedAI : public CreatureAI
|
||||||
@@ -46,7 +46,7 @@ public:
|
|||||||
void JustDied(Unit*) override;
|
void JustDied(Unit*) override;
|
||||||
void KilledUnit(Unit* victim) override;
|
void KilledUnit(Unit* victim) override;
|
||||||
|
|
||||||
static int Permissible(Creature const*) { return PERMIT_BASE_IDLE; }
|
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class NullCreatureAI : public CreatureAI
|
class NullCreatureAI : public CreatureAI
|
||||||
@@ -60,7 +60,7 @@ public:
|
|||||||
void EnterEvadeMode(EvadeReason /*why*/) override {}
|
void EnterEvadeMode(EvadeReason /*why*/) override {}
|
||||||
void OnCharmed(bool /*apply*/) override {}
|
void OnCharmed(bool /*apply*/) override {}
|
||||||
|
|
||||||
static int Permissible(Creature const*) { return PERMIT_BASE_IDLE; }
|
static int32 Permissible(Creature const* creature);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CritterAI : public PassiveAI
|
class CritterAI : public PassiveAI
|
||||||
@@ -72,6 +72,7 @@ public:
|
|||||||
void EnterEvadeMode(EvadeReason why) override;
|
void EnterEvadeMode(EvadeReason why) override;
|
||||||
void UpdateAI(uint32) override;
|
void UpdateAI(uint32) override;
|
||||||
|
|
||||||
|
static int32 Permissible(Creature const* creature);
|
||||||
// Xinef: Added
|
// Xinef: Added
|
||||||
private:
|
private:
|
||||||
uint32 _combatTimer;
|
uint32 _combatTimer;
|
||||||
@@ -82,6 +83,8 @@ class TriggerAI : public NullCreatureAI
|
|||||||
public:
|
public:
|
||||||
explicit TriggerAI(Creature* c) : NullCreatureAI(c) {}
|
explicit TriggerAI(Creature* c) : NullCreatureAI(c) {}
|
||||||
void IsSummonedBy(Unit* summoner) override;
|
void IsSummonedBy(Unit* summoner) override;
|
||||||
|
|
||||||
|
static int32 Permissible(Creature const* creature);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -28,11 +28,18 @@
|
|||||||
#include "SpellMgr.h"
|
#include "SpellMgr.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
int PetAI::Permissible(Creature const* creature)
|
int32 PetAI::Permissible(Creature const* creature)
|
||||||
{
|
{
|
||||||
if (creature->IsPet())
|
if (creature->IsPet())
|
||||||
return PERMIT_BASE_SPECIAL;
|
return PERMIT_BASE_SPECIAL;
|
||||||
|
|
||||||
|
if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
|
||||||
|
{
|
||||||
|
if (reinterpret_cast<Guardian const*>(creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
return PERMIT_BASE_PROACTIVE;
|
||||||
|
return PERMIT_BASE_REACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
return PERMIT_BASE_NO;
|
return PERMIT_BASE_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public:
|
|||||||
explicit PetAI(Creature* c);
|
explicit PetAI(Creature* c);
|
||||||
|
|
||||||
void UpdateAI(uint32) override;
|
void UpdateAI(uint32) override;
|
||||||
static int Permissible(Creature const*);
|
static int32 Permissible(Creature const* creature);
|
||||||
|
|
||||||
void KilledUnit(Unit* /*victim*/) override;
|
void KilledUnit(Unit* /*victim*/) override;
|
||||||
void AttackStart(Unit* target) override;
|
void AttackStart(Unit* target) override;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "CreatureAIImpl.h"
|
#include "CreatureAIImpl.h"
|
||||||
#include "Errors.h"
|
#include "Errors.h"
|
||||||
|
|
||||||
int ReactorAI::Permissible(Creature const* creature)
|
int32 ReactorAI::Permissible(Creature const* creature)
|
||||||
{
|
{
|
||||||
if (creature->IsCivilian() || creature->IsNeutralToAll())
|
if (creature->IsCivilian() || creature->IsNeutralToAll())
|
||||||
return PERMIT_BASE_REACTIVE;
|
return PERMIT_BASE_REACTIVE;
|
||||||
|
|||||||
@@ -30,6 +30,6 @@ public:
|
|||||||
void MoveInLineOfSight(Unit*) override {}
|
void MoveInLineOfSight(Unit*) override {}
|
||||||
void UpdateAI(uint32 diff) override;
|
void UpdateAI(uint32 diff) override;
|
||||||
|
|
||||||
static int Permissible(Creature const*);
|
static int32 Permissible(Creature const* creature);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
#include "SpellMgr.h"
|
#include "SpellMgr.h"
|
||||||
#include "Totem.h"
|
#include "Totem.h"
|
||||||
|
|
||||||
int TotemAI::Permissible(Creature const* creature)
|
int32 TotemAI::Permissible(Creature const* creature)
|
||||||
{
|
{
|
||||||
if (creature->IsTotem())
|
if (creature->IsTotem())
|
||||||
return PERMIT_BASE_PROACTIVE;
|
return PERMIT_BASE_PROACTIVE;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public:
|
|||||||
void DoAction(int32 param) override;
|
void DoAction(int32 param) override;
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override;
|
void UpdateAI(uint32 diff) override;
|
||||||
static int Permissible(Creature const* creature);
|
static int32 Permissible(Creature const* creature);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ObjectGuid i_victimGuid;
|
ObjectGuid i_victimGuid;
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ private:
|
|||||||
bool m_MoveInLineOfSight_locked;
|
bool m_MoveInLineOfSight_locked;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Permitions
|
enum Permitions : int32
|
||||||
{
|
{
|
||||||
PERMIT_BASE_NO = -1,
|
PERMIT_BASE_NO = -1,
|
||||||
PERMIT_BASE_IDLE = 1,
|
PERMIT_BASE_IDLE = 1,
|
||||||
|
|||||||
@@ -19,60 +19,32 @@
|
|||||||
#define ACORE_CREATUREAIFACTORY_H
|
#define ACORE_CREATUREAIFACTORY_H
|
||||||
|
|
||||||
#include "FactoryHolder.h"
|
#include "FactoryHolder.h"
|
||||||
#include "GameObjectAI.h"
|
|
||||||
#include "ObjectRegistry.h"
|
#include "ObjectRegistry.h"
|
||||||
|
|
||||||
struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature>
|
typedef FactoryHolder<CreatureAI, Creature> CreatureAICreator;
|
||||||
|
|
||||||
|
struct SelectableAI : public CreatureAICreator, public Permissible<Creature>
|
||||||
{
|
{
|
||||||
SelectableAI(const char* id) : FactoryHolder<CreatureAI>(id) {}
|
SelectableAI(std::string const& name) : CreatureAICreator(name), Permissible<Creature>() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class REAL_AI>
|
template<class REAL_AI>
|
||||||
struct CreatureAIFactory : public SelectableAI
|
struct CreatureAIFactory : public SelectableAI
|
||||||
{
|
{
|
||||||
CreatureAIFactory(const char* name) : SelectableAI(name) {}
|
CreatureAIFactory(std::string const& name) : SelectableAI(name) { }
|
||||||
|
|
||||||
CreatureAI* Create(void*) const;
|
inline CreatureAI* Create(Creature* c) const override
|
||||||
|
{
|
||||||
|
return new REAL_AI(c);
|
||||||
|
}
|
||||||
|
|
||||||
int Permit(Creature const* c) const { return REAL_AI::Permissible(c); }
|
int32 Permit(Creature const* c) const override
|
||||||
|
{
|
||||||
|
return REAL_AI::Permissible(c);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class REAL_AI>
|
typedef CreatureAICreator::FactoryHolderRegistry CreatureAIRegistry;
|
||||||
inline CreatureAI*
|
#define sCreatureAIRegistry CreatureAIRegistry::instance()
|
||||||
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;
|
|
||||||
|
|
||||||
//GO
|
|
||||||
struct SelectableGameObjectAI : public FactoryHolder<GameObjectAI>, public Permissible<GameObject>
|
|
||||||
{
|
|
||||||
SelectableGameObjectAI(const char* id) : FactoryHolder<GameObjectAI>(id) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class REAL_GO_AI>
|
|
||||||
struct GameObjectAIFactory : public SelectableGameObjectAI
|
|
||||||
{
|
|
||||||
GameObjectAIFactory(const char* name) : SelectableGameObjectAI(name) {}
|
|
||||||
|
|
||||||
GameObjectAI* Create(void*) const;
|
|
||||||
|
|
||||||
int Permit(GameObject const* g) const { return REAL_GO_AI::Permissible(g); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class REAL_GO_AI>
|
|
||||||
inline GameObjectAI*
|
|
||||||
GameObjectAIFactory<REAL_GO_AI>::Create(void* data) const
|
|
||||||
{
|
|
||||||
GameObject* go = reinterpret_cast<GameObject*>(data);
|
|
||||||
return (new REAL_GO_AI(go));
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef FactoryHolder<GameObjectAI> GameObjectAICreator;
|
|
||||||
typedef FactoryHolder<GameObjectAI>::FactoryHolderRegistry GameObjectAIRegistry;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "CombatAI.h"
|
#include "CombatAI.h"
|
||||||
#include "CreatureAIFactory.h"
|
#include "CreatureAIFactory.h"
|
||||||
#include "GuardAI.h"
|
#include "GuardAI.h"
|
||||||
#include "MovementGeneratorImpl.h"
|
#include "MovementGenerator.h"
|
||||||
#include "PassiveAI.h"
|
#include "PassiveAI.h"
|
||||||
#include "PetAI.h"
|
#include "PetAI.h"
|
||||||
#include "RandomMovementGenerator.h"
|
#include "RandomMovementGenerator.h"
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "SmartAI.h"
|
#include "SmartAI.h"
|
||||||
#include "TotemAI.h"
|
#include "TotemAI.h"
|
||||||
#include "WaypointMovementGenerator.h"
|
#include "WaypointMovementGenerator.h"
|
||||||
|
#include "GameObjectAIFactory.h"
|
||||||
|
|
||||||
namespace AIRegistry
|
namespace AIRegistry
|
||||||
{
|
{
|
||||||
@@ -47,10 +48,12 @@ namespace AIRegistry
|
|||||||
(new CreatureAIFactory<VehicleAI>("VehicleAI"))->RegisterSelf();
|
(new CreatureAIFactory<VehicleAI>("VehicleAI"))->RegisterSelf();
|
||||||
(new CreatureAIFactory<SmartAI>("SmartAI"))->RegisterSelf();
|
(new CreatureAIFactory<SmartAI>("SmartAI"))->RegisterSelf();
|
||||||
|
|
||||||
|
(new GameObjectAIFactory<NullGameObjectAI>("NullGameObjectAI"))->RegisterSelf();
|
||||||
(new GameObjectAIFactory<GameObjectAI>("GameObjectAI"))->RegisterSelf();
|
(new GameObjectAIFactory<GameObjectAI>("GameObjectAI"))->RegisterSelf();
|
||||||
(new GameObjectAIFactory<SmartGameObjectAI>("SmartGameObjectAI"))->RegisterSelf();
|
(new GameObjectAIFactory<SmartGameObjectAI>("SmartGameObjectAI"))->RegisterSelf();
|
||||||
|
|
||||||
(new MovementGeneratorFactory<RandomMovementGenerator<Creature> >(RANDOM_MOTION_TYPE))->RegisterSelf();
|
(new IdleMovementFactory())->RegisterSelf();
|
||||||
(new MovementGeneratorFactory<WaypointMovementGenerator<Creature> >(WAYPOINT_MOTION_TYPE))->RegisterSelf();
|
(new MovementGeneratorFactory<RandomMovementGenerator<Creature>>(RANDOM_MOTION_TYPE))->RegisterSelf();
|
||||||
|
(new MovementGeneratorFactory<WaypointMovementGenerator<Creature>>(WAYPOINT_MOTION_TYPE))->RegisterSelf();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,132 +15,102 @@
|
|||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "CreatureAISelector.h"
|
|
||||||
#include "Creature.h"
|
#include "Creature.h"
|
||||||
|
#include "CreatureAISelector.h"
|
||||||
#include "CreatureAIFactory.h"
|
#include "CreatureAIFactory.h"
|
||||||
|
|
||||||
#include "MovementGenerator.h"
|
#include "MovementGenerator.h"
|
||||||
#include "PassiveAI.h"
|
|
||||||
#include "Pet.h"
|
#include "GameObject.h"
|
||||||
|
#include "GameObjectAIFactory.h"
|
||||||
|
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "TemporarySummon.h"
|
|
||||||
|
|
||||||
namespace FactorySelector
|
namespace FactorySelector
|
||||||
{
|
{
|
||||||
CreatureAI* selectAI(Creature* creature)
|
template <class T>
|
||||||
|
struct PermissibleOrderPred
|
||||||
{
|
{
|
||||||
const CreatureAICreator* ai_factory = nullptr;
|
public:
|
||||||
CreatureAIRegistry& ai_registry(*CreatureAIRegistry::instance());
|
PermissibleOrderPred(T const* obj) : _obj(obj) { }
|
||||||
|
|
||||||
// xinef: if we have controlable guardian, define petai for players as they can steer him, otherwise db / normal ai
|
template <class Value>
|
||||||
// xinef: dont remember why i changed this qq commented out as may break some quests
|
bool operator()(Value const& left, Value const& right) const
|
||||||
if (creature->IsPet()/* || (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)*/)
|
{
|
||||||
ai_factory = ai_registry.GetRegistryItem("PetAI");
|
Permissible<T> const* leftPermit = ASSERT_NOTNULL(dynamic_cast<Permissible<T> const*>(left.second.get()));
|
||||||
|
Permissible<T> const* rightPermit = ASSERT_NOTNULL(dynamic_cast<Permissible<T> const*>(right.second.get()));
|
||||||
|
|
||||||
//scriptname in db
|
return leftPermit->Permit(_obj) < rightPermit->Permit(_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T const* const _obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
CreatureAI* SelectAI(Creature* creature)
|
||||||
|
{
|
||||||
|
CreatureAICreator const* ai_factory = nullptr;
|
||||||
|
|
||||||
|
// scriptname in db
|
||||||
if (!ai_factory)
|
if (!ai_factory)
|
||||||
if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature))
|
if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature))
|
||||||
return scriptedAI;
|
return scriptedAI;
|
||||||
|
|
||||||
// AIname in db
|
// AIname in db
|
||||||
std::string ainame = creature->GetAIName();
|
std::string const& aiName = creature->GetAIName();
|
||||||
if (!ai_factory && !ainame.empty())
|
if (!ai_factory && !aiName.empty())
|
||||||
ai_factory = ai_registry.GetRegistryItem(ainame);
|
ai_factory = sCreatureAIRegistry->GetRegistryItem(aiName);
|
||||||
|
|
||||||
// select by NPC flags
|
|
||||||
if (!ai_factory)
|
|
||||||
{
|
|
||||||
if (creature->IsVehicle())
|
|
||||||
ai_factory = ai_registry.GetRegistryItem("VehicleAI");
|
|
||||||
else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
ai_factory = ai_registry.GetRegistryItem("PetAI");
|
|
||||||
else if (creature->HasNpcFlag(UNIT_NPC_FLAG_SPELLCLICK))
|
|
||||||
ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
|
|
||||||
else if (creature->IsGuard())
|
|
||||||
ai_factory = ai_registry.GetRegistryItem("GuardAI");
|
|
||||||
else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
|
|
||||||
ai_factory = ai_registry.GetRegistryItem("PetAI");
|
|
||||||
else if (creature->IsTotem())
|
|
||||||
ai_factory = ai_registry.GetRegistryItem("TotemAI");
|
|
||||||
else if (creature->IsTrigger())
|
|
||||||
{
|
|
||||||
if (creature->m_spells[0])
|
|
||||||
ai_factory = ai_registry.GetRegistryItem("TriggerAI");
|
|
||||||
else
|
|
||||||
ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
|
|
||||||
}
|
|
||||||
else if (creature->IsCritter() && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
|
|
||||||
ai_factory = ai_registry.GetRegistryItem("CritterAI");
|
|
||||||
}
|
|
||||||
|
|
||||||
// select by permit check
|
// select by permit check
|
||||||
if (!ai_factory)
|
if (!ai_factory)
|
||||||
{
|
{
|
||||||
int best_val = -1;
|
CreatureAIRegistry::RegistryMapType const& items = sCreatureAIRegistry->GetRegisteredItems();
|
||||||
typedef CreatureAIRegistry::RegistryMapType RMT;
|
auto itr = std::max_element(items.begin(), items.end(), PermissibleOrderPred<Creature>(creature));
|
||||||
RMT const& l = ai_registry.GetRegisteredItems();
|
if (itr != items.end())
|
||||||
for (RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
|
ai_factory = itr->second.get();
|
||||||
{
|
|
||||||
const CreatureAICreator* factory = iter->second;
|
|
||||||
const SelectableAI* p = dynamic_cast<const SelectableAI*>(factory);
|
|
||||||
ASSERT(p);
|
|
||||||
int val = p->Permit(creature);
|
|
||||||
if (val > best_val)
|
|
||||||
{
|
|
||||||
best_val = val;
|
|
||||||
ai_factory = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// select NullCreatureAI if not another cases
|
if (!ai_factory)
|
||||||
ainame = (!ai_factory) ? "NullCreatureAI" : ai_factory->key();
|
ai_factory = sCreatureAIRegistry->GetRegistryItem("NullCreatureAI");
|
||||||
LOG_DEBUG("scripts.ai", "Creature {} used AI is {}.", creature->GetGUID().ToString(), ainame);
|
|
||||||
return (!ai_factory ? new NullCreatureAI(creature) : ai_factory->Create(creature));
|
return ASSERT_NOTNULL(ai_factory)->Create(creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
MovementGenerator* selectMovementGenerator(Creature* creature)
|
MovementGenerator* SelectMovementGenerator(Unit* unit)
|
||||||
{
|
{
|
||||||
MovementGeneratorRegistry& mv_registry(*MovementGeneratorRegistry::instance());
|
MovementGeneratorType type = IDLE_MOTION_TYPE;
|
||||||
ASSERT(creature->GetCreatureTemplate());
|
if (unit->GetTypeId() == TYPEID_UNIT)
|
||||||
const MovementGeneratorCreator* mv_factory = mv_registry.GetRegistryItem(creature->GetDefaultMovementType());
|
type = unit->ToCreature()->GetDefaultMovementType();
|
||||||
|
|
||||||
/* if (mv_factory == nullptr)
|
MovementGeneratorCreator const* mv_factory = sMovementGeneratorRegistry->GetRegistryItem(type);
|
||||||
{
|
return ASSERT_NOTNULL(mv_factory)->Create(unit);
|
||||||
int best_val = -1;
|
|
||||||
std::vector<std::string> l;
|
|
||||||
mv_registry.GetRegisteredItems(l);
|
|
||||||
for (std::vector<std::string>::iterator iter = l.begin(); iter != l.end(); ++iter)
|
|
||||||
{
|
|
||||||
const MovementGeneratorCreator *factory = mv_registry.GetRegistryItem((*iter).c_str());
|
|
||||||
const SelectableMovement *p = dynamic_cast<const SelectableMovement *>(factory);
|
|
||||||
ASSERT(p != nullptr);
|
|
||||||
int val = p->Permit(creature);
|
|
||||||
if (val > best_val)
|
|
||||||
{
|
|
||||||
best_val = val;
|
|
||||||
mv_factory = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return (!mv_factory ? nullptr : mv_factory->Create(creature));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GameObjectAI* SelectGameObjectAI(GameObject* go)
|
GameObjectAI* SelectGameObjectAI(GameObject* go)
|
||||||
{
|
{
|
||||||
const GameObjectAICreator* ai_factory = nullptr;
|
GameObjectAICreator const* ai_factory = nullptr;
|
||||||
GameObjectAIRegistry& ai_registry(*GameObjectAIRegistry::instance());
|
|
||||||
|
|
||||||
|
// scriptname in db
|
||||||
if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go))
|
if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go))
|
||||||
return scriptedAI;
|
return scriptedAI;
|
||||||
|
|
||||||
ai_factory = ai_registry.GetRegistryItem(go->GetAIName());
|
// AIname in db
|
||||||
|
std::string const& aiName = go->GetAIName();
|
||||||
|
if (!ai_factory && !aiName.empty())
|
||||||
|
ai_factory = sGameObjectAIRegistry->GetRegistryItem(aiName);
|
||||||
|
|
||||||
//future goAI types go here
|
// select by permit check
|
||||||
|
if (!ai_factory)
|
||||||
|
{
|
||||||
|
GameObjectAIRegistry::RegistryMapType const& items = sGameObjectAIRegistry->GetRegisteredItems();
|
||||||
|
auto itr = std::max_element(items.begin(), items.end(), PermissibleOrderPred<GameObject>(go));
|
||||||
|
if (itr != items.end())
|
||||||
|
ai_factory = itr->second.get();
|
||||||
|
}
|
||||||
|
|
||||||
std::string ainame = (!ai_factory || go->GetScriptId()) ? "NullGameObjectAI" : ai_factory->key();
|
if (!ai_factory)
|
||||||
LOG_DEBUG("scripts.ai", "GameObject {} used AI is {}.", go->GetGUID().ToString(), ainame);
|
ai_factory = sGameObjectAIRegistry->GetRegistryItem("NullGameObjectAI");
|
||||||
|
|
||||||
return (!ai_factory ? new NullGameObjectAI(go) : ai_factory->Create(go));
|
return ASSERT_NOTNULL(ai_factory)->Create(go);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,14 @@
|
|||||||
class CreatureAI;
|
class CreatureAI;
|
||||||
class Creature;
|
class Creature;
|
||||||
class MovementGenerator;
|
class MovementGenerator;
|
||||||
|
class Unit;
|
||||||
class GameObjectAI;
|
class GameObjectAI;
|
||||||
class GameObject;
|
class GameObject;
|
||||||
|
|
||||||
namespace FactorySelector
|
namespace FactorySelector
|
||||||
{
|
{
|
||||||
CreatureAI* selectAI(Creature*);
|
AC_GAME_API CreatureAI* SelectAI(Creature* creature);
|
||||||
MovementGenerator* selectMovementGenerator(Creature*);
|
AC_GAME_API MovementGenerator* SelectMovementGenerator(Unit* unit);
|
||||||
GameObjectAI* SelectGameObjectAI(GameObject*);
|
AC_GAME_API GameObjectAI* SelectGameObjectAI(GameObject* go);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 3 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 Affero General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ACORE_GAMEOBJECTAIFACTORY_H
|
||||||
|
#define ACORE_GAMEOBJECTAIFACTORY_H
|
||||||
|
|
||||||
|
#include "ObjectRegistry.h"
|
||||||
|
#include "FactoryHolder.h"
|
||||||
|
|
||||||
|
typedef FactoryHolder<GameObjectAI, GameObject> GameObjectAICreator;
|
||||||
|
|
||||||
|
struct SelectableGameObjectAI : public GameObjectAICreator, public Permissible<GameObject>
|
||||||
|
{
|
||||||
|
SelectableGameObjectAI(std::string const& name) : GameObjectAICreator(name), Permissible<GameObject>() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class REAL_GO_AI>
|
||||||
|
struct GameObjectAIFactory : public SelectableGameObjectAI
|
||||||
|
{
|
||||||
|
GameObjectAIFactory(std::string const& name) : SelectableGameObjectAI(name) { }
|
||||||
|
|
||||||
|
GameObjectAI* Create(GameObject* go) const override
|
||||||
|
{
|
||||||
|
return new REAL_GO_AI(go);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 Permit(GameObject const* go) const override
|
||||||
|
{
|
||||||
|
return REAL_GO_AI::Permissible(go);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef GameObjectAICreator::FactoryHolderRegistry GameObjectAIRegistry;
|
||||||
|
|
||||||
|
#define sGameObjectAIRegistry GameObjectAIRegistry::instance()
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -763,13 +763,6 @@ void SmartAI::JustRespawned()
|
|||||||
mFollowArrivedAlive = true;
|
mFollowArrivedAlive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SmartAI::Permissible(Creature const* creature)
|
|
||||||
{
|
|
||||||
if (creature->GetAIName() == "SmartAI")
|
|
||||||
return PERMIT_BASE_SPECIAL;
|
|
||||||
return PERMIT_BASE_NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SmartAI::JustReachedHome()
|
void SmartAI::JustReachedHome()
|
||||||
{
|
{
|
||||||
GetScript()->OnReset();
|
GetScript()->OnReset();
|
||||||
@@ -1133,13 +1126,6 @@ void SmartGameObjectAI::SummonedCreatureDies(Creature* summon, Unit* /*killer*/)
|
|||||||
GetScript()->ProcessEventsFor(SMART_EVENT_SUMMONED_UNIT_DIES, summon);
|
GetScript()->ProcessEventsFor(SMART_EVENT_SUMMONED_UNIT_DIES, summon);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SmartGameObjectAI::Permissible(GameObject const* g)
|
|
||||||
{
|
|
||||||
if (g->GetAIName() == "SmartGameObjectAI")
|
|
||||||
return PERMIT_BASE_SPECIAL;
|
|
||||||
return PERMIT_BASE_NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SmartGameObjectAI::UpdateAI(uint32 diff)
|
void SmartGameObjectAI::UpdateAI(uint32 diff)
|
||||||
{
|
{
|
||||||
GetScript()->OnUpdate(diff);
|
GetScript()->OnUpdate(diff);
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ public:
|
|||||||
ObjectGuid GetGUID(int32 id = 0) const override;
|
ObjectGuid GetGUID(int32 id = 0) const override;
|
||||||
|
|
||||||
//core related
|
//core related
|
||||||
static int32 Permissible(Creature const*);
|
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||||
|
|
||||||
// Called at movepoint reached
|
// Called at movepoint reached
|
||||||
void MovepointReached(uint32 id);
|
void MovepointReached(uint32 id);
|
||||||
@@ -259,7 +259,7 @@ public:
|
|||||||
void InitializeAI() override;
|
void InitializeAI() override;
|
||||||
void Reset() override;
|
void Reset() override;
|
||||||
SmartScript* GetScript() { return &mScript; }
|
SmartScript* GetScript() { return &mScript; }
|
||||||
static int32 Permissible(GameObject const* g);
|
static int32 Permissible(GameObject const* /*go*/) { return PERMIT_BASE_NO; }
|
||||||
|
|
||||||
bool GossipHello(Player* player, bool reportUse) override;
|
bool GossipHello(Player* player, bool reportUse) override;
|
||||||
bool GossipSelect(Player* player, uint32 sender, uint32 action) override;
|
bool GossipSelect(Player* player, uint32 sender, uint32 action) override;
|
||||||
|
|||||||
@@ -1020,7 +1020,7 @@ bool Creature::AIM_Initialize(CreatureAI* ai)
|
|||||||
// Xinef: called in add to world
|
// Xinef: called in add to world
|
||||||
//Motion_Initialize();
|
//Motion_Initialize();
|
||||||
|
|
||||||
i_AI = ai ? ai : FactorySelector::selectAI(this);
|
i_AI = ai ? ai : FactorySelector::SelectAI(this);
|
||||||
delete oldAI;
|
delete oldAI;
|
||||||
IsAIEnabled = true;
|
IsAIEnabled = true;
|
||||||
i_AI->InitializeAI();
|
i_AI->InitializeAI();
|
||||||
@@ -2860,7 +2860,7 @@ uint8 Creature::getLevelForTarget(WorldObject const* target) const
|
|||||||
return uint8(level);
|
return uint8(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Creature::GetAIName() const
|
std::string const& Creature::GetAIName() const
|
||||||
{
|
{
|
||||||
return sObjectMgr->GetCreatureTemplate(GetEntry())->AIName;
|
return sObjectMgr->GetCreatureTemplate(GetEntry())->AIName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ public:
|
|||||||
void SetDetectionDistance(float dist){ m_detectionDistance = dist; }
|
void SetDetectionDistance(float dist){ m_detectionDistance = dist; }
|
||||||
[[nodiscard]] CreatureAddon const* GetCreatureAddon() const;
|
[[nodiscard]] CreatureAddon const* GetCreatureAddon() const;
|
||||||
|
|
||||||
[[nodiscard]] std::string GetAIName() const;
|
[[nodiscard]] std::string const& GetAIName() const;
|
||||||
[[nodiscard]] std::string GetScriptName() const;
|
[[nodiscard]] std::string GetScriptName() const;
|
||||||
[[nodiscard]] uint32 GetScriptId() const;
|
[[nodiscard]] uint32 GetScriptId() const;
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ bool GameObject::AIM_Initialize()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GameObject::GetAIName() const
|
std::string const& GameObject::GetAIName() const
|
||||||
{
|
{
|
||||||
return sObjectMgr->GetGameObjectTemplate(GetEntry())->AIName;
|
return sObjectMgr->GetGameObjectTemplate(GetEntry())->AIName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1000,7 +1000,7 @@ public:
|
|||||||
[[nodiscard]] virtual uint32 GetScriptId() const;
|
[[nodiscard]] virtual uint32 GetScriptId() const;
|
||||||
[[nodiscard]] GameObjectAI* AI() const { return m_AI; }
|
[[nodiscard]] GameObjectAI* AI() const { return m_AI; }
|
||||||
|
|
||||||
[[nodiscard]] std::string GetAIName() const;
|
[[nodiscard]] std::string const& GetAIName() const;
|
||||||
void SetDisplayId(uint32 displayid);
|
void SetDisplayId(uint32 displayid);
|
||||||
[[nodiscard]] uint32 GetDisplayId() const { return GetUInt32Value(GAMEOBJECT_DISPLAYID); }
|
[[nodiscard]] uint32 GetDisplayId() const { return GetUInt32Value(GAMEOBJECT_DISPLAYID); }
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,11 @@
|
|||||||
#include "TargetedMovementGenerator.h"
|
#include "TargetedMovementGenerator.h"
|
||||||
#include "WaypointMovementGenerator.h"
|
#include "WaypointMovementGenerator.h"
|
||||||
|
|
||||||
|
inline MovementGenerator* GetIdleMovementGenerator()
|
||||||
|
{
|
||||||
|
return sMovementGeneratorRegistry->GetRegistryItem(IDLE_MOTION_TYPE)->Create();
|
||||||
|
}
|
||||||
|
|
||||||
// ---- ChaseRange ---- //
|
// ---- ChaseRange ---- //
|
||||||
|
|
||||||
ChaseRange::ChaseRange(float range) : MinRange(range > CONTACT_DISTANCE ? 0 : range - CONTACT_DISTANCE), MinTolerance(range), MaxRange(range + CONTACT_DISTANCE), MaxTolerance(range) { }
|
ChaseRange::ChaseRange(float range) : MinRange(range > CONTACT_DISTANCE ? 0 : range - CONTACT_DISTANCE), MinTolerance(range), MaxRange(range + CONTACT_DISTANCE), MaxTolerance(range) { }
|
||||||
@@ -59,9 +64,9 @@ bool ChaseAngle::IsAngleOkay(float relativeAngle) const
|
|||||||
return (std::min(diff, float(2 * M_PI) - diff) <= Tolerance);
|
return (std::min(diff, float(2 * M_PI) - diff) <= Tolerance);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isStatic(MovementGenerator* mv)
|
inline bool isStatic(MovementGenerator* movement)
|
||||||
{
|
{
|
||||||
return (mv == &si_idleMovement);
|
return (movement == GetIdleMovementGenerator());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MotionMaster::Initialize()
|
void MotionMaster::Initialize()
|
||||||
@@ -80,16 +85,7 @@ void MotionMaster::Initialize()
|
|||||||
// set new default movement generator
|
// set new default movement generator
|
||||||
void MotionMaster::InitDefault()
|
void MotionMaster::InitDefault()
|
||||||
{
|
{
|
||||||
// Xinef: Do not allow to initialize any motion generator for dead creatures
|
Mutate(FactorySelector::SelectMovementGenerator(_owner), MOTION_SLOT_IDLE);
|
||||||
if (_owner->GetTypeId() == TYPEID_UNIT && _owner->IsAlive())
|
|
||||||
{
|
|
||||||
MovementGenerator* movement = FactorySelector::selectMovementGenerator(_owner->ToCreature());
|
|
||||||
Mutate(!movement ? &si_idleMovement : movement, MOTION_SLOT_IDLE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Mutate(&si_idleMovement, MOTION_SLOT_IDLE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MotionMaster::~MotionMaster()
|
MotionMaster::~MotionMaster()
|
||||||
@@ -236,7 +232,7 @@ void MotionMaster::MoveIdle()
|
|||||||
{
|
{
|
||||||
//! Should be preceded by MovementExpired or Clear if there's an overlying movementgenerator active
|
//! Should be preceded by MovementExpired or Clear if there's an overlying movementgenerator active
|
||||||
if (empty() || !isStatic(top()))
|
if (empty() || !isStatic(top()))
|
||||||
Mutate(&si_idleMovement, MOTION_SLOT_IDLE);
|
Mutate(GetIdleMovementGenerator(), MOTION_SLOT_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MotionMaster::MoveRandom(float wanderDistance)
|
void MotionMaster::MoveRandom(float wanderDistance)
|
||||||
|
|||||||
@@ -16,7 +16,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MovementGenerator.h"
|
#include "MovementGenerator.h"
|
||||||
|
#include "IdleMovementGenerator.h"
|
||||||
|
|
||||||
MovementGenerator::~MovementGenerator()
|
MovementGenerator::~MovementGenerator()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MovementGenerator* IdleMovementFactory::Create(Unit* /*object*/) const
|
||||||
|
{
|
||||||
|
static IdleMovementGenerator instance;
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|||||||
@@ -82,19 +82,28 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SelectableMovement : public FactoryHolder<MovementGenerator, MovementGeneratorType>
|
typedef FactoryHolder<MovementGenerator, Unit, MovementGeneratorType> MovementGeneratorCreator;
|
||||||
|
|
||||||
|
template<class Movement>
|
||||||
|
struct MovementGeneratorFactory : public MovementGeneratorCreator
|
||||||
{
|
{
|
||||||
SelectableMovement(MovementGeneratorType mgt) : FactoryHolder<MovementGenerator, MovementGeneratorType>(mgt) {}
|
MovementGeneratorFactory(MovementGeneratorType movementGeneratorType) : MovementGeneratorCreator(movementGeneratorType) { }
|
||||||
|
|
||||||
|
MovementGenerator* Create(Unit* /*object*/) const
|
||||||
|
{
|
||||||
|
return new Movement();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class REAL_MOVEMENT>
|
struct IdleMovementFactory : public MovementGeneratorCreator
|
||||||
struct MovementGeneratorFactory : public SelectableMovement
|
|
||||||
{
|
{
|
||||||
MovementGeneratorFactory(MovementGeneratorType mgt) : SelectableMovement(mgt) {}
|
IdleMovementFactory() : MovementGeneratorCreator(IDLE_MOTION_TYPE) { }
|
||||||
|
|
||||||
MovementGenerator* Create(void*) const;
|
MovementGenerator* Create(Unit* object) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef FactoryHolder<MovementGenerator, MovementGeneratorType> MovementGeneratorCreator;
|
typedef MovementGeneratorCreator::FactoryHolderRegistry MovementGeneratorRegistry;
|
||||||
typedef FactoryHolder<MovementGenerator, MovementGeneratorType>::FactoryHolderRegistry MovementGeneratorRegistry;
|
|
||||||
|
#define sMovementGeneratorRegistry MovementGeneratorRegistry::instance()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Affero General Public License as published by the
|
|
||||||
* Free Software Foundation; either version 3 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 Affero General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ACORE_MOVEMENTGENERATOR_IMPL_H
|
|
||||||
#define ACORE_MOVEMENTGENERATOR_IMPL_H
|
|
||||||
|
|
||||||
#include "MovementGenerator.h"
|
|
||||||
|
|
||||||
template<class MOVEMENT_GEN>
|
|
||||||
inline MovementGenerator*
|
|
||||||
MovementGeneratorFactory<MOVEMENT_GEN>::Create(void* /*data*/) const
|
|
||||||
{
|
|
||||||
return (new MOVEMENT_GEN());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -19,8 +19,6 @@
|
|||||||
#include "Creature.h"
|
#include "Creature.h"
|
||||||
#include "CreatureAI.h"
|
#include "CreatureAI.h"
|
||||||
|
|
||||||
IdleMovementGenerator si_idleMovement;
|
|
||||||
|
|
||||||
// StopMoving is needed to make unit stop if its last movement generator expires
|
// StopMoving is needed to make unit stop if its last movement generator expires
|
||||||
// But it should not be sent otherwise there are many redundent packets
|
// But it should not be sent otherwise there are many redundent packets
|
||||||
void IdleMovementGenerator::Initialize(Unit* owner)
|
void IdleMovementGenerator::Initialize(Unit* owner)
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ public:
|
|||||||
MovementGeneratorType GetMovementGeneratorType() override { return IDLE_MOTION_TYPE; }
|
MovementGeneratorType GetMovementGeneratorType() override { return IDLE_MOTION_TYPE; }
|
||||||
};
|
};
|
||||||
|
|
||||||
extern IdleMovementGenerator si_idleMovement;
|
|
||||||
|
|
||||||
class RotateMovementGenerator : public MovementGenerator
|
class RotateMovementGenerator : public MovementGenerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -16,10 +16,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MapBuilder.h"
|
#include "MapBuilder.h"
|
||||||
|
#include "IntermediateValues.h"
|
||||||
#include "MapDefines.h"
|
#include "MapDefines.h"
|
||||||
#include "MapTree.h"
|
#include "MapTree.h"
|
||||||
#include "ModelInstance.h"
|
#include "ModelInstance.h"
|
||||||
#include "PathCommon.h"
|
#include "PathCommon.h"
|
||||||
|
#include "StringFormat.h"
|
||||||
|
#include "VMapFactory.h"
|
||||||
|
#include "VMapMgr2.h"
|
||||||
#include <DetourCommon.h>
|
#include <DetourCommon.h>
|
||||||
#include <DetourNavMesh.h>
|
#include <DetourNavMesh.h>
|
||||||
#include <DetourNavMeshBuilder.h>
|
#include <DetourNavMeshBuilder.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user