diff --git a/HookMgr.cpp b/HookMgr.cpp index 7e012c7..5e3f35d 100644 --- a/HookMgr.cpp +++ b/HookMgr.cpp @@ -8,6 +8,8 @@ #include "LuaEngine.h" #include "Includes.h" +using namespace HookMgr; + /* Call model for EventBind: @@ -30,26 +32,27 @@ ENDCALL(); lua_State* L = sEluna->L; \ uint32 _LuaEvent = EVENT; \ int _LuaStackTop = lua_gettop(L); \ - EventBind* _LuaBindMap = sEluna->BINDMAP; \ + for (int i = 0; i < sEluna->BINDMAP->Bindings[EVENT].size(); ++i) \ + lua_rawgeti(L, LUA_REGISTRYINDEX, (sEluna->BINDMAP->Bindings[EVENT][i])); \ + int _LuaFuncTop = lua_gettop(L); \ Eluna::Push(L, _LuaEvent); // use LUA_MULTRET for multiple return values // return values will be at top of stack if any #define EVENT_EXECUTE(RETVALS) \ int _LuaReturnValues = RETVALS; \ - int _LuaParams = lua_gettop(L) - _LuaStackTop; \ + int _LuaParams = lua_gettop(L) - _LuaFuncTop; \ if (_LuaParams < 1) \ - { \ + { \ ELUNA_LOG_ERROR("[Eluna]: Executing event %u, params was %i. Report to devs", _LuaEvent, _LuaParams); \ - } \ - for (EventBind::ElunaBindingMap::const_iterator it = _LuaBindMap->Bindings[_LuaEvent].begin(); it != _LuaBindMap->Bindings[_LuaEvent].end(); ++it) \ - { \ - lua_rawgeti(L, LUA_REGISTRYINDEX, (*it)); \ - int stacktop = lua_gettop(L); \ - for (int i = stacktop - _LuaParams; i < stacktop; ++i) \ - lua_pushvalue(L, i); \ + } \ + for (int j = _LuaFuncTop-_LuaStackTop; j > 0; --j) \ + { \ + for (int i = 0; i <= _LuaParams; ++i) \ + lua_pushvalue(L, _LuaFuncTop+i); \ Eluna::ExecuteCall(L, _LuaParams, _LuaReturnValues); \ - } \ + lua_remove(L, _LuaFuncTop--); \ + } \ for (int i = _LuaParams; i > 0; --i) \ if (!lua_isnone(L, i)) \ lua_remove(L, i); @@ -75,9 +78,9 @@ ENDCALL(); #define ENDCALL() \ if (_LuaReturnValues != LUA_MULTRET && lua_gettop(L) != _LuaStackTop + _LuaReturnValues) \ - { \ + { \ ELUNA_LOG_ERROR("[Eluna]: Ending event %u, stack top was %i and was supposed to be %i. Report to devs", _LuaEvent, lua_gettop(L), _LuaStackTop); \ - } \ + } \ lua_settop(L, _LuaStackTop); void Eluna::OnLuaStateClose() @@ -173,7 +176,7 @@ void Eluna::OnPacketSendAny(Player* player, WorldPacket& packet, bool& result) } void Eluna::OnPacketSendOne(Player* player, WorldPacket& packet, bool& result) { - ENTRY_BEGIN(PacketEventBindings, OpcodesList(packet.GetOpcode()), SERVER_EVENT_ON_PACKET_SEND, return); + ENTRY_BEGIN(PacketEventBindings, OpcodesList(packet.GetOpcode()), PACKET_EVENT_ON_PACKET_SEND, return); Push(L, new WorldPacket(packet)); Push(L, player); ENTRY_EXECUTE(2); @@ -224,7 +227,7 @@ void Eluna::OnPacketReceiveAny(Player* player, WorldPacket& packet, bool& result } void Eluna::OnPacketReceiveOne(Player* player, WorldPacket& packet, bool& result) { - ENTRY_BEGIN(PacketEventBindings, OpcodesList(packet.GetOpcode()), SERVER_EVENT_ON_PACKET_RECEIVE, return); + ENTRY_BEGIN(PacketEventBindings, OpcodesList(packet.GetOpcode()), PACKET_EVENT_ON_PACKET_RECEIVE, return); Push(L, new WorldPacket(packet)); Push(L, player); ENTRY_EXECUTE(2); @@ -473,7 +476,7 @@ bool Eluna::OnCommand(Player* player, const char* text) } } bool result = true; - EVENT_BEGIN(ServerEventBindings, PLAYER_EVENT_ON_COMMAND, return result); + EVENT_BEGIN(PlayerEventBindings, PLAYER_EVENT_ON_COMMAND, return result); Push(L, player); Push(L, fullcmd); EVENT_EXECUTE(1); diff --git a/HookMgr.h b/HookMgr.h index 6f66170..4d2983e 100644 --- a/HookMgr.h +++ b/HookMgr.h @@ -7,255 +7,263 @@ #ifndef LUAHOOKS_H #define LUAHOOKS_H -enum RegisterTypes +namespace HookMgr { - REGTYPE_PACKET, - REGTYPE_SERVER, - REGTYPE_PLAYER, - REGTYPE_GUILD, - REGTYPE_GROUP, - REGTYPE_CREATURE, - REGTYPE_VEHICLE, - REGTYPE_CREATURE_GOSSIP, - REGTYPE_GAMEOBJECT, - REGTYPE_GAMEOBJECT_GOSSIP, - REGTYPE_ITEM, - REGTYPE_ITEM_GOSSIP, - REGTYPE_PLAYER_GOSSIP, - REGTYPE_COUNT -}; + enum RegisterTypes + { + REGTYPE_PACKET, + REGTYPE_SERVER, + REGTYPE_PLAYER, + REGTYPE_GUILD, + REGTYPE_GROUP, + REGTYPE_CREATURE, + REGTYPE_VEHICLE, + REGTYPE_CREATURE_GOSSIP, + REGTYPE_GAMEOBJECT, + REGTYPE_GAMEOBJECT_GOSSIP, + REGTYPE_ITEM, + REGTYPE_ITEM_GOSSIP, + REGTYPE_PLAYER_GOSSIP, + REGTYPE_COUNT + }; -// RegisterPacketEvent(Opcode, event, function) -// SERVER_EVENT_ON_PACKET_RECEIVE = 5, // (event, packet, player) - Player only if accessible. Can return false or a new packet -// SERVER_EVENT_ON_PACKET_RECEIVE_UNKNOWN = 6, // Not Implemented -// SERVER_EVENT_ON_PACKET_SEND = 7, // (event, packet, player) - Player only if accessible. Can return false or a new packet + // RegisterPacketEvent(Opcode, event, function) + enum PacketEvents + { + PACKET_EVENT_ON_PACKET_RECEIVE = 5, // (event, packet, player) - Player only if accessible. Can return false or a new packet + PACKET_EVENT_ON_PACKET_RECEIVE_UNKNOWN = 6, // Not Implemented + PACKET_EVENT_ON_PACKET_SEND = 7, // (event, packet, player) - Player only if accessible. Can return false or a new packet -// RegisterServerEvent(EventId, function) -enum ServerEvents -{ - // Server - SERVER_EVENT_ON_NETWORK_START = 1, // Not Implemented - SERVER_EVENT_ON_NETWORK_STOP = 2, // Not Implemented - SERVER_EVENT_ON_SOCKET_OPEN = 3, // Not Implemented - SERVER_EVENT_ON_SOCKET_CLOSE = 4, // Not Implemented - SERVER_EVENT_ON_PACKET_RECEIVE = 5, // (event, packet, player) - Player only if accessible. Can return false or a new packet - SERVER_EVENT_ON_PACKET_RECEIVE_UNKNOWN = 6, // Not Implemented - SERVER_EVENT_ON_PACKET_SEND = 7, // (event, packet, player) - Player only if accessible. Can return false or a new packet + PACKET_EVENT_COUNT + }; - // World // Not implemented on mangos - WORLD_EVENT_ON_OPEN_STATE_CHANGE = 8, // (event, open) - WORLD_EVENT_ON_CONFIG_LOAD = 9, // (event, reload) - // UNUSED = 10, // (event) - WORLD_EVENT_ON_SHUTDOWN_INIT = 11, // (event, code, mask) - WORLD_EVENT_ON_SHUTDOWN_CANCEL = 12, // (event) - WORLD_EVENT_ON_UPDATE = 13, // (event, diff) - WORLD_EVENT_ON_STARTUP = 14, // (event) - WORLD_EVENT_ON_SHUTDOWN = 15, // (event) + // RegisterServerEvent(EventId, function) + enum ServerEvents + { + // Server + SERVER_EVENT_ON_NETWORK_START = 1, // Not Implemented + SERVER_EVENT_ON_NETWORK_STOP = 2, // Not Implemented + SERVER_EVENT_ON_SOCKET_OPEN = 3, // Not Implemented + SERVER_EVENT_ON_SOCKET_CLOSE = 4, // Not Implemented + SERVER_EVENT_ON_PACKET_RECEIVE = 5, // (event, packet, player) - Player only if accessible. Can return false or a new packet + SERVER_EVENT_ON_PACKET_RECEIVE_UNKNOWN = 6, // Not Implemented + SERVER_EVENT_ON_PACKET_SEND = 7, // (event, packet, player) - Player only if accessible. Can return false or a new packet - // Eluna - ELUNA_EVENT_ON_LUA_STATE_CLOSE = 16, // (event) + // World // Not implemented on mangos + WORLD_EVENT_ON_OPEN_STATE_CHANGE = 8, // (event, open) + WORLD_EVENT_ON_CONFIG_LOAD = 9, // (event, reload) + // UNUSED = 10, // (event) + WORLD_EVENT_ON_SHUTDOWN_INIT = 11, // (event, code, mask) + WORLD_EVENT_ON_SHUTDOWN_CANCEL = 12, // (event) + WORLD_EVENT_ON_UPDATE = 13, // (event, diff) + WORLD_EVENT_ON_STARTUP = 14, // (event) + WORLD_EVENT_ON_SHUTDOWN = 15, // (event) - // Map - MAP_EVENT_ON_CREATE = 17, // (event, map) - MAP_EVENT_ON_DESTROY = 18, // (event, map) - MAP_EVENT_ON_GRID_LOAD = 19, // Not Implemented - MAP_EVENT_ON_GRID_UNLOAD = 20, // Not Implemented - MAP_EVENT_ON_PLAYER_ENTER = 21, // (event, map, player) - MAP_EVENT_ON_PLAYER_LEAVE = 22, // (event, map, player) - MAP_EVENT_ON_UPDATE = 23, // (event, map, diff) + // Eluna + ELUNA_EVENT_ON_LUA_STATE_CLOSE = 16, // (event) - // Area trigger - TRIGGER_EVENT_ON_TRIGGER = 24, // (event, player, triggerId) + // Map + MAP_EVENT_ON_CREATE = 17, // (event, map) + MAP_EVENT_ON_DESTROY = 18, // (event, map) + MAP_EVENT_ON_GRID_LOAD = 19, // Not Implemented + MAP_EVENT_ON_GRID_UNLOAD = 20, // Not Implemented + MAP_EVENT_ON_PLAYER_ENTER = 21, // (event, map, player) + MAP_EVENT_ON_PLAYER_LEAVE = 22, // (event, map, player) + MAP_EVENT_ON_UPDATE = 23, // (event, map, diff) - // Weather - WEATHER_EVENT_ON_CHANGE = 25, // (event, weather, state, grade) + // Area trigger + TRIGGER_EVENT_ON_TRIGGER = 24, // (event, player, triggerId) - // Auction house - AUCTION_EVENT_ON_ADD = 26, // (event, AHObject) - AUCTION_EVENT_ON_REMOVE = 27, // (event, AHObject) - AUCTION_EVENT_ON_SUCCESSFUL = 28, // (event, AHObject) // Not Implemented - AUCTION_EVENT_ON_EXPIRE = 29, // (event, AHObject) // Not Implemented + // Weather + WEATHER_EVENT_ON_CHANGE = 25, // (event, weather, state, grade) - // AddOns - ADDON_EVENT_ON_MESSAGE = 30, // (event, sender, type, prefix, msg, target) - target can be nil/whisper_target/guid/group/channel + // Auction house + AUCTION_EVENT_ON_ADD = 26, // (event, AHObject) + AUCTION_EVENT_ON_REMOVE = 27, // (event, AHObject) + AUCTION_EVENT_ON_SUCCESSFUL = 28, // (event, AHObject) // Not Implemented + AUCTION_EVENT_ON_EXPIRE = 29, // (event, AHObject) // Not Implemented - SERVER_EVENT_COUNT -}; + // AddOns + ADDON_EVENT_ON_MESSAGE = 30, // (event, sender, type, prefix, msg, target) - target can be nil/whisper_target/guid/group/channel -// RegisterPlayerEvent(eventId, function) -enum PlayerEvents -{ - PLAYER_EVENT_ON_CHARACTER_CREATE = 1, // (event, player) - PLAYER_EVENT_ON_CHARACTER_DELETE = 2, // (event, guid) - PLAYER_EVENT_ON_LOGIN = 3, // (event, player) - PLAYER_EVENT_ON_LOGOUT = 4, // (event, player) - PLAYER_EVENT_ON_SPELL_CAST = 5, // (event, player, spell, skipCheck) - PLAYER_EVENT_ON_KILL_PLAYER = 6, // (event, killer, killed) - PLAYER_EVENT_ON_KILL_CREATURE = 7, // (event, killer, killed) - PLAYER_EVENT_ON_KILLED_BY_CREATURE = 8, // (event, killer, killed) - PLAYER_EVENT_ON_DUEL_REQUEST = 9, // (event, target, challenger) - PLAYER_EVENT_ON_DUEL_START = 10, // (event, player1, player2) - PLAYER_EVENT_ON_DUEL_END = 11, // (event, winner, loser, type) - PLAYER_EVENT_ON_GIVE_XP = 12, // (event, player, amount, victim) - Can return new XP amount - PLAYER_EVENT_ON_LEVEL_CHANGE = 13, // (event, player, oldLevel) - PLAYER_EVENT_ON_MONEY_CHANGE = 14, // (event, player, amount) - PLAYER_EVENT_ON_REPUTATION_CHANGE = 15, // (event, player, factionId, standing, incremental) - Can return new standing - PLAYER_EVENT_ON_TALENTS_CHANGE = 16, // (event, player, points) - PLAYER_EVENT_ON_TALENTS_RESET = 17, // (event, player, noCost) - PLAYER_EVENT_ON_CHAT = 18, // (event, player, msg, Type, lang) - Can return false or new msg - PLAYER_EVENT_ON_WHISPER = 19, // (event, player, msg, Type, lang, receiver) - Can return false or new msg - PLAYER_EVENT_ON_GROUP_CHAT = 20, // (event, player, msg, Type, lang, group) - Can return false or new msg - PLAYER_EVENT_ON_GUILD_CHAT = 21, // (event, player, msg, Type, lang, guild) - Can return false or new msg - PLAYER_EVENT_ON_CHANNEL_CHAT = 22, // (event, player, msg, Type, lang, channel) - Can return false or new msg - PLAYER_EVENT_ON_EMOTE = 23, // (event, player, emote) - Not triggered on any known emote - PLAYER_EVENT_ON_TEXT_EMOTE = 24, // (event, player, textEmote, emoteNum, guid) - PLAYER_EVENT_ON_SAVE = 25, // (event, player) - PLAYER_EVENT_ON_BIND_TO_INSTANCE = 26, // (event, player, difficulty, mapid, permanent) - PLAYER_EVENT_ON_UPDATE_ZONE = 27, // (event, player, newZone, newArea) - PLAYER_EVENT_ON_MAP_CHANGE = 28, // (event, player) + SERVER_EVENT_COUNT + }; - // Custom - PLAYER_EVENT_ON_EQUIP = 29, // (event, player, item, bag, slot) - PLAYER_EVENT_ON_FIRST_LOGIN = 30, // (event, player) - PLAYER_EVENT_ON_CAN_USE_ITEM = 31, // (event, player, itemEntry) - PLAYER_EVENT_ON_LOOT_ITEM = 32, // (event, player, item, count) - PLAYER_EVENT_ON_ENTER_COMBAT = 33, // (event, player, enemy) - PLAYER_EVENT_ON_LEAVE_COMBAT = 34, // (event, player) - PLAYER_EVENT_ON_REPOP = 35, // (event, player) - PLAYER_EVENT_ON_RESURRECT = 36, // (event, player) - PLAYER_EVENT_ON_LOOT_MONEY = 37, // (event, player, amount) - PLAYER_EVENT_ON_QUEST_ABANDON = 38, // (event, player, questId) - // UNUSED = 39, // (event, player) - // UNUSED = 40, // (event, player) - // UNUSED = 41, // (event, player) - PLAYER_EVENT_ON_COMMAND = 42, // (event, player, command) - Can return false + // RegisterPlayerEvent(eventId, function) + enum PlayerEvents + { + PLAYER_EVENT_ON_CHARACTER_CREATE = 1, // (event, player) + PLAYER_EVENT_ON_CHARACTER_DELETE = 2, // (event, guid) + PLAYER_EVENT_ON_LOGIN = 3, // (event, player) + PLAYER_EVENT_ON_LOGOUT = 4, // (event, player) + PLAYER_EVENT_ON_SPELL_CAST = 5, // (event, player, spell, skipCheck) + PLAYER_EVENT_ON_KILL_PLAYER = 6, // (event, killer, killed) + PLAYER_EVENT_ON_KILL_CREATURE = 7, // (event, killer, killed) + PLAYER_EVENT_ON_KILLED_BY_CREATURE = 8, // (event, killer, killed) + PLAYER_EVENT_ON_DUEL_REQUEST = 9, // (event, target, challenger) + PLAYER_EVENT_ON_DUEL_START = 10, // (event, player1, player2) + PLAYER_EVENT_ON_DUEL_END = 11, // (event, winner, loser, type) + PLAYER_EVENT_ON_GIVE_XP = 12, // (event, player, amount, victim) - Can return new XP amount + PLAYER_EVENT_ON_LEVEL_CHANGE = 13, // (event, player, oldLevel) + PLAYER_EVENT_ON_MONEY_CHANGE = 14, // (event, player, amount) + PLAYER_EVENT_ON_REPUTATION_CHANGE = 15, // (event, player, factionId, standing, incremental) - Can return new standing + PLAYER_EVENT_ON_TALENTS_CHANGE = 16, // (event, player, points) + PLAYER_EVENT_ON_TALENTS_RESET = 17, // (event, player, noCost) + PLAYER_EVENT_ON_CHAT = 18, // (event, player, msg, Type, lang) - Can return false or new msg + PLAYER_EVENT_ON_WHISPER = 19, // (event, player, msg, Type, lang, receiver) - Can return false or new msg + PLAYER_EVENT_ON_GROUP_CHAT = 20, // (event, player, msg, Type, lang, group) - Can return false or new msg + PLAYER_EVENT_ON_GUILD_CHAT = 21, // (event, player, msg, Type, lang, guild) - Can return false or new msg + PLAYER_EVENT_ON_CHANNEL_CHAT = 22, // (event, player, msg, Type, lang, channel) - Can return false or new msg + PLAYER_EVENT_ON_EMOTE = 23, // (event, player, emote) - Not triggered on any known emote + PLAYER_EVENT_ON_TEXT_EMOTE = 24, // (event, player, textEmote, emoteNum, guid) + PLAYER_EVENT_ON_SAVE = 25, // (event, player) + PLAYER_EVENT_ON_BIND_TO_INSTANCE = 26, // (event, player, difficulty, mapid, permanent) + PLAYER_EVENT_ON_UPDATE_ZONE = 27, // (event, player, newZone, newArea) + PLAYER_EVENT_ON_MAP_CHANGE = 28, // (event, player) - PLAYER_EVENT_COUNT -}; + // Custom + PLAYER_EVENT_ON_EQUIP = 29, // (event, player, item, bag, slot) + PLAYER_EVENT_ON_FIRST_LOGIN = 30, // (event, player) + PLAYER_EVENT_ON_CAN_USE_ITEM = 31, // (event, player, itemEntry) + PLAYER_EVENT_ON_LOOT_ITEM = 32, // (event, player, item, count) + PLAYER_EVENT_ON_ENTER_COMBAT = 33, // (event, player, enemy) + PLAYER_EVENT_ON_LEAVE_COMBAT = 34, // (event, player) + PLAYER_EVENT_ON_REPOP = 35, // (event, player) + PLAYER_EVENT_ON_RESURRECT = 36, // (event, player) + PLAYER_EVENT_ON_LOOT_MONEY = 37, // (event, player, amount) + PLAYER_EVENT_ON_QUEST_ABANDON = 38, // (event, player, questId) + // UNUSED = 39, // (event, player) + // UNUSED = 40, // (event, player) + // UNUSED = 41, // (event, player) + PLAYER_EVENT_ON_COMMAND = 42, // (event, player, command) - Can return false -// RegisterGuildEvent(eventId, function) -enum GuildEventTypes -{ - // Guild - GUILD_EVENT_ON_ADD_MEMBER = 1, // (event, guild, player, rank) - GUILD_EVENT_ON_REMOVE_MEMBER = 2, // (event, guild, isDisbanding) - GUILD_EVENT_ON_MOTD_CHANGE = 3, // (event, guild, newMotd) - GUILD_EVENT_ON_INFO_CHANGE = 4, // (event, guild, newInfo) - GUILD_EVENT_ON_CREATE = 5, // (event, guild, leader, name) // Not on TC - GUILD_EVENT_ON_DISBAND = 6, // (event, guild) - GUILD_EVENT_ON_MONEY_WITHDRAW = 7, // (event, guild, player, amount, isRepair) - GUILD_EVENT_ON_MONEY_DEPOSIT = 8, // (event, guild, player, amount) - GUILD_EVENT_ON_ITEM_MOVE = 9, // (event, guild, player, item, isSrcBank, srcContainer, srcSlotId, isDestBank, destContainer, destSlotId) // TODO - GUILD_EVENT_ON_EVENT = 10, // (event, guild, eventType, plrGUIDLow1, plrGUIDLow2, newRank) // TODO - GUILD_EVENT_ON_BANK_EVENT = 11, // (event, guild, eventType, tabId, playerGUIDLow, itemOrMoney, itemStackCount, destTabId) + PLAYER_EVENT_COUNT + }; - GUILD_EVENT_COUNT -}; + // RegisterGuildEvent(eventId, function) + enum GuildEvents + { + // Guild + GUILD_EVENT_ON_ADD_MEMBER = 1, // (event, guild, player, rank) + GUILD_EVENT_ON_REMOVE_MEMBER = 2, // (event, guild, isDisbanding) + GUILD_EVENT_ON_MOTD_CHANGE = 3, // (event, guild, newMotd) + GUILD_EVENT_ON_INFO_CHANGE = 4, // (event, guild, newInfo) + GUILD_EVENT_ON_CREATE = 5, // (event, guild, leader, name) // Not on TC + GUILD_EVENT_ON_DISBAND = 6, // (event, guild) + GUILD_EVENT_ON_MONEY_WITHDRAW = 7, // (event, guild, player, amount, isRepair) + GUILD_EVENT_ON_MONEY_DEPOSIT = 8, // (event, guild, player, amount) + GUILD_EVENT_ON_ITEM_MOVE = 9, // (event, guild, player, item, isSrcBank, srcContainer, srcSlotId, isDestBank, destContainer, destSlotId) // TODO + GUILD_EVENT_ON_EVENT = 10, // (event, guild, eventType, plrGUIDLow1, plrGUIDLow2, newRank) // TODO + GUILD_EVENT_ON_BANK_EVENT = 11, // (event, guild, eventType, tabId, playerGUIDLow, itemOrMoney, itemStackCount, destTabId) -// RegisterGroupEvent(eventId, function) -enum GroupEvents -{ - // Group - GROUP_EVENT_ON_MEMBER_ADD = 1, // (event, group, guid) - GROUP_EVENT_ON_MEMBER_INVITE = 2, // (event, group, guid) - GROUP_EVENT_ON_MEMBER_REMOVE = 3, // (event, group, guid, method, kicker, reason) - GROUP_EVENT_ON_LEADER_CHANGE = 4, // (event, group, newLeaderGuid, oldLeaderGuid) - GROUP_EVENT_ON_DISBAND = 5, // (event, group) - GROUP_EVENT_ON_CREATE = 6, // (event, group, leaderGuid, groupType) + GUILD_EVENT_COUNT + }; - GROUP_EVENT_COUNT -}; + // RegisterGroupEvent(eventId, function) + enum GroupEvents + { + // Group + GROUP_EVENT_ON_MEMBER_ADD = 1, // (event, group, guid) + GROUP_EVENT_ON_MEMBER_INVITE = 2, // (event, group, guid) + GROUP_EVENT_ON_MEMBER_REMOVE = 3, // (event, group, guid, method, kicker, reason) + GROUP_EVENT_ON_LEADER_CHANGE = 4, // (event, group, newLeaderGuid, oldLeaderGuid) + GROUP_EVENT_ON_DISBAND = 5, // (event, group) + GROUP_EVENT_ON_CREATE = 6, // (event, group, leaderGuid, groupType) -// RegisterVehicleEvent(eventId, function) -enum VehicleEvents -{ - VEHICLE_EVENT_ON_INSTALL = 1, // (event, vehicle) - VEHICLE_EVENT_ON_UNINSTALL = 2, // (event, vehicle) - // UNUSED = 3, // (event, vehicle) - VEHICLE_EVENT_ON_INSTALL_ACCESSORY = 4, // (event, vehicle, creature) - VEHICLE_EVENT_ON_ADD_PASSENGER = 5, // (event, vehicle, unit, seatId) - VEHICLE_EVENT_ON_REMOVE_PASSENGER = 6, // (event, vehicle, unit) + GROUP_EVENT_COUNT + }; - VEHICLE_EVENT_COUNT -}; + // RegisterVehicleEvent(eventId, function) + enum VehicleEvents + { + VEHICLE_EVENT_ON_INSTALL = 1, // (event, vehicle) + VEHICLE_EVENT_ON_UNINSTALL = 2, // (event, vehicle) + // UNUSED = 3, // (event, vehicle) + VEHICLE_EVENT_ON_INSTALL_ACCESSORY = 4, // (event, vehicle, creature) + VEHICLE_EVENT_ON_ADD_PASSENGER = 5, // (event, vehicle, unit, seatId) + VEHICLE_EVENT_ON_REMOVE_PASSENGER = 6, // (event, vehicle, unit) -// RegisterCreatureEvent(entry, EventId, function) -enum CreatureEvents -{ - CREATURE_EVENT_ON_ENTER_COMBAT = 1, // (event, creature, target) - CREATURE_EVENT_ON_LEAVE_COMBAT = 2, // (event, creature) - CREATURE_EVENT_ON_TARGET_DIED = 3, // (event, creature, victim) - CREATURE_EVENT_ON_DIED = 4, // (event, creature, killer) - CREATURE_EVENT_ON_SPAWN = 5, // (event, creature) - CREATURE_EVENT_ON_REACH_WP = 6, // (event, creature, type, id) - CREATURE_EVENT_ON_AIUPDATE = 7, // (event, creature, diff) - CREATURE_EVENT_ON_RECEIVE_EMOTE = 8, // (event, creature, player, emoteid) - CREATURE_EVENT_ON_DAMAGE_TAKEN = 9, // (event, creature, attacker, damage) - CREATURE_EVENT_ON_PRE_COMBAT = 10, // (event, creature, target) - CREATURE_EVENT_ON_ATTACKED_AT = 11, // (event, creature, attacker) - CREATURE_EVENT_ON_OWNER_ATTACKED = 12, // (event, creature, target) // Not on mangos - CREATURE_EVENT_ON_OWNER_ATTACKED_AT = 13, // (event, creature, attacker) // Not on mangos - CREATURE_EVENT_ON_HIT_BY_SPELL = 14, // (event, creature, caster, spellid) - CREATURE_EVENT_ON_SPELL_HIT_TARGET = 15, // (event, creature, target, spellid) - // UNUSED = 16, // (event, creature) - // UNUSED = 17, // (event, creature) - // UNUSED = 18, // (event, creature) - CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE = 19, // (event, creature, summon) - CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN = 20, // (event, creature, summon) - CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED = 21, // (event, creature, summon, killer) // Not on mangos - CREATURE_EVENT_ON_SUMMONED = 22, // (event, creature, summoner) - CREATURE_EVENT_ON_RESET = 23, // (event, creature) - CREATURE_EVENT_ON_REACH_HOME = 24, // (event, creature) - // UNUSED = 25, // (event, creature) - CREATURE_EVENT_ON_CORPSE_REMOVED = 26, // (event, creature, respawndelay) - CREATURE_EVENT_ON_MOVE_IN_LOS = 27, // (event, creature, unit) // Doesnt actually check LOS - // UNUSED = 28, // (event, creature) - // UNUSED = 29, // (event, creature) - CREATURE_EVENT_ON_DUMMY_EFFECT = 30, // (event, caster, spellid, effindex, creature) - CREATURE_EVENT_ON_QUEST_ACCEPT = 31, // (event, player, creature, quest) - // UNUSED = 32, // (event, creature) - CREATURE_EVENT_ON_QUEST_COMPLETE = 33, // (event, player, creature, quest) - CREATURE_EVENT_ON_QUEST_REWARD = 34, // (event, player, creature, quest, opt) - CREATURE_EVENT_ON_DIALOG_STATUS = 35, // (event, player, creature) - CREATURE_EVENT_COUNT -}; + VEHICLE_EVENT_COUNT + }; -// RegisterGameObjectEvent(entry, EventId, function) -enum GameObjectEvents -{ - GAMEOBJECT_EVENT_ON_AIUPDATE = 1, // (event, go, diff) - GAMEOBJECT_EVENT_ON_SPAWN = 2, // (event, go) - GAMEOBJECT_EVENT_ON_DUMMY_EFFECT = 3, // (event, caster, spellid, effindex, go) - GAMEOBJECT_EVENT_ON_QUEST_ACCEPT = 4, // (event, player, go, quest) - GAMEOBJECT_EVENT_ON_QUEST_REWARD = 5, // (event, player, go, quest, opt) - GAMEOBJECT_EVENT_ON_DIALOG_STATUS = 6, // (event, player, go) - GAMEOBJECT_EVENT_ON_DESTROYED = 7, // (event, go, player) - GAMEOBJECT_EVENT_ON_DAMAGED = 8, // (event, go, player) - GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE = 9, // (event, go, state) - GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED = 10, // (event, go, state) - GAMEOBJECT_EVENT_ON_QUEST_COMPLETE = 11, // (event, player, go, quest) - GAMEOBJECT_EVENT_COUNT -}; + // RegisterCreatureEvent(entry, EventId, function) + enum CreatureEvents + { + CREATURE_EVENT_ON_ENTER_COMBAT = 1, // (event, creature, target) + CREATURE_EVENT_ON_LEAVE_COMBAT = 2, // (event, creature) + CREATURE_EVENT_ON_TARGET_DIED = 3, // (event, creature, victim) + CREATURE_EVENT_ON_DIED = 4, // (event, creature, killer) + CREATURE_EVENT_ON_SPAWN = 5, // (event, creature) + CREATURE_EVENT_ON_REACH_WP = 6, // (event, creature, type, id) + CREATURE_EVENT_ON_AIUPDATE = 7, // (event, creature, diff) + CREATURE_EVENT_ON_RECEIVE_EMOTE = 8, // (event, creature, player, emoteid) + CREATURE_EVENT_ON_DAMAGE_TAKEN = 9, // (event, creature, attacker, damage) + CREATURE_EVENT_ON_PRE_COMBAT = 10, // (event, creature, target) + CREATURE_EVENT_ON_ATTACKED_AT = 11, // (event, creature, attacker) + CREATURE_EVENT_ON_OWNER_ATTACKED = 12, // (event, creature, target) // Not on mangos + CREATURE_EVENT_ON_OWNER_ATTACKED_AT = 13, // (event, creature, attacker) // Not on mangos + CREATURE_EVENT_ON_HIT_BY_SPELL = 14, // (event, creature, caster, spellid) + CREATURE_EVENT_ON_SPELL_HIT_TARGET = 15, // (event, creature, target, spellid) + // UNUSED = 16, // (event, creature) + // UNUSED = 17, // (event, creature) + // UNUSED = 18, // (event, creature) + CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE = 19, // (event, creature, summon) + CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN = 20, // (event, creature, summon) + CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED = 21, // (event, creature, summon, killer) // Not on mangos + CREATURE_EVENT_ON_SUMMONED = 22, // (event, creature, summoner) + CREATURE_EVENT_ON_RESET = 23, // (event, creature) + CREATURE_EVENT_ON_REACH_HOME = 24, // (event, creature) + // UNUSED = 25, // (event, creature) + CREATURE_EVENT_ON_CORPSE_REMOVED = 26, // (event, creature, respawndelay) + CREATURE_EVENT_ON_MOVE_IN_LOS = 27, // (event, creature, unit) // Doesnt actually check LOS + // UNUSED = 28, // (event, creature) + // UNUSED = 29, // (event, creature) + CREATURE_EVENT_ON_DUMMY_EFFECT = 30, // (event, caster, spellid, effindex, creature) + CREATURE_EVENT_ON_QUEST_ACCEPT = 31, // (event, player, creature, quest) + // UNUSED = 32, // (event, creature) + CREATURE_EVENT_ON_QUEST_COMPLETE = 33, // (event, player, creature, quest) + CREATURE_EVENT_ON_QUEST_REWARD = 34, // (event, player, creature, quest, opt) + CREATURE_EVENT_ON_DIALOG_STATUS = 35, // (event, player, creature) + CREATURE_EVENT_COUNT + }; -// RegisterItemEvent(entry, EventId, function) -enum ItemEvents -{ - ITEM_EVENT_ON_DUMMY_EFFECT = 1, // (event, caster, spellid, effindex, item) - ITEM_EVENT_ON_USE = 2, // (event, player, item, target) - ITEM_EVENT_ON_QUEST_ACCEPT = 3, // (event, player, item, quest) - ITEM_EVENT_ON_EXPIRE = 4, // (event, player, itemid) - ITEM_EVENT_ON_REMOVE = 5, // (event, player, item) - ITEM_EVENT_COUNT -}; + // RegisterGameObjectEvent(entry, EventId, function) + enum GameObjectEvents + { + GAMEOBJECT_EVENT_ON_AIUPDATE = 1, // (event, go, diff) + GAMEOBJECT_EVENT_ON_SPAWN = 2, // (event, go) + GAMEOBJECT_EVENT_ON_DUMMY_EFFECT = 3, // (event, caster, spellid, effindex, go) + GAMEOBJECT_EVENT_ON_QUEST_ACCEPT = 4, // (event, player, go, quest) + GAMEOBJECT_EVENT_ON_QUEST_REWARD = 5, // (event, player, go, quest, opt) + GAMEOBJECT_EVENT_ON_DIALOG_STATUS = 6, // (event, player, go) + GAMEOBJECT_EVENT_ON_DESTROYED = 7, // (event, go, player) + GAMEOBJECT_EVENT_ON_DAMAGED = 8, // (event, go, player) + GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE = 9, // (event, go, state) + GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED = 10, // (event, go, state) + GAMEOBJECT_EVENT_ON_QUEST_COMPLETE = 11, // (event, player, go, quest) + GAMEOBJECT_EVENT_COUNT + }; -// RegisterCreatureGossipEvent(entry, EventId, function) -// RegisterGameObjectGossipEvent(entry, EventId, function) -// RegisterItemGossipEvent(entry, EventId, function) -// RegisterPlayerGossipEvent(menu_id, EventId, function) -enum GossipEvents -{ - GOSSIP_EVENT_ON_HELLO = 1, // (event, player, object) - Object is the Creature/GameObject/Item - GOSSIP_EVENT_ON_SELECT = 2, // (event, player, object, sender, intid, code, menu_id) - Object is the Creature/GameObject/Item/Player, menu_id is only for player gossip - GOSSIP_EVENT_COUNT + // RegisterItemEvent(entry, EventId, function) + enum ItemEvents + { + ITEM_EVENT_ON_DUMMY_EFFECT = 1, // (event, caster, spellid, effindex, item) + ITEM_EVENT_ON_USE = 2, // (event, player, item, target) + ITEM_EVENT_ON_QUEST_ACCEPT = 3, // (event, player, item, quest) + ITEM_EVENT_ON_EXPIRE = 4, // (event, player, itemid) + ITEM_EVENT_ON_REMOVE = 5, // (event, player, item) + ITEM_EVENT_COUNT + }; + + // RegisterCreatureGossipEvent(entry, EventId, function) + // RegisterGameObjectGossipEvent(entry, EventId, function) + // RegisterItemGossipEvent(entry, EventId, function) + // RegisterPlayerGossipEvent(menu_id, EventId, function) + enum GossipEvents + { + GOSSIP_EVENT_ON_HELLO = 1, // (event, player, object) - Object is the Creature/GameObject/Item + GOSSIP_EVENT_ON_SELECT = 2, // (event, player, object, sender, intid, code, menu_id) - Object is the Creature/GameObject/Item/Player, menu_id is only for player gossip + GOSSIP_EVENT_COUNT + }; }; #endif diff --git a/LuaEngine.cpp b/LuaEngine.cpp index 17ba5cc..70a9d91 100644 --- a/LuaEngine.cpp +++ b/LuaEngine.cpp @@ -40,6 +40,7 @@ void Eluna::Initialize() void Eluna::Uninitialize() { delete GEluna; + scripts.clear(); } void Eluna::ReloadEluna() @@ -53,20 +54,20 @@ L(luaL_newstate()), m_EventMgr(new EventMgr(*this)), -ServerEventBindings(new EventBind(*this)), -PlayerEventBindings(new EventBind(*this)), -GuildEventBindings(new EventBind(*this)), -GroupEventBindings(new EventBind(*this)), -VehicleEventBindings(new EventBind(*this)), +ServerEventBindings(new EventBind(*this)), +PlayerEventBindings(new EventBind(*this)), +GuildEventBindings(new EventBind(*this)), +GroupEventBindings(new EventBind(*this)), +VehicleEventBindings(new EventBind(*this)), -PacketEventBindings(new EntryBind(*this)), -CreatureEventBindings(new EntryBind(*this)), -CreatureGossipBindings(new EntryBind(*this)), -GameObjectEventBindings(new EntryBind(*this)), -GameObjectGossipBindings(new EntryBind(*this)), -ItemEventBindings(new EntryBind(*this)), -ItemGossipBindings(new EntryBind(*this)), -playerGossipBindings(new EntryBind(*this)) +PacketEventBindings(new EntryBind(*this)), +CreatureEventBindings(new EntryBind(*this)), +CreatureGossipBindings(new EntryBind(*this)), +GameObjectEventBindings(new EntryBind(*this)), +GameObjectGossipBindings(new EntryBind(*this)), +ItemEventBindings(new EntryBind(*this)), +ItemGossipBindings(new EntryBind(*this)), +playerGossipBindings(new EntryBind(*this)) { // open base lua luaL_openlibs(L); @@ -525,56 +526,63 @@ void Eluna::Register(uint8 regtype, uint32 id, uint32 evt, int functionRef) { switch (regtype) { - case REGTYPE_PACKET: - if (evt < NUM_MSG_TYPES) - { - PacketEventBindings->Insert(id, evt, functionRef); - return; - } - break; - - case REGTYPE_SERVER: - if (evt < SERVER_EVENT_COUNT) + case HookMgr::REGTYPE_SERVER: + if (evt < HookMgr::SERVER_EVENT_COUNT) { ServerEventBindings->Insert(evt, functionRef); return; } break; - case REGTYPE_PLAYER: - if (evt < PLAYER_EVENT_COUNT) + case HookMgr::REGTYPE_PLAYER: + if (evt < HookMgr::PLAYER_EVENT_COUNT) { PlayerEventBindings->Insert(evt, functionRef); return; } break; - case REGTYPE_GUILD: - if (evt < GUILD_EVENT_COUNT) + case HookMgr::REGTYPE_GUILD: + if (evt < HookMgr::GUILD_EVENT_COUNT) { GuildEventBindings->Insert(evt, functionRef); return; } break; - case REGTYPE_GROUP: - if (evt < GROUP_EVENT_COUNT) + case HookMgr::REGTYPE_GROUP: + if (evt < HookMgr::GROUP_EVENT_COUNT) { GroupEventBindings->Insert(evt, functionRef); return; } break; - case REGTYPE_VEHICLE: - if (evt < VEHICLE_EVENT_COUNT) + case HookMgr::REGTYPE_VEHICLE: + if (evt < HookMgr::VEHICLE_EVENT_COUNT) { VehicleEventBindings->Insert(evt, functionRef); return; } break; - case REGTYPE_CREATURE: - if (evt < CREATURE_EVENT_COUNT) + case HookMgr::REGTYPE_PACKET: + if (evt < HookMgr::PACKET_EVENT_COUNT) + { + if (id >= NUM_MSG_TYPES) + { + luaL_unref(L, LUA_REGISTRYINDEX, functionRef); + luaL_error(L, "Couldn't find a creature with (ID: %d)!", id); + return; + } + + PacketEventBindings->Insert(id, evt, functionRef); + return; + } + break; + + case HookMgr::REGTYPE_CREATURE: + if (evt < HookMgr::CREATURE_EVENT_COUNT) { if (!eObjectMgr->GetCreatureTemplate(id)) { @@ -588,8 +596,8 @@ void Eluna::Register(uint8 regtype, uint32 id, uint32 evt, int functionRef) } break; - case REGTYPE_CREATURE_GOSSIP: - if (evt < GOSSIP_EVENT_COUNT) + case HookMgr::REGTYPE_CREATURE_GOSSIP: + if (evt < HookMgr::GOSSIP_EVENT_COUNT) { if (!eObjectMgr->GetCreatureTemplate(id)) { @@ -603,8 +611,8 @@ void Eluna::Register(uint8 regtype, uint32 id, uint32 evt, int functionRef) } break; - case REGTYPE_GAMEOBJECT: - if (evt < GAMEOBJECT_EVENT_COUNT) + case HookMgr::REGTYPE_GAMEOBJECT: + if (evt < HookMgr::GAMEOBJECT_EVENT_COUNT) { if (!eObjectMgr->GetGameObjectTemplate(id)) { @@ -618,8 +626,8 @@ void Eluna::Register(uint8 regtype, uint32 id, uint32 evt, int functionRef) } break; - case REGTYPE_GAMEOBJECT_GOSSIP: - if (evt < GOSSIP_EVENT_COUNT) + case HookMgr::REGTYPE_GAMEOBJECT_GOSSIP: + if (evt < HookMgr::GOSSIP_EVENT_COUNT) { if (!eObjectMgr->GetGameObjectTemplate(id)) { @@ -633,8 +641,8 @@ void Eluna::Register(uint8 regtype, uint32 id, uint32 evt, int functionRef) } break; - case REGTYPE_ITEM: - if (evt < ITEM_EVENT_COUNT) + case HookMgr::REGTYPE_ITEM: + if (evt < HookMgr::ITEM_EVENT_COUNT) { if (!eObjectMgr->GetItemTemplate(id)) { @@ -648,8 +656,8 @@ void Eluna::Register(uint8 regtype, uint32 id, uint32 evt, int functionRef) } break; - case REGTYPE_ITEM_GOSSIP: - if (evt < GOSSIP_EVENT_COUNT) + case HookMgr::REGTYPE_ITEM_GOSSIP: + if (evt < HookMgr::GOSSIP_EVENT_COUNT) { if (!eObjectMgr->GetItemTemplate(id)) { @@ -663,8 +671,8 @@ void Eluna::Register(uint8 regtype, uint32 id, uint32 evt, int functionRef) } break; - case REGTYPE_PLAYER_GOSSIP: - if (evt < GOSSIP_EVENT_COUNT) + case HookMgr::REGTYPE_PLAYER_GOSSIP: + if (evt < HookMgr::GOSSIP_EVENT_COUNT) { playerGossipBindings->Insert(id, evt, functionRef); return; @@ -675,53 +683,6 @@ void Eluna::Register(uint8 regtype, uint32 id, uint32 evt, int functionRef) luaL_error(L, "Unknown event type (regtype %d, id %d, event %d)", regtype, id, evt); } -void EventBind::Clear() -{ - for (ElunaEntryMap::iterator itr = Bindings.begin(); itr != Bindings.end(); ++itr) - { - for (ElunaBindingMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it) - luaL_unref(E.L, LUA_REGISTRYINDEX, (*it)); - itr->second.clear(); - } - Bindings.clear(); -} - -void EventBind::Insert(int eventId, int funcRef) -{ - Bindings[eventId].push_back(funcRef); -} - -bool EventBind::HasEvents(int eventId) const -{ - if (Bindings.empty()) - return false; - if (Bindings.find(eventId) == Bindings.end()) - return false; - return true; -} - -void EntryBind::Clear() -{ - for (ElunaEntryMap::iterator itr = Bindings.begin(); itr != Bindings.end(); ++itr) - { - for (ElunaBindingMap::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it) - luaL_unref(E.L, LUA_REGISTRYINDEX, it->second); - itr->second.clear(); - } - Bindings.clear(); -} - -void EntryBind::Insert(uint32 entryId, int eventId, int funcRef) -{ - if (Bindings[entryId][eventId]) - { - luaL_unref(E.L, LUA_REGISTRYINDEX, funcRef); // free the unused ref - luaL_error(E.L, "A function is already registered for entry (%d) event (%d)", entryId, eventId); - } - else - Bindings[entryId][eventId] = funcRef; -} - EventMgr::LuaEvent::LuaEvent(Eluna& _E, EventProcessor* _events, int _funcRef, uint32 _delay, uint32 _calls, Object* _obj): E(_E), events(_events), funcRef(_funcRef), delay(_delay), calls(_calls), obj(_obj) { diff --git a/LuaEngine.h b/LuaEngine.h index 2acbe30..bd49037 100644 --- a/LuaEngine.h +++ b/LuaEngine.h @@ -20,6 +20,7 @@ extern "C" #include #include // enums & singletons +#include "HookMgr.h" #ifdef MANGOS #include "AccountMgr.h" #include "Config/Config.h" @@ -334,10 +335,12 @@ struct EventMgr } }; +template struct EventBind { typedef std::vector ElunaBindingMap; - typedef std::map ElunaEntryMap; + typedef std::map ElunaEntryMap; + Eluna& E; EventBind(Eluna& _E): E(_E) @@ -349,11 +352,25 @@ struct EventBind Clear(); } - void Clear(); // unregisters all registered functions and clears all registered events from the bind std::maps (reset) - void Insert(int eventId, int funcRef); // Inserts a new registered event + // unregisters all registered functions and clears all registered events from the bind std::maps (reset) + void Clear() + { + for (ElunaEntryMap::iterator itr = Bindings.begin(); itr != Bindings.end(); ++itr) + { + for (ElunaBindingMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it) + luaL_unref(E.L, LUA_REGISTRYINDEX, (*it)); + itr->second.clear(); + } + Bindings.clear(); + } + + void Insert(int eventId, int funcRef) // Inserts a new registered event + { + Bindings[eventId].push_back(funcRef); + } // Gets the binding std::map containing all registered events with the function refs for the entry - ElunaBindingMap* GetBindMap(int eventId) + ElunaBindingMap* GetBindMap(T eventId) { if (Bindings.empty()) return NULL; @@ -365,15 +382,24 @@ struct EventBind } // Checks if there are events for ID - bool HasEvents(int eventId) const; + bool HasEvents(T eventId) const + { + if (Bindings.empty()) + return false; + if (Bindings.find(eventId) == Bindings.end()) + return false; + return true; + } ElunaEntryMap Bindings; // Binding store Bindings[eventId] = {funcRef}; }; +template struct EntryBind { - typedef std::map ElunaBindingMap; + typedef std::map ElunaBindingMap; typedef UNORDERED_MAP ElunaEntryMap; + Eluna& E; EntryBind(Eluna& _E): E(_E) @@ -385,11 +411,30 @@ struct EntryBind Clear(); } - void Clear(); // unregisters all registered functions and clears all registered events from the bind std::maps (reset) - void Insert(uint32 entryId, int eventId, int funcRef); // Inserts a new registered event + void Clear() // unregisters all registered functions and clears all registered events from the bind std::maps (reset) + { + for (ElunaEntryMap::iterator itr = Bindings.begin(); itr != Bindings.end(); ++itr) + { + for (ElunaBindingMap::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it) + luaL_unref(E.L, LUA_REGISTRYINDEX, it->second); + itr->second.clear(); + } + Bindings.clear(); + } + + void Insert(uint32 entryId, int eventId, int funcRef) // Inserts a new registered event + { + if (Bindings[entryId][eventId]) + { + luaL_unref(E.L, LUA_REGISTRYINDEX, funcRef); // free the unused ref + luaL_error(E.L, "A function is already registered for entry (%d) event (%d)", entryId, eventId); + } + else + Bindings[entryId][eventId] = funcRef; + } // Gets the function ref of an entry for an event - int GetBind(uint32 entryId, int eventId) const + int GetBind(uint32 entryId, T eventId) const { if (Bindings.empty()) return 0; @@ -445,21 +490,20 @@ public: EventMgr* m_EventMgr; - // Use templates for EventBind - EventBind* ServerEventBindings; - EventBind* PlayerEventBindings; - EventBind* GuildEventBindings; - EventBind* GroupEventBindings; - EventBind* VehicleEventBindings; + EventBind* ServerEventBindings; + EventBind* PlayerEventBindings; + EventBind* GuildEventBindings; + EventBind* GroupEventBindings; + EventBind* VehicleEventBindings; - EntryBind* PacketEventBindings; - EntryBind* CreatureEventBindings; - EntryBind* CreatureGossipBindings; - EntryBind* GameObjectEventBindings; - EntryBind* GameObjectGossipBindings; - EntryBind* ItemEventBindings; - EntryBind* ItemGossipBindings; - EntryBind* playerGossipBindings; + EntryBind* PacketEventBindings; + EntryBind* CreatureEventBindings; + EntryBind* CreatureGossipBindings; + EntryBind* GameObjectEventBindings; + EntryBind* GameObjectGossipBindings; + EntryBind* ItemEventBindings; + EntryBind* ItemGossipBindings; + EntryBind* playerGossipBindings; Eluna(); ~Eluna();