mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01:37:00 +00:00
[12676] AI-Event throwing and receiving implementation
Add new AI hooks to * SendAIEvent (either around the npc, or to a specified npc) * ReceiveAIEvent (hook to receive sent events)
This commit is contained in:
parent
60a7bec73f
commit
c7a07a7dc6
5 changed files with 141 additions and 63 deletions
|
|
@ -20,6 +20,9 @@
|
|||
#include "Creature.h"
|
||||
#include "DBCStores.h"
|
||||
#include "Spell.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "CellImpl.h"
|
||||
|
||||
CreatureAI::~CreatureAI()
|
||||
{
|
||||
|
|
@ -152,3 +155,79 @@ void CreatureAI::HandleMovementOnAttackStart(Unit* victim)
|
|||
m_creature->StopMoving();
|
||||
}
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Event system
|
||||
// ////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class AiDelayEventAround : public BasicEvent
|
||||
{
|
||||
public:
|
||||
AiDelayEventAround(AIEventType eventType, ObjectGuid invokerGuid, Creature& owner, std::list<Creature*> const& receivers) :
|
||||
BasicEvent(),
|
||||
m_eventType(eventType),
|
||||
m_invokerGuid(invokerGuid),
|
||||
m_owner(owner)
|
||||
{
|
||||
// Pushing guids because in delay can happen some creature gets despawned => invalid pointer
|
||||
m_receiverGuids.reserve(receivers.size());
|
||||
for (std::list<Creature*>::const_iterator itr = receivers.begin(); itr != receivers.end(); ++itr)
|
||||
m_receiverGuids.push_back((*itr)->GetObjectGuid());
|
||||
}
|
||||
|
||||
bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) override
|
||||
{
|
||||
Unit* pInvoker = m_owner.GetMap()->GetUnit(m_invokerGuid);
|
||||
|
||||
for (GuidVector::const_reverse_iterator itr = m_receiverGuids.rbegin(); itr != m_receiverGuids.rend(); ++itr)
|
||||
{
|
||||
if (Creature* pReceiver = m_owner.GetMap()->GetAnyTypeCreature(*itr))
|
||||
{
|
||||
pReceiver->AI()->ReceiveAIEvent(m_eventType, &m_owner, pInvoker);
|
||||
// Special case for type 0 (call-assistance)
|
||||
if (m_eventType == AI_EVENT_CALL_ASSISTANCE && pInvoker && pReceiver->CanAssistTo(&m_owner, pInvoker))
|
||||
{
|
||||
pReceiver->SetNoCallAssistance(true);
|
||||
pReceiver->AI()->AttackStart(pInvoker);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_receiverGuids.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
AiDelayEventAround();
|
||||
|
||||
ObjectGuid m_invokerGuid;
|
||||
GuidVector m_receiverGuids;
|
||||
Creature& m_owner;
|
||||
|
||||
AIEventType m_eventType;
|
||||
};
|
||||
|
||||
void CreatureAI::SendAIEvent(AIEventType eventType, Unit* pInvoker, uint32 uiDelay, float fRadius) const
|
||||
{
|
||||
if (fRadius > 0)
|
||||
{
|
||||
std::list<Creature*> receiverList;
|
||||
|
||||
// Use this check here to collect only assitable creatures in case of CALL_ASSISTANCE, else be less strict
|
||||
MaNGOS::AnyAssistCreatureInRangeCheck u_check(m_creature, eventType == AI_EVENT_CALL_ASSISTANCE ? pInvoker : NULL, fRadius);
|
||||
MaNGOS::CreatureListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck> searcher(receiverList, u_check);
|
||||
Cell::VisitGridObjects(m_creature, searcher, fRadius);
|
||||
|
||||
if (!receiverList.empty())
|
||||
{
|
||||
AiDelayEventAround* e = new AiDelayEventAround(eventType, pInvoker ? pInvoker->GetObjectGuid() : ObjectGuid(), *m_creature, receiverList);
|
||||
m_creature->m_Events.AddEvent(e, m_creature->m_Events.CalculateTime(uiDelay));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureAI::SendAIEvent(AIEventType eventType, Unit* pInvoker, Creature* pReceiver) const
|
||||
{
|
||||
MANGOS_ASSERT(pReceiver);
|
||||
pReceiver->AI()->ReceiveAIEvent(eventType, m_creature, pInvoker);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue