mirror of
https://github.com/azerothcore/mod-ale
synced 2025-11-29 15:38:17 +08:00
Feat(AllCreatureEvent): Add RegisterAllCreatureEvent and support for CreatureTemplate object. (#312)
This commit is contained in:
@@ -57,6 +57,7 @@ public:
|
||||
void OnCreatureAddWorld(Creature* creature) override
|
||||
{
|
||||
sEluna->OnAddToWorld(creature);
|
||||
sEluna->OnAllCreatureAddToWorld(creature);
|
||||
|
||||
if (creature->IsGuardian() && creature->ToTempSummon() && creature->ToTempSummon()->GetSummonerGUID().IsPlayer())
|
||||
sEluna->OnPetAddedToWorld(creature->ToTempSummon()->GetSummonerUnit()->ToPlayer(), creature);
|
||||
@@ -65,6 +66,7 @@ public:
|
||||
void OnCreatureRemoveWorld(Creature* creature) override
|
||||
{
|
||||
sEluna->OnRemoveFromWorld(creature);
|
||||
sEluna->OnAllCreatureRemoveFromWorld(creature);
|
||||
}
|
||||
|
||||
bool CanCreatureQuestAccept(Player* player, Creature* creature, Quest const* quest) override
|
||||
@@ -92,6 +94,16 @@ public:
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OnCreatureSelectLevel(const CreatureTemplate* cinfo, Creature* creature) override
|
||||
{
|
||||
sEluna->OnAllCreatureSelectLevel(cinfo, creature);
|
||||
}
|
||||
|
||||
void OnBeforeCreatureSelectLevel(const CreatureTemplate* cinfo, Creature* creature, uint8& level) override
|
||||
{
|
||||
sEluna->OnAllCreatureBeforeSelectLevel(cinfo, creature, level);
|
||||
}
|
||||
};
|
||||
|
||||
class Eluna_AllGameObjectScript : public AllGameObjectScript
|
||||
|
||||
@@ -88,6 +88,7 @@ namespace Hooks
|
||||
REGTYPE_INSTANCE,
|
||||
REGTYPE_TICKET,
|
||||
REGTYPE_SPELL,
|
||||
REGTYPE_ALL_CREATURE,
|
||||
REGTYPE_COUNT
|
||||
};
|
||||
|
||||
@@ -398,6 +399,15 @@ namespace Hooks
|
||||
SPELL_EVENT_ON_CAST_CANCEL = 3, // (event, caster, spell, bySelf)
|
||||
SPELL_EVENT_COUNT
|
||||
};
|
||||
|
||||
enum AllCreatureEvents
|
||||
{
|
||||
ALL_CREATURE_EVENT_ON_ADD = 1, // (event, creature)
|
||||
ALL_CREATURE_EVENT_ON_REMOVE = 2, // (event, creature)
|
||||
ALL_CREATURE_EVENT_ON_SELECT_LEVEL = 3, // (event, creature_template, creature)
|
||||
ALL_CREATURE_EVENT_ON_BEFORE_SELECT_LEVEL = 4, // (event, creature_template, creature, level) - Can return the new level
|
||||
ALL_CREATURE_EVENT_COUNT
|
||||
};
|
||||
};
|
||||
|
||||
#endif // _HOOKS_H
|
||||
|
||||
@@ -194,6 +194,7 @@ GuildEventBindings(NULL),
|
||||
GroupEventBindings(NULL),
|
||||
VehicleEventBindings(NULL),
|
||||
BGEventBindings(NULL),
|
||||
AllCreatureEventBindings(NULL),
|
||||
|
||||
PacketEventBindings(NULL),
|
||||
CreatureEventBindings(NULL),
|
||||
@@ -298,6 +299,7 @@ void Eluna::CreateBindStores()
|
||||
VehicleEventBindings = new BindingMap< EventKey<Hooks::VehicleEvents> >(L);
|
||||
BGEventBindings = new BindingMap< EventKey<Hooks::BGEvents> >(L);
|
||||
TicketEventBindings = new BindingMap< EventKey<Hooks::TicketEvents> >(L);
|
||||
AllCreatureEventBindings = new BindingMap< EventKey<Hooks::AllCreatureEvents> >(L);
|
||||
|
||||
PacketEventBindings = new BindingMap< EntryKey<Hooks::PacketEvents> >(L);
|
||||
CreatureEventBindings = new BindingMap< EntryKey<Hooks::CreatureEvents> >(L);
|
||||
@@ -321,6 +323,7 @@ void Eluna::DestroyBindStores()
|
||||
delete GuildEventBindings;
|
||||
delete GroupEventBindings;
|
||||
delete VehicleEventBindings;
|
||||
delete AllCreatureEventBindings;
|
||||
|
||||
delete PacketEventBindings;
|
||||
delete CreatureEventBindings;
|
||||
@@ -342,6 +345,7 @@ void Eluna::DestroyBindStores()
|
||||
GuildEventBindings = NULL;
|
||||
GroupEventBindings = NULL;
|
||||
VehicleEventBindings = NULL;
|
||||
AllCreatureEventBindings = NULL;
|
||||
|
||||
PacketEventBindings = NULL;
|
||||
CreatureEventBindings = NULL;
|
||||
@@ -1034,6 +1038,11 @@ void Eluna::Push(lua_State* luastate, SpellEntry const& spell)
|
||||
Push(luastate, &spell);
|
||||
}
|
||||
|
||||
void Eluna::Push(lua_State* luastate, CreatureTemplate const* creatureTemplate)
|
||||
{
|
||||
Push<CreatureTemplate>(luastate, creatureTemplate);
|
||||
}
|
||||
|
||||
std::string Eluna::FormatQuery(lua_State* L, const char* query)
|
||||
{
|
||||
int numArgs = lua_gettop(L);
|
||||
@@ -1476,6 +1485,7 @@ int Eluna::Register(lua_State* L, uint8 regtype, uint32 entry, ObjectGuid guid,
|
||||
return 1; // Stack: callback
|
||||
}
|
||||
break;
|
||||
|
||||
case Hooks::REGTYPE_MAP:
|
||||
if (event_id < Hooks::INSTANCE_EVENT_COUNT)
|
||||
{
|
||||
@@ -1485,6 +1495,7 @@ int Eluna::Register(lua_State* L, uint8 regtype, uint32 entry, ObjectGuid guid,
|
||||
return 1; // Stack: callback
|
||||
}
|
||||
break;
|
||||
|
||||
case Hooks::REGTYPE_INSTANCE:
|
||||
if (event_id < Hooks::INSTANCE_EVENT_COUNT)
|
||||
{
|
||||
@@ -1494,6 +1505,7 @@ int Eluna::Register(lua_State* L, uint8 regtype, uint32 entry, ObjectGuid guid,
|
||||
return 1; // Stack: callback
|
||||
}
|
||||
break;
|
||||
|
||||
case Hooks::REGTYPE_TICKET:
|
||||
if (event_id < Hooks::TICKET_EVENT_COUNT)
|
||||
{
|
||||
@@ -1503,6 +1515,7 @@ int Eluna::Register(lua_State* L, uint8 regtype, uint32 entry, ObjectGuid guid,
|
||||
return 1; // Stack: callback
|
||||
}
|
||||
break;
|
||||
|
||||
case Hooks::REGTYPE_SPELL:
|
||||
if (event_id < Hooks::SPELL_EVENT_COUNT)
|
||||
{
|
||||
@@ -1519,6 +1532,16 @@ int Eluna::Register(lua_State* L, uint8 regtype, uint32 entry, ObjectGuid guid,
|
||||
return 1; // Stack: callback
|
||||
}
|
||||
break;
|
||||
|
||||
case Hooks::REGTYPE_ALL_CREATURE:
|
||||
if (event_id < Hooks::ALL_CREATURE_EVENT_COUNT)
|
||||
{
|
||||
auto key = EventKey<Hooks::AllCreatureEvents>((Hooks::AllCreatureEvents)event_id);
|
||||
bindingID = AllCreatureEventBindings->Insert(key, functionRef, shots);
|
||||
createCancelCallback(L, bindingID, AllCreatureEventBindings);
|
||||
return 1; // Stack: callback
|
||||
}
|
||||
break;
|
||||
}
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, functionRef);
|
||||
std::ostringstream oss;
|
||||
|
||||
@@ -226,6 +226,7 @@ private:
|
||||
void Push(const std::string& value) { Push(L, value); ++push_counter; }
|
||||
void Push(const char* value) { Push(L, value); ++push_counter; }
|
||||
void Push(ObjectGuid const value) { Push(L, value); ++push_counter; }
|
||||
void Push(const CreatureTemplate* value) { Push(L, value); ++push_counter; }
|
||||
template<typename T>
|
||||
void Push(T const* ptr) { Push(L, ptr); ++push_counter; }
|
||||
|
||||
@@ -244,6 +245,7 @@ public:
|
||||
BindingMap< EventKey<Hooks::GroupEvents> >* GroupEventBindings;
|
||||
BindingMap< EventKey<Hooks::VehicleEvents> >* VehicleEventBindings;
|
||||
BindingMap< EventKey<Hooks::BGEvents> >* BGEventBindings;
|
||||
BindingMap< EventKey<Hooks::AllCreatureEvents> >* AllCreatureEventBindings;
|
||||
|
||||
BindingMap< EntryKey<Hooks::PacketEvents> >* PacketEventBindings;
|
||||
BindingMap< EntryKey<Hooks::CreatureEvents> >* CreatureEventBindings;
|
||||
@@ -299,6 +301,7 @@ public:
|
||||
static void Push(lua_State* luastate, ObjectGuid const guid);
|
||||
static void Push(lua_State* luastate, GemPropertiesEntry const& gemProperties);
|
||||
static void Push(lua_State* luastate, SpellEntry const& spell);
|
||||
static void Push(lua_State* luastate, CreatureTemplate const* creatureTemplate);
|
||||
template<typename T>
|
||||
static void Push(lua_State* luastate, T const* ptr)
|
||||
{
|
||||
@@ -588,6 +591,12 @@ public:
|
||||
void OnSpellPrepare(Unit* caster, Spell* spell, SpellInfo const* spellInfo);
|
||||
void OnSpellCast(Unit* caster, Spell* spell, SpellInfo const* spellInfo, bool skipCheck);
|
||||
void OnSpellCastCancel(Unit* caster, Spell* spell, SpellInfo const* spellInfo, bool bySelf);
|
||||
|
||||
/* AllCreature */
|
||||
void OnAllCreatureAddToWorld(Creature* creature);
|
||||
void OnAllCreatureRemoveFromWorld(Creature* creature);
|
||||
void OnAllCreatureSelectLevel(const CreatureTemplate* cinfo, Creature* creature);
|
||||
void OnAllCreatureBeforeSelectLevel(const CreatureTemplate* cinfo, Creature* creature, uint8& level);
|
||||
};
|
||||
template<> Unit* Eluna::CHECKOBJ<Unit>(lua_State* L, int narg, bool error);
|
||||
template<> Object* Eluna::CHECKOBJ<Object>(lua_State* L, int narg, bool error);
|
||||
|
||||
@@ -70,6 +70,8 @@ luaL_Reg GlobalMethods[] =
|
||||
{ "RegisterInstanceEvent", &LuaGlobalFunctions::RegisterInstanceEvent },
|
||||
{ "RegisterTicketEvent", &LuaGlobalFunctions::RegisterTicketEvent },
|
||||
{ "RegisterSpellEvent", &LuaGlobalFunctions::RegisterSpellEvent },
|
||||
{ "RegisterAllCreatureEvent", &LuaGlobalFunctions::RegisterAllCreatureEvent },
|
||||
|
||||
|
||||
{ "ClearBattleGroundEvents", &LuaGlobalFunctions::ClearBattleGroundEvents },
|
||||
{ "ClearCreatureEvents", &LuaGlobalFunctions::ClearCreatureEvents },
|
||||
@@ -89,6 +91,7 @@ luaL_Reg GlobalMethods[] =
|
||||
{ "ClearInstanceEvents", &LuaGlobalFunctions::ClearInstanceEvents },
|
||||
{ "ClearTicketEvents", &LuaGlobalFunctions::ClearTicketEvents },
|
||||
{ "ClearSpellEvents", &LuaGlobalFunctions::ClearSpellEvents },
|
||||
{ "ClearAllCreatureEvents", &LuaGlobalFunctions::ClearAllCreatureEvents },
|
||||
|
||||
// Getters
|
||||
{ "GetLuaEngine", &LuaGlobalFunctions::GetLuaEngine },
|
||||
@@ -1941,6 +1944,8 @@ void RegisterFunctions(Eluna* E)
|
||||
ElunaTemplate<SpellEntry>::Register(E, "SpellEntry");
|
||||
ElunaTemplate<SpellEntry>::SetMethods(E, SpellEntryMethods);
|
||||
|
||||
ElunaTemplate<CreatureTemplate>::Register(E, "CreatureTemplate");
|
||||
|
||||
ElunaTemplate<long long>::Register(E, "long long", true);
|
||||
|
||||
ElunaTemplate<unsigned long long>::Register(E, "unsigned long long", true);
|
||||
|
||||
78
src/LuaEngine/hooks/AllCreatureHooks.cpp
Normal file
78
src/LuaEngine/hooks/AllCreatureHooks.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2010 - 2016 Eluna Lua Engine <http://emudevs.com/>
|
||||
* This program is free software licensed under GPL version 3
|
||||
* Please see the included DOCS/LICENSE.md for more information
|
||||
*/
|
||||
|
||||
#include "Hooks.h"
|
||||
#include "HookHelpers.h"
|
||||
#include "LuaEngine.h"
|
||||
#include "BindingMap.h"
|
||||
#include "ElunaIncludes.h"
|
||||
#include "ElunaTemplate.h"
|
||||
|
||||
using namespace Hooks;
|
||||
|
||||
#define START_HOOK(EVENT) \
|
||||
if (!ElunaConfig::GetInstance().IsElunaEnabled())\
|
||||
return;\
|
||||
auto key = EventKey<AllCreatureEvents>(EVENT);\
|
||||
if (!AllCreatureEventBindings->HasBindingsFor(key))\
|
||||
return;\
|
||||
LOCK_ELUNA
|
||||
|
||||
#define START_HOOK_WITH_RETVAL(EVENT, RETVAL) \
|
||||
if (!ElunaConfig::GetInstance().IsElunaEnabled())\
|
||||
return RETVAL;\
|
||||
auto key = EventKey<AllCreatureEvents>(EVENT);\
|
||||
if (!AllCreatureEventBindings->HasBindingsFor(key))\
|
||||
return RETVAL;\
|
||||
LOCK_ELUNA
|
||||
|
||||
void Eluna::OnAllCreatureAddToWorld(Creature* creature)
|
||||
{
|
||||
START_HOOK(ALL_CREATURE_EVENT_ON_ADD);
|
||||
Push(creature);
|
||||
CallAllFunctions(AllCreatureEventBindings, key);
|
||||
}
|
||||
|
||||
void Eluna::OnAllCreatureRemoveFromWorld(Creature* creature)
|
||||
{
|
||||
START_HOOK(ALL_CREATURE_EVENT_ON_REMOVE);
|
||||
Push(creature);
|
||||
CallAllFunctions(AllCreatureEventBindings, key);
|
||||
}
|
||||
|
||||
void Eluna::OnAllCreatureSelectLevel(const CreatureTemplate* cinfo, Creature* creature)
|
||||
{
|
||||
START_HOOK(ALL_CREATURE_EVENT_ON_SELECT_LEVEL);
|
||||
Push(cinfo);
|
||||
Push(creature);
|
||||
CallAllFunctions(AllCreatureEventBindings, key);
|
||||
}
|
||||
|
||||
void Eluna::OnAllCreatureBeforeSelectLevel(const CreatureTemplate* cinfo, Creature* creature, uint8& level)
|
||||
{
|
||||
START_HOOK(ALL_CREATURE_EVENT_ON_BEFORE_SELECT_LEVEL);
|
||||
Push(cinfo);
|
||||
Push(creature);
|
||||
Push(level);
|
||||
int levelIndex = lua_gettop(L);
|
||||
int n = SetupStack(AllCreatureEventBindings, key, 3);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 3, 1);
|
||||
|
||||
if (lua_isnumber(L, r))
|
||||
{
|
||||
level = CHECKVAL<uint8>(L, r);
|
||||
// Update the stack for subsequent calls.
|
||||
ReplaceArgument(level, levelIndex);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
CleanUpStack(3);
|
||||
}
|
||||
@@ -1336,6 +1336,29 @@ namespace LuaGlobalFunctions
|
||||
return RegisterEntryHelper(L, Hooks::REGTYPE_SPELL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a [Creature] event handler. It used AllCreatureScript so this don't need creature entry as a key.
|
||||
*
|
||||
* <pre>
|
||||
* enum AllCreatureEvents
|
||||
* {
|
||||
* ALL_CREATURE_EVENT_ON_ADD = 1, // (event, creature)
|
||||
* ALL_CREATURE_EVENT_ON_REMOVE = 2, // (event, creature)
|
||||
* ALL_CREATURE_EVENT_ON_SELECT_LEVEL = 3, // (event, creature_template, creature)
|
||||
* ALL_CREATURE_EVENT_ON_BEFORE_SELECT_LEVEL = 4, // (event, creature_template, creature, level) - Can return the new level
|
||||
* ALL_CREATURE_EVENT_COUNT
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* @param uint32 event : event ID, refer to AllCreatureEvents above
|
||||
* @param function function : function to register
|
||||
* @param uint32 shots = 0 : the number of times the function will be called, 0 means "always call this function"
|
||||
*/
|
||||
int RegisterAllCreatureEvent(lua_State* L)
|
||||
{
|
||||
return RegisterEventHelper(L, Hooks::REGTYPE_ALL_CREATURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the Lua engine.
|
||||
*/
|
||||
@@ -3302,6 +3325,33 @@ namespace LuaGlobalFunctions
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbinds event handlers for either all [Creature] events, or one type of [Creature] event.
|
||||
*
|
||||
* If `event_type` is `nil`, all [Creature] event handlers are cleared.
|
||||
*
|
||||
* Otherwise, only event handlers for `event_type` are cleared.
|
||||
*
|
||||
* @proto ()
|
||||
* @proto (event_type)
|
||||
* @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterAllCreatureEvent]
|
||||
*/
|
||||
int ClearAllCreatureEvents(lua_State* L)
|
||||
{
|
||||
typedef EventKey<Hooks::AllCreatureEvents> Key;
|
||||
|
||||
if (lua_isnoneornil(L, 1))
|
||||
{
|
||||
Eluna::GetEluna(L)->AllCreatureEventBindings->Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 event_type = Eluna::CHECKVAL<uint32>(L, 1);
|
||||
Eluna::GetEluna(L)->AllCreatureEventBindings->Clear(Key((Hooks::AllCreatureEvents)event_type));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the faction which is the current owner of Halaa in Nagrand
|
||||
* 0 = Alliance
|
||||
|
||||
Reference in New Issue
Block a user