Skip to content

Commit cdeeadf

Browse files
Niam5mostlikely4r
andcommitted
-PlayerbotAI implementation: Hooks (On update ai, on trigger check, on action execute), Methods (GetBot, GetAIValue, IsTriggerActive, ExecuteCommand)
Co-Authored-By: mostlikely4r <[email protected]>
1 parent f654490 commit cdeeadf

18 files changed

+409
-10
lines changed

BindingMap.h

+43
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,24 @@ struct UniqueObjectKey
249249
{ }
250250
};
251251

252+
#if defined ELUNA_PLAYERBOTS
253+
/*
254+
* A `BindingMap` key type for event ID/String bindings
255+
* (currently just PlayerbotAI).
256+
*/
257+
template <typename T>
258+
struct StringKey
259+
{
260+
T event_id;
261+
std::string qualifier;
262+
263+
StringKey(T event_id, std::string qualifier) :
264+
event_id(event_id),
265+
qualifier(qualifier)
266+
{ }
267+
};
268+
#endif
269+
252270
class hash_helper
253271
{
254272
public:
@@ -326,6 +344,18 @@ namespace std
326344
}
327345
};
328346

347+
#if defined ELUNA_PLAYERBOTS
348+
template<typename T>
349+
struct equal_to < StringKey<T> >
350+
{
351+
bool operator()(StringKey<T> const& lhs, StringKey<T> const& rhs) const
352+
{
353+
return lhs.event_id == rhs.event_id
354+
&& (lhs.qualifier.empty() || rhs.qualifier.empty() || lhs.qualifier == rhs.qualifier);
355+
}
356+
};
357+
#endif
358+
329359
template<typename T>
330360
struct hash < EventKey<T> >
331361
{
@@ -358,6 +388,19 @@ namespace std
358388
return hash_helper::hash(k.event_id, k.instance_id, k.guid);
359389
}
360390
};
391+
392+
#if defined ELUNA_PLAYERBOTS
393+
template<typename T>
394+
struct hash < StringKey<T> >
395+
{
396+
typedef StringKey<T> argument_type;
397+
398+
hash_helper::result_type operator()(argument_type const& k) const
399+
{
400+
return hash_helper::hash(k.event_id, k.qualifier);
401+
}
402+
};
403+
#endif
361404
}
362405

363406
#endif // _BINDING_MAP_H

ElunaIncludes.h

+4
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@
120120
#endif
121121
#endif
122122

123+
#if defined ELUNA_PLAYERBOTS
124+
#include "playerbot/PlayerbotAI.h"
125+
#endif
126+
123127
#if !defined ELUNA_MANGOS
124128
#if ELUNA_EXPANSION > EXP_CLASSIC
125129
typedef Opcodes OpcodesList;

ElunaTemplate.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ ElunaConstrainedObjectRef<BattleGround> GetWeakPtrFor(BattleGround const* obj) {
2424
ElunaConstrainedObjectRef<Group> GetWeakPtrFor(Group const* obj) { return { obj->GetWeakPtr(), nullptr }; }
2525
ElunaConstrainedObjectRef<Guild> GetWeakPtrFor(Guild const* obj) { return { obj->GetWeakPtr(), nullptr }; }
2626
ElunaConstrainedObjectRef<Map> GetWeakPtrFor(Map const* obj) { return { obj->GetWeakPtr(), obj }; }
27+
#if defined ELUNA_PLAYERBOTS
28+
ElunaConstrainedObjectRef<PlayerbotAI> GetWeakPtrFor(PlayerbotAI const* obj) { return { obj->GetWeakPtr(), nullptr }; }
29+
#endif
2730
ElunaConstrainedObjectRef<Object> GetWeakPtrForObjectImpl(Object const* obj)
2831
{
2932
if (obj->isType(TYPEMASK_WORLDOBJECT))

ElunaTemplate.h

+3
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ ElunaConstrainedObjectRef<Map> GetWeakPtrFor(Map const* obj);
6868
ElunaConstrainedObjectRef<Object> GetWeakPtrForObjectImpl(Object const* obj);
6969
ElunaConstrainedObjectRef<Quest> GetWeakPtrFor(Quest const* obj);
7070
ElunaConstrainedObjectRef<Spell> GetWeakPtrFor(Spell const* obj);
71+
#if defined ELUNA_PLAYERBOTS
72+
ElunaConstrainedObjectRef<PlayerbotAI> GetWeakPtrFor(PlayerbotAI const* obj);
73+
#endif
7174
#if ELUNA_EXPANSION >= EXP_WOTLK
7275
ElunaConstrainedObjectRef<Vehicle> GetWeakPtrFor(Vehicle const* obj);
7376
#endif

LuaEngine.cpp

+29-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ eventMgr(NULL),
5757

5858
ServerEventBindings(NULL),
5959
PlayerEventBindings(NULL),
60+
#if defined ELUNA_PLAYERBOTS
61+
PlayerbotAIEventBindings(NULL),
62+
#endif
6063
GuildEventBindings(NULL),
6164
GroupEventBindings(NULL),
6265
VehicleEventBindings(NULL),
@@ -181,6 +184,9 @@ void Eluna::CreateBindStores()
181184

182185
ServerEventBindings = new BindingMap< EventKey<Hooks::ServerEvents> >(L);
183186
PlayerEventBindings = new BindingMap< EventKey<Hooks::PlayerEvents> >(L);
187+
#if defined ELUNA_PLAYERBOTS
188+
PlayerbotAIEventBindings = new BindingMap< StringKey<Hooks::PlayerbotAIEvents> >(L);
189+
#endif
184190
GuildEventBindings = new BindingMap< EventKey<Hooks::GuildEvents> >(L);
185191
GroupEventBindings = new BindingMap< EventKey<Hooks::GroupEvents> >(L);
186192
VehicleEventBindings = new BindingMap< EventKey<Hooks::VehicleEvents> >(L);
@@ -205,6 +211,9 @@ void Eluna::DestroyBindStores()
205211
{
206212
delete ServerEventBindings;
207213
delete PlayerEventBindings;
214+
#if defined ELUNA_PLAYERBOTS
215+
delete PlayerbotAIEventBindings;
216+
#endif
208217
delete GuildEventBindings;
209218
delete GroupEventBindings;
210219
delete VehicleEventBindings;
@@ -226,6 +235,9 @@ void Eluna::DestroyBindStores()
226235

227236
ServerEventBindings = NULL;
228237
PlayerEventBindings = NULL;
238+
#if defined ELUNA_PLAYERBOTS
239+
PlayerbotAIEventBindings = NULL;
240+
#endif
229241
GuildEventBindings = NULL;
230242
GroupEventBindings = NULL;
231243
VehicleEventBindings = NULL;
@@ -732,7 +744,11 @@ static void createCancelCallback(Eluna* e, uint64 bindingID, BindingMap<K>* bind
732744
}
733745

734746
// Saves the function reference ID given to the register type's store for given entry under the given event
735-
int Eluna::Register(uint8 regtype, uint32 entry, ObjectGuid guid, uint32 instanceId, uint32 event_id, int functionRef, uint32 shots)
747+
int Eluna::Register(uint8 regtype, uint32 entry, ObjectGuid guid, uint32 instanceId, uint32 event_id, int functionRef, uint32 shots
748+
#if defined ELUNA_PLAYERBOTS
749+
, std::string qualifier
750+
#endif
751+
)
736752
{
737753
uint64 bindingID;
738754

@@ -768,6 +784,18 @@ int Eluna::Register(uint8 regtype, uint32 entry, ObjectGuid guid, uint32 instanc
768784
}
769785
break;
770786

787+
#if defined ELUNA_PLAYERBOTS
788+
case Hooks::REGTYPE_PLAYERBOTAI:
789+
if (event_id < Hooks::PLAYERBOTAI_EVENT_COUNT)
790+
{
791+
auto key = StringKey<Hooks::PlayerbotAIEvents>((Hooks::PlayerbotAIEvents)event_id, qualifier);
792+
bindingID = PlayerbotAIEventBindings->Insert(key, functionRef, shots);
793+
createCancelCallback(this, bindingID, PlayerbotAIEventBindings);
794+
return 1; // Stack: callback
795+
}
796+
break;
797+
#endif
798+
771799
case Hooks::REGTYPE_GROUP:
772800
if (event_id < Hooks::GROUP_EVENT_COUNT)
773801
{

LuaEngine.h

+22-1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ typedef VehicleInfo Vehicle;
100100
#endif
101101
#endif
102102

103+
#if defined ELUNA_PLAYERBOTS
104+
class PlayerbotAI;
105+
#endif
106+
103107
struct lua_State;
104108
class EventMgr;
105109
class ElunaObject;
@@ -109,6 +113,9 @@ template<typename K> class BindingMap;
109113
template<typename T> struct EventKey;
110114
template<typename T> struct EntryKey;
111115
template<typename T> struct UniqueObjectKey;
116+
#if defined ELUNA_PLAYERBOTS
117+
template<typename T> struct StringKey;
118+
#endif
112119

113120
struct LuaScript
114121
{
@@ -245,6 +252,9 @@ class ELUNA_GAME_API Eluna
245252

246253
BindingMap< EventKey<Hooks::ServerEvents> >* ServerEventBindings;
247254
BindingMap< EventKey<Hooks::PlayerEvents> >* PlayerEventBindings;
255+
#if defined ELUNA_PLAYERBOTS
256+
BindingMap< StringKey<Hooks::PlayerbotAIEvents> >* PlayerbotAIEventBindings;
257+
#endif
248258
BindingMap< EventKey<Hooks::GuildEvents> >* GuildEventBindings;
249259
BindingMap< EventKey<Hooks::GroupEvents> >* GroupEventBindings;
250260
BindingMap< EventKey<Hooks::VehicleEvents> >* VehicleEventBindings;
@@ -333,7 +343,11 @@ class ELUNA_GAME_API Eluna
333343
#if !defined TRACKABLE_PTR_NAMESPACE
334344
uint64 GetCallstackId() const { return callstackid; }
335345
#endif
336-
int Register(uint8 reg, uint32 entry, ObjectGuid guid, uint32 instanceId, uint32 event_id, int functionRef, uint32 shots);
346+
int Register(uint8 reg, uint32 entry, ObjectGuid guid, uint32 instanceId, uint32 event_id, int functionRef, uint32 shots
347+
#if defined ELUNA_PLAYERBOTS
348+
, std::string qualifier = ""
349+
#endif
350+
);
337351
void UpdateEluna(uint32 diff);
338352

339353
// Checks
@@ -513,6 +527,13 @@ class ELUNA_GAME_API Eluna
513527
void HandleGossipSelectOption(Player* pPlayer, uint32 menuId, uint32 sender, uint32 action, const std::string& code);
514528
void OnAchievementComplete(Player* pPlayer, uint32 achievementId);
515529

530+
#if defined ELUNA_PLAYERBOTS
531+
/* PlayerbotAI*/
532+
void OnUpdateAI(PlayerbotAI* pPlayer, std::string botName);
533+
void OnTriggerCheck(PlayerbotAI* ai, std::string triggerName, bool enabled);
534+
void OnActionExecute(PlayerbotAI* ai, std::string action, bool success);
535+
#endif
536+
516537
#if ELUNA_EXPANSION >= EXP_WOTLK
517538
/* Vehicle */
518539
void OnInstall(Vehicle* vehicle);

hooks/Hooks.h

+13
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ namespace Hooks
7373
REGTYPE_PACKET,
7474
REGTYPE_SERVER,
7575
REGTYPE_PLAYER,
76+
#if defined ELUNA_PLAYERBOTS
77+
REGTYPE_PLAYERBOTAI,
78+
#endif
7679
REGTYPE_GUILD,
7780
REGTYPE_GROUP,
7881
REGTYPE_CREATURE,
@@ -221,6 +224,16 @@ namespace Hooks
221224
PLAYER_EVENT_COUNT
222225
};
223226

227+
#if defined ELUNA_PLAYERBOTS
228+
enum PlayerbotAIEvents
229+
{
230+
PLAYERBOTAI_EVENT_ON_UPDATE_AI = 1, // (event, ai) - Qualifier: Bot name
231+
PLAYERBOTAI_EVENT_ON_TRIGGER_CHECK = 2, // (event, ai, trigger, triggered) - Qualifier: Trigger
232+
PLAYERBOTAI_EVENT_ON_ACTION_EXECUTE = 3, // (event, ai, action, executed) - Qualifier: Action
233+
PLAYERBOTAI_EVENT_COUNT
234+
};
235+
#endif
236+
224237
enum GuildEvents
225238
{
226239
// Guild

hooks/PlayerbotAIHooks.cpp

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (C) 2010 - 2024 Eluna Lua Engine <https://elunaluaengine.github.io/>
3+
* This program is free software licensed under GPL version 3
4+
* Please see the included DOCS/LICENSE.md for more information
5+
*/
6+
7+
#if defined ELUNA_PLAYERBOTS
8+
#include "Hooks.h"
9+
#include "HookHelpers.h"
10+
#include "LuaEngine.h"
11+
#include "BindingMap.h"
12+
#include "ElunaIncludes.h"
13+
#include "ElunaTemplate.h"
14+
#include "ElunaLoader.h"
15+
16+
using namespace Hooks;
17+
18+
#define START_HOOK(EVENT, QUALIFIER) \
19+
auto key = StringKey<PlayerbotAIEvents>(EVENT, QUALIFIER);\
20+
if (!PlayerbotAIEventBindings->HasBindingsFor(key))\
21+
return;\
22+
23+
#define START_HOOK_WITH_RETVAL(EVENT, QUALIFIER, RETVAL) \
24+
auto key = String<PlayerbotAIEvents>(EVENT, QUALIFIER);\
25+
if (!PlayerbotAIEventBindings->HasBindingsFor(key))\
26+
return RETVAL;\
27+
28+
void Eluna::OnUpdateAI(PlayerbotAI* ai, std::string botName)
29+
{
30+
START_HOOK(PLAYERBOTAI_EVENT_ON_UPDATE_AI, botName);
31+
Push(ai);
32+
CallAllFunctions(PlayerbotAIEventBindings, key);
33+
}
34+
void Eluna::OnTriggerCheck(PlayerbotAI* ai, std::string trigger, bool enabled)
35+
{
36+
START_HOOK(PLAYERBOTAI_EVENT_ON_TRIGGER_CHECK, trigger);
37+
Push(ai);
38+
Push(trigger);
39+
Push(enabled);
40+
CallAllFunctions(PlayerbotAIEventBindings, key);
41+
}
42+
void Eluna::OnActionExecute(PlayerbotAI* ai, std::string action, bool success)
43+
{
44+
START_HOOK(PLAYERBOTAI_EVENT_ON_ACTION_EXECUTE, action);
45+
Push(ai);
46+
Push(action);
47+
Push(success);
48+
CallAllFunctions(PlayerbotAIEventBindings, key);
49+
}
50+
#endif //ELUNA_PLAYERBOTS

0 commit comments

Comments
 (0)