From 84f64b5f5bcfb932b97d75b354cd43b74c269575 Mon Sep 17 00:00:00 2001 From: iThorgrim Date: Thu, 22 Jan 2026 10:44:03 +0100 Subject: [PATCH 1/8] feat: doing stuff --- src/ALE_SC.cpp | 1344 +- src/LuaEngine/.editorconfig | 7 - src/LuaEngine/ALECompat.cpp | 88 - src/LuaEngine/ALECompat.h | 47 - src/LuaEngine/ALEConfig.cpp | 30 - src/LuaEngine/ALEConfig.h | 53 - src/LuaEngine/ALECreatureAI.h | 196 - src/LuaEngine/ALEDBCRegistry.cpp | 7 - src/LuaEngine/ALEDBCRegistry.h | 38 - src/LuaEngine/ALEEventMgr.cpp | 160 - src/LuaEngine/ALEEventMgr.h | 104 - src/LuaEngine/ALEFileWatcher.cpp | 216 - src/LuaEngine/ALEFileWatcher.h | 43 - src/LuaEngine/ALEIncludes.h | 76 - src/LuaEngine/ALEInstanceAI.cpp | 228 - src/LuaEngine/ALEInstanceAI.h | 133 - src/LuaEngine/ALETemplate.h | 389 - src/LuaEngine/ALEUtility.cpp | 188 - src/LuaEngine/ALEUtility.h | 135 - src/LuaEngine/BindingMap.h | 375 - src/LuaEngine/Compilation/BytecodeCache.cpp | 161 + src/LuaEngine/Compilation/BytecodeCache.h | 136 + src/LuaEngine/Compilation/ScriptCompiler.cpp | 276 + src/LuaEngine/Compilation/ScriptCompiler.h | 144 + src/LuaEngine/Compilation/Statistics.h | 231 + src/LuaEngine/Events/EventManager.cpp | 136 + src/LuaEngine/Events/EventManager.h | 883 + src/LuaEngine/Events/TimedEventManager.cpp | 310 + src/LuaEngine/Events/TimedEventManager.h | 207 + src/LuaEngine/HookHelpers.h | 121 - src/LuaEngine/Hooks.h | 431 - src/LuaEngine/Hooks/PlayerHooks.hpp | 175 + src/LuaEngine/Hooks/WorldHooks.hpp | 173 + src/LuaEngine/Hooks/WorldObjectHooks.hpp | 63 + src/LuaEngine/HttpManager.cpp | 275 - src/LuaEngine/HttpManager.h | 61 - src/LuaEngine/Loading/EclipseScriptLoader.cpp | 411 + src/LuaEngine/Loading/EclipseScriptLoader.h | 267 + src/LuaEngine/LuaEngine.cpp | 1722 - src/LuaEngine/LuaEngine.h | 626 - src/LuaEngine/LuaFunctions.cpp | 1958 -- src/LuaEngine/Methods/GlobalMethods.cpp | 182 + src/LuaEngine/Methods/Methods.hpp | 66 + src/LuaEngine/Methods/PlayerMethods.hpp | 88 + src/LuaEngine/Methods/TimedEventMethods.cpp | 122 + src/LuaEngine/Methods/TimedEventMethods.h | 193 + src/LuaEngine/Methods/UnitMethods.hpp | 322 + src/LuaEngine/State/StateManager.cpp | 394 + src/LuaEngine/State/StateManager.h | 195 + .../docs/ALEDoc/templates/index.html | 5 +- src/LuaEngine/docs/DOC_GEN.md | 4 +- src/LuaEngine/hooks/AllCreatureHooks.cpp | 277 - src/LuaEngine/hooks/BattleGroundHooks.cpp | 58 - src/LuaEngine/hooks/CreatureHooks.cpp | 528 - src/LuaEngine/hooks/GameObjectHooks.cpp | 138 - src/LuaEngine/hooks/GossipHooks.cpp | 147 - src/LuaEngine/hooks/GroupHooks.cpp | 71 - src/LuaEngine/hooks/GuildHooks.cpp | 164 - src/LuaEngine/hooks/InstanceHooks.cpp | 83 - src/LuaEngine/hooks/ItemHooks.cpp | 117 - src/LuaEngine/hooks/PacketHooks.cpp | 139 - src/LuaEngine/hooks/PlayerHooks.cpp | 969 - src/LuaEngine/hooks/ServerHooks.cpp | 334 - src/LuaEngine/hooks/SpellHooks.cpp | 60 - src/LuaEngine/hooks/TicketHooks.cpp | 59 - src/LuaEngine/hooks/VehicleHooks.cpp | 60 - src/LuaEngine/lmarshal.cpp | 580 - src/LuaEngine/lmarshal.h | 12 - src/LuaEngine/methods/ALEQueryMethods.h | 316 - src/LuaEngine/methods/AchievementMethods.h | 59 - src/LuaEngine/methods/AuraMethods.h | 169 - src/LuaEngine/methods/BattleGroundMethods.h | 213 - src/LuaEngine/methods/ChatHandlerMethods.h | 199 - src/LuaEngine/methods/CorpseMethods.h | 77 - src/LuaEngine/methods/CreatureMethods.h | 1372 - src/LuaEngine/methods/GameObjectMethods.h | 373 - .../methods/GemPropertiesEntryMethods.h | 48 - src/LuaEngine/methods/GlobalMethods.h | 3804 +- src/LuaEngine/methods/GroupMethods.h | 435 - src/LuaEngine/methods/GuildMethods.h | 412 - src/LuaEngine/methods/ItemMethods.h | 774 - src/LuaEngine/methods/ItemTemplateMethods.h | 224 - src/LuaEngine/methods/LootMethods.h | 605 - src/LuaEngine/methods/MapMethods.h | 383 - src/LuaEngine/methods/ObjectMethods.h | 467 - src/LuaEngine/methods/PetMethods.h | 665 - src/LuaEngine/methods/PlayerMethods.h | 4986 --- src/LuaEngine/methods/QuestMethods.h | 179 - src/LuaEngine/methods/RollMethods.h | 219 - src/LuaEngine/methods/SpellEntryMethods.h | 2405 -- src/LuaEngine/methods/SpellInfoMethods.h | 990 - src/LuaEngine/methods/SpellMethods.h | 196 - src/LuaEngine/methods/TicketMethods.h | 323 - src/LuaEngine/methods/UnitMethods.h | 2760 -- src/LuaEngine/methods/VehicleMethods.h | 93 - src/LuaEngine/methods/WorldObjectMethods.h | 1098 - src/LuaEngine/methods/WorldPacketMethods.h | 337 - src/lualib/lua/CMakeLists.txt | 28 +- src/lualib/luajit/CMakeLists.txt | 6 +- src/sol/config.hpp | 137 + src/sol/sol.hpp | 28908 ++++++++++++++++ 101 files changed, 34472 insertions(+), 36779 deletions(-) delete mode 100644 src/LuaEngine/.editorconfig delete mode 100644 src/LuaEngine/ALECompat.cpp delete mode 100644 src/LuaEngine/ALECompat.h delete mode 100644 src/LuaEngine/ALEConfig.cpp delete mode 100644 src/LuaEngine/ALEConfig.h delete mode 100644 src/LuaEngine/ALECreatureAI.h delete mode 100644 src/LuaEngine/ALEDBCRegistry.cpp delete mode 100644 src/LuaEngine/ALEDBCRegistry.h delete mode 100644 src/LuaEngine/ALEEventMgr.cpp delete mode 100644 src/LuaEngine/ALEEventMgr.h delete mode 100644 src/LuaEngine/ALEFileWatcher.cpp delete mode 100644 src/LuaEngine/ALEFileWatcher.h delete mode 100644 src/LuaEngine/ALEIncludes.h delete mode 100644 src/LuaEngine/ALEInstanceAI.cpp delete mode 100644 src/LuaEngine/ALEInstanceAI.h delete mode 100644 src/LuaEngine/ALETemplate.h delete mode 100644 src/LuaEngine/ALEUtility.cpp delete mode 100644 src/LuaEngine/ALEUtility.h delete mode 100644 src/LuaEngine/BindingMap.h create mode 100644 src/LuaEngine/Compilation/BytecodeCache.cpp create mode 100644 src/LuaEngine/Compilation/BytecodeCache.h create mode 100644 src/LuaEngine/Compilation/ScriptCompiler.cpp create mode 100644 src/LuaEngine/Compilation/ScriptCompiler.h create mode 100644 src/LuaEngine/Compilation/Statistics.h create mode 100644 src/LuaEngine/Events/EventManager.cpp create mode 100644 src/LuaEngine/Events/EventManager.h create mode 100644 src/LuaEngine/Events/TimedEventManager.cpp create mode 100644 src/LuaEngine/Events/TimedEventManager.h delete mode 100644 src/LuaEngine/HookHelpers.h delete mode 100644 src/LuaEngine/Hooks.h create mode 100644 src/LuaEngine/Hooks/PlayerHooks.hpp create mode 100644 src/LuaEngine/Hooks/WorldHooks.hpp create mode 100644 src/LuaEngine/Hooks/WorldObjectHooks.hpp delete mode 100644 src/LuaEngine/HttpManager.cpp delete mode 100644 src/LuaEngine/HttpManager.h create mode 100644 src/LuaEngine/Loading/EclipseScriptLoader.cpp create mode 100644 src/LuaEngine/Loading/EclipseScriptLoader.h delete mode 100644 src/LuaEngine/LuaEngine.cpp delete mode 100644 src/LuaEngine/LuaEngine.h delete mode 100644 src/LuaEngine/LuaFunctions.cpp create mode 100644 src/LuaEngine/Methods/GlobalMethods.cpp create mode 100644 src/LuaEngine/Methods/Methods.hpp create mode 100644 src/LuaEngine/Methods/PlayerMethods.hpp create mode 100644 src/LuaEngine/Methods/TimedEventMethods.cpp create mode 100644 src/LuaEngine/Methods/TimedEventMethods.h create mode 100644 src/LuaEngine/Methods/UnitMethods.hpp create mode 100644 src/LuaEngine/State/StateManager.cpp create mode 100644 src/LuaEngine/State/StateManager.h delete mode 100644 src/LuaEngine/hooks/AllCreatureHooks.cpp delete mode 100644 src/LuaEngine/hooks/BattleGroundHooks.cpp delete mode 100644 src/LuaEngine/hooks/CreatureHooks.cpp delete mode 100644 src/LuaEngine/hooks/GameObjectHooks.cpp delete mode 100644 src/LuaEngine/hooks/GossipHooks.cpp delete mode 100644 src/LuaEngine/hooks/GroupHooks.cpp delete mode 100644 src/LuaEngine/hooks/GuildHooks.cpp delete mode 100644 src/LuaEngine/hooks/InstanceHooks.cpp delete mode 100644 src/LuaEngine/hooks/ItemHooks.cpp delete mode 100644 src/LuaEngine/hooks/PacketHooks.cpp delete mode 100644 src/LuaEngine/hooks/PlayerHooks.cpp delete mode 100644 src/LuaEngine/hooks/ServerHooks.cpp delete mode 100644 src/LuaEngine/hooks/SpellHooks.cpp delete mode 100644 src/LuaEngine/hooks/TicketHooks.cpp delete mode 100644 src/LuaEngine/hooks/VehicleHooks.cpp delete mode 100644 src/LuaEngine/lmarshal.cpp delete mode 100644 src/LuaEngine/lmarshal.h delete mode 100644 src/LuaEngine/methods/ALEQueryMethods.h delete mode 100644 src/LuaEngine/methods/AchievementMethods.h delete mode 100644 src/LuaEngine/methods/AuraMethods.h delete mode 100644 src/LuaEngine/methods/BattleGroundMethods.h delete mode 100644 src/LuaEngine/methods/ChatHandlerMethods.h delete mode 100644 src/LuaEngine/methods/CorpseMethods.h delete mode 100644 src/LuaEngine/methods/CreatureMethods.h delete mode 100644 src/LuaEngine/methods/GameObjectMethods.h delete mode 100644 src/LuaEngine/methods/GemPropertiesEntryMethods.h delete mode 100644 src/LuaEngine/methods/GroupMethods.h delete mode 100644 src/LuaEngine/methods/GuildMethods.h delete mode 100644 src/LuaEngine/methods/ItemMethods.h delete mode 100644 src/LuaEngine/methods/ItemTemplateMethods.h delete mode 100644 src/LuaEngine/methods/LootMethods.h delete mode 100644 src/LuaEngine/methods/MapMethods.h delete mode 100644 src/LuaEngine/methods/ObjectMethods.h delete mode 100644 src/LuaEngine/methods/PetMethods.h delete mode 100644 src/LuaEngine/methods/PlayerMethods.h delete mode 100644 src/LuaEngine/methods/QuestMethods.h delete mode 100644 src/LuaEngine/methods/RollMethods.h delete mode 100644 src/LuaEngine/methods/SpellEntryMethods.h delete mode 100644 src/LuaEngine/methods/SpellInfoMethods.h delete mode 100644 src/LuaEngine/methods/SpellMethods.h delete mode 100644 src/LuaEngine/methods/TicketMethods.h delete mode 100644 src/LuaEngine/methods/UnitMethods.h delete mode 100644 src/LuaEngine/methods/VehicleMethods.h delete mode 100644 src/LuaEngine/methods/WorldObjectMethods.h delete mode 100644 src/LuaEngine/methods/WorldPacketMethods.h create mode 100644 src/sol/config.hpp create mode 100644 src/sol/sol.hpp diff --git a/src/ALE_SC.cpp b/src/ALE_SC.cpp index 2c60dda823..5bdd08b44c 100644 --- a/src/ALE_SC.cpp +++ b/src/ALE_SC.cpp @@ -16,1347 +16,25 @@ */ #include "Chat.h" -#include "ALEEventMgr.h" #include "Log.h" -#include "LuaEngine.h" #include "Pet.h" #include "Player.h" #include "ScriptMgr.h" #include "ScriptedGossip.h" -class ALE_AllCreatureScript : public AllCreatureScript -{ -public: - ALE_AllCreatureScript() : AllCreatureScript("ALE_AllCreatureScript") { } - - // Creature - bool CanCreatureGossipHello(Player* player, Creature* creature) override - { - if (sALE->OnGossipHello(player, creature)) - return true; - - return false; - } - - bool CanCreatureGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action) override - { - if (sALE->OnGossipSelect(player, creature, sender, action)) - return true; - - return false; - } - - bool CanCreatureGossipSelectCode(Player* player, Creature* creature, uint32 sender, uint32 action, const char* code) override - { - if (sALE->OnGossipSelectCode(player, creature, sender, action, code)) - return true; - - return false; - } - - void OnCreatureAddWorld(Creature* creature) override - { - sALE->OnAddToWorld(creature); - sALE->OnAllCreatureAddToWorld(creature); - - if (creature->IsGuardian() && creature->ToTempSummon() && creature->ToTempSummon()->GetSummonerGUID().IsPlayer()) - sALE->OnPetAddedToWorld(creature->ToTempSummon()->GetSummonerUnit()->ToPlayer(), creature); - } - - void OnCreatureRemoveWorld(Creature* creature) override - { - sALE->OnRemoveFromWorld(creature); - sALE->OnAllCreatureRemoveFromWorld(creature); - } - - bool CanCreatureQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - sALE->OnPlayerQuestAccept(player, quest); - sALE->OnQuestAccept(player, creature, quest); - return false; - } - - bool CanCreatureQuestReward(Player* player, Creature* creature, Quest const* quest, uint32 opt) override - { - if (sALE->OnQuestReward(player, creature, quest, opt)) - { - ClearGossipMenuFor(player); - return true; - } - - return false; - } - - CreatureAI* GetCreatureAI(Creature* creature) const override - { - if (CreatureAI* luaAI = sALE->GetAI(creature)) - return luaAI; - - return nullptr; - } - - void OnCreatureSelectLevel(const CreatureTemplate* cinfo, Creature* creature) override - { - sALE->OnAllCreatureSelectLevel(cinfo, creature); - } - - void OnBeforeCreatureSelectLevel(const CreatureTemplate* cinfo, Creature* creature, uint8& level) override - { - sALE->OnAllCreatureBeforeSelectLevel(cinfo, creature, level); - } -}; - -class ALE_AllGameObjectScript : public AllGameObjectScript -{ -public: - ALE_AllGameObjectScript() : AllGameObjectScript("ALE_AllGameObjectScript") { } - - void OnGameObjectAddWorld(GameObject* go) override - { - sALE->OnAddToWorld(go); - } - - void OnGameObjectRemoveWorld(GameObject* go) override - { - sALE->OnRemoveFromWorld(go); - } - - void OnGameObjectUpdate(GameObject* go, uint32 diff) override - { - sALE->UpdateAI(go, diff); - } - - bool CanGameObjectGossipHello(Player* player, GameObject* go) override - { - if (sALE->OnGossipHello(player, go)) - return true; - - if (sALE->OnGameObjectUse(player, go)) - return true; - - return false; - } - - void OnGameObjectDamaged(GameObject* go, Player* player) override - { - sALE->OnDamaged(go, player); - } - - void OnGameObjectDestroyed(GameObject* go, Player* player) override - { - sALE->OnDestroyed(go, player); - } - - void OnGameObjectLootStateChanged(GameObject* go, uint32 state, Unit* /*unit*/) override - { - sALE->OnLootStateChanged(go, state); - } - - void OnGameObjectStateChanged(GameObject* go, uint32 state) override - { - sALE->OnGameObjectStateChanged(go, state); - } - - bool CanGameObjectQuestAccept(Player* player, GameObject* go, Quest const* quest) override - { - sALE->OnPlayerQuestAccept(player, quest); - sALE->OnQuestAccept(player, go, quest); - return false; - } - - bool CanGameObjectGossipSelect(Player* player, GameObject* go, uint32 sender, uint32 action) override - { - if (sALE->OnGossipSelect(player, go, sender, action)) - return true; - - return false; - } - - bool CanGameObjectGossipSelectCode(Player* player, GameObject* go, uint32 sender, uint32 action, const char* code) override - { - if (sALE->OnGossipSelectCode(player, go, sender, action, code)) - return true; - - return false; - } - - bool CanGameObjectQuestReward(Player* player, GameObject* go, Quest const* quest, uint32 opt) override - { - if (sALE->OnQuestAccept(player, go, quest)) - { - sALE->OnPlayerQuestAccept(player, quest); - return false; - } - - if (sALE->OnQuestReward(player, go, quest, opt)) - return false; - - return false; - } - - GameObjectAI* GetGameObjectAI(GameObject* go) const override - { - sALE->OnSpawn(go); - return nullptr; - } -}; - -class ALE_AllItemScript : public AllItemScript -{ -public: - ALE_AllItemScript() : AllItemScript("ALE_AllItemScript") { } - - bool CanItemQuestAccept(Player* player, Item* item, Quest const* quest) override - { - if (sALE->OnQuestAccept(player, item, quest)) - { - sALE->OnPlayerQuestAccept(player, quest); - return false; - } - - return true; - } - - bool CanItemUse(Player* player, Item* item, SpellCastTargets const& targets) override - { - if (!sALE->OnUse(player, item, targets)) - return true; - - return false; - } - - bool CanItemExpire(Player* player, ItemTemplate const* proto) override - { - if (sALE->OnExpire(player, proto)) - return false; - - return true; - } - - bool CanItemRemove(Player* player, Item* item) override - { - if (sALE->OnRemove(player, item)) - return false; - - return true; - } - - void OnItemGossipSelect(Player* player, Item* item, uint32 sender, uint32 action) override - { - sALE->HandleGossipSelectOption(player, item, sender, action, ""); - } - - void OnItemGossipSelectCode(Player* player, Item* item, uint32 sender, uint32 action, const char* code) override - { - sALE->HandleGossipSelectOption(player, item, sender, action, code); - } -}; - -class ALE_AllMapScript : public AllMapScript -{ -public: - ALE_AllMapScript() : AllMapScript("ALE_AllMapScript", { - ALLMAPHOOK_ON_BEFORE_CREATE_INSTANCE_SCRIPT, - ALLMAPHOOK_ON_DESTROY_INSTANCE, - ALLMAPHOOK_ON_CREATE_MAP, - ALLMAPHOOK_ON_DESTROY_MAP, - ALLMAPHOOK_ON_PLAYER_ENTER_ALL, - ALLMAPHOOK_ON_PLAYER_LEAVE_ALL, - ALLMAPHOOK_ON_MAP_UPDATE - }) { } - - void OnBeforeCreateInstanceScript(InstanceMap* instanceMap, InstanceScript** instanceData, bool /*load*/, std::string /*data*/, uint32 /*completedEncounterMask*/) override - { - if (instanceData) - *instanceData = sALE->GetInstanceData(instanceMap); - } - - void OnDestroyInstance(MapInstanced* /*mapInstanced*/, Map* map) override - { - sALE->FreeInstanceId(map->GetInstanceId()); - } - - void OnCreateMap(Map* map) override - { - sALE->OnCreate(map); - } - - void OnDestroyMap(Map* map) override - { - sALE->OnDestroy(map); - } - - void OnPlayerEnterAll(Map* map, Player* player) override - { - sALE->OnPlayerEnter(map, player); - } - - void OnPlayerLeaveAll(Map* map, Player* player) override - { - sALE->OnPlayerLeave(map, player); - } - - void OnMapUpdate(Map* map, uint32 diff) override - { - sALE->OnUpdate(map, diff); - } -}; - -class ALE_AuctionHouseScript : public AuctionHouseScript -{ -public: - ALE_AuctionHouseScript() : AuctionHouseScript("ALE_AuctionHouseScript", { - AUCTIONHOUSEHOOK_ON_AUCTION_ADD, - AUCTIONHOUSEHOOK_ON_AUCTION_REMOVE, - AUCTIONHOUSEHOOK_ON_AUCTION_SUCCESSFUL, - AUCTIONHOUSEHOOK_ON_AUCTION_EXPIRE - }) { } - - void OnAuctionAdd(AuctionHouseObject* ah, AuctionEntry* entry) override - { - sALE->OnAdd(ah, entry); - } - - void OnAuctionRemove(AuctionHouseObject* ah, AuctionEntry* entry) override - { - sALE->OnRemove(ah, entry); - } - - void OnAuctionSuccessful(AuctionHouseObject* ah, AuctionEntry* entry) override - { - sALE->OnSuccessful(ah, entry); - } - - void OnAuctionExpire(AuctionHouseObject* ah, AuctionEntry* entry) override - { - sALE->OnExpire(ah, entry); - } -}; - -class ALE_BGScript : public BGScript -{ -public: - ALE_BGScript() : BGScript("ALE_BGScript", { - ALLBATTLEGROUNDHOOK_ON_BATTLEGROUND_START, - ALLBATTLEGROUNDHOOK_ON_BATTLEGROUND_END, - ALLBATTLEGROUNDHOOK_ON_BATTLEGROUND_DESTROY, - ALLBATTLEGROUNDHOOK_ON_BATTLEGROUND_CREATE - }) { } - - void OnBattlegroundStart(Battleground* bg) override - { - sALE->OnBGStart(bg, bg->GetBgTypeID(), bg->GetInstanceID()); - } - - void OnBattlegroundEnd(Battleground* bg, TeamId winnerTeam) override - { - sALE->OnBGEnd(bg, bg->GetBgTypeID(), bg->GetInstanceID(), winnerTeam); - } - - void OnBattlegroundDestroy(Battleground* bg) override - { - sALE->OnBGDestroy(bg, bg->GetBgTypeID(), bg->GetInstanceID()); - } - - void OnBattlegroundCreate(Battleground* bg) override - { - sALE->OnBGCreate(bg, bg->GetBgTypeID(), bg->GetInstanceID()); - } -}; - -class ALE_CommandSC : public CommandSC -{ -public: - ALE_CommandSC() : CommandSC("ALE_CommandSC", { - ALLCOMMANDHOOK_ON_TRY_EXECUTE_COMMAND - }) { } - - bool OnTryExecuteCommand(ChatHandler& handler, std::string_view cmdStr) override - { - if (!sALE->OnCommand(handler, std::string(cmdStr).c_str())) - { - return false; - } - - return true; - } -}; - -class ALE_ALEScript : public ALEScript -{ -public: - ALE_ALEScript() : ALEScript("ALE_ALEScript") { } - - // Weather - void OnWeatherChange(Weather* weather, WeatherState state, float grade) override - { - sALE->OnChange(weather, weather->GetZone(), state, grade); - } - - // AreaTriger - bool CanAreaTrigger(Player* player, AreaTrigger const* trigger) override - { - if (sALE->OnAreaTrigger(player, trigger)) - return true; - - return false; - } -}; - -class ALE_GameEventScript : public GameEventScript -{ -public: - ALE_GameEventScript() : GameEventScript("ALE_GameEventScript", { - GAMEEVENTHOOK_ON_START, - GAMEEVENTHOOK_ON_STOP - }) { } - - void OnStart(uint16 eventID) override - { - sALE->OnGameEventStart(eventID); - } - - void OnStop(uint16 eventID) override - { - sALE->OnGameEventStop(eventID); - } -}; - -class ALE_GroupScript : public GroupScript -{ -public: - ALE_GroupScript() : GroupScript("ALE_GroupScript", { - GROUPHOOK_ON_ADD_MEMBER, - GROUPHOOK_ON_INVITE_MEMBER, - GROUPHOOK_ON_REMOVE_MEMBER, - GROUPHOOK_ON_CHANGE_LEADER, - GROUPHOOK_ON_DISBAND, - GROUPHOOK_ON_CREATE - }) { } - - void OnAddMember(Group* group, ObjectGuid guid) override - { - sALE->OnAddMember(group, guid); - } - - void OnInviteMember(Group* group, ObjectGuid guid) override - { - sALE->OnInviteMember(group, guid); - } - - void OnRemoveMember(Group* group, ObjectGuid guid, RemoveMethod method, ObjectGuid /* kicker */, const char* /* reason */) override - { - sALE->OnRemoveMember(group, guid, method); - } - - void OnChangeLeader(Group* group, ObjectGuid newLeaderGuid, ObjectGuid oldLeaderGuid) override - { - sALE->OnChangeLeader(group, newLeaderGuid, oldLeaderGuid); - } - - void OnDisband(Group* group) override - { - sALE->OnDisband(group); - } - - void OnCreate(Group* group, Player* leader) override - { - sALE->OnCreate(group, leader->GetGUID(), group->GetGroupType()); - } -}; - -class ALE_GuildScript : public GuildScript -{ -public: - ALE_GuildScript() : GuildScript("ALE_GuildScript", { - GUILDHOOK_ON_ADD_MEMBER, - GUILDHOOK_ON_REMOVE_MEMBER, - GUILDHOOK_ON_MOTD_CHANGED, - GUILDHOOK_ON_INFO_CHANGED, - GUILDHOOK_ON_CREATE, - GUILDHOOK_ON_DISBAND, - GUILDHOOK_ON_MEMBER_WITDRAW_MONEY, - GUILDHOOK_ON_MEMBER_DEPOSIT_MONEY, - GUILDHOOK_ON_ITEM_MOVE, - GUILDHOOK_ON_EVENT, - GUILDHOOK_ON_BANK_EVENT - }) { } - - void OnAddMember(Guild* guild, Player* player, uint8& plRank) override - { - sALE->OnAddMember(guild, player, plRank); - } - - void OnRemoveMember(Guild* guild, Player* player, bool isDisbanding, bool /*isKicked*/) override - { - sALE->OnRemoveMember(guild, player, isDisbanding); - } - - void OnMOTDChanged(Guild* guild, const std::string& newMotd) override - { - sALE->OnMOTDChanged(guild, newMotd); - } - - void OnInfoChanged(Guild* guild, const std::string& newInfo) override - { - sALE->OnInfoChanged(guild, newInfo); - } - - void OnCreate(Guild* guild, Player* leader, const std::string& name) override - { - sALE->OnCreate(guild, leader, name); - } - - void OnDisband(Guild* guild) override - { - sALE->OnDisband(guild); - } - - void OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, bool isRepair) override - { - sALE->OnMemberWitdrawMoney(guild, player, amount, isRepair); - } - - void OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount) override - { - sALE->OnMemberDepositMoney(guild, player, amount); - } - - void OnItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId, - bool isDestBank, uint8 destContainer, uint8 destSlotId) override - { - sALE->OnItemMove(guild, player, pItem, isSrcBank, srcContainer, srcSlotId, isDestBank, destContainer, destSlotId); - } - - void OnEvent(Guild* guild, uint8 eventType, ObjectGuid::LowType playerGuid1, ObjectGuid::LowType playerGuid2, uint8 newRank) override - { - sALE->OnEvent(guild, eventType, playerGuid1, playerGuid2, newRank); - } - - void OnBankEvent(Guild* guild, uint8 eventType, uint8 tabId, ObjectGuid::LowType playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) override - { - sALE->OnBankEvent(guild, eventType, tabId, playerGuid, itemOrMoney, itemStackCount, destTabId); - } -}; - -class ALE_LootScript : public LootScript -{ -public: - ALE_LootScript() : LootScript("ALE_LootScript", { - LOOTHOOK_ON_LOOT_MONEY - }) { } - - void OnLootMoney(Player* player, uint32 gold) override - { - sALE->OnLootMoney(player, gold); - } -}; - -class ALE_MiscScript : public MiscScript -{ -public: - ALE_MiscScript() : MiscScript("ALE_MiscScript", { - MISCHOOK_GET_DIALOG_STATUS - }) { } - - void GetDialogStatus(Player* player, Object* questgiver) override - { - if (questgiver->GetTypeId() == TYPEID_GAMEOBJECT) - sALE->GetDialogStatus(player, questgiver->ToGameObject()); - else if (questgiver->GetTypeId() == TYPEID_UNIT) - sALE->GetDialogStatus(player, questgiver->ToCreature()); - } -}; - -class ALE_PetScript : public PetScript -{ -public: - ALE_PetScript() : PetScript("ALE_PetScript", { - PETHOOK_ON_PET_ADD_TO_WORLD - }) { } - - void OnPetAddToWorld(Pet* pet) override - { - sALE->OnPetAddedToWorld(pet->GetOwner(), pet); - } -}; - -class ALE_PlayerScript : public PlayerScript -{ -public: - ALE_PlayerScript() : PlayerScript("ALE_PlayerScript", { - PLAYERHOOK_ON_PLAYER_RESURRECT, - PLAYERHOOK_CAN_PLAYER_USE_CHAT, - PLAYERHOOK_CAN_PLAYER_USE_PRIVATE_CHAT, - PLAYERHOOK_CAN_PLAYER_USE_GROUP_CHAT, - PLAYERHOOK_CAN_PLAYER_USE_GUILD_CHAT, - PLAYERHOOK_CAN_PLAYER_USE_CHANNEL_CHAT, - PLAYERHOOK_ON_LOOT_ITEM, - PLAYERHOOK_ON_PLAYER_LEARN_TALENTS, - PLAYERHOOK_CAN_USE_ITEM, - PLAYERHOOK_ON_EQUIP, - PLAYERHOOK_ON_PLAYER_ENTER_COMBAT, - PLAYERHOOK_ON_PLAYER_LEAVE_COMBAT, - PLAYERHOOK_CAN_REPOP_AT_GRAVEYARD, - PLAYERHOOK_ON_QUEST_ABANDON, - PLAYERHOOK_ON_MAP_CHANGED, - PLAYERHOOK_ON_GOSSIP_SELECT, - PLAYERHOOK_ON_GOSSIP_SELECT_CODE, - PLAYERHOOK_ON_PVP_KILL, - PLAYERHOOK_ON_CREATURE_KILL, - PLAYERHOOK_ON_PLAYER_KILLED_BY_CREATURE, - PLAYERHOOK_ON_LEVEL_CHANGED, - PLAYERHOOK_ON_FREE_TALENT_POINTS_CHANGED, - PLAYERHOOK_ON_TALENTS_RESET, - PLAYERHOOK_ON_MONEY_CHANGED, - PLAYERHOOK_ON_GIVE_EXP, - PLAYERHOOK_ON_REPUTATION_CHANGE, - PLAYERHOOK_ON_DUEL_REQUEST, - PLAYERHOOK_ON_DUEL_START, - PLAYERHOOK_ON_DUEL_END, - PLAYERHOOK_ON_EMOTE, - PLAYERHOOK_ON_TEXT_EMOTE, - PLAYERHOOK_ON_SPELL_CAST, - PLAYERHOOK_ON_LOGIN, - PLAYERHOOK_ON_LOGOUT, - PLAYERHOOK_ON_CREATE, - PLAYERHOOK_ON_SAVE, - PLAYERHOOK_ON_DELETE, - PLAYERHOOK_ON_BIND_TO_INSTANCE, - PLAYERHOOK_ON_UPDATE_AREA, - PLAYERHOOK_ON_UPDATE_ZONE, - PLAYERHOOK_ON_FIRST_LOGIN, - PLAYERHOOK_ON_LEARN_SPELL, - PLAYERHOOK_ON_ACHI_COMPLETE, - PLAYERHOOK_ON_FFA_PVP_STATE_UPDATE, - PLAYERHOOK_CAN_INIT_TRADE, - PLAYERHOOK_CAN_SEND_MAIL, - PLAYERHOOK_CAN_JOIN_LFG, - PLAYERHOOK_ON_QUEST_REWARD_ITEM, - PLAYERHOOK_ON_GROUP_ROLL_REWARD_ITEM, - PLAYERHOOK_ON_CREATE_ITEM, - PLAYERHOOK_ON_STORE_NEW_ITEM, - PLAYERHOOK_ON_PLAYER_COMPLETE_QUEST, - PLAYERHOOK_CAN_GROUP_INVITE, - PLAYERHOOK_ON_BATTLEGROUND_DESERTION, - PLAYERHOOK_ON_CREATURE_KILLED_BY_PET, - PLAYERHOOK_ON_CAN_UPDATE_SKILL, - PLAYERHOOK_ON_BEFORE_UPDATE_SKILL, - PLAYERHOOK_ON_UPDATE_SKILL, - PLAYERHOOK_CAN_RESURRECT - }) { } - - void OnPlayerResurrect(Player* player, float /*restore_percent*/, bool /*applySickness*/) override - { - sALE->OnResurrect(player); - } - - bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 lang, std::string& msg) override - { - if (type != CHAT_MSG_SAY && type != CHAT_MSG_YELL && type != CHAT_MSG_EMOTE) - return true; - - if (!sALE->OnChat(player, type, lang, msg)) - return false; - - return true; - } - - bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 lang, std::string& msg, Player* target) override - { - if (!sALE->OnChat(player, type, lang, msg, target)) - return false; - - return true; - } - - bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group) override - { - if (!sALE->OnChat(player, type, lang, msg, group)) - return false; - - return true; - } - - bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild) override - { - if (!sALE->OnChat(player, type, lang, msg, guild)) - return false; - - return true; - } - - bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 lang, std::string& msg, Channel* channel) override - { - if (!sALE->OnChat(player, type, lang, msg, channel)) - return false; - - return true; - } - - void OnPlayerLootItem(Player* player, Item* item, uint32 count, ObjectGuid lootguid) override - { - sALE->OnLootItem(player, item, count, lootguid); - } - - void OnPlayerLearnTalents(Player* player, uint32 talentId, uint32 talentRank, uint32 spellid) override - { - sALE->OnLearnTalents(player, talentId, talentRank, spellid); - } - - bool OnPlayerCanUseItem(Player* player, ItemTemplate const* proto, InventoryResult& result) override - { - result = sALE->OnCanUseItem(player, proto->ItemId); - return result != EQUIP_ERR_OK ? false : true; - } - - void OnPlayerEquip(Player* player, Item* it, uint8 bag, uint8 slot, bool /*update*/) override - { - sALE->OnEquip(player, it, bag, slot); - } - - void OnPlayerEnterCombat(Player* player, Unit* enemy) override - { - sALE->OnPlayerEnterCombat(player, enemy); - } - - void OnPlayerLeaveCombat(Player* player) override - { - sALE->OnPlayerLeaveCombat(player); - } - - bool OnPlayerCanRepopAtGraveyard(Player* player) override - { - sALE->OnRepop(player); - return true; - } - - void OnPlayerQuestAbandon(Player* player, uint32 questId) override - { - sALE->OnQuestAbandon(player, questId); - } - - void OnPlayerMapChanged(Player* player) override - { - sALE->OnMapChanged(player); - } - - void OnPlayerGossipSelect(Player* player, uint32 menu_id, uint32 sender, uint32 action) override - { - sALE->HandleGossipSelectOption(player, menu_id, sender, action, ""); - } - - void OnPlayerGossipSelectCode(Player* player, uint32 menu_id, uint32 sender, uint32 action, const char* code) override - { - sALE->HandleGossipSelectOption(player, menu_id, sender, action, code); - } - - void OnPlayerPVPKill(Player* killer, Player* killed) override - { - sALE->OnPVPKill(killer, killed); - } - - void OnPlayerCreatureKill(Player* killer, Creature* killed) override - { - sALE->OnCreatureKill(killer, killed); - } - - void OnPlayerKilledByCreature(Creature* killer, Player* killed) override - { - sALE->OnPlayerKilledByCreature(killer, killed); - } - - void OnPlayerLevelChanged(Player* player, uint8 oldLevel) override - { - sALE->OnLevelChanged(player, oldLevel); - } - - void OnPlayerFreeTalentPointsChanged(Player* player, uint32 points) override - { - sALE->OnFreeTalentPointsChanged(player, points); - } - - void OnPlayerTalentsReset(Player* player, bool noCost) override - { - sALE->OnTalentsReset(player, noCost); - } - - void OnPlayerMoneyChanged(Player* player, int32& amount) override - { - sALE->OnMoneyChanged(player, amount); - } - - void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource) override - { - sALE->OnGiveXP(player, amount, victim, xpSource); - } - - bool OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental) override - { - return sALE->OnReputationChange(player, factionID, standing, incremental); - } - - void OnPlayerDuelRequest(Player* target, Player* challenger) override - { - sALE->OnDuelRequest(target, challenger); - } - - void OnPlayerDuelStart(Player* player1, Player* player2) override - { - sALE->OnDuelStart(player1, player2); - } - - void OnPlayerDuelEnd(Player* winner, Player* loser, DuelCompleteType type) override - { - sALE->OnDuelEnd(winner, loser, type); - } - - void OnPlayerEmote(Player* player, uint32 emote) override - { - sALE->OnEmote(player, emote); - } - - void OnPlayerTextEmote(Player* player, uint32 textEmote, uint32 emoteNum, ObjectGuid guid) override - { - sALE->OnTextEmote(player, textEmote, emoteNum, guid); - } - - void OnPlayerSpellCast(Player* player, Spell* spell, bool skipCheck) override - { - sALE->OnPlayerSpellCast(player, spell, skipCheck); - } - - void OnPlayerLogin(Player* player) override - { - sALE->OnLogin(player); - } - - void OnPlayerLogout(Player* player) override - { - sALE->OnLogout(player); - } - - void OnPlayerCreate(Player* player) override - { - sALE->OnCreate(player); - } - - void OnPlayerSave(Player* player) override - { - sALE->OnSave(player); - } - - void OnPlayerDelete(ObjectGuid guid, uint32 /*accountId*/) override - { - sALE->OnDelete(guid.GetCounter()); - } - - void OnPlayerBindToInstance(Player* player, Difficulty difficulty, uint32 mapid, bool permanent) override - { - sALE->OnBindToInstance(player, difficulty, mapid, permanent); - } - - void OnPlayerUpdateArea(Player* player, uint32 oldArea, uint32 newArea) override - { - sALE->OnUpdateArea(player, oldArea, newArea); - } - - void OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newArea) override - { - sALE->OnUpdateZone(player, newZone, newArea); - } - - void OnPlayerFirstLogin(Player* player) override - { - sALE->OnFirstLogin(player); - } - - void OnPlayerLearnSpell(Player* player, uint32 spellId) override - { - sALE->OnLearnSpell(player, spellId); - } - - void OnPlayerAchievementComplete(Player* player, AchievementEntry const* achievement) override - { - sALE->OnAchiComplete(player, achievement); - } - - void OnPlayerFfaPvpStateUpdate(Player* player, bool IsFlaggedForFfaPvp) override - { - sALE->OnFfaPvpStateUpdate(player, IsFlaggedForFfaPvp); - } - - bool OnPlayerCanInitTrade(Player* player, Player* target) override - { - return sALE->OnCanInitTrade(player, target); - } - - bool OnPlayerCanSendMail(Player* player, ObjectGuid receiverGuid, ObjectGuid mailbox, std::string& subject, std::string& body, uint32 money, uint32 cod, Item* item) override - { - return sALE->OnCanSendMail(player, receiverGuid, mailbox, subject, body, money, cod, item); - } - - bool OnPlayerCanJoinLfg(Player* player, uint8 roles, lfg::LfgDungeonSet& dungeons, const std::string& comment) override - { - return sALE->OnCanJoinLfg(player, roles, dungeons, comment); - } - - void OnPlayerQuestRewardItem(Player* player, Item* item, uint32 count) override - { - sALE->OnQuestRewardItem(player, item, count); - } - - void OnPlayerGroupRollRewardItem(Player* player, Item* item, uint32 count, RollVote voteType, Roll* roll) override - { - sALE->OnGroupRollRewardItem(player, item, count, voteType, roll); - } - - void OnPlayerCreateItem(Player* player, Item* item, uint32 count) override - { - sALE->OnCreateItem(player, item, count); - } - - void OnPlayerStoreNewItem(Player* player, Item* item, uint32 count) override - { - sALE->OnStoreNewItem(player, item, count); - } - - void OnPlayerCompleteQuest(Player* player, Quest const* quest) override - { - sALE->OnPlayerCompleteQuest(player, quest); - } - - bool OnPlayerCanGroupInvite(Player* player, std::string& memberName) override - { - return sALE->OnCanGroupInvite(player, memberName); - } - - void OnPlayerBattlegroundDesertion(Player* player, const BattlegroundDesertionType type) override - { - sALE->OnBattlegroundDesertion(player, type); - } - - void OnPlayerCreatureKilledByPet(Player* player, Creature* killed) override - { - sALE->OnCreatureKilledByPet(player, killed); - } - - bool OnPlayerCanUpdateSkill(Player* player, uint32 skill_id) override - { - return sALE->OnPlayerCanUpdateSkill(player, skill_id); - } - - void OnPlayerBeforeUpdateSkill(Player* player, uint32 skill_id, uint32& value, uint32 max, uint32 step) override - { - sALE->OnPlayerBeforeUpdateSkill(player, skill_id, value, max, step); - } - - void OnPlayerUpdateSkill(Player* player, uint32 skill_id, uint32 value, uint32 max, uint32 step, uint32 new_value) override - { - sALE->OnPlayerUpdateSkill(player, skill_id, value, max, step, new_value); - } - - bool OnPlayerCanResurrect(Player* player) override - { - return sALE->CanPlayerResurrect(player); - } -}; - -class ALE_ServerScript : public ServerScript -{ -public: - ALE_ServerScript() : ServerScript("ALE_ServerScript", { - SERVERHOOK_CAN_PACKET_SEND, - SERVERHOOK_CAN_PACKET_RECEIVE - }) { } - - bool CanPacketSend(WorldSession* session, WorldPacket& packet) override - { - if (!sALE->OnPacketSend(session, packet)) - return false; - - return true; - } - - bool CanPacketReceive(WorldSession* session, WorldPacket& packet) override - { - if (!sALE->OnPacketReceive(session, packet)) - return false; - - return true; - } -}; - -class ALE_SpellSC : public SpellSC -{ -public: - ALE_SpellSC() : SpellSC("ALE_SpellSC", { - ALLSPELLHOOK_ON_DUMMY_EFFECT_GAMEOBJECT, - ALLSPELLHOOK_ON_DUMMY_EFFECT_CREATURE, - ALLSPELLHOOK_ON_DUMMY_EFFECT_ITEM, - ALLSPELLHOOK_ON_CAST_CANCEL, - ALLSPELLHOOK_ON_CAST, - ALLSPELLHOOK_ON_PREPARE - }) { } - - void OnDummyEffect(WorldObject* caster, uint32 spellID, SpellEffIndex effIndex, GameObject* gameObjTarget) override - { - sALE->OnDummyEffect(caster, spellID, effIndex, gameObjTarget); - } - - void OnDummyEffect(WorldObject* caster, uint32 spellID, SpellEffIndex effIndex, Creature* creatureTarget) override - { - sALE->OnDummyEffect(caster, spellID, effIndex, creatureTarget); - } - - void OnDummyEffect(WorldObject* caster, uint32 spellID, SpellEffIndex effIndex, Item* itemTarget) override - { - sALE->OnDummyEffect(caster, spellID, effIndex, itemTarget); - } - - void OnSpellCastCancel(Spell* spell, Unit* caster, SpellInfo const* spellInfo, bool bySelf) override - { - sALE->OnSpellCastCancel(caster, spell, spellInfo, bySelf); - } - - void OnSpellCast(Spell* spell, Unit* caster, SpellInfo const* spellInfo, bool skipCheck) override - { - sALE->OnSpellCast(caster, spell, spellInfo, skipCheck); - } - - void OnSpellPrepare(Spell* spell, Unit* caster, SpellInfo const* spellInfo) override - { - sALE->OnSpellPrepare(caster, spell, spellInfo); - } -}; - -class ALE_VehicleScript : public VehicleScript -{ -public: - ALE_VehicleScript() : VehicleScript("ALE_VehicleScript") { } - - void OnInstall(Vehicle* veh) override - { - sALE->OnInstall(veh); - } - - void OnUninstall(Vehicle* veh) override - { - sALE->OnUninstall(veh); - } - - void OnInstallAccessory(Vehicle* veh, Creature* accessory) override - { - sALE->OnInstallAccessory(veh, accessory); - } - - void OnAddPassenger(Vehicle* veh, Unit* passenger, int8 seatId) override - { - sALE->OnAddPassenger(veh, passenger, seatId); - } - - void OnRemovePassenger(Vehicle* veh, Unit* passenger) override - { - sALE->OnRemovePassenger(veh, passenger); - } -}; - -class ALE_WorldObjectScript : public WorldObjectScript -{ -public: - ALE_WorldObjectScript() : WorldObjectScript("ALE_WorldObjectScript", { - WORLDOBJECTHOOK_ON_WORLD_OBJECT_DESTROY, - WORLDOBJECTHOOK_ON_WORLD_OBJECT_CREATE, - WORLDOBJECTHOOK_ON_WORLD_OBJECT_SET_MAP, - WORLDOBJECTHOOK_ON_WORLD_OBJECT_UPDATE - }) { } - - void OnWorldObjectDestroy(WorldObject* object) override - { - delete object->ALEEvents; - object->ALEEvents = nullptr; - } - - void OnWorldObjectCreate(WorldObject* object) override - { - object->ALEEvents = nullptr; - } - - void OnWorldObjectSetMap(WorldObject* object, Map* /*map*/) override - { - if (!object->ALEEvents) - object->ALEEvents = new ALEEventProcessor(&ALE::GALE, object); - } - - void OnWorldObjectUpdate(WorldObject* object, uint32 diff) override - { - object->ALEEvents->Update(diff); - } -}; - -class ALE_WorldScript : public WorldScript -{ -public: - ALE_WorldScript() : WorldScript("ALE_WorldScript", { - WORLDHOOK_ON_OPEN_STATE_CHANGE, - WORLDHOOK_ON_BEFORE_CONFIG_LOAD, - WORLDHOOK_ON_AFTER_CONFIG_LOAD, - WORLDHOOK_ON_SHUTDOWN_INITIATE, - WORLDHOOK_ON_SHUTDOWN_CANCEL, - WORLDHOOK_ON_UPDATE, - WORLDHOOK_ON_STARTUP, - WORLDHOOK_ON_SHUTDOWN, - WORLDHOOK_ON_AFTER_UNLOAD_ALL_MAPS, - WORLDHOOK_ON_BEFORE_WORLD_INITIALIZED - }) { } - - void OnOpenStateChange(bool open) override - { - sALE->OnOpenStateChange(open); - } - - void OnBeforeConfigLoad(bool reload) override - { - ALEConfig::GetInstance().Initialize(reload); - if (!reload) - { - ///- Initialize Lua Engine - LOG_INFO("ALE", "Initialize ALE Lua Engine..."); - ALE::Initialize(); - } - - sALE->OnConfigLoad(reload, true); - } - - void OnAfterConfigLoad(bool reload) override - { - sALE->OnConfigLoad(reload, false); - } - - void OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask) override - { - sALE->OnShutdownInitiate(code, mask); - } - - void OnShutdownCancel() override - { - sALE->OnShutdownCancel(); - } - - void OnUpdate(uint32 diff) override - { - sALE->OnWorldUpdate(diff); - } - - void OnStartup() override - { - sALE->OnStartup(); - } - - void OnShutdown() override - { - sALE->OnShutdown(); - } - - void OnAfterUnloadAllMaps() override - { - ALE::Uninitialize(); - } - - void OnBeforeWorldInitialized() override - { - ///- Run ALE scripts. - // in multithread foreach: run scripts - sALE->RunScripts(); - sALE->OnConfigLoad(false, false); // Must be done after ALE is initialized and scripts have run. - } -}; - -class ALE_TicketScript : public TicketScript -{ -public: - ALE_TicketScript() : TicketScript("ALE_TicketScript", { - TICKETHOOK_ON_TICKET_CREATE, - TICKETHOOK_ON_TICKET_UPDATE_LAST_CHANGE, - TICKETHOOK_ON_TICKET_CLOSE, - TICKETHOOK_ON_TICKET_RESOLVE - }) { } - - void OnTicketCreate(GmTicket* ticket) override - { - sALE->OnTicketCreate(ticket); - } - - void OnTicketUpdateLastChange(GmTicket* ticket) override - { - sALE->OnTicketUpdateLastChange(ticket); - } - - void OnTicketClose(GmTicket* ticket) override - { - sALE->OnTicketClose(ticket); - } - - void OnTicketResolve(GmTicket* ticket) override - { - sALE->OnTicketResolve(ticket); - } -}; - -class ALE_UnitScript : public UnitScript -{ -public: - ALE_UnitScript() : UnitScript("ALE_UnitScript") { } - - void OnAuraApply(Unit* unit, Aura* aura) override - { - if (!unit || !aura) return; - - if (unit->IsPlayer()) - sALE->OnPlayerAuraApply(unit->ToPlayer(), aura); - - if (unit->IsCreature()) - { - sALE->OnCreatureAuraApply(unit->ToCreature(), aura); - sALE->OnAllCreatureAuraApply(unit->ToCreature(), aura); - } - } - - void OnAuraRemove(Unit* unit, AuraApplication* aurApp, AuraRemoveMode mode) override - { - if (!unit || !aurApp->GetBase()) return; - - if (unit->IsPlayer()) - sALE->OnPlayerAuraRemove(unit->ToPlayer(), aurApp->GetBase(), mode); - - if (unit->IsCreature()) - { - sALE->OnCreatureAuraRemove(unit->ToCreature(), aurApp->GetBase(), mode); - sALE->OnAllCreatureAuraRemove(unit->ToCreature(), aurApp->GetBase(), mode); - } - } - - void OnHeal(Unit* healer, Unit* receiver, uint32& gain) override - { - if (!receiver || !healer) return; - - if (healer->IsPlayer()) - sALE->OnPlayerHeal(healer->ToPlayer(), receiver, gain); - - if (healer->IsCreature()) - { - sALE->OnCreatureHeal(healer->ToCreature(), receiver, gain); - sALE->OnAllCreatureHeal(healer->ToCreature(), receiver, gain); - } - } - - void OnDamage(Unit* attacker, Unit* receiver, uint32& damage) override - { - if (!attacker || !receiver) return; - - if (attacker->IsPlayer()) - sALE->OnPlayerDamage(attacker->ToPlayer(), receiver, damage); - - if (attacker->IsCreature()) - { - sALE->OnCreatureDamage(attacker->ToCreature(), receiver, damage); - sALE->OnAllCreatureDamage(attacker->ToCreature(), receiver, damage); - } - } - - void ModifyPeriodicDamageAurasTick(Unit* target, Unit* attacker, uint32& damage, SpellInfo const* spellInfo) override - { - if (!target || !attacker) return; - - if (attacker->IsPlayer()) - sALE->OnPlayerModifyPeriodicDamageAurasTick(attacker->ToPlayer(), target, damage, spellInfo); - - if (attacker->IsCreature()) - { - sALE->OnCreatureModifyPeriodicDamageAurasTick(attacker->ToCreature(), target, damage, spellInfo); - sALE->OnAllCreatureModifyPeriodicDamageAurasTick(attacker->ToCreature(), target, damage, spellInfo); - } - } - - void ModifyMeleeDamage(Unit* target, Unit* attacker, uint32& damage) override - { - if (!target || !attacker) return; - - if (attacker->IsPlayer()) - sALE->OnPlayerModifyMeleeDamage(attacker->ToPlayer(), target, damage); - - if (attacker->IsCreature()) - { - sALE->OnCreatureModifyMeleeDamage(attacker->ToCreature(), target, damage); - sALE->OnAllCreatureModifyMeleeDamage(attacker->ToCreature(), target, damage); - } - } - - void ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& damage, SpellInfo const* spellInfo) override - { - if (!target || !attacker) return; - - if (attacker->IsPlayer()) - sALE->OnPlayerModifySpellDamageTaken(attacker->ToPlayer(), target, damage, spellInfo); - - if (attacker->IsCreature()) - { - sALE->OnCreatureModifySpellDamageTaken(attacker->ToCreature(), target, damage, spellInfo); - sALE->OnAllCreatureModifySpellDamageTaken(attacker->ToCreature(), target, damage, spellInfo); - } - } - - void ModifyHealReceived(Unit* target, Unit* healer, uint32& heal, SpellInfo const* spellInfo) override - { - if (!target || !healer) return; - - if (healer->IsPlayer()) - sALE->OnPlayerModifyHealReceived(healer->ToPlayer(), target, heal, spellInfo); - - if (healer->IsCreature()) - { - sALE->OnCreatureModifyHealReceived(healer->ToCreature(), target, heal, spellInfo); - sALE->OnAllCreatureModifyHealReceived(healer->ToCreature(), target, heal, spellInfo); - } - } - - uint32 DealDamage(Unit* AttackerUnit, Unit* pVictim, uint32 damage, DamageEffectType damagetype) override - { - if (!AttackerUnit || !pVictim) return damage; - - if (AttackerUnit->IsPlayer()) - return sALE->OnPlayerDealDamage(AttackerUnit->ToPlayer(), pVictim, damage, damagetype); - - if (AttackerUnit->IsCreature()) - return sALE->OnCreatureDealDamage(AttackerUnit->ToCreature(), pVictim, damage, damagetype); +#include "StateManager.h" +#include "EventManager.h" +#include "EclipseScriptLoader.h" +#include "ScriptCompiler.h" - return damage; - } -}; +#include "WorldHooks.hpp" +#include "PlayerHooks.hpp" +#include "WorldObjectHooks.hpp" -// Group all custom scripts void AddSC_ALE() { - new ALE_AllCreatureScript(); - new ALE_AllGameObjectScript(); - new ALE_AllItemScript(); - new ALE_AllMapScript(); - new ALE_AuctionHouseScript(); - new ALE_BGScript(); - new ALE_CommandSC(); - new ALE_ALEScript(); - new ALE_GameEventScript(); - new ALE_GroupScript(); - new ALE_GuildScript(); - new ALE_LootScript(); - new ALE_MiscScript(); - new ALE_PetScript(); - new ALE_PlayerScript(); - new ALE_ServerScript(); - new ALE_SpellSC(); - new ALE_TicketScript(); - new ALE_VehicleScript(); - new ALE_WorldObjectScript(); - new ALE_WorldScript(); - new ALE_UnitScript(); + // new ALE_WorldScript(); + new Eclipse::Hooks::WorldHooks(); + new Eclipse::Hooks::PlayerHooks(); + new Eclipse::Hooks::WorldObjectHooks(); } diff --git a/src/LuaEngine/.editorconfig b/src/LuaEngine/.editorconfig deleted file mode 100644 index a34283ac17..0000000000 --- a/src/LuaEngine/.editorconfig +++ /dev/null @@ -1,7 +0,0 @@ -[*] -charset = utf-8 -indent_style = space -indent_size = 4 -tab_width = 4 -insert_final_newline = true -trim_trailing_whitespace = true diff --git a/src/LuaEngine/ALECompat.cpp b/src/LuaEngine/ALECompat.cpp deleted file mode 100644 index 18535df499..0000000000 --- a/src/LuaEngine/ALECompat.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * This program is free software licensed under GPL version 3 - * Please see the included DOCS/LICENSE.md for more information - */ - -#include "ALECompat.h" - -#if LUA_VERSION_NUM == 501 -const char* luaL_tolstring(lua_State* L, int idx, size_t* len) { - if (!luaL_callmeta(L, idx, "__tostring")) { - int t = lua_type(L, idx), tt = 0; - char const* name = NULL; - switch (t) { - case LUA_TNIL: - lua_pushliteral(L, "nil"); - break; - case LUA_TSTRING: - case LUA_TNUMBER: - lua_pushvalue(L, idx); - break; - case LUA_TBOOLEAN: - if (lua_toboolean(L, idx)) - lua_pushliteral(L, "true"); - else - lua_pushliteral(L, "false"); - break; - default: - tt = luaL_getmetafield(L, idx, "__name"); - name = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : lua_typename(L, t); - lua_pushfstring(L, "%s: %p", name, lua_topointer(L, idx)); - if (tt != LUA_TNIL) - lua_replace(L, -2); - break; - } - } - else { - if (!lua_isstring(L, -1)) - luaL_error(L, "'__tostring' must return a string"); - } - return lua_tolstring(L, -1, len); -} - -int luaL_getsubtable(lua_State* L, int i, const char* name) { - int abs_i = lua_absindex(L, i); - luaL_checkstack(L, 3, "not enough stack slots"); - lua_pushstring(L, name); - lua_gettable(L, abs_i); - if (lua_istable(L, -1)) - return 1; - lua_pop(L, 1); - lua_newtable(L); - lua_pushstring(L, name); - lua_pushvalue(L, -2); - lua_settable(L, abs_i); - return 0; -} - -int lua_absindex(lua_State* L, int i) { - if (i < 0 && i > LUA_REGISTRYINDEX) - i += lua_gettop(L) + 1; - return i; -} - -#if !defined LUAJIT_VERSION -void* luaL_testudata(lua_State* L, int index, const char* tname) { - void* ud = lua_touserdata(L, index); - if (ud) - { - if (lua_getmetatable(L, index)) - { - luaL_getmetatable(L, tname); - if (!lua_rawequal(L, -1, -2)) - ud = NULL; - lua_pop(L, 2); - return ud; - } - } - return NULL; -} - -void luaL_setmetatable(lua_State* L, const char* tname) { - lua_pushstring(L, tname); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_setmetatable(L, -2); -} -#endif -#endif diff --git a/src/LuaEngine/ALECompat.h b/src/LuaEngine/ALECompat.h deleted file mode 100644 index 42d783d7e5..0000000000 --- a/src/LuaEngine/ALECompat.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * This program is free software licensed under GPL version 3 - * Please see the included DOCS/LICENSE.md for more information - */ - -#ifndef ALECOMPAT_H -#define ALECOMPAT_H - -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -}; - -/* Compatibility layer for compiling with Lua 5.1 or LuaJIT */ -#if LUA_VERSION_NUM == 501 - int luaL_getsubtable(lua_State* L, int i, const char* name); - const char* luaL_tolstring(lua_State* L, int idx, size_t* len); - int lua_absindex(lua_State* L, int i); - #define lua_pushglobaltable(L) \ - lua_pushvalue((L), LUA_GLOBALSINDEX) - #define lua_rawlen(L, idx) \ - lua_objlen(L, idx) - #define lua_pushunsigned(L, u) \ - lua_pushinteger(L, u) - #define lua_load(L, buf_read, dec_buf, str, NULL) \ - lua_load(L, buf_read, dec_buf, str) - - #ifndef LUA_OK - #define LUA_OK 0 - #endif - -#if !defined LUAJIT_VERSION - void* luaL_testudata(lua_State* L, int index, const char* tname); - void luaL_setmetatable(lua_State* L, const char* tname); - #define luaL_setfuncs(L, l, n) luaL_register(L, NULL, l) -#endif -#endif - -#if LUA_VERSION_NUM > 502 - #define lua_dump(L, writer, data) \ - lua_dump(L, writer, data, 0) - #define lua_pushunsigned(L, u) \ - lua_pushinteger(L, u) -#endif -#endif diff --git a/src/LuaEngine/ALEConfig.cpp b/src/LuaEngine/ALEConfig.cpp deleted file mode 100644 index e3eca213bd..0000000000 --- a/src/LuaEngine/ALEConfig.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "ALEConfig.h" - -ALEConfig& ALEConfig::GetInstance() -{ - static ALEConfig instance; - return instance; -} - -ALEConfig::ALEConfig() : ConfigValueCache(ALEConfigValues::CONFIG_VALUE_COUNT) -{ -} - -void ALEConfig::Initialize(bool reload) -{ - ConfigValueCache::Initialize(reload); -} - -void ALEConfig::BuildConfigCache() -{ - SetConfigValue(ALEConfigValues::ENABLED, "ALE.Enabled", "false"); - SetConfigValue(ALEConfigValues::TRACEBACK_ENABLED, "ALE.TraceBack", "false"); - SetConfigValue(ALEConfigValues::AUTORELOAD_ENABLED, "ALE.AutoReload", "false"); - SetConfigValue(ALEConfigValues::BYTECODE_CACHE_ENABLED, "ALE.BytecodeCache", "false"); - - SetConfigValue(ALEConfigValues::SCRIPT_PATH, "ALE.ScriptPath", "lua_scripts"); - SetConfigValue(ALEConfigValues::REQUIRE_PATH, "ALE.RequirePaths", ""); - SetConfigValue(ALEConfigValues::REQUIRE_CPATH, "ALE.RequireCPaths", ""); - - SetConfigValue(ALEConfigValues::AUTORELOAD_INTERVAL, "ALE.AutoReloadInterval", 1); -} diff --git a/src/LuaEngine/ALEConfig.h b/src/LuaEngine/ALEConfig.h deleted file mode 100644 index b413b4a451..0000000000 --- a/src/LuaEngine/ALEConfig.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef ALE_CONFIG_HPP -#define ALE_CONFIG_HPP - -#include "ConfigValueCache.h" - -enum class ALEConfigValues : uint32 -{ - // Boolean - ENABLED = 0, - TRACEBACK_ENABLED, - AUTORELOAD_ENABLED, - BYTECODE_CACHE_ENABLED, - - // String - SCRIPT_PATH, - REQUIRE_PATH, - REQUIRE_CPATH, - - // Number - AUTORELOAD_INTERVAL, - - CONFIG_VALUE_COUNT -}; - -class ALEConfig final : public ConfigValueCache -{ - public: - static ALEConfig& GetInstance(); - - void Initialize(bool reload = false); - - bool IsALEEnabled() const { return GetConfigValue(ALEConfigValues::ENABLED); } - bool IsTraceBackEnabled() const { return GetConfigValue(ALEConfigValues::TRACEBACK_ENABLED); } - bool IsAutoReloadEnabled() const { return GetConfigValue(ALEConfigValues::AUTORELOAD_ENABLED); } - bool IsByteCodeCacheEnabled() const { return GetConfigValue(ALEConfigValues::BYTECODE_CACHE_ENABLED); } - - std::string_view GetScriptPath() const { return GetConfigValue(ALEConfigValues::SCRIPT_PATH); } - std::string_view GetRequirePath() const { return GetConfigValue(ALEConfigValues::REQUIRE_PATH); } - std::string_view GetRequireCPath() const { return GetConfigValue(ALEConfigValues::REQUIRE_CPATH); } - - uint32 GetAutoReloadInterval() const { return GetConfigValue(ALEConfigValues::AUTORELOAD_INTERVAL); } - - protected: - void BuildConfigCache() override; - - private: - ALEConfig(); - ~ALEConfig() = default; - ALEConfig(const ALEConfig&) = delete; - ALEConfig& operator=(const ALEConfig&) = delete; -}; - -#endif // ALE_CONFIG_H \ No newline at end of file diff --git a/src/LuaEngine/ALECreatureAI.h b/src/LuaEngine/ALECreatureAI.h deleted file mode 100644 index cb9ccdae7c..0000000000 --- a/src/LuaEngine/ALECreatureAI.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * This program is free software licensed under GPL version 3 - * Please see the included DOCS/LICENSE.md for more information - */ - -#ifndef _ALE_CREATURE_AI_H -#define _ALE_CREATURE_AI_H - -#include "LuaEngine.h" - -struct ScriptedAI; - -struct ALECreatureAI : ScriptedAI -{ - // used to delay the spawn hook triggering on AI creation - bool justSpawned; - // used to delay movementinform hook (WP hook) - std::vector< std::pair > movepoints; - - ALECreatureAI(Creature* creature) : ScriptedAI(creature), justSpawned(true) - { - } - ~ALECreatureAI() { } - - //Called at World update tick - void UpdateAI(uint32 diff) override - { - if (justSpawned) - { - justSpawned = false; - - JustRespawned(); - } - - if (!movepoints.empty()) - { - for (auto& point : movepoints) - { - if (!sALE->MovementInform(me, point.first, point.second)) - ScriptedAI::MovementInform(point.first, point.second); - } - movepoints.clear(); - } - - if (!sALE->UpdateAI(me, diff)) - { - if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC)) - ScriptedAI::UpdateAI(diff); - } - } - - // Called for reaction when initially engaged - this will always happen _after_ JustEnteredCombat - // Called at creature aggro either by MoveInLOS or Attack Start - void JustEngagedWith(Unit* target) override - { - if (!sALE->EnterCombat(me, target)) - ScriptedAI::JustEngagedWith(target); - } - - // Called at any Damage from any attacker (before damage apply) - void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask) override - { - if (!sALE->DamageTaken(me, attacker, damage)) - { - ScriptedAI::DamageTaken(attacker, damage, damagetype, damageSchoolMask); - } - } - - //Called at creature death - void JustDied(Unit* killer) override - { - if (!sALE->JustDied(me, killer)) - ScriptedAI::JustDied(killer); - } - - //Called at creature killing another unit - void KilledUnit(Unit* victim) override - { - if (!sALE->KilledUnit(me, victim)) - ScriptedAI::KilledUnit(victim); - } - - // Called when the creature summon successfully other creature - void JustSummoned(Creature* summon) override - { - if (!sALE->JustSummoned(me, summon)) - ScriptedAI::JustSummoned(summon); - } - - // Called when a summoned creature is despawned - void SummonedCreatureDespawn(Creature* summon) override - { - if (!sALE->SummonedCreatureDespawn(me, summon)) - ScriptedAI::SummonedCreatureDespawn(summon); - } - - //Called at waypoint reached or PointMovement end - void MovementInform(uint32 type, uint32 id) override - { - // delayed since hook triggers before actually reaching the point - // and starting new movement would bug - movepoints.push_back(std::make_pair(type, id)); - } - - // Called before EnterCombat even before the creature is in combat. - void AttackStart(Unit* target) override - { - if (!sALE->AttackStart(me, target)) - ScriptedAI::AttackStart(target); - } - - // Called for reaction at stopping attack at no attackers or targets - void EnterEvadeMode(EvadeReason /*why*/) override - { - if (!sALE->EnterEvadeMode(me)) - ScriptedAI::EnterEvadeMode(); - } - - // Called when creature is spawned or respawned (for reseting variables) - void JustRespawned() override - { - if (!sALE->JustRespawned(me)) - ScriptedAI::JustRespawned(); - } - - // Called at reaching home after evade - void JustReachedHome() override - { - if (!sALE->JustReachedHome(me)) - ScriptedAI::JustReachedHome(); - } - - // Called at text emote receive from player - void ReceiveEmote(Player* player, uint32 emoteId) override - { - if (!sALE->ReceiveEmote(me, player, emoteId)) - ScriptedAI::ReceiveEmote(player, emoteId); - } - - // called when the corpse of this creature gets removed - void CorpseRemoved(uint32& respawnDelay) override - { - if (!sALE->CorpseRemoved(me, respawnDelay)) - ScriptedAI::CorpseRemoved(respawnDelay); - } - - void MoveInLineOfSight(Unit* who) override - { - if (!sALE->MoveInLineOfSight(me, who)) - ScriptedAI::MoveInLineOfSight(who); - } - - // Called when hit by a spell - void SpellHit(Unit* caster, SpellInfo const* spell) override - { - if (!sALE->SpellHit(me, caster, spell)) - ScriptedAI::SpellHit(caster, spell); - } - - // Called when spell hits a target - void SpellHitTarget(Unit* target, SpellInfo const* spell) override - { - if (!sALE->SpellHitTarget(me, target, spell)) - ScriptedAI::SpellHitTarget(target, spell); - } - - // Called when the creature is summoned successfully by other creature - void IsSummonedBy(WorldObject* summoner) override - { - if (!summoner->ToUnit() || !sALE->OnSummoned(me, summoner->ToUnit())) - ScriptedAI::IsSummonedBy(summoner); - } - - void SummonedCreatureDies(Creature* summon, Unit* killer) override - { - if (!sALE->SummonedCreatureDies(me, summon, killer)) - ScriptedAI::SummonedCreatureDies(summon, killer); - } - - // Called when owner takes damage - void OwnerAttackedBy(Unit* attacker) override - { - if (!sALE->OwnerAttackedBy(me, attacker)) - ScriptedAI::OwnerAttackedBy(attacker); - } - - // Called when owner attacks something - void OwnerAttacked(Unit* target) override - { - if (!sALE->OwnerAttacked(me, target)) - ScriptedAI::OwnerAttacked(target); - } -}; - -#endif diff --git a/src/LuaEngine/ALEDBCRegistry.cpp b/src/LuaEngine/ALEDBCRegistry.cpp deleted file mode 100644 index 4acc31124a..0000000000 --- a/src/LuaEngine/ALEDBCRegistry.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "ALEDBCRegistry.h" - -std::vector dbcRegistry = { - REGISTER_DBC(GemProperties, GemPropertiesEntry, sGemPropertiesStore), - REGISTER_DBC(Spell, SpellEntry, sSpellStore), -}; - diff --git a/src/LuaEngine/ALEDBCRegistry.h b/src/LuaEngine/ALEDBCRegistry.h deleted file mode 100644 index b525ce8e49..0000000000 --- a/src/LuaEngine/ALEDBCRegistry.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef ALEDBCREGISTRY_H -#define ALEDBCREGISTRY_H - -#include -#include -#include -#include - -#include "DBCStores.h" -#include "LuaEngine.h" - -struct DBCDefinition -{ - std::string name; - void* storage; - const std::type_info& type; - std::function lookupFunction; - std::function pushFunction; -}; - -extern std::vector dbcRegistry; - -#define REGISTER_DBC(dbcName, entryType, store) \ - { \ - #dbcName, \ - reinterpret_cast(&store), \ - typeid(DBCStorage), \ - [](uint32 id) -> const void* { \ - return store.LookupEntry(id); \ - }, \ - [](lua_State* L, const void* entry) { \ - auto cast_entry = static_cast(entry); \ - ALE::Push(L, *cast_entry); \ - } \ - } - -#endif // ALEDBCREGISTRY_H - diff --git a/src/LuaEngine/ALEEventMgr.cpp b/src/LuaEngine/ALEEventMgr.cpp deleted file mode 100644 index f90cee3167..0000000000 --- a/src/LuaEngine/ALEEventMgr.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#include "ALEEventMgr.h" -#include "LuaEngine.h" -#include "Object.h" - -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -}; - -ALEEventProcessor::ALEEventProcessor(ALE** _E, WorldObject* _obj) : m_time(0), obj(_obj), E(_E) -{ - // can be called from multiple threads - if (obj) - { - EventMgr::Guard guard((*E)->eventMgr->GetLock()); - (*E)->eventMgr->processors.insert(this); - } -} - -ALEEventProcessor::~ALEEventProcessor() -{ - // can be called from multiple threads - { - LOCK_ALE; - RemoveEvents_internal(); - } - - if (obj && ALE::IsInitialized()) - { - EventMgr::Guard guard((*E)->eventMgr->GetLock()); - (*E)->eventMgr->processors.erase(this); - } -} - -void ALEEventProcessor::Update(uint32 diff) -{ - m_time += diff; - for (EventList::iterator it = eventList.begin(); it != eventList.end() && it->first <= m_time; it = eventList.begin()) - { - LuaEvent* luaEvent = it->second; - eventList.erase(it); - - if (luaEvent->state != LUAEVENT_STATE_ERASE) - eventMap.erase(luaEvent->funcRef); - - if (luaEvent->state == LUAEVENT_STATE_RUN) - { - uint32 delay = luaEvent->delay; - bool remove = luaEvent->repeats == 1; - if (!remove) - AddEvent(luaEvent); // Reschedule before calling incase RemoveEvents used - - // Call the timed event - (*E)->OnTimedEvent(luaEvent->funcRef, delay, luaEvent->repeats ? luaEvent->repeats-- : luaEvent->repeats, obj); - - if (!remove) - continue; - } - - // Event should be deleted (executed last time or set to be aborted) - RemoveEvent(luaEvent); - } -} - -void ALEEventProcessor::SetStates(LuaEventState state) -{ - for (EventList::iterator it = eventList.begin(); it != eventList.end(); ++it) - it->second->SetState(state); - if (state == LUAEVENT_STATE_ERASE) - eventMap.clear(); -} - -void ALEEventProcessor::RemoveEvents_internal() -{ - //if (!final) - //{ - // for (EventList::iterator it = eventList.begin(); it != eventList.end(); ++it) - // it->second->to_Abort = true; - // return; - //} - - for (EventList::iterator it = eventList.begin(); it != eventList.end(); ++it) - RemoveEvent(it->second); - - eventList.clear(); - eventMap.clear(); -} - -void ALEEventProcessor::SetState(int eventId, LuaEventState state) -{ - if (eventMap.find(eventId) != eventMap.end()) - eventMap[eventId]->SetState(state); - if (state == LUAEVENT_STATE_ERASE) - eventMap.erase(eventId); -} - -void ALEEventProcessor::AddEvent(LuaEvent* luaEvent) -{ - luaEvent->GenerateDelay(); - eventList.insert(std::pair(m_time + luaEvent->delay, luaEvent)); - eventMap[luaEvent->funcRef] = luaEvent; -} - -void ALEEventProcessor::AddEvent(int funcRef, uint32 min, uint32 max, uint32 repeats) -{ - AddEvent(new LuaEvent(funcRef, min, max, repeats)); -} - -void ALEEventProcessor::RemoveEvent(LuaEvent* luaEvent) -{ - // Unreference if should and if ALE was not yet uninitialized and if the lua state still exists - if (luaEvent->state != LUAEVENT_STATE_ERASE && ALE::IsInitialized() && (*E)->HasLuaState()) - { - // Free lua function ref - luaL_unref((*E)->L, LUA_REGISTRYINDEX, luaEvent->funcRef); - } - delete luaEvent; -} - -EventMgr::EventMgr(ALE** _E) : globalProcessor(new ALEEventProcessor(_E, NULL)), E(_E) -{ -} - -EventMgr::~EventMgr() -{ - { - Guard guard(GetLock()); - if (!processors.empty()) - for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors - (*it)->RemoveEvents_internal(); - globalProcessor->RemoveEvents_internal(); - } - delete globalProcessor; - globalProcessor = NULL; -} - -void EventMgr::SetStates(LuaEventState state) -{ - Guard guard(GetLock()); - if (!processors.empty()) - for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors - (*it)->SetStates(state); - globalProcessor->SetStates(state); -} - -void EventMgr::SetState(int eventId, LuaEventState state) -{ - Guard guard(GetLock()); - if (!processors.empty()) - for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors - (*it)->SetState(eventId, state); - globalProcessor->SetState(eventId, state); -} diff --git a/src/LuaEngine/ALEEventMgr.h b/src/LuaEngine/ALEEventMgr.h deleted file mode 100644 index 5302ecead2..0000000000 --- a/src/LuaEngine/ALEEventMgr.h +++ /dev/null @@ -1,104 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef _ALE_EVENT_MGR_H -#define _ALE_EVENT_MGR_H - -#include "ALEUtility.h" -#include "Common.h" -#include "Util.h" -#include - -#include "Define.h" - -class ALE; -class EventMgr; -class ALEEventProcessor; -class WorldObject; - -enum LuaEventState -{ - LUAEVENT_STATE_RUN, // On next call run the function normally - LUAEVENT_STATE_ABORT, // On next call unregisters reffed function and erases the data - LUAEVENT_STATE_ERASE, // On next call just erases the data -}; - -struct LuaEvent -{ - LuaEvent(int _funcRef, uint32 _min, uint32 _max, uint32 _repeats) : - min(_min), max(_max), delay(0), repeats(_repeats), funcRef(_funcRef), state(LUAEVENT_STATE_RUN) - { - } - - void SetState(LuaEventState _state) - { - if (state != LUAEVENT_STATE_ERASE) - state = _state; - } - - void GenerateDelay() - { - delay = urand(min, max); - } - - uint32 min; // Minimum delay between event calls - uint32 max; // Maximum delay between event calls - uint32 delay; // The currently used waiting time - uint32 repeats; // Amount of repeats to make, 0 for infinite - int funcRef; // Lua function reference ID, also used as event ID - LuaEventState state; // State for next call -}; - -class ALEEventProcessor -{ - friend class EventMgr; - -public: - typedef std::multimap EventList; - typedef std::unordered_map EventMap; - - ALEEventProcessor(ALE** _E, WorldObject* _obj); - ~ALEEventProcessor(); - - void Update(uint32 diff); - // removes all timed events on next tick or at tick end - void SetStates(LuaEventState state); - // set the event to be removed when executing - void SetState(int eventId, LuaEventState state); - void AddEvent(int funcRef, uint32 min, uint32 max, uint32 repeats); - EventMap eventMap; - -private: - void RemoveEvents_internal(); - void AddEvent(LuaEvent* luaEvent); - void RemoveEvent(LuaEvent* luaEvent); - EventList eventList; - uint64 m_time; - WorldObject* obj; - ALE** E; -}; - -class EventMgr : public ALEUtil::Lockable -{ -public: - typedef std::unordered_set ProcessorSet; - ProcessorSet processors; - ALEEventProcessor* globalProcessor; - ALE** E; - - EventMgr(ALE** _E); - ~EventMgr(); - - // Set the state of all timed events - // Execute only in safe env - void SetStates(LuaEventState state); - - // Sets the eventId's state in all processors - // Execute only in safe env - void SetState(int eventId, LuaEventState state); -}; - -#endif diff --git a/src/LuaEngine/ALEFileWatcher.cpp b/src/LuaEngine/ALEFileWatcher.cpp deleted file mode 100644 index aa3cd37a36..0000000000 --- a/src/LuaEngine/ALEFileWatcher.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#include "ALEFileWatcher.h" -#include "LuaEngine.h" -#include "ALEUtility.h" -#include - -ALEFileWatcher::ALEFileWatcher() : running(false), checkInterval(1) -{ -} - -ALEFileWatcher::~ALEFileWatcher() -{ - StopWatching(); -} - -void ALEFileWatcher::StartWatching(const std::string& scriptPath, uint32 intervalSeconds) -{ - if (running.load()) - { - ALE_LOG_DEBUG("[ALEFileWatcher]: Already watching files"); - return; - } - - if (scriptPath.empty()) - { - ALE_LOG_ERROR("[ALEFileWatcher]: Cannot start watching - script path is empty"); - return; - } - - watchPath = scriptPath; - checkInterval = intervalSeconds; - running.store(true); - - ScanDirectory(watchPath); - - watcherThread = std::thread(&ALEFileWatcher::WatchLoop, this); - - ALE_LOG_INFO("[ALEFileWatcher]: Started watching '{}' (interval: {}s)", watchPath, checkInterval); -} - -void ALEFileWatcher::StopWatching() -{ - if (!running.load()) - return; - - running.store(false); - - if (watcherThread.joinable()) - watcherThread.join(); - - fileTimestamps.clear(); - - ALE_LOG_INFO("[ALEFileWatcher]: Stopped watching files"); -} - -void ALEFileWatcher::WatchLoop() -{ - while (running.load()) - { - try - { - CheckForChanges(); - } - catch (const std::exception& e) - { - ALE_LOG_ERROR("[ALEFileWatcher]: Error during file watching: {}", e.what()); - } - - std::this_thread::sleep_for(std::chrono::seconds(checkInterval)); - } -} - -bool ALEFileWatcher::IsWatchedFileType(const std::string& filename) { - return (filename.length() >= 4 && filename.substr(filename.length() - 4) == ".lua") || - (filename.length() >= 4 && filename.substr(filename.length() - 4) == ".ext") || - (filename.length() >= 5 && filename.substr(filename.length() - 5) == ".moon"); -} - -void ALEFileWatcher::ScanDirectory(const std::string& path) -{ - try - { - boost::filesystem::path dir(path); - - if (!boost::filesystem::exists(dir) || !boost::filesystem::is_directory(dir)) - return; - - boost::filesystem::directory_iterator end_iter; - - for (boost::filesystem::directory_iterator dir_iter(dir); dir_iter != end_iter; ++dir_iter) - { - std::string fullpath = dir_iter->path().generic_string(); - - if (boost::filesystem::is_directory(dir_iter->status())) - { - ScanDirectory(fullpath); - } - else if (boost::filesystem::is_regular_file(dir_iter->status())) - { - std::string filename = dir_iter->path().filename().generic_string(); - - if (IsWatchedFileType(filename)) - { - fileTimestamps[fullpath] = boost::filesystem::last_write_time(dir_iter->path()); - } - } - } - } - catch (const std::exception& e) - { - ALE_LOG_ERROR("[ALEFileWatcher]: Error scanning directory '{}': {}", path, e.what()); - } -} - -void ALEFileWatcher::CheckForChanges() -{ - bool hasChanges = false; - - try - { - boost::filesystem::path dir(watchPath); - - if (!boost::filesystem::exists(dir) || !boost::filesystem::is_directory(dir)) - return; - - boost::filesystem::directory_iterator end_iter; - - for (boost::filesystem::directory_iterator dir_iter(dir); dir_iter != end_iter; ++dir_iter) - { - if (ShouldReloadFile(dir_iter->path().generic_string())) - hasChanges = true; - } - - for (auto it = fileTimestamps.begin(); it != fileTimestamps.end();) - { - if (!boost::filesystem::exists(it->first)) - { - ALE_LOG_DEBUG("[ALEFileWatcher]: File deleted: {}", it->first); - it = fileTimestamps.erase(it); - hasChanges = true; - } - else - { - ++it; - } - } - } - catch (const std::exception& e) - { - ALE_LOG_ERROR("[ALEFileWatcher]: Error checking for changes: {}", e.what()); - return; - } - - if (hasChanges) - { - ALE_LOG_INFO("[ALEFileWatcher]: Lua script changes detected - triggering reload"); - ALE::ReloadALE(); - - ScanDirectory(watchPath); - } -} - -bool ALEFileWatcher::ShouldReloadFile(const std::string& filepath) -{ - try - { - boost::filesystem::path file(filepath); - - if (boost::filesystem::is_directory(file)) - { - boost::filesystem::directory_iterator end_iter; - - for (boost::filesystem::directory_iterator dir_iter(file); dir_iter != end_iter; ++dir_iter) - { - if (ShouldReloadFile(dir_iter->path().generic_string())) - return true; - } - return false; - } - - if (!boost::filesystem::is_regular_file(file)) - return false; - - std::string filename = file.filename().generic_string(); - - if (!IsWatchedFileType(filename)) return false; - - auto currentTime = boost::filesystem::last_write_time(file); - auto it = fileTimestamps.find(filepath); - - if (it == fileTimestamps.end()) - { - ALE_LOG_DEBUG("[ALEFileWatcher]: New file detected: {}", filepath); - fileTimestamps[filepath] = currentTime; - return true; - } - - if (it->second != currentTime) - { - ALE_LOG_DEBUG("[ALEFileWatcher]: File modified: {}", filepath); - it->second = currentTime; - return true; - } - } - catch (const std::exception& e) - { - ALE_LOG_ERROR("[ALEFileWatcher]: Error checking file '{}': {}", filepath, e.what()); - } - - return false; -} diff --git a/src/LuaEngine/ALEFileWatcher.h b/src/LuaEngine/ALEFileWatcher.h deleted file mode 100644 index 75364a6a48..0000000000 --- a/src/LuaEngine/ALEFileWatcher.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef ALE_FILE_WATCHER_H -#define ALE_FILE_WATCHER_H - -#include -#include -#include -#include -#include -#include -#include "Common.h" - -class ALEFileWatcher -{ -public: - ALEFileWatcher(); - ~ALEFileWatcher(); - - void StartWatching(const std::string& scriptPath, uint32 intervalSeconds = 1); - void StopWatching(); - bool IsWatching() const { return running.load(); } - -private: - void WatchLoop(); - void ScanDirectory(const std::string& path); - void CheckForChanges(); - bool ShouldReloadFile(const std::string& filepath); - bool IsWatchedFileType(const std::string& filename); - - std::thread watcherThread; - std::atomic running; - std::string watchPath; - uint32 checkInterval; - - std::map fileTimestamps; -}; - -#endif diff --git a/src/LuaEngine/ALEIncludes.h b/src/LuaEngine/ALEIncludes.h deleted file mode 100644 index 7b305cd636..0000000000 --- a/src/LuaEngine/ALEIncludes.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef _ALE_INCLUDES_H -#define _ALE_INCLUDES_H - -// Required -#include "AccountMgr.h" -#include "AuctionHouseMgr.h" -#include "Cell.h" -#include "CellImpl.h" -#include "Chat.h" -#include "Channel.h" -#include "DBCStores.h" -#include "GameEventMgr.h" -#include "GossipDef.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" -#include "Group.h" -#include "Guild.h" -#include "GuildMgr.h" -#include "Language.h" -#include "Mail.h" -#include "ObjectAccessor.h" -#include "ObjectMgr.h" -#include "Opcodes.h" -#include "Player.h" -#include "Pet.h" -#include "ReputationMgr.h" -#include "ScriptMgr.h" -#include "Spell.h" -#include "SpellAuras.h" -#include "SpellInfo.h" -#include "SpellMgr.h" -#include "TemporarySummon.h" -#include "WorldPacket.h" -#include "WorldSession.h" -#include "MapMgr.h" -#include "Config.h" -#include "GameEventMgr.h" -#include "GitRevision.h" -#include "GroupMgr.h" -#include "ScriptedCreature.h" -#include "WeatherMgr.h" -#include "Battleground.h" -#include "MotionMaster.h" -#include "DatabaseEnv.h" -#include "Bag.h" -#include "Vehicle.h" -#include "ArenaTeam.h" -#include "WorldSessionMgr.h" - -typedef Opcodes OpcodesList; - -/* - * Note: if you add or change a CORE_NAME or CORE_VERSION #define, - * please update LuaGlobalFunctions::GetCoreName or LuaGlobalFunctions::GetCoreVersion documentation example string. - */ -#define CORE_NAME "AzerothCore" - -#define CORE_VERSION (GitRevision::GetFullVersion()) -#define eWorldSessionMgr (sWorldSessionMgr) -#define eWorld (sWorld) -#define eMapMgr (sMapMgr) -#define eConfigMgr (sConfigMgr) -#define eGuildMgr (sGuildMgr) -#define eObjectMgr (sObjectMgr) -#define eAccountMgr (sAccountMgr) -#define eAuctionMgr (sAuctionMgr) -#define eGameEventMgr (sGameEventMgr) -#define eObjectAccessor() ObjectAccessor:: - -#endif // _ALE_INCLUDES_H diff --git a/src/LuaEngine/ALEInstanceAI.cpp b/src/LuaEngine/ALEInstanceAI.cpp deleted file mode 100644 index ea32f2feaa..0000000000 --- a/src/LuaEngine/ALEInstanceAI.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * This program is free software licensed under GPL version 3 - * Please see the included DOCS/LICENSE.md for more information - */ - -#include "ALEInstanceAI.h" -#include "ALEUtility.h" -#include "lmarshal.h" - - -void ALEInstanceAI::Initialize() -{ - LOCK_ALE; - - ASSERT(!sALE->HasInstanceData(instance)); - - // Create a new table for instance data. - lua_State* L = sALE->L; - lua_newtable(L); - sALE->CreateInstanceData(instance); - - sALE->OnInitialize(this); -} - -void ALEInstanceAI::Load(const char* data) -{ - LOCK_ALE; - - // If we get passed NULL (i.e. `Reload` was called) then use - // the last known save data (or maybe just an empty string). - if (!data) - { - data = lastSaveData.c_str(); - } - else // Otherwise, copy the new data into our buffer. - { - lastSaveData.assign(data); - } - - if (data[0] == '\0') - { - ASSERT(!sALE->HasInstanceData(instance)); - - // Create a new table for instance data. - lua_State* L = sALE->L; - lua_newtable(L); - sALE->CreateInstanceData(instance); - - sALE->OnLoad(this); - // Stack: (empty) - return; - } - - size_t decodedLength; - const unsigned char* decodedData = ALEUtil::DecodeData(data, &decodedLength); - lua_State* L = sALE->L; - - if (decodedData) - { - // Stack: (empty) - - lua_pushcfunction(L, mar_decode); - lua_pushlstring(L, (const char*)decodedData, decodedLength); - // Stack: mar_decode, decoded_data - - // Call `mar_decode` and check for success. - if (lua_pcall(L, 1, 1, 0) == 0) - { - // Stack: data - // Only use the data if it's a table. - if (lua_istable(L, -1)) - { - sALE->CreateInstanceData(instance); - // Stack: (empty) - sALE->OnLoad(this); - // WARNING! lastSaveData might be different after `OnLoad` if the Lua code saved data. - } - else - { - ALE_LOG_ERROR("Error while loading instance data: Expected data to be a table (type 5), got type {} instead", lua_type(L, -1)); - lua_pop(L, 1); - // Stack: (empty) - - Initialize(); - } - } - else - { - // Stack: error_message - ALE_LOG_ERROR("Error while parsing instance data with lua-marshal: {}", lua_tostring(L, -1)); - lua_pop(L, 1); - // Stack: (empty) - - Initialize(); - } - - delete[] decodedData; - } - else - { - ALE_LOG_ERROR("Error while decoding instance data: Data is not valid base-64"); - - Initialize(); - } -} - -const char* ALEInstanceAI::Save() const -{ - LOCK_ALE; - lua_State* L = sALE->L; - // Stack: (empty) - - /* - * Need to cheat because this method actually does modify this instance, - * even though it's declared as `const`. - * - * Declaring virtual methods as `const` is BAD! - * Don't dictate to children that their methods must be pure. - */ - ALEInstanceAI* self = const_cast(this); - - lua_pushcfunction(L, mar_encode); - sALE->PushInstanceData(L, self, false); - // Stack: mar_encode, instance_data - - if (lua_pcall(L, 1, 1, 0) != 0) - { - // Stack: error_message - ALE_LOG_ERROR("Error while saving: {}", lua_tostring(L, -1)); - lua_pop(L, 1); - return NULL; - } - - // Stack: data - size_t dataLength; - const unsigned char* data = (const unsigned char*)lua_tolstring(L, -1, &dataLength); - ALEUtil::EncodeData(data, dataLength, self->lastSaveData); - - lua_pop(L, 1); - // Stack: (empty) - - return lastSaveData.c_str(); -} - -uint32 ALEInstanceAI::GetData(uint32 key) const -{ - LOCK_ALE; - lua_State* L = sALE->L; - // Stack: (empty) - - sALE->PushInstanceData(L, const_cast(this), false); - // Stack: instance_data - - ALE::Push(L, key); - // Stack: instance_data, key - - lua_gettable(L, -2); - // Stack: instance_data, value - - uint32 value = ALE::CHECKVAL(L, -1, 0); - lua_pop(L, 2); - // Stack: (empty) - - return value; -} - -void ALEInstanceAI::SetData(uint32 key, uint32 value) -{ - LOCK_ALE; - lua_State* L = sALE->L; - // Stack: (empty) - - sALE->PushInstanceData(L, this, false); - // Stack: instance_data - - ALE::Push(L, key); - ALE::Push(L, value); - // Stack: instance_data, key, value - - lua_settable(L, -3); - // Stack: instance_data - - lua_pop(L, 1); - // Stack: (empty) -} - -uint64 ALEInstanceAI::GetData64(uint32 key) const -{ - LOCK_ALE; - lua_State* L = sALE->L; - // Stack: (empty) - - sALE->PushInstanceData(L, const_cast(this), false); - // Stack: instance_data - - ALE::Push(L, key); - // Stack: instance_data, key - - lua_gettable(L, -2); - // Stack: instance_data, value - - uint64 value = ALE::CHECKVAL(L, -1, 0); - lua_pop(L, 2); - // Stack: (empty) - - return value; -} - -void ALEInstanceAI::SetData64(uint32 key, uint64 value) -{ - LOCK_ALE; - lua_State* L = sALE->L; - // Stack: (empty) - - sALE->PushInstanceData(L, this, false); - // Stack: instance_data - - ALE::Push(L, key); - ALE::Push(L, value); - // Stack: instance_data, key, value - - lua_settable(L, -3); - // Stack: instance_data - - lua_pop(L, 1); - // Stack: (empty) -} diff --git a/src/LuaEngine/ALEInstanceAI.h b/src/LuaEngine/ALEInstanceAI.h deleted file mode 100644 index ebc5037db0..0000000000 --- a/src/LuaEngine/ALEInstanceAI.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef _ALE_INSTANCE_DATA_H -#define _ALE_INSTANCE_DATA_H - -#include "LuaEngine.h" -#include "InstanceScript.h" - -/* - * This class is a small wrapper around `InstanceData`, - * allowing instances to be scripted with ALE. - * - * - * Note 1 - * ====== - * - * Instances of `ALEInstanceAI` are owned by the core, so they - * are not deleted when ALE is reloaded. Thus `Load` is only called - * by the core once, no matter how many times ALE is reloaded. - * - * However, when ALE reloads, all instance data in ALE is lost. - * So the solution is as follows: - * - * 1. Store the last save data in the member var `lastSaveData`. - * - * At first this is just the data given to us by the core when it calls `Load`, - * but later on once we start saving new data this is from ALE. - * - * 2. When retrieving instance data from ALE, check if it's missing. - * - * The data will be missing if ALE is reloaded, since a new Lua state is created. - * - * 3. If it *is* missing, call `Reload`. - * - * This reloads the last known instance save data into ALE, and calls the appropriate hooks. - * - * - * Note 2 - * ====== - * - * CMaNGOS expects some of these methods to be `const`. However, any of these - * methods are free to call `Save`, resulting in mutation of `lastSaveData`. - * - * Therefore, none of the hooks are `const`-safe, and `const_cast` is used - * to escape from these restrictions. - */ -class ALEInstanceAI : public InstanceData -{ -private: - // The last save data to pass through this class, - // either through `Load` or `Save`. - std::string lastSaveData; - -public: - ALEInstanceAI(Map* map) : InstanceData(map) - { - } - - void Initialize() override; - - /* - * These are responsible for serializing/deserializing the instance's - * data table to/from the core. - */ - void Load(const char* data) override; - // Simply calls Save, since the functions are a bit different in name and data types on different cores - std::string GetSaveData() override - { - return Save(); - } - const char* Save() const; - - - /* - * Calls `Load` with the last save data that was passed to - * or from ALE. - * - * See: big documentation blurb at the top of this class. - */ - void Reload() - { - Load(NULL); - } - - /* - * These methods allow non-Lua scripts (e.g. DB, C++) to get/set instance data. - */ - uint32 GetData(uint32 key) const override; - void SetData(uint32 key, uint32 value) override; - - uint64 GetData64(uint32 key) const override; - void SetData64(uint32 key, uint64 value) override; - - /* - * These methods are just thin wrappers around ALE. - */ - void Update(uint32 diff) override - { - // If ALE is reloaded, it will be missing our instance data. - // Reload here instead of waiting for the next hook call (possibly never). - // This avoids having to have an empty Update hook handler just to trigger the reload. - if (!sALE->HasInstanceData(instance)) - Reload(); - - sALE->OnUpdateInstance(this, diff); - } - - bool IsEncounterInProgress() const override - { - return sALE->OnCheckEncounterInProgress(const_cast(this)); - } - - void OnPlayerEnter(Player* player) override - { - sALE->OnPlayerEnterInstance(this, player); - } - - void OnGameObjectCreate(GameObject* gameobject) override - { - sALE->OnGameObjectCreate(this, gameobject); - } - - void OnCreatureCreate(Creature* creature) override - { - sALE->OnCreatureCreate(this, creature); - } -}; - -#endif // _ALE_INSTANCE_DATA_H diff --git a/src/LuaEngine/ALETemplate.h b/src/LuaEngine/ALETemplate.h deleted file mode 100644 index a8d6fc497a..0000000000 --- a/src/LuaEngine/ALETemplate.h +++ /dev/null @@ -1,389 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef _ALE_TEMPLATE_H -#define _ALE_TEMPLATE_H - -extern "C" -{ -#include "lua.h" -#include "lualib.h" -#include "lauxlib.h" -}; -#include "LuaEngine.h" -#include "ALECompat.h" -#include "ALEUtility.h" -#include "SharedDefines.h" - -class ALEGlobal -{ -public: - static int thunk(lua_State* L) - { - luaL_Reg* l = static_cast(lua_touserdata(L, lua_upvalueindex(1))); - int top = lua_gettop(L); - int expected = l->func(L); - int args = lua_gettop(L) - top; - if (args < 0 || args > expected) - { - ALE_LOG_ERROR("[ALE]: {} returned unexpected amount of arguments {} out of {}. Report to devs", l->name, args, expected); - ASSERT(false); - } - lua_settop(L, top + expected); - return expected; - } - - static void SetMethods(ALE* E, luaL_Reg* methodTable) - { - ASSERT(E); - ASSERT(methodTable); - - lua_pushglobaltable(E->L); - - for (; methodTable && methodTable->name && methodTable->func; ++methodTable) - { - lua_pushstring(E->L, methodTable->name); - lua_pushlightuserdata(E->L, (void*)methodTable); - lua_pushcclosure(E->L, thunk, 1); - lua_rawset(E->L, -3); - } - - lua_remove(E->L, -1); - } -}; - -class ALEObject -{ -public: - template - ALEObject(T * obj, bool manageMemory); - - ~ALEObject() - { - } - - // Get wrapped object pointer - void* GetObj() const { return object; } - // Returns whether the object is valid or not - bool IsValid() const { return !callstackid || callstackid == sALE->GetCallstackId(); } - // Returns whether the object can be invalidated or not - bool CanInvalidate() const { return _invalidate; } - // Returns pointer to the wrapped object's type name - const char* GetTypeName() const { return type_name; } - - // Sets the object pointer that is wrapped - void SetObj(void* obj) - { - ASSERT(obj); - object = obj; - SetValid(true); - } - // Sets the object pointer to valid or invalid - void SetValid(bool valid) - { - ASSERT(!valid || (valid && object)); - if (valid) - if (CanInvalidate()) - callstackid = sALE->GetCallstackId(); - else - callstackid = 0; - else - callstackid = 1; - } - // Sets whether the pointer will be invalidated at end of calls - void SetValidation(bool invalidate) - { - _invalidate = invalidate; - } - // Invalidates the pointer if it should be invalidated - void Invalidate() - { - if (CanInvalidate()) - callstackid = 1; - } - -private: - uint64 callstackid; - bool _invalidate; - void* object; - const char* type_name; -}; - -template -struct ALERegister -{ - const char* name; - int(*mfunc)(lua_State*, T*); -}; - -template -class ALETemplate -{ -public: - static const char* tname; - static bool manageMemory; - - // name will be used as type name - // If gc is true, lua will handle the memory management for object pushed - // gc should be used if pushing for example WorldPacket, - // that will only be needed on lua side and will not be managed by TC/mangos/ - static void Register(ALE* E, const char* name, bool gc = false) - { - ASSERT(E); - ASSERT(name); - - // check that metatable isn't already there - lua_getglobal(E->L, name); - ASSERT(lua_isnoneornil(E->L, -1)); - - // pop nil - lua_pop(E->L, 1); - - tname = name; - manageMemory = gc; - - // create metatable for userdata of this type - luaL_newmetatable(E->L, tname); - int metatable = lua_gettop(E->L); - - // push methodtable to stack to be accessed and modified by users - lua_pushvalue(E->L, metatable); - lua_setglobal(E->L, tname); - - // tostring - lua_pushcfunction(E->L, ToString); - lua_setfield(E->L, metatable, "__tostring"); - - // garbage collecting - lua_pushcfunction(E->L, CollectGarbage); - lua_setfield(E->L, metatable, "__gc"); - - // make methods accessible through metatable - lua_pushvalue(E->L, metatable); - lua_setfield(E->L, metatable, "__index"); - - // make new indexes saved to methods - lua_pushcfunction(E->L, Add); - lua_setfield(E->L, metatable, "__add"); - - // make new indexes saved to methods - lua_pushcfunction(E->L, Substract); - lua_setfield(E->L, metatable, "__sub"); - - // make new indexes saved to methods - lua_pushcfunction(E->L, Multiply); - lua_setfield(E->L, metatable, "__mul"); - - // make new indexes saved to methods - lua_pushcfunction(E->L, Divide); - lua_setfield(E->L, metatable, "__div"); - - // make new indexes saved to methods - lua_pushcfunction(E->L, Mod); - lua_setfield(E->L, metatable, "__mod"); - - // make new indexes saved to methods - lua_pushcfunction(E->L, Pow); - lua_setfield(E->L, metatable, "__pow"); - - // make new indexes saved to methods - lua_pushcfunction(E->L, UnaryMinus); - lua_setfield(E->L, metatable, "__unm"); - - // make new indexes saved to methods - lua_pushcfunction(E->L, Concat); - lua_setfield(E->L, metatable, "__concat"); - - // make new indexes saved to methods - lua_pushcfunction(E->L, Length); - lua_setfield(E->L, metatable, "__len"); - - // make new indexes saved to methods - lua_pushcfunction(E->L, Equal); - lua_setfield(E->L, metatable, "__eq"); - - // make new indexes saved to methods - lua_pushcfunction(E->L, Less); - lua_setfield(E->L, metatable, "__lt"); - - // make new indexes saved to methods - lua_pushcfunction(E->L, LessOrEqual); - lua_setfield(E->L, metatable, "__le"); - - // make new indexes saved to methods - lua_pushcfunction(E->L, Call); - lua_setfield(E->L, metatable, "__call"); - - // special method to get the object type - lua_pushcfunction(E->L, GetType); - lua_setfield(E->L, metatable, "GetObjectType"); - - // special method to decide object invalidation at end of call - lua_pushcfunction(E->L, SetInvalidation); - lua_setfield(E->L, metatable, "SetInvalidation"); - - // pop metatable - lua_pop(E->L, 1); - } - - template - static void SetMethods(ALE* E, ALERegister* methodTable) - { - ASSERT(E); - ASSERT(tname); - ASSERT(methodTable); - - // get metatable - lua_pushstring(E->L, tname); - lua_rawget(E->L, LUA_REGISTRYINDEX); - ASSERT(lua_istable(E->L, -1)); - - for (; methodTable && methodTable->name && methodTable->mfunc; ++methodTable) - { - lua_pushstring(E->L, methodTable->name); - lua_pushlightuserdata(E->L, (void*)methodTable); - lua_pushcclosure(E->L, CallMethod, 1); - lua_rawset(E->L, -3); - } - - lua_pop(E->L, 1); - } - - static int Push(lua_State* L, T const* obj) - { - if (!obj) - { - lua_pushnil(L); - return 1; - } - - // Create new userdata - ALEObject** ptrHold = static_cast(lua_newuserdata(L, sizeof(ALEObject*))); - if (!ptrHold) - { - ALE_LOG_ERROR("{} could not create new userdata", tname); - lua_pushnil(L); - return 1; - } - *ptrHold = new ALEObject(const_cast(obj), manageMemory); - - // Set metatable for it - lua_pushstring(L, tname); - lua_rawget(L, LUA_REGISTRYINDEX); - if (!lua_istable(L, -1)) - { - ALE_LOG_ERROR("{} missing metatable", tname); - lua_pop(L, 2); - lua_pushnil(L); - return 1; - } - lua_setmetatable(L, -2); - return 1; - } - - static T* Check(lua_State* L, int narg, bool error = true) - { - ALEObject* ALEObj = ALE::CHECKTYPE(L, narg, tname, error); - if (!ALEObj) - return NULL; - - if (!ALEObj->IsValid()) - { - char buff[256]; - snprintf(buff, 256, "%s expected, got pointer to nonexisting (invalidated) object (%s). Check your code.", tname, luaL_typename(L, narg)); - if (error) - { - luaL_argerror(L, narg, buff); - } - else - { - ALE_LOG_ERROR("{}", buff); - } - return NULL; - } - return static_cast(ALEObj->GetObj()); - } - - static int GetType(lua_State* L) - { - lua_pushstring(L, tname); - return 1; - } - - static int SetInvalidation(lua_State* L) - { - ALEObject* ALEObj = ALE::CHECKOBJ(L, 1); - bool invalidate = ALE::CHECKVAL(L, 2); - - ALEObj->SetValidation(invalidate); - return 0; - } - - static int CallMethod(lua_State* L) - { - T* obj = ALE::CHECKOBJ(L, 1); // get self - if (!obj) - return 0; - ALERegister* l = static_cast*>(lua_touserdata(L, lua_upvalueindex(1))); - int top = lua_gettop(L); - int expected = l->mfunc(L, obj); - int args = lua_gettop(L) - top; - if (args < 0 || args > expected) - { - ALE_LOG_ERROR("[ALE]: {} returned unexpected amount of arguments {} out of {}. Report to devs", l->name, args, expected); - ASSERT(false); - } - lua_settop(L, top + expected); - return expected; - } - - // Metamethods ("virtual") - - // Remember special cases like ALETemplate::CollectGarbage - static int CollectGarbage(lua_State* L) - { - // Get object pointer (and check type, no error) - ALEObject* obj = ALE::CHECKOBJ(L, 1, false); - if (obj && manageMemory) - delete static_cast(obj->GetObj()); - delete obj; - return 0; - } - - static int ToString(lua_State* L) - { - T* obj = ALE::CHECKOBJ(L, 1, true); // get self - lua_pushfstring(L, "%s: %p", tname, obj); - return 1; - } - - static int ArithmeticError(lua_State* L) { return luaL_error(L, "attempt to perform arithmetic on a %s value", tname); } - static int CompareError(lua_State* L) { return luaL_error(L, "attempt to compare %s", tname); } - static int Add(lua_State* L) { return ArithmeticError(L); } - static int Substract(lua_State* L) { return ArithmeticError(L); } - static int Multiply(lua_State* L) { return ArithmeticError(L); } - static int Divide(lua_State* L) { return ArithmeticError(L); } - static int Mod(lua_State* L) { return ArithmeticError(L); } - static int Pow(lua_State* L) { return ArithmeticError(L); } - static int UnaryMinus(lua_State* L) { return ArithmeticError(L); } - static int Concat(lua_State* L) { return luaL_error(L, "attempt to concatenate a %s value", tname); } - static int Length(lua_State* L) { return luaL_error(L, "attempt to get length of a %s value", tname); } - static int Equal(lua_State* L) { ALE::Push(L, ALE::CHECKOBJ(L, 1) == ALE::CHECKOBJ(L, 2)); return 1; } - static int Less(lua_State* L) { return CompareError(L); } - static int LessOrEqual(lua_State* L) { return CompareError(L); } - static int Call(lua_State* L) { return luaL_error(L, "attempt to call a %s value", tname); } -}; - -template -ALEObject::ALEObject(T * obj, bool manageMemory) : callstackid(1), _invalidate(!manageMemory), object(obj), type_name(ALETemplate::tname) -{ - SetValid(true); -} - -template const char* ALETemplate::tname = NULL; -template bool ALETemplate::manageMemory = false; - -#endif diff --git a/src/LuaEngine/ALEUtility.cpp b/src/LuaEngine/ALEUtility.cpp deleted file mode 100644 index 9817465efa..0000000000 --- a/src/LuaEngine/ALEUtility.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#include "ALEUtility.h" -#include "World.h" -#include "Object.h" -#include "Unit.h" -#include "GameObject.h" -#include "DBCStores.h" - -uint32 ALEUtil::GetCurrTime() -{ - return getMSTime(); -} - -uint32 ALEUtil::GetTimeDiff(uint32 oldMSTime) -{ - return GetMSTimeDiffToNow(oldMSTime); -} - -ALEUtil::ObjectGUIDCheck::ObjectGUIDCheck(ObjectGuid guid) : _guid(guid) -{ -} - -bool ALEUtil::ObjectGUIDCheck::operator()(WorldObject* object) -{ - return object->GET_GUID() == _guid; -} - -ALEUtil::ObjectDistanceOrderPred::ObjectDistanceOrderPred(WorldObject const* pRefObj, bool ascending) : m_refObj(pRefObj), m_ascending(ascending) -{ -} -bool ALEUtil::ObjectDistanceOrderPred::operator()(WorldObject const* pLeft, WorldObject const* pRight) const -{ - return m_ascending ? m_refObj->GetDistanceOrder(pLeft, pRight) : !m_refObj->GetDistanceOrder(pLeft, pRight); -} - -ALEUtil::WorldObjectInRangeCheck::WorldObjectInRangeCheck(bool nearest, WorldObject const* obj, float range, - uint16 typeMask, uint32 entry, uint32 hostile, uint32 dead) : - i_obj(obj), i_obj_unit(nullptr), i_obj_fact(nullptr), i_hostile(hostile), i_entry(entry), i_range(range), i_typeMask(typeMask), i_dead(dead), i_nearest(nearest) -{ - i_obj_unit = i_obj->ToUnit(); - if (!i_obj_unit) - if (GameObject const* go = i_obj->ToGameObject()) - i_obj_unit = go->GetOwner(); - if (!i_obj_unit) - i_obj_fact = sFactionTemplateStore.LookupEntry(14); -} -WorldObject const& ALEUtil::WorldObjectInRangeCheck::GetFocusObject() const -{ - return *i_obj; -} -bool ALEUtil::WorldObjectInRangeCheck::operator()(WorldObject* u) -{ - if (i_typeMask && !u->isType(TypeMask(i_typeMask))) - return false; - if (i_entry && u->GetEntry() != i_entry) - return false; - if (i_obj->GET_GUID() == u->GET_GUID()) - return false; - if (!i_obj->IsWithinDistInMap(u, i_range)) - return false; - Unit const* target = u->ToUnit(); - if (!target) - if (GameObject const* go = u->ToGameObject()) - target = go->GetOwner(); - if (target) - { - if (i_dead && (i_dead == 1) != target->IsAlive()) - return false; - - if (i_hostile) - { - if (!i_obj_unit) - { - if (i_obj_fact) - { - if ((i_obj_fact->IsHostileTo(*target->GetFactionTemplateEntry())) != (i_hostile == 1)) - return false; - } - else if (i_hostile == 1) - return false; - } - else if ((i_hostile == 1) != i_obj_unit->IsHostileTo(target)) - return false; - } - } - if (i_nearest) - i_range = i_obj->GetDistance(u); - return true; -} - -static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/'}; -static char decoding_table[256]; -static int mod_table[] = {0, 2, 1}; - -static void build_decoding_table() -{ - for (int i = 0; i < 64; i++) - decoding_table[(unsigned char)encoding_table[i]] = i; -} - -void ALEUtil::EncodeData(const unsigned char* data, size_t input_length, std::string& output) -{ - size_t output_length = 4 * ((input_length + 2) / 3); - char* buffer = new char[output_length]; - - for (size_t i = 0, j = 0; i < input_length;) - { - uint32 octet_a = i < input_length ? (unsigned char)data[i++] : 0; - uint32 octet_b = i < input_length ? (unsigned char)data[i++] : 0; - uint32 octet_c = i < input_length ? (unsigned char)data[i++] : 0; - - uint32 triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; - - buffer[j++] = encoding_table[(triple >> (3 * 6)) & 0x3F]; - buffer[j++] = encoding_table[(triple >> (2 * 6)) & 0x3F]; - buffer[j++] = encoding_table[(triple >> (1 * 6)) & 0x3F]; - buffer[j++] = encoding_table[(triple >> (0 * 6)) & 0x3F]; - } - - for (int i = 0; i < mod_table[input_length % 3]; i++) - buffer[output_length - 1 - i] = '='; - - output.assign(buffer, output_length); // Need length because `buffer` is not terminated! - delete[] buffer; -} - -unsigned char* ALEUtil::DecodeData(const char *data, size_t *output_length) -{ - if (decoding_table[(unsigned char)'B'] == 0) - build_decoding_table(); - - size_t input_length = strlen(data); - - if (input_length % 4 != 0) - return NULL; - - // Make sure there's no invalid characters in the data. - for (size_t i = 0; i < input_length; ++i) - { - unsigned char byte = data[i]; - - if (byte == '=') - continue; - - // Every invalid character (and 'A') will map to 0 (due to `calloc`). - if (decoding_table[byte] == 0 && byte != 'A') - return NULL; - } - - *output_length = input_length / 4 * 3; - if (data[input_length - 1] == '=') (*output_length)--; - if (data[input_length - 2] == '=') (*output_length)--; - - unsigned char *decoded_data = new unsigned char[*output_length]; - if (!decoded_data) - return NULL; - - for (size_t i = 0, j = 0; i < input_length;) - { - uint32 sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[(unsigned char)data[i++]]; - uint32 sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[(unsigned char)data[i++]]; - uint32 sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[(unsigned char)data[i++]]; - uint32 sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[(unsigned char)data[i++]]; - - uint32 triple = (sextet_a << (3 * 6)) - + (sextet_b << (2 * 6)) - + (sextet_c << (1 * 6)) - + (sextet_d << (0 * 6)); - - if (j < *output_length) decoded_data[j++] = (triple >> (2 * 8)) & 0xFF; - if (j < *output_length) decoded_data[j++] = (triple >> (1 * 8)) & 0xFF; - if (j < *output_length) decoded_data[j++] = (triple >> (0 * 8)) & 0xFF; - } - - return decoded_data; -} diff --git a/src/LuaEngine/ALEUtility.h b/src/LuaEngine/ALEUtility.h deleted file mode 100644 index 5af4ad8519..0000000000 --- a/src/LuaEngine/ALEUtility.h +++ /dev/null @@ -1,135 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef _ALE_UTIL_H -#define _ALE_UTIL_H - -#include -#include -#include -#include -#include "Common.h" -#include "SharedDefines.h" -#include "ObjectGuid.h" -#include "Database/QueryResult.h" -#include "Log.h" - -typedef QueryResult ALEQuery; -#define GET_GUID GetGUID -#define HIGHGUID_PLAYER HighGuid::Player -#define HIGHGUID_UNIT HighGuid::Unit -#define HIGHGUID_ITEM HighGuid::Item -#define HIGHGUID_GAMEOBJECT HighGuid::GameObject -#define HIGHGUID_PET HighGuid::Pet -#define HIGHGUID_TRANSPORT HighGuid::Transport -#define HIGHGUID_VEHICLE HighGuid::Vehicle -#define HIGHGUID_CONTAINER HighGuid::Container -#define HIGHGUID_DYNAMICOBJECT HighGuid::DynamicObject -#define HIGHGUID_CORPSE HighGuid::Corpse -#define HIGHGUID_MO_TRANSPORT HighGuid::Mo_Transport -#define HIGHGUID_INSTANCE HighGuid::Instance -#define HIGHGUID_GROUP HighGuid::Group - -#define ALE_LOG_INFO(...) LOG_INFO("ALE", __VA_ARGS__); -#define ALE_LOG_ERROR(...) LOG_ERROR("ALE", __VA_ARGS__); -#define ALE_LOG_DEBUG(...) LOG_DEBUG("ALE", __VA_ARGS__); - -#ifndef MAKE_NEW_GUID -#define MAKE_NEW_GUID(l, e, h) ObjectGuid(h, e, l) -#endif -#ifndef GUID_ENPART -#define GUID_ENPART(guid) ObjectGuid(guid).GetEntry() -#endif -#ifndef GUID_LOPART -#define GUID_LOPART(guid) ObjectGuid(guid).GetCounter() -#endif -#ifndef GUID_HIPART -#define GUID_HIPART(guid) ObjectGuid(guid).GetHigh() -#endif - -class Unit; -class WorldObject; -struct FactionTemplateEntry; - -namespace ALEUtil -{ - uint32 GetCurrTime(); - - uint32 GetTimeDiff(uint32 oldMSTime); - - class ObjectGUIDCheck - { - public: - ObjectGUIDCheck(ObjectGuid guid); - bool operator()(WorldObject* object); - - ObjectGuid _guid; - }; - - // Binary predicate to sort WorldObjects based on the distance to a reference WorldObject - class ObjectDistanceOrderPred - { - public: - ObjectDistanceOrderPred(WorldObject const* pRefObj, bool ascending = true); - bool operator()(WorldObject const* pLeft, WorldObject const* pRight) const; - - WorldObject const* m_refObj; - const bool m_ascending; - }; - - // Doesn't get self - class WorldObjectInRangeCheck - { - public: - WorldObjectInRangeCheck(bool nearest, WorldObject const* obj, float range, - uint16 typeMask = 0, uint32 entry = 0, uint32 hostile = 0, uint32 dead = 0); - WorldObject const& GetFocusObject() const; - bool operator()(WorldObject* u); - - WorldObject const* const i_obj; - Unit const* i_obj_unit; - FactionTemplateEntry const* i_obj_fact; - uint32 const i_hostile; // 0 both, 1 hostile, 2 friendly - uint32 const i_entry; - float i_range; - uint16 const i_typeMask; - uint32 const i_dead; // 0 both, 1 alive, 2 dead - bool const i_nearest; - }; - - /* - * Usage: - * Inherit this class, then when needing lock, use - * Guard guard(GetLock()); - * - * The lock is automatically released at end of scope - */ - class Lockable - { - public: - typedef std::mutex LockType; - typedef std::lock_guard Guard; - - LockType& GetLock() { return _lock; } - - private: - LockType _lock; - }; - - /* - * Encodes `data` in Base-64 and store the result in `output`. - */ - void EncodeData(const unsigned char* data, size_t input_length, std::string& output); - - /* - * Decodes `data` from Base-64 and returns a pointer to the result, or `NULL` on error. - * - * The returned result buffer must be `delete[]`ed by the caller. - */ - unsigned char* DecodeData(const char* data, size_t *output_length); -}; - -#endif diff --git a/src/LuaEngine/BindingMap.h b/src/LuaEngine/BindingMap.h deleted file mode 100644 index c14ce6d335..0000000000 --- a/src/LuaEngine/BindingMap.h +++ /dev/null @@ -1,375 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef _BINDING_MAP_H -#define _BINDING_MAP_H - -#include -#include "Common.h" -#include "ALEUtility.h" -#include - -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -}; - - -/* - * A set of bindings from keys of type `K` to Lua references. - */ -template -class BindingMap : public ALEUtil::Lockable -{ -private: - lua_State* L; - uint64 maxBindingID; - - struct Binding - { - uint64 id; - lua_State* L; - uint32 remainingShots; - int functionReference; - - Binding(lua_State* L, uint64 id, int functionReference, uint32 remainingShots) : - id(id), - L(L), - remainingShots(remainingShots), - functionReference(functionReference) - { } - - ~Binding() - { - luaL_unref(L, LUA_REGISTRYINDEX, functionReference); - } - }; - - typedef std::vector< std::unique_ptr > BindingList; - - std::unordered_map bindings; - /* - * This table is for fast removal of bindings by ID. - * - * Instead of having to look through (potentially) every BindingList to find - * the Binding with the right ID, this allows you to go directly to the - * BindingList that might have the Binding with that ID. - * - * However, you must be careful not to store pointers to BindingLists - * that no longer exist (see `void Clear(const K& key)` implementation). - */ - std::unordered_map id_lookup_table; - -public: - BindingMap(lua_State* L) : - L(L), - maxBindingID(0) - { } - - /* - * Insert a new binding from `key` to `ref`, which lasts for `shots`-many pushes. - * - * If `shots` is 0, it will never automatically expire, but can still be - * removed with `Clear` or `Remove`. - */ - uint64 Insert(const K& key, int ref, uint32 shots) - { - Guard guard(GetLock()); - - uint64 id = (++maxBindingID); - BindingList& list = bindings[key]; - list.push_back(std::unique_ptr(new Binding(L, id, ref, shots))); - id_lookup_table[id] = &list; - return id; - } - - /* - * Clear all bindings for `key`. - */ - void Clear(const K& key) - { - Guard guard(GetLock()); - - if (bindings.empty()) - return; - - auto iter = bindings.find(key); - if (iter == bindings.end()) - return; - - BindingList& list = iter->second; - - // Remove all pointers to `list` from `id_lookup_table`. - for (auto i = list.begin(); i != list.end(); ++i) - { - std::unique_ptr& binding = *i; - id_lookup_table.erase(binding->id); - } - - bindings.erase(key); - } - - /* - * Clear all bindings for all keys. - */ - void Clear() - { - Guard guard(GetLock()); - - if (bindings.empty()) - return; - - id_lookup_table.clear(); - bindings.clear(); - } - - /* - * Remove a specific binding identified by `id`. - * - * If `id` in invalid, nothing is removed. - */ - void Remove(uint64 id) - { - Guard guard(GetLock()); - - auto iter = id_lookup_table.find(id); - if (iter == id_lookup_table.end()) - return; - - BindingList* list = iter->second; - auto i = list->begin(); - - for (; i != list->end(); ++i) - { - std::unique_ptr& binding = *i; - if (binding->id == id) - break; - } - - if (i != list->end()) - list->erase(i); - - // Unconditionally erase the ID in the lookup table because - // it was either already invalid, or it's no longer valid. - id_lookup_table.erase(id); - } - - /* - * Check whether `key` has any bindings. - */ - bool HasBindingsFor(const K& key) - { - Guard guard(GetLock()); - - if (bindings.empty()) - return false; - - auto result = bindings.find(key); - if (result == bindings.end()) - return false; - - BindingList& list = result->second; - return !list.empty(); - } - - /* - * Push all Lua references for `key` onto the stack. - */ - void PushRefsFor(const K& key) - { - Guard guard(GetLock()); - - if (bindings.empty()) - return; - - auto result = bindings.find(key); - if (result == bindings.end()) - return; - - BindingList& list = result->second; - for (auto i = list.begin(); i != list.end();) - { - std::unique_ptr& binding = (*i); - auto i_prev = (i++); - - lua_rawgeti(L, LUA_REGISTRYINDEX, binding->functionReference); - - if (binding->remainingShots > 0) - { - binding->remainingShots -= 1; - - if (binding->remainingShots == 0) - { - id_lookup_table.erase(binding->id); - list.erase(i_prev); - } - } - } - } -}; - - -/* - * A `BindingMap` key type for simple event ID bindings - * (ServerEvents, GuildEvents, etc.). - */ -template -struct EventKey -{ - T event_id; - - EventKey(T event_id) : - event_id(event_id) - { } -}; - -/* - * A `BindingMap` key type for event ID/Object entry ID bindings - * (CreatureEvents, GameObjectEvents, etc.). - */ -template -struct EntryKey -{ - T event_id; - uint32 entry; - - EntryKey(T event_id, uint32 entry) : - event_id(event_id), - entry(entry) - { } -}; - -/* - * A `BindingMap` key type for event ID/unique Object bindings - * (currently just CreatureEvents). - */ -template -struct UniqueObjectKey -{ - T event_id; - ObjectGuid guid; - uint32 instance_id; - - UniqueObjectKey(T event_id, ObjectGuid guid, uint32 instance_id) : - event_id(event_id), - guid(guid), - instance_id(instance_id) - { } -}; - -class hash_helper -{ -public: - typedef std::size_t result_type; - - template - static inline result_type hash(T1 const & t1, T2 const & t2, T const &... t) - { - result_type seed = 0; - _hash_combine(seed, t1, t2, t...); - return seed; - } - - template ::value>::type* = nullptr> - static inline result_type hash(T const & t) - { - return std::hash::type>()(t); - } - - template ::value>::type* = nullptr> - static inline result_type hash(T const & t) - { - return std::hash()(t); - } - -private: - template - static inline void _hash_combine(result_type& seed, T const & v) - { - // from http://www.boost.org/doc/libs/1_40_0/boost/functional/hash/hash.hpp - seed ^= hash(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - } - - template - static inline void _hash_combine(result_type& seed, H const & h, T1 const & t1, T const &... t) - { - _hash_combine(seed, h); - _hash_combine(seed, t1, t...); - } -}; - -/* - * Implementations of various std functions on the above key types, - * so that they can be used within an unordered_map. - */ -namespace std -{ - template - struct equal_to < EventKey > - { - bool operator()(EventKey const& lhs, EventKey const& rhs) const - { - return lhs.event_id == rhs.event_id; - } - }; - - template - struct equal_to < EntryKey > - { - bool operator()(EntryKey const& lhs, EntryKey const& rhs) const - { - return lhs.event_id == rhs.event_id - && lhs.entry == rhs.entry; - } - }; - - template - struct equal_to < UniqueObjectKey > - { - bool operator()(UniqueObjectKey const& lhs, UniqueObjectKey const& rhs) const - { - return lhs.event_id == rhs.event_id - && lhs.guid == rhs.guid - && lhs.instance_id == rhs.instance_id; - } - }; - - template - struct hash < EventKey > - { - typedef EventKey argument_type; - - hash_helper::result_type operator()(argument_type const& k) const - { - return hash_helper::hash(k.event_id); - } - }; - - template - struct hash < EntryKey > - { - typedef EntryKey argument_type; - - hash_helper::result_type operator()(argument_type const& k) const - { - return hash_helper::hash(k.event_id, k.entry); - } - }; - - template - struct hash < UniqueObjectKey > - { - typedef UniqueObjectKey argument_type; - - hash_helper::result_type operator()(argument_type const& k) const - { - return hash_helper::hash(k.event_id, k.instance_id, k.guid.GetRawValue()); - } - }; -} - -#endif // _BINDING_MAP_H diff --git a/src/LuaEngine/Compilation/BytecodeCache.cpp b/src/LuaEngine/Compilation/BytecodeCache.cpp new file mode 100644 index 0000000000..6087906097 --- /dev/null +++ b/src/LuaEngine/Compilation/BytecodeCache.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#include "BytecodeCache.h" +#include "../State/StateManager.h" +#include "Statistics.h" +#include "Log.h" +#include +#include + +using Eclipse::Statistics::EclipseStatistics; + +namespace Eclipse::Core +{ + BytecodeCache& BytecodeCache::GetInstance() + { + static BytecodeCache instance; + return instance; + } + + BytecodeCache::BytecodeCache() { } + + /** + * @brief Destructor - clears all cached bytecode + */ + BytecodeCache::~BytecodeCache() + { + ClearAll(); + } + + /** + * @brief Get bytecode from cache (no compilation) + */ + const CompiledBytecode* BytecodeCache::Get(const std::string& filepath) + { + // Check if entry exists + auto it = m_cache.find(filepath); + if (it == m_cache.end()) + { + EclipseStatistics::GetInstance().IncrementCacheMiss(); + return nullptr; + } + + // Validate bytecode is non-empty + if (it->second->bytecode.empty() || !it->second->isValid()) + { + m_cache.erase(it); + return nullptr; + } + + // Validate file hasn't changed (timestamp check) + std::time_t currentModTime = GetFileModTime(filepath); + if (it->second->last_modified != currentModTime || currentModTime == 0) + { + m_cache.erase(it); + EclipseStatistics::GetInstance().IncrementCacheMiss(); + return nullptr; + } + + EclipseStatistics::GetInstance().IncrementCacheHit(); + return it->second.get(); + } + + /** + * @brief Store compiled bytecode in cache + */ + void BytecodeCache::Store(const std::string& filepath, std::shared_ptr bytecode) + { + if (!bytecode || !bytecode->isValid()) + { + LOG_ERROR("server.loading", "[Eclipse] BytecodeCache::Store - Invalid bytecode for {}", filepath); + return; + } + + m_cache[filepath] = bytecode; + EclipseStatistics::GetInstance().SetCacheTotalScripts(m_cache.size()); + EclipseStatistics::GetInstance().SetCacheTotalMemory(GetTotalMemory()); + + LOG_DEBUG("server.loading", "[Eclipse] BytecodeCache::Store - Cached {} ({} bytes)", filepath, bytecode->size()); + } + + /** + * @brief Clear all cached bytecode + * + * Called on script reload or server shutdown. + * Forces recompilation on next load. + */ + void BytecodeCache::ClearAll() + { + size_t count = m_cache.size(); + if (count > 0) + { + LOG_INFO("server.loading", "[Eclipse] BytecodeCache - Clearing {} cached entries", count); + m_cache.clear(); + } + m_timestampCache.clear(); + } + + /** + * @brief Clear timestamp cache + * + * Forces fresh stat() calls on next cache validation. + * Useful after bulk file modifications. + */ + void BytecodeCache::ClearTimestampCache() + { + m_timestampCache.clear(); + } + + /** + * @brief Get number of cached scripts + * @return Cache entry count + */ + size_t BytecodeCache::GetCacheSize() const + { + return m_cache.size(); + } + + /** + * @brief Get total memory used by cache + * + * Iterates all cached bytecode and sums sizes. + * + * @return Total bytes used by all cached bytecode + */ + size_t BytecodeCache::GetTotalMemory() const + { + size_t total = 0; + for (const auto& [_, entry] : m_cache) + total += entry->size(); + + return total; + } + + /** + * @brief Get file modification time + * + * @param filepath Path to file + * @return Unix timestamp, 0 if file doesn't exist + */ + std::time_t BytecodeCache::GetFileModTime(const std::string& filepath) + { + // Check timestamp cache first + auto it = m_timestampCache.find(filepath); + if (it != m_timestampCache.end()) + return it->second; + + // Get actual file modification time via stat() + struct stat fileInfo; + std::time_t modTime = 0; + if (stat(filepath.c_str(), &fileInfo) == 0) + modTime = fileInfo.st_mtime; + + // Cache the timestamp for future checks + m_timestampCache[filepath] = modTime; + return modTime; + } +} // namespace Eclipse::Core diff --git a/src/LuaEngine/Compilation/BytecodeCache.h b/src/LuaEngine/Compilation/BytecodeCache.h new file mode 100644 index 0000000000..c375b2f0dd --- /dev/null +++ b/src/LuaEngine/Compilation/BytecodeCache.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _SOL_BYTECODE_CACHE_H +#define _SOL_BYTECODE_CACHE_H + +#include +#include +#include +#include +#include +#include "Common.h" + +namespace Eclipse::Core +{ + /** + * @struct CompiledBytecode + * @brief Represents compiled Lua bytecode using Sol2's native bytecode format + */ + struct CompiledBytecode + { + sol::bytecode bytecode; // < Sol2 native bytecode object + std::string filepath; // < Original source file path + std::time_t last_modified; // < File modification time (unix timestamp) + + /** + * @brief Default constructor + */ + CompiledBytecode() : last_modified(0) {} + + /** + * @brief Check if bytecode is valid + * @return true if bytecode exists and is non-empty + */ + bool isValid() const { return !bytecode.as_string_view().empty(); } + + /** + * @brief Get bytecode size in bytes + * @return Size of compiled bytecode + */ + size_t size() const { return bytecode.as_string_view().size(); } + }; + + /** + * @class BytecodeCache + * @brief In-memory cache for compiled Lua/MoonScript bytecode + */ + class BytecodeCache + { + public: + BytecodeCache(); + ~BytecodeCache(); + + BytecodeCache(const BytecodeCache&) = delete; + BytecodeCache& operator=(const BytecodeCache&) = delete; + BytecodeCache(BytecodeCache&&) = delete; + BytecodeCache& operator=(BytecodeCache&&) = delete; + + /** + * @brief Get singleton instance + * @return Reference to the global BytecodeCache + */ + static BytecodeCache& GetInstance(); + + /** + * @brief Get bytecode from cache (no compilation) + * + * Validates: + * 1. Entry exists in cache + * 2. File timestamp matches (not modified) + * 3. Bytecode is valid (non-empty) + * + * @param filepath Path to script file + * @return Pointer to cached bytecode, nullptr if not found/outdated + */ + const CompiledBytecode* Get(const std::string& filepath); + + /** + * @brief Store compiled bytecode in cache + * + * Replaces any existing entry for this filepath. + * + * @param filepath Path to script file (used as cache key) + * @param bytecode Compiled bytecode to store + */ + void Store(const std::string& filepath, std::shared_ptr bytecode); + + /** + * @brief Clear all cached bytecode + * + * Called on script reload or server shutdown. + * Forces recompilation on next load. + */ + void ClearAll(); + + /** + * @brief Clear timestamp cache + * + * Forces fresh stat() calls on next cache check. + * Useful after bulk file operations. + */ + void ClearTimestampCache(); + + /** + * @brief Get number of cached scripts + * @return Cache entry count + */ + size_t GetCacheSize() const; + + /** + * @brief Get total memory used by cache + * @return Sum of all bytecode sizes in bytes + */ + size_t GetTotalMemory() const; + + /** + * @brief Get file modification time (with caching) + * + * Caches timestamp to avoid repeated stat() calls. + * + * @param filepath Path to file + * @return Unix timestamp, 0 if file doesn't exist + */ + std::time_t GetFileModTime(const std::string& filepath); + + private: + std::unordered_map> m_cache; // < Bytecode storage + std::unordered_map m_timestampCache; // < File timestamp cache + }; + +} // namespace Eclipse::Core + +#endif // _SOL_BYTECODE_CACHE_H diff --git a/src/LuaEngine/Compilation/ScriptCompiler.cpp b/src/LuaEngine/Compilation/ScriptCompiler.cpp new file mode 100644 index 0000000000..ecf1eb3843 --- /dev/null +++ b/src/LuaEngine/Compilation/ScriptCompiler.cpp @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#include "ScriptCompiler.h" +#include "StateManager.h" +#include "Statistics.h" +#include "Log.h" +#include +#include +#include +#include + +namespace Eclipse::API +{ + using Core::BytecodeCache; + using Core::StateManager; + using Core::CompiledBytecode; + using Statistics::EclipseStatistics; + + ScriptCompiler& ScriptCompiler::GetInstance() + { + static ScriptCompiler instance; + return instance; + } + + ScriptCompiler::ScriptCompiler() { } + + ScriptCompiler::~ScriptCompiler() + { + auto stats = EclipseStatistics::GetInstance().GetSnapshot(); + LOG_INFO("server.loading", "Eclipse::ScriptCompiler - Shutting down. Stats: {} successful, {} failed", stats.compilationSuccess, stats.compilationFailed); + } + + const CompiledBytecode* ScriptCompiler::CompileFile(const std::string& filepath, const CompileOptions& options) + { + auto& cache = BytecodeCache::GetInstance(); + auto& stats = EclipseStatistics::GetInstance(); + + // Try to get from cache first + const auto* cached = cache.Get(filepath); + if (cached) + return cached; + + // Determine file type and compile accordingly + // Priority: .ext > .cout > .moon > .lua + std::shared_ptr bytecode; + + if (IsCoutFile(filepath)) + { + bytecode = LoadCoutFile(filepath); + } + else if (IsMoonScriptFile(filepath)) + { + bytecode = CompileMoonScriptFile(filepath); + } + else // Both .lua and .ext use CompileLuaFile (Lua syntax) + { + bytecode = CompileLuaFile(filepath); + } + + if (bytecode && bytecode->isValid()) + { + // Store in cache + cache.Store(filepath, bytecode); + + // Update statistics + stats.IncrementCompilationSuccess(); + stats.AddCompilationBytecodeSize(bytecode->size()); + + return bytecode.get(); + } + + stats.IncrementCompilationFailed(); + return nullptr; + } + + std::shared_ptr ScriptCompiler::CompileLuaFile(const std::string& filepath) + { + try + { + sol::state* masterState = GetMasterStateOrNull("CompileLuaFile"); + if (!masterState) + return nullptr; + + // Load Lua file + sol::load_result loadResult = masterState->load_file(filepath); + + if (!loadResult.valid()) + { + sol::error err = loadResult; + LOG_ERROR("server.loading", "[Eclipse] ScriptCompiler::CompileLuaFile - Failed to load {}: {}", + filepath, err.what()); + return nullptr; + } + + // Convert to protected_function and dump to bytecode + sol::protected_function pf = std::move(loadResult).get(); + sol::bytecode bc = pf.dump(); + + // Validate bytecode + if (!ValidateBytecode(bc, filepath, "CompileLuaFile")) + return nullptr; + + // Create bytecode structure + auto bytecode = CreateBytecodeStructure(std::move(bc), filepath); + + LOG_DEBUG("server.loading", "[Eclipse] ScriptCompiler::CompileLuaFile - Compiled {} ({} bytes)", + filepath, bytecode->size()); + + // Track statistics (.ext files are priority Lua) + if (IsExtFile(filepath)) + EclipseStatistics::GetInstance().IncrementCompilationExtFile(); + + return bytecode; + } + catch (const std::exception& e) + { + LOG_ERROR("server.loading", "[Eclipse] ScriptCompiler::CompileLuaFile - Exception compiling {}: {}", + filepath, e.what()); + return nullptr; + } + } + + std::shared_ptr ScriptCompiler::CompileMoonScriptFile(const std::string& filepath) + { + try + { + sol::state* masterState = GetMasterStateOrNull("CompileMoonScriptFile"); + if (!masterState) + return nullptr; + + std::string moonLoader = "return require('moonscript').loadfile([[" + filepath + "]])"; + sol::load_result moonLoadResult = masterState->load(moonLoader); + + if (!moonLoadResult.valid()) + { + sol::error err = moonLoadResult; + LOG_ERROR("server.loading", "[Eclipse] ScriptCompiler::CompileMoonScriptFile - Failed to load MoonScript {}: {}", filepath, err.what()); + return nullptr; + } + + // Execute moonscript.loadfile to get compiled function + sol::protected_function_result pfr = moonLoadResult(); + if (!pfr.valid()) + { + sol::error err = pfr; + LOG_ERROR("server.loading", "[Eclipse] ScriptCompiler::CompileMoonScriptFile - Failed to compile MoonScript {}: {}", filepath, err.what()); + return nullptr; + } + + // Extract compiled function and dump to bytecode + sol::protected_function pf = pfr; + sol::bytecode bc = pf.dump(); + + // Validate bytecode + if (!ValidateBytecode(bc, filepath, "CompileMoonScriptFile")) + return nullptr; + + // Create bytecode structure + auto bytecode = CreateBytecodeStructure(std::move(bc), filepath); + + LOG_DEBUG("server.loading", "[Eclipse] ScriptCompiler::CompileMoonScriptFile - Compiled {} ({} bytes)", filepath, bytecode->size()); + + EclipseStatistics::GetInstance().IncrementCompilationMoonScript(); + + return bytecode; + } + catch (const std::exception& e) + { + LOG_ERROR("server.loading", "[Eclipse] ScriptCompiler::CompileMoonScriptFile - Exception compiling {}: {}", filepath, e.what()); + return nullptr; + } + } + + std::shared_ptr ScriptCompiler::LoadCoutFile(const std::string& filepath) + { + try + { + // Read the bytecode file + std::ifstream file(filepath, std::ios::binary); + if (!file.is_open()) + { + LOG_ERROR("server.loading", "[Eclipse] ScriptCompiler::LoadCoutFile - Failed to open: {}", filepath); + return nullptr; + } + + // Get file size + file.seekg(0, std::ios::end); + size_t fileSize = file.tellg(); + file.seekg(0, std::ios::beg); + + if (fileSize == 0) + { + file.close(); + LOG_ERROR("server.loading", "[Eclipse] ScriptCompiler::LoadCoutFile - Empty bytecode file: {}", filepath); + return nullptr; + } + + // Read directly into std::byte buffer (native bytecode format) + std::vector byteBuffer(fileSize); + file.read(reinterpret_cast(byteBuffer.data()), fileSize); + file.close(); + + // Create bytecode from buffer (zero-copy from file to sol::bytecode) + sol::bytecode bc(byteBuffer.begin(), byteBuffer.end()); + + // Validate bytecode + if (!ValidateBytecode(bc, filepath, "LoadCoutFile")) + return nullptr; + + // Create bytecode structure + auto bytecode = CreateBytecodeStructure(std::move(bc), filepath); + + LOG_DEBUG("server.loading", "[Eclipse] ScriptCompiler::LoadCoutFile - Loaded {} ({} bytes)", filepath, bytecode->size()); + + EclipseStatistics::GetInstance().IncrementCompilationCoutFile(); + + return bytecode; + } + catch (const std::exception& e) + { + LOG_ERROR("server.loading", "[Eclipse] ScriptCompiler::LoadCoutFile - Exception loading {}: {}", filepath, e.what()); + return nullptr; + } + } + + sol::state* ScriptCompiler::GetMasterStateOrNull(const char* callerName) + { + auto& stateManager = StateManager::GetInstance(); + sol::state* masterState = stateManager.GetMasterState(); + + if (!masterState) + { + LOG_ERROR("server.loading", "[Eclipse] ScriptCompiler::{} - Master state not available", callerName); + return nullptr; + } + + return masterState; + } + + bool ScriptCompiler::ValidateBytecode(const sol::bytecode& bc, const std::string& filepath, const char* callerName) + { + if (bc.as_string_view().empty()) + { + LOG_ERROR("server.loading", "[Eclipse] ScriptCompiler::{} - Failed to dump bytecode: {}", callerName, filepath); + return false; + } + return true; + } + + bool ScriptCompiler::HasExtension(const std::string& filepath, const std::string& extension) + { + std::filesystem::path path(filepath); + return path.extension() == extension; + } + + std::shared_ptr ScriptCompiler::CreateBytecodeStructure(sol::bytecode&& bc, const std::string& filepath) + { + auto& cache = BytecodeCache::GetInstance(); + + // Get file modification time + std::time_t modTime = cache.GetFileModTime(filepath); + + // Create and populate bytecode structure + auto bytecode = std::make_shared(); + bytecode->bytecode = std::move(bc); + bytecode->filepath = filepath; + bytecode->last_modified = modTime; + + return bytecode; + } + +} diff --git a/src/LuaEngine/Compilation/ScriptCompiler.h b/src/LuaEngine/Compilation/ScriptCompiler.h new file mode 100644 index 0000000000..fa50f0eb3a --- /dev/null +++ b/src/LuaEngine/Compilation/ScriptCompiler.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _SOL_SCRIPT_COMPILER_H +#define _SOL_SCRIPT_COMPILER_H + +#include +#include +#include +#include "BytecodeCache.h" +#include "Statistics.h" +#include "Common.h" + +namespace Eclipse::API +{ + // Import Core types + using Core::CompiledBytecode; + + /** + * @brief Script compilation options + */ + struct CompileOptions + { + bool stripDebugInfo = false; + bool optimizeCode = true; + bool allowMoonScript = true; + std::string moonScriptPath; + }; + + /** + * @class ScriptCompiler + * @brief Compiles Lua/MoonScript files to bytecode with caching + * + */ + class ScriptCompiler + { + public: + ScriptCompiler(); + ~ScriptCompiler(); + + ScriptCompiler(const ScriptCompiler&) = delete; + ScriptCompiler& operator=(const ScriptCompiler&) = delete; + static ScriptCompiler& GetInstance(); + + /** + * @brief Compile a script file to bytecode + * + * @param filepath Path to the script file (delegates to BytecodeCache) + * @param options Compilation options (currently unused, delegated to cache) + * @return Const pointer to compiled bytecode, or nullptr if failed + */ + const CompiledBytecode* CompileFile(const std::string& filepath, const CompileOptions& options = CompileOptions()); + + /** + * @brief Check if a file is a MoonScript file (.moon extension) + * + * @param filepath File path to check (absolute or relative) + * @return true if extension is ".moon", false otherwise + */ + static inline bool IsMoonScriptFile(const std::string& filepath) + { + return HasExtension(filepath, ".moon"); + } + + /** + * @brief Check if file is .ext file + * @param filepath File path to check + * @return true if .ext extension + */ + static inline bool IsExtFile(const std::string& filepath) + { + return HasExtension(filepath, ".ext"); + } + + /** + * @brief Check if file is .cout file + * @param filepath File path to check + * @return true if .cout extension + */ + static inline bool IsCoutFile(const std::string& filepath) + { + return HasExtension(filepath, ".cout"); + } + + private: + /** + * @brief Compile Lua file to bytecode (handles both .lua and .ext files) + * @param filepath Path to .lua or .ext file + * @return Compiled bytecode or nullptr if failed + */ + std::shared_ptr CompileLuaFile(const std::string& filepath); + + /** + * @brief Load pre-compiled .cout file (bytecode) + * @param filepath Path to .cout file + * @return CompiledBytecode or nullptr if failed + */ + std::shared_ptr LoadCoutFile(const std::string& filepath); + + /** + * @brief Compile MoonScript file to bytecode + * @param filepath Path to .moon file + * @return Compiled bytecode or nullptr if failed + */ + std::shared_ptr CompileMoonScriptFile(const std::string& filepath); + + /** + * @brief Create CompiledBytecode structure from bytecode + * @param bc Sol2 bytecode object + * @param filepath Original source file path + * @return Populated CompiledBytecode shared_ptr + */ + std::shared_ptr CreateBytecodeStructure(sol::bytecode&& bc, const std::string& filepath); + + /** + * @brief Get master state with validation + * @param callerName Name of calling function for error logging + * @return Pointer to master state, or nullptr if unavailable (logs error) + */ + sol::state* GetMasterStateOrNull(const char* callerName); + + /** + * @brief Validate bytecode is non-empty + * @param bc Bytecode to validate + * @param filepath File path for error logging + * @param callerName Caller function name for error logging + * @return true if valid (non-empty) + */ + bool ValidateBytecode(const sol::bytecode& bc, const std::string& filepath, const char* callerName); + + /** + * @brief Check if file has specific extension + * @param filepath File path to check + * @param extension Extension to match (e.g., ".moon") + * @return true if extension matches + */ + static bool HasExtension(const std::string& filepath, const std::string& extension); + }; +} + +#endif // _SOL_SCRIPT_COMPILER_H diff --git a/src/LuaEngine/Compilation/Statistics.h b/src/LuaEngine/Compilation/Statistics.h new file mode 100644 index 0000000000..d4d3dd980d --- /dev/null +++ b/src/LuaEngine/Compilation/Statistics.h @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _ECLIPSE_STATISTICS_H +#define _ECLIPSE_STATISTICS_H + +#include +#include +#include + +namespace Eclipse::Statistics +{ + /** + * @class EclipseStatistics + * @brief Centralized lock-free statistics for ALL Eclipse components + * + */ + class EclipseStatistics + { + public: + /** + * @struct Snapshot + * @brief Complete statistics snapshot from all components + */ + struct Snapshot + { + // ===== Compilation (ScriptCompiler) ===== + size_t compilationSuccess = 0; + size_t compilationFailed = 0; + size_t compilationTotalBytecodeSize = 0; + size_t compilationMoonScript = 0; + size_t compilationExtFiles = 0; // .ext files compiled + size_t compilationCoutFiles = 0; // .cout files loaded + + // ===== BytecodeCache ===== + size_t cacheTotalScripts = 0; + size_t cacheTotalMemory = 0; + size_t cacheCompilationCount = 0; + size_t cacheHits = 0; + size_t cacheMisses = 0; + + // ===== Loading (ScriptLoader) ===== + uint32 loadingTotalScripts = 0; + uint32 loadingLuaScripts = 0; + uint32 loadingMoonScripts = 0; + uint32 loadingExtScripts = 0; // .ext files + uint32 loadingCoutScripts = 0; // .cout files + uint32 loadingSuccessful = 0; + uint32 loadingFailed = 0; + + // ===== Events (EventManager) ===== + size_t eventsGlobalHandlers = 0; + size_t eventsEntryHandlers = 0; + size_t eventsUniqueHandlers = 0; + uint64 eventsTotalTriggers = 0; + uint64 eventsTotalHandlersExecuted = 0; + }; + + /** + * @brief Get singleton instance + */ + static EclipseStatistics& GetInstance() + { + static EclipseStatistics instance; + return instance; + } + + EclipseStatistics(const EclipseStatistics&) = delete; + EclipseStatistics& operator=(const EclipseStatistics&) = delete; + EclipseStatistics(EclipseStatistics&&) = delete; + EclipseStatistics& operator=(EclipseStatistics&&) = delete; + + // ===== COMPILATION METRICS ===== + void IncrementCompilationSuccess() { m_compilationSuccess.fetch_add(1, std::memory_order_relaxed); } + void IncrementCompilationFailed() { m_compilationFailed.fetch_add(1, std::memory_order_relaxed); } + void AddCompilationBytecodeSize(size_t size) { m_compilationTotalBytecodeSize.fetch_add(size, std::memory_order_relaxed); } + void IncrementCompilationMoonScript() { m_compilationMoonScript.fetch_add(1, std::memory_order_relaxed); } + void IncrementCompilationExtFile() { m_compilationExtFiles.fetch_add(1, std::memory_order_relaxed); } + void IncrementCompilationCoutFile() { m_compilationCoutFiles.fetch_add(1, std::memory_order_relaxed); } + + // ===== CACHE METRICS ===== + void SetCacheTotalScripts(size_t count) { m_cacheTotalScripts.store(count, std::memory_order_relaxed); } + void SetCacheTotalMemory(size_t bytes) { m_cacheTotalMemory.store(bytes, std::memory_order_relaxed); } + void IncrementCacheCompilation() { m_cacheCompilationCount.fetch_add(1, std::memory_order_relaxed); } + void IncrementCacheHit() { m_cacheHits.fetch_add(1, std::memory_order_relaxed); } + void IncrementCacheMiss() { m_cacheMisses.fetch_add(1, std::memory_order_relaxed); } + + // ===== LOADING METRICS ===== + void SetLoadingTotalScripts(uint32 count) { m_loadingTotalScripts.store(count, std::memory_order_relaxed); } + void SetLoadingLuaScripts(uint32 count) { m_loadingLuaScripts.store(count, std::memory_order_relaxed); } + void SetLoadingMoonScripts(uint32 count) { m_loadingMoonScripts.store(count, std::memory_order_relaxed); } + void SetLoadingExtScripts(uint32 count) { m_loadingExtScripts.store(count, std::memory_order_relaxed); } + void SetLoadingCoutScripts(uint32 count) { m_loadingCoutScripts.store(count, std::memory_order_relaxed); } + void IncrementLoadingSuccessful() { m_loadingSuccessful.fetch_add(1, std::memory_order_relaxed); } + void IncrementLoadingFailed() { m_loadingFailed.fetch_add(1, std::memory_order_relaxed); } + void ResetLoadingCounters() + { + m_loadingSuccessful.store(0, std::memory_order_relaxed); + m_loadingFailed.store(0, std::memory_order_relaxed); + } + + // ===== EVENT METRICS ===== + void IncrementEventsGlobalHandlers() { m_eventsGlobalHandlers.fetch_add(1, std::memory_order_relaxed); } + void DecrementEventsGlobalHandlers(size_t count) { m_eventsGlobalHandlers.fetch_sub(count, std::memory_order_relaxed); } + void IncrementEventsEntryHandlers() { m_eventsEntryHandlers.fetch_add(1, std::memory_order_relaxed); } + void DecrementEventsEntryHandlers(size_t count) { m_eventsEntryHandlers.fetch_sub(count, std::memory_order_relaxed); } + void IncrementEventsUniqueHandlers() { m_eventsUniqueHandlers.fetch_add(1, std::memory_order_relaxed); } + void IncrementEventsTrigger() { m_eventsTotalTriggers.fetch_add(1, std::memory_order_relaxed); } + void IncrementEventsHandlerExecuted() { m_eventsTotalHandlersExecuted.fetch_add(1, std::memory_order_relaxed); } + + /** + * @brief Get complete statistics snapshot + * @return Snapshot of all metrics (eventually consistent) + */ + Snapshot GetSnapshot() const + { + Snapshot snapshot; + + // Compilation + snapshot.compilationSuccess = m_compilationSuccess.load(std::memory_order_relaxed); + snapshot.compilationFailed = m_compilationFailed.load(std::memory_order_relaxed); + snapshot.compilationTotalBytecodeSize = m_compilationTotalBytecodeSize.load(std::memory_order_relaxed); + snapshot.compilationMoonScript = m_compilationMoonScript.load(std::memory_order_relaxed); + snapshot.compilationExtFiles = m_compilationExtFiles.load(std::memory_order_relaxed); + snapshot.compilationCoutFiles = m_compilationCoutFiles.load(std::memory_order_relaxed); + + // Cache + snapshot.cacheTotalScripts = m_cacheTotalScripts.load(std::memory_order_relaxed); + snapshot.cacheTotalMemory = m_cacheTotalMemory.load(std::memory_order_relaxed); + snapshot.cacheCompilationCount = m_cacheCompilationCount.load(std::memory_order_relaxed); + snapshot.cacheHits = m_cacheHits.load(std::memory_order_relaxed); + snapshot.cacheMisses = m_cacheMisses.load(std::memory_order_relaxed); + + // Loading + snapshot.loadingTotalScripts = m_loadingTotalScripts.load(std::memory_order_relaxed); + snapshot.loadingLuaScripts = m_loadingLuaScripts.load(std::memory_order_relaxed); + snapshot.loadingMoonScripts = m_loadingMoonScripts.load(std::memory_order_relaxed); + snapshot.loadingExtScripts = m_loadingExtScripts.load(std::memory_order_relaxed); + snapshot.loadingCoutScripts = m_loadingCoutScripts.load(std::memory_order_relaxed); + snapshot.loadingSuccessful = m_loadingSuccessful.load(std::memory_order_relaxed); + snapshot.loadingFailed = m_loadingFailed.load(std::memory_order_relaxed); + + // Events + snapshot.eventsGlobalHandlers = m_eventsGlobalHandlers.load(std::memory_order_relaxed); + snapshot.eventsEntryHandlers = m_eventsEntryHandlers.load(std::memory_order_relaxed); + snapshot.eventsUniqueHandlers = m_eventsUniqueHandlers.load(std::memory_order_relaxed); + snapshot.eventsTotalTriggers = m_eventsTotalTriggers.load(std::memory_order_relaxed); + snapshot.eventsTotalHandlersExecuted = m_eventsTotalHandlersExecuted.load(std::memory_order_relaxed); + + return snapshot; + } + + /** + * @brief Reset ALL counters to zero + */ + void ResetAll() + { + // Compilation + m_compilationSuccess.store(0, std::memory_order_relaxed); + m_compilationFailed.store(0, std::memory_order_relaxed); + m_compilationTotalBytecodeSize.store(0, std::memory_order_relaxed); + m_compilationMoonScript.store(0, std::memory_order_relaxed); + m_compilationExtFiles.store(0, std::memory_order_relaxed); + m_compilationCoutFiles.store(0, std::memory_order_relaxed); + + // Cache + m_cacheTotalScripts.store(0, std::memory_order_relaxed); + m_cacheTotalMemory.store(0, std::memory_order_relaxed); + m_cacheCompilationCount.store(0, std::memory_order_relaxed); + m_cacheHits.store(0, std::memory_order_relaxed); + m_cacheMisses.store(0, std::memory_order_relaxed); + + // Loading + m_loadingTotalScripts.store(0, std::memory_order_relaxed); + m_loadingLuaScripts.store(0, std::memory_order_relaxed); + m_loadingMoonScripts.store(0, std::memory_order_relaxed); + m_loadingExtScripts.store(0, std::memory_order_relaxed); + m_loadingCoutScripts.store(0, std::memory_order_relaxed); + m_loadingSuccessful.store(0, std::memory_order_relaxed); + m_loadingFailed.store(0, std::memory_order_relaxed); + + // Events + m_eventsGlobalHandlers.store(0, std::memory_order_relaxed); + m_eventsEntryHandlers.store(0, std::memory_order_relaxed); + m_eventsUniqueHandlers.store(0, std::memory_order_relaxed); + m_eventsTotalTriggers.store(0, std::memory_order_relaxed); + m_eventsTotalHandlersExecuted.store(0, std::memory_order_relaxed); + } + + private: + EclipseStatistics() = default; + ~EclipseStatistics() = default; + + // Compilation atomics + std::atomic m_compilationSuccess{0}; + std::atomic m_compilationFailed{0}; + std::atomic m_compilationTotalBytecodeSize{0}; + std::atomic m_compilationMoonScript{0}; + std::atomic m_compilationExtFiles{0}; + std::atomic m_compilationCoutFiles{0}; + + // Cache atomics + std::atomic m_cacheTotalScripts{0}; + std::atomic m_cacheTotalMemory{0}; + std::atomic m_cacheCompilationCount{0}; + std::atomic m_cacheHits{0}; + std::atomic m_cacheMisses{0}; + + // Loading atomics + std::atomic m_loadingTotalScripts{0}; + std::atomic m_loadingLuaScripts{0}; + std::atomic m_loadingMoonScripts{0}; + std::atomic m_loadingExtScripts{0}; + std::atomic m_loadingCoutScripts{0}; + std::atomic m_loadingSuccessful{0}; + std::atomic m_loadingFailed{0}; + + // Event atomics + std::atomic m_eventsGlobalHandlers{0}; + std::atomic m_eventsEntryHandlers{0}; + std::atomic m_eventsUniqueHandlers{0}; + std::atomic m_eventsTotalTriggers{0}; + std::atomic m_eventsTotalHandlersExecuted{0}; + }; + +} // namespace Eclipse::Statistics + +#endif // _ECLIPSE_STATISTICS_H diff --git a/src/LuaEngine/Events/EventManager.cpp b/src/LuaEngine/Events/EventManager.cpp new file mode 100644 index 0000000000..3dd93e7a4f --- /dev/null +++ b/src/LuaEngine/Events/EventManager.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#include "EventManager.h" +#include "StateManager.h" +#include "Log.h" + +namespace Eclipse::Core +{ + /** + * @brief Get EventManager singleton instance + * + * @return Reference to the global EventManager + */ + EventManager& EventManager::GetInstance() + { + static EventManager instance; + return instance; + } + + /** + * @brief Constructor - initializes state + */ + EventManager::EventManager() : m_nextHandlerId(1), m_initialized(false) { } + + /** + * @brief Destructor - cleanup all handlers + */ + EventManager::~EventManager() + { + Shutdown(); + } + + /** + * @brief Initialize event manager + * + * Called from EclipseScriptLoader during server startup. + * + * @return true on success (always succeeds) + */ + bool EventManager::Initialize() + { + if (m_initialized) + { + LOG_WARN("server.loading", "[Eclipse] EventManager - Already initialized"); + return true; + } + + LOG_INFO("server.loading", "[Eclipse] EventManager - Initializing event manager"); + + m_nextHandlerId = 1; + m_initialized = true; + + LOG_INFO("server.loading", "[Eclipse] EventManager - Initialization complete"); + return true; + } + + /** + * @brief Shutdown event manager + * + * Cancels ALL registered handlers and logs final statistics. + * Called from EclipseScriptLoader during server shutdown. + */ + void EventManager::Shutdown() + { + if (!m_initialized) + return; + + CancelAllEvents(); + m_initialized = false; + } + + /** + * @brief Cancel a specific event handler by ID + * + * Searches all three storage maps (global, entry, unique). + * + * @param handlerId Handler ID returned by Register*Event + * @return true if handler was found and removed + */ + bool EventManager::CancelEvent(uint64 handlerId) + { + // Search in all three handler maps + if (FindAndCancelHandler(m_globalHandlers, handlerId, "global")) + return true; + + if (FindAndCancelHandler(m_entryHandlers, handlerId, "entry")) + return true; + + if (FindAndCancelHandler(m_uniqueHandlers, handlerId, "unique")) + return true; + + LOG_WARN("eclipse.events", "[Eclipse] EventManager - Handler {} not found for cancellation", handlerId); + return false; + } + + /** + * @brief Cancel all handlers for a specific state + * + * Removes all handlers matching stateId across all event types. + * Used when a Lua state is destroyed (future per-map cleanup). + * + * @param stateId State ID to cleanup + */ + void EventManager::CancelStateEvents(int32 stateId) + { + size_t totalCancelled = 0; + + totalCancelled += CancelStateHandlersInMap(m_globalHandlers, stateId); + totalCancelled += CancelStateHandlersInMap(m_entryHandlers, stateId); + totalCancelled += CancelStateHandlersInMap(m_uniqueHandlers, stateId); + + LOG_DEBUG("eclipse.events", "[Eclipse] EventManager - Cancelled {} handlers for state {}", totalCancelled, stateId); + } + + /** + * @brief Cancel ALL registered events + * + * Complete cleanup of all event handlers. + * Called during shutdown or Lua reload. + */ + void EventManager::CancelAllEvents() + { + size_t total = m_globalHandlers.size() + m_entryHandlers.size() + m_uniqueHandlers.size(); + + m_globalHandlers.clear(); + m_entryHandlers.clear(); + m_uniqueHandlers.clear(); + + LOG_DEBUG("eclipse.events", "[Eclipse] EventManager - Cancelled all event handlers (total: {})", total); + } + +} // namespace Eclipse::Core diff --git a/src/LuaEngine/Events/EventManager.h b/src/LuaEngine/Events/EventManager.h new file mode 100644 index 0000000000..3bb0a2643a --- /dev/null +++ b/src/LuaEngine/Events/EventManager.h @@ -0,0 +1,883 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _ECLIPSE_EVENT_MANAGER_H +#define _ECLIPSE_EVENT_MANAGER_H + +#include +#include +#include +#include "Common.h" +#include "Log.h" + +namespace Eclipse::Core +{ + /** + * @enum PlayerEvent + * @brief Player-specific event types + * + * Triggered by PlayerHooks when player state changes occur. + */ + enum class PlayerEvent : uint32 + { + ON_CHARACTER_CREATE = 1, ///< Character created in database + ON_CHARACTER_DELETE = 2, ///< Character deleted from database + ON_LOGIN = 3, ///< Player logged into the world + ON_LOGOUT = 4, ///< Player logged out + ON_FIRST_LOGIN = 5, ///< First time login for character + ON_LEVEL_CHANGE = 6, ///< Player gained/lost a level + ON_MONEY_CHANGE = 7, ///< Player money changed + ON_GIVE_XP = 8, ///< Player received experience + ON_REPUTATION_CHANGE = 9, ///< Reputation with faction changed + ON_KILL_PLAYER = 10, ///< Player killed another player + ON_KILL_CREATURE = 11 ///< Player killed a creature + }; + + /** + * @enum WorldEvent + * @brief World-level event types + * + * Triggered by WorldHooks for server-wide events. + */ + enum class WorldEvent : uint32 + { + ON_UPDATE = 1, ///< World update tick + ON_CONFIG_LOAD = 2, ///< Configuration reloaded + ON_SHUTDOWN_INIT = 3, ///< Shutdown initiated + ON_SHUTDOWN_CANCEL = 4, ///< Shutdown cancelled + ON_STARTUP = 5, ///< Server startup complete + ON_SHUTDOWN = 6 ///< Server shutting down + }; + + /** + * @enum WorldObjectEvent + * @brief WorldObject lifecycle event types + * + * Triggered by WorldObjectHooks for GameObjects. + */ + enum class WorldObjectEvent : uint32 + { + ON_CREATE = 1, ///< GameObject created in world + ON_DESTROY = 2, ///< GameObject removed from world + ON_UPDATE = 3, ///< GameObject updated + ON_REPOP = 4 ///< GameObject respawned + }; + + /** + * @struct EventHandler + * @brief Lua callback wrapper with execution tracking + * + * Stores a Lua function and metadata for shot-limited execution. + * Move semantics ensure callbacks are never copied. + */ + struct EventHandler + { + sol::protected_function function; ///< Lua callback (moved, never copied) + uint32 shots; ///< Total allowed executions (0 = infinite) + uint32 callCount; ///< Executions so far + int32 stateId; ///< State ID (-1 = all states, future use) + + /** + * @brief Construct an event handler + * @param func Lua callback function (moved) + * @param shotCount Execution limit (0 = infinite) + * @param sid State ID (-1 for global) + */ + EventHandler(sol::protected_function&& func, uint32 shotCount = 0, int32 sid = -1) + : function(std::move(func)) + , shots(shotCount) + , callCount(0) + , stateId(sid) + { + } + + /** + * @brief Check if handler should execute + * @return true if under shot limit or infinite + */ + bool ShouldExecute() const + { + return shots == 0 || callCount < shots; + } + + /** + * @brief Check if handler has expired + * @return true if shot limit reached + */ + bool IsExpired() const + { + return shots > 0 && callCount >= shots; + } + }; + + /** + * @struct GlobalEventKey + * @brief Hash key for global events (type-safe enum discrimination) + * + * Uses typeid hash to prevent collisions between different enum types + * with identical values (e.g., PlayerEvent::ON_LOGIN=3 vs WorldEvent::ON_UPDATE=1). + */ + struct GlobalEventKey + { + size_t eventCategory; ///< typeid(EventEnum).hash_code() + uint32 eventType; ///< Event enum value cast to uint32 + + bool operator==(const GlobalEventKey& other) const + { + return eventCategory == other.eventCategory && eventType == other.eventType; + } + }; + + /** + * @struct EntryEventKey + * @brief Hash key for entry-based events (Creature/GameObject by template ID) + */ + struct EntryEventKey + { + size_t eventCategory; ///< typeid(EventEnum).hash_code() + uint32 eventType; ///< Event enum value + uint32 entry; ///< creature_template.entry or gameobject_template.entry + + bool operator==(const EntryEventKey& other) const + { + return eventCategory == other.eventCategory + && eventType == other.eventType + && entry == other.entry; + } + }; + + /** + * @struct UniqueEventKey + * @brief Hash key for unique instance events (specific GUID) + */ + struct UniqueEventKey + { + size_t eventCategory; ///< typeid(EventEnum).hash_code() + uint32 eventType; ///< Event enum value + uint64 guid; ///< Object GUID + + bool operator==(const UniqueEventKey& other) const + { + return eventCategory == other.eventCategory + && eventType == other.eventType + && guid == other.guid; + } + }; +} + +/** + * @brief Hash specializations for event keys + * + * Optimized hash functions combining category + type + optional ID. + * Uses XOR with bit shifts to minimize collisions. + */ +namespace std +{ + template<> + struct hash + { + size_t operator()(const Eclipse::Core::GlobalEventKey& key) const noexcept + { + return key.eventCategory ^ (hash()(key.eventType) << 1); + } + }; + + template<> + struct hash + { + size_t operator()(const Eclipse::Core::EntryEventKey& key) const noexcept + { + return key.eventCategory + ^ (hash()(key.eventType) << 1) + ^ (hash()(key.entry) << 2); + } + }; + + template<> + struct hash + { + size_t operator()(const Eclipse::Core::UniqueEventKey& key) const noexcept + { + return key.eventCategory + ^ (hash()(key.eventType) << 1) + ^ (hash()(key.guid) << 2); + } + }; +} + + +namespace Eclipse::Core +{ + /** + * @class EventManager + * @brief High-performance generic event dispatcher for Lua callbacks + * + * **Architecture Overview:** + * - Type-safe: Uses C++ templates + typeid discrimination for enum safety + * - Lock-free: No mutexes (state -1 is single-threaded, future per-map states thread-isolated) + * - Three event types: + * 1. Global: RegisterPlayerEvent(), etc. + * 2. Entry: RegisterCreatureGossipEvent(entry, ...) + * 3. Unique: Future use for specific GUID events + * + * **Design Pattern:** + * Singleton for state -1, future: per-map instances managed by StateManager. + * + * **Performance Characteristics:** + * - Register: O(1) amortized (hash insert + vector push) + * - Trigger: O(n) where n = handlers for that event (unavoidable) + * - Cancel: O(1) hash lookup + O(k) vector cleanup (k = handlers in bucket) + * + * **Memory Layout:** + * Handlers stored in vector> for cache locality. + * Event keys use typeid hash to prevent cross-enum collisions. + * + * @note Currently operates on master state (-1) only + */ + class EventManager + { + public: + EventManager(); + ~EventManager(); + + EventManager(const EventManager&) = delete; + EventManager& operator=(const EventManager&) = delete; + EventManager(EventManager&&) = delete; + EventManager& operator=(EventManager&&) = delete; + + static EventManager& GetInstance(); + + /** + * @brief Initialize the event manager + * @return true on success + */ + bool Initialize(); + + /** + * @brief Shutdown and cleanup all events + */ + void Shutdown(); + + /** + * @brief Register a global event handler + * + * Global events are not tied to specific object instances. + * Example: RegisterPlayerEvent(PlayerEvent::ON_LOGIN, callback) + * + * @tparam EventEnum Event type enum (PlayerEvent, WorldEvent, etc.) + * @param eventType Event enum value + * @param handler Lua callback (moved, not copied) + * @param shots Execution limit (0 = infinite) + * @param stateId State ID (-1 = all states, future use) + * @return Unique handler ID for cancellation + */ + template + uint64 RegisterGlobalEvent( + EventEnum eventType, + sol::protected_function&& handler, + uint32 shots = 0, + int32 stateId = -1 + ); + + /** + * @brief Register an entry-based event handler + * + * Entry events are tied to template IDs (creature_template, gameobject_template). + * Example: RegisterCreatureGossipEvent(CreatureEvent::ON_GOSSIP_HELLO, 1234, callback) + * + * @tparam EventEnum Event type enum + * @param eventType Event enum value + * @param entry Template entry ID + * @param handler Lua callback (moved, not copied) + * @param shots Execution limit (0 = infinite) + * @param stateId State ID (-1 = all states, future use) + * @return Unique handler ID for cancellation + */ + template + uint64 RegisterEntryEvent( + EventEnum eventType, + uint32 entry, + sol::protected_function&& handler, + uint32 shots = 0, + int32 stateId = -1 + ); + + /** + * @brief Register a unique instance event handler + * + * Unique events are tied to specific object GUIDs. + * + * @tparam EventEnum Event type enum + * @param eventType Event enum value + * @param guid Object GUID + * @param handler Lua callback (moved, not copied) + * @param shots Execution limit (0 = infinite) + * @param stateId State ID (-1 = all states, future use) + * @return Unique handler ID for cancellation + */ + template + uint64 RegisterUniqueEvent( + EventEnum eventType, + uint64 guid, + sol::protected_function&& handler, + uint32 shots = 0, + int32 stateId = -1 + ); + + /** + * @brief Cancel a specific event handler + * @param handlerId Handler ID returned by Register*Event + * @return true if handler existed and was removed + */ + bool CancelEvent(uint64 handlerId); + + /** + * @brief Cancel all handlers for a global event + * @tparam EventEnum Event type enum + * @param eventType Event enum value + */ + template + void CancelGlobalEvent(EventEnum eventType); + + /** + * @brief Cancel all handlers for an entry event + * @tparam EventEnum Event type enum + * @param eventType Event enum value + * @param entry Template entry ID + */ + template + void CancelEntryEvent(EventEnum eventType, uint32 entry); + + /** + * @brief Cancel all handlers for a unique event + * @tparam EventEnum Event type enum + * @param eventType Event enum value + * @param guid Object GUID + */ + template + void CancelUniqueEvent(EventEnum eventType, uint64 guid); + + /** + * @brief Cancel all events for a specific state + * @param stateId State ID to clean up + */ + void CancelStateEvents(int32 stateId); + + /** + * @brief Cancel ALL registered events (shutdown) + */ + void CancelAllEvents(); + + /** + * @brief Trigger a global event (hot path) + * + * Executes all registered handlers for this event type. + * Removes expired handlers after execution. + * + * @tparam EventEnum Event type enum + * @tparam Args Variadic argument types for Lua callback + * @param eventType Event enum value + * @param args Arguments forwarded to Lua callbacks + * @return Number of handlers successfully executed + */ + template + uint32 TriggerGlobalEvent(EventEnum eventType, Args&&... args); + + /** + * @brief Trigger an entry event (hot path) + * + * @tparam EventEnum Event type enum + * @tparam Args Variadic argument types for Lua callback + * @param eventType Event enum value + * @param entry Template entry ID + * @param args Arguments forwarded to Lua callbacks + * @return Number of handlers successfully executed + */ + template + uint32 TriggerEntryEvent(EventEnum eventType, uint32 entry, Args&&... args); + + /** + * @brief Trigger a unique instance event (hot path) + * + * @tparam EventEnum Event type enum + * @tparam Args Variadic argument types for Lua callback + * @param eventType Event enum value + * @param guid Object GUID + * @param args Arguments forwarded to Lua callbacks + * @return Number of handlers successfully executed + */ + template + uint32 TriggerUniqueEvent(EventEnum eventType, uint64 guid, Args&&... args); + + /** + * @brief Trigger global event with return value capture + * + * Executes all handlers and captures return value from LAST successful handler. + * Use case: Events that modify values (e.g., OnGiveXP returning modified amount). + * + * @tparam ReturnType Type of return value to capture + * @tparam EventEnum Event type enum + * @tparam Args Variadic argument types for Lua callback + * @param eventType Event enum value + * @param defaultValue Default return value if no handlers execute + * @param args Arguments forwarded to Lua callbacks + * @return Last valid return value from Lua, or defaultValue if none + */ + template + ReturnType TriggerGlobalEventWithReturn(EventEnum eventType, ReturnType defaultValue, Args&&... args); + + /** + * @brief Trigger entry event with return value capture + * + * @tparam ReturnType Type of return value to capture + * @tparam EventEnum Event type enum + * @tparam Args Variadic argument types for Lua callback + * @param eventType Event enum value + * @param entry Template entry ID + * @param defaultValue Default return value if no handlers execute + * @param args Arguments forwarded to Lua callbacks + * @return Last valid return value from Lua, or defaultValue if none + */ + template + ReturnType TriggerEntryEventWithReturn(EventEnum eventType, uint32 entry, ReturnType defaultValue, Args&&... args); + + private: + // Handler storage: vector for cache locality, pair for tracking + using GlobalHandlerMap = std::unordered_map>>; + using EntryHandlerMap = std::unordered_map>>; + using UniqueHandlerMap = std::unordered_map>>; + + GlobalHandlerMap m_globalHandlers; // < Global event storage + EntryHandlerMap m_entryHandlers; // < Entry-based event storage + UniqueHandlerMap m_uniqueHandlers; // < Unique instance event storage + + uint64 m_nextHandlerId; // < Monotonic counter for unique IDs + bool m_initialized; // < Initialization state + + /** + * @brief Generate next unique handler ID + * @return Monotonically increasing ID + */ + uint64 GenerateHandlerId() { return m_nextHandlerId++; } + + /** + * @brief Execute a handler and update its state + * @tparam Args Variadic argument types + * @param handler Handler to execute + * @param args Arguments to forward to Lua + * @return true if execution succeeded (not expired) + */ + template + bool ExecuteHandler(EventHandler& handler, Args&&... args); + + /** + * @brief Remove expired handlers from a vector (batch cleanup) + * @tparam T Handler type (EventHandler) + * @param handlers Vector of pairs + */ + template + void RemoveExpiredHandlers(std::vector>& handlers); + + /** + * @brief Helper: Find and cancel handler by ID in a map (DRY) + * @tparam MapType Handler map type (GlobalHandlerMap, EntryHandlerMap, UniqueHandlerMap) + * @param handlerMap Map to search + * @param handlerId Handler ID to find + * @param logType Type name for logging ("global", "entry", "unique") + * @return true if handler found and cancelled + */ + template + bool FindAndCancelHandler(MapType& handlerMap, uint64 handlerId, const char* logType); + + /** + * @brief Helper: Cancel all handlers for a state in a map (DRY) + * @tparam MapType Handler map type + * @param handlerMap Map to process + * @param stateId State ID to match + * @return Number of handlers cancelled + */ + template + size_t CancelStateHandlersInMap(MapType& handlerMap, int32 stateId); + }; + + /** + * @brief Trigger global event + * + */ + template + uint32 EventManager::TriggerGlobalEvent(EventEnum eventType, Args&&... args) + { + GlobalEventKey key{ typeid(EventEnum).hash_code(), static_cast(eventType) }; + + // Early exit: no handlers registered + auto it = m_globalHandlers.find(key); + if (it == m_globalHandlers.end()) + { + return 0; + } + + // Execute all handlers for this event + uint32 executed = 0; + auto& handlers = it->second; + + for (auto& [handlerId, handler] : handlers) + { + if (ExecuteHandler(handler, std::forward(args)...)) + { + executed++; + } + } + + // Batch remove expired handlers (shot limit reached) + RemoveExpiredHandlers(handlers); + + return executed; + } + + /** + * @brief Trigger entry event + */ + template + uint32 EventManager::TriggerEntryEvent(EventEnum eventType, uint32 entry, Args&&... args) + { + EntryEventKey key{ typeid(EventEnum).hash_code(), static_cast(eventType), entry }; + + auto it = m_entryHandlers.find(key); + if (it == m_entryHandlers.end()) + { + return 0; + } + + uint32 executed = 0; + auto& handlers = it->second; + + for (auto& [handlerId, handler] : handlers) + { + if (ExecuteHandler(handler, std::forward(args)...)) + { + executed++; + } + } + + RemoveExpiredHandlers(handlers); + + return executed; + } + + /** + * @brief Trigger unique event + */ + template + uint32 EventManager::TriggerUniqueEvent(EventEnum eventType, uint64 guid, Args&&... args) + { + UniqueEventKey key{ typeid(EventEnum).hash_code(), static_cast(eventType), guid }; + + auto it = m_uniqueHandlers.find(key); + if (it == m_uniqueHandlers.end()) + return 0; + + uint32 executed = 0; + auto& handlers = it->second; + + for (auto& [handlerId, handler] : handlers) + { + if (ExecuteHandler(handler, std::forward(args)...)) + { + executed++; + } + } + + RemoveExpiredHandlers(handlers); + + return executed; + } + + /** + * @brief Execute handler with Lua error handling + */ + template + bool EventManager::ExecuteHandler(EventHandler& handler, Args&&... args) + { + if (!handler.ShouldExecute()) + return false; + + try + { + auto result = handler.function(std::forward(args)...); + if (!result.valid()) + { + sol::error err = result; + // Errors logged by sol2, just track execution + return false; + } + + handler.callCount++; + return true; + } + catch (const std::exception&) + { + // Exception logged by sol2 + return false; + } + } + + /** + * @brief Batch remove expired handlers + */ + template + void EventManager::RemoveExpiredHandlers(std::vector>& handlers) + { + handlers.erase( + std::remove_if(handlers.begin(), handlers.end(), + [](const auto& pair) { return pair.second.IsExpired(); }), + handlers.end() + ); + } + + /** + * @brief Register global event + */ + template + uint64 EventManager::RegisterGlobalEvent(EventEnum eventType, sol::protected_function&& handler, uint32 shots, int32 stateId) + { + GlobalEventKey key{ typeid(EventEnum).hash_code(), static_cast(eventType) }; + uint64 handlerId = GenerateHandlerId(); + + // Emplace handler + m_globalHandlers[key].emplace_back(handlerId, EventHandler(std::move(handler), shots, stateId)); + + return handlerId; + } + + /** + * @brief Register entry event + */ + template + uint64 EventManager::RegisterEntryEvent(EventEnum eventType, uint32 entry, sol::protected_function&& handler, uint32 shots, int32 stateId) + { + EntryEventKey key{ typeid(EventEnum).hash_code(), static_cast(eventType), entry }; + uint64 handlerId = GenerateHandlerId(); + + // Emplace handler + m_entryHandlers[key].emplace_back(handlerId, EventHandler(std::move(handler), shots, stateId)); + + return handlerId; + } + + /** + * @brief Register unique event + */ + template + uint64 EventManager::RegisterUniqueEvent(EventEnum eventType, uint64 guid, sol::protected_function&& handler, uint32 shots, int32 stateId) + { + UniqueEventKey key{ typeid(EventEnum).hash_code(), static_cast(eventType), guid }; + uint64 handlerId = GenerateHandlerId(); + + // Emplace handler + m_uniqueHandlers[key].emplace_back(handlerId, EventHandler(std::move(handler), shots, stateId)); + + return handlerId; + } + + /** + * @brief Cancel global event - cleanup all handlers + */ + template + void EventManager::CancelGlobalEvent(EventEnum eventType) + { + GlobalEventKey key{ typeid(EventEnum).hash_code(), static_cast(eventType) }; + auto it = m_globalHandlers.find(key); + + if (it != m_globalHandlers.end()) + m_globalHandlers.erase(it); + } + + /** + * @brief Cancel entry event - cleanup all handlers + */ + template + void EventManager::CancelEntryEvent(EventEnum eventType, uint32 entry) + { + EntryEventKey key{ typeid(EventEnum).hash_code(), static_cast(eventType), entry }; + auto it = m_entryHandlers.find(key); + + if (it != m_entryHandlers.end()) + { + m_entryHandlers.erase(it); + } + } + + /** + * @brief Cancel unique event - cleanup all handlers + */ + template + void EventManager::CancelUniqueEvent(EventEnum eventType, uint64 guid) + { + UniqueEventKey key{ typeid(EventEnum).hash_code(), static_cast(eventType), guid }; + auto it = m_uniqueHandlers.find(key); + + if (it != m_uniqueHandlers.end()) + { + m_uniqueHandlers.erase(it); + } + } + + /** + * @brief Helper: Find and cancel handler in map + */ + template + bool EventManager::FindAndCancelHandler(MapType& handlerMap, uint64 handlerId, const char* logType) + { + for (auto& [key, handlers] : handlerMap) + { + auto it = std::find_if(handlers.begin(), handlers.end(), + [handlerId](const auto& pair) { return pair.first == handlerId; }); + + if (it != handlers.end()) + { + handlers.erase(it); + LOG_INFO("eclipse.events", "[Eclipse] EventManager - Cancelled {} event handler {}", logType, handlerId); + return true; + } + } + return false; + } + + /** + * @brief Helper: Cancel state handlers in map + */ + template + size_t EventManager::CancelStateHandlersInMap(MapType& handlerMap, int32 stateId) + { + size_t totalCancelled = 0; + for (auto& [key, handlers] : handlerMap) + { + auto originalSize = handlers.size(); + handlers.erase( + std::remove_if(handlers.begin(), handlers.end(), + [stateId](const auto& pair) { return pair.second.stateId == stateId; }), + handlers.end() + ); + auto cancelled = originalSize - handlers.size(); + totalCancelled += cancelled; + } + return totalCancelled; + } + + /** + * @brief Trigger global event with return value capture + * + * Executes all handlers sequentially. If a handler returns a value, + * that value becomes the new returnValue (last handler wins). + */ + template + ReturnType EventManager::TriggerGlobalEventWithReturn(EventEnum eventType, ReturnType defaultValue, Args&&... args) + { + GlobalEventKey key{ typeid(EventEnum).hash_code(), static_cast(eventType) }; + + auto it = m_globalHandlers.find(key); + if (it == m_globalHandlers.end()) + { + return defaultValue; + } + + ReturnType returnValue = defaultValue; + uint32 executed = 0; + auto& handlers = it->second; + + for (auto& [handlerId, handler] : handlers) + { + if (!handler.ShouldExecute()) + continue; + + try + { + auto result = handler.function(std::forward(args)...); + if (!result.valid()) + { + sol::error err = result; + LOG_ERROR("eclipse.events", "[Eclipse] EventManager - Lua error in handler {}: {}", handlerId, err.what()); + continue; + } + + handler.callCount++; + executed++; + + // Try to extract return value from Lua result + if (result.return_count() > 0) + { + sol::optional luaReturn = result; + if (luaReturn) + returnValue = *luaReturn; + } + } + catch (const std::exception& e) + { + LOG_ERROR("eclipse.events", "[Eclipse] EventManager - Exception in handler {}: {}", handlerId, e.what()); + } + } + + RemoveExpiredHandlers(handlers); + + return returnValue; + } + + /** + * @brief Trigger entry event with return value capture + */ + template + ReturnType EventManager::TriggerEntryEventWithReturn(EventEnum eventType, uint32 entry, ReturnType defaultValue, Args&&... args) + { + EntryEventKey key{ typeid(EventEnum).hash_code(), static_cast(eventType), entry }; + + auto it = m_entryHandlers.find(key); + if (it == m_entryHandlers.end()) + return defaultValue; + + ReturnType returnValue = defaultValue; + uint32 executed = 0; + auto& handlers = it->second; + + for (auto& [handlerId, handler] : handlers) + { + if (!handler.ShouldExecute()) + continue; + + try + { + auto result = handler.function(std::forward(args)...); + if (!result.valid()) + { + sol::error err = result; + LOG_ERROR("eclipse.events", "[Eclipse] EventManager - Lua error in entry handler {}: {}", handlerId, err.what()); + continue; + } + + handler.callCount++; + executed++; + + // Try to extract return value from Lua result + if (result.return_count() > 0) + { + sol::optional luaReturn = result; + if (luaReturn) + returnValue = *luaReturn; + } + } + catch (const std::exception& e) + { + LOG_ERROR("eclipse.events", "[Eclipse] EventManager - Exception in entry handler {}: {}", handlerId, e.what()); + } + } + + RemoveExpiredHandlers(handlers); + + return returnValue; + } + +} // namespace Eclipse::Core + +#endif // _ECLIPSE_EVENT_MANAGER_H diff --git a/src/LuaEngine/Events/TimedEventManager.cpp b/src/LuaEngine/Events/TimedEventManager.cpp new file mode 100644 index 0000000000..dafd6c0479 --- /dev/null +++ b/src/LuaEngine/Events/TimedEventManager.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#include "TimedEventManager.h" +#include "Player.h" +#include "Creature.h" +#include "GameObject.h" +#include "Log.h" + +namespace Eclipse::Core +{ + TimedEventManager::TimedEventManager(int32 mapId) : m_nextEventId(1), m_mapId(mapId) + { + m_globalEvents.reserve(16); + m_eventsToRemove.reserve(8); + } + + TimedEventManager::~TimedEventManager() + { + Clear(); + } + + uint64 TimedEventManager::RegisterGlobalEvent(sol::protected_function&& callback, uint32 delay, uint32 repeats) + { + uint64 eventId = m_nextEventId++; + + m_events.emplace(eventId, TimedEvent(eventId, std::move(callback), delay, repeats)); + m_globalEvents.push_back(eventId); + + LOG_DEBUG("scripts.eclipse", "Registered global event {} (delay={}ms, repeats={})", + eventId, delay, repeats); + + return eventId; + } + + uint64 TimedEventManager::RegisterObjectEvent(ObjectGuid objectGuid, sol::protected_function&& callback, uint32 delay, uint32 repeats, TimedEventObjectType objectType) + { + uint64 eventId = m_nextEventId++; + + m_events.emplace(eventId, TimedEvent(eventId, std::move(callback), delay, repeats, objectGuid, objectType)); + + m_objectEvents[objectGuid].push_back(eventId); + + LOG_DEBUG("scripts.eclipse", "Registered object event {} for GUID {} (type={}, delay={}ms, repeats={})", + eventId, objectGuid.ToString(), static_cast(objectType), delay, repeats); + + return eventId; + } + + bool TimedEventManager::RemoveEvent(uint64 eventId) + { + auto eventIt = m_events.find(eventId); + if (eventIt == m_events.end()) + return false; // Event not found + + const TimedEvent& event = eventIt->second; + + // Remove from appropriate index + if (event.objectType == TimedEventObjectType::GLOBAL) + { + // Remove from global events list + auto it = std::find(m_globalEvents.begin(), m_globalEvents.end(), eventId); + if (it != m_globalEvents.end()) + { + std::swap(*it, m_globalEvents.back()); + m_globalEvents.pop_back(); + } + } + else + { + // Remove from object events index + auto objIt = m_objectEvents.find(event.objectGuid); + if (objIt != m_objectEvents.end()) + { + auto& eventList = objIt->second; + auto it = std::find(eventList.begin(), eventList.end(), eventId); + if (it != eventList.end()) + { + std::swap(*it, eventList.back()); + eventList.pop_back(); + } + + if (eventList.empty()) + m_objectEvents.erase(objIt); + } + } + + // Remove event from main storage + m_events.erase(eventIt); + + LOG_DEBUG("scripts.eclipse", "Removed event {}", eventId); + return true; + } + + void TimedEventManager::RemoveObjectEvents(ObjectGuid objectGuid) + { + auto it = m_objectEvents.find(objectGuid); + if (it == m_objectEvents.end()) + return; // No events for this object + + // Remove all events for this object from main storage + for (uint64 eventId : it->second) + m_events.erase(eventId); + + LOG_DEBUG("scripts.eclipse", "Removed {} events for object {}", it->second.size(), objectGuid.ToString()); + + // Remove object entry from index + m_objectEvents.erase(it); + } + + void TimedEventManager::RemoveAllGlobalEvents() + { + // Remove all global events from main storage + for (uint64 eventId : m_globalEvents) + m_events.erase(eventId); + + LOG_DEBUG("scripts.eclipse", "Removed {} global events", m_globalEvents.size()); + + m_globalEvents.clear(); + } + + void TimedEventManager::Update(uint32 diff) + { + // Early exit: No global events to update + if (m_globalEvents.empty()) + return; + + // Clear removal buffer (reuse allocation from previous frame) + m_eventsToRemove.clear(); + + // Update only global events (object events updated via UpdateObjectEvents) + for (uint64 eventId : m_globalEvents) + { + auto eventIt = m_events.find(eventId); + if (eventIt == m_events.end()) + continue; // Event was removed externally + + TimedEvent& event = eventIt->second; + event.elapsed += diff; + + // Check if ready to execute + if (event.elapsed >= event.delay) + { + ExecuteEvent(event, nullptr); // nullptr = no object (global event) + + // Reset timer for next iteration + event.elapsed = 0; + + // Handle repeat count + if (event.repeats > 0) + { + event.remainingRepeats--; + if (event.remainingRepeats == 0) + m_eventsToRemove.push_back(eventId); + } + } + } + + // Batch remove expired events + for (uint64 eventId : m_eventsToRemove) + RemoveEvent(eventId); + } + + void TimedEventManager::UpdateObjectEvents(WorldObject* obj, uint32 diff) + { + // Null check + if (!obj) + return; + + // Early exit: No events for this object + ObjectGuid guid = obj->GetGUID(); + auto objEventsIt = m_objectEvents.find(guid); + if (objEventsIt == m_objectEvents.end()) + { + return; + } + + // Clear removal buffer + m_eventsToRemove.clear(); + + // Update events for this specific object + for (uint64 eventId : objEventsIt->second) + { + auto eventIt = m_events.find(eventId); + if (eventIt == m_events.end()) + { + continue; // Event was removed externally + } + + TimedEvent& event = eventIt->second; + event.elapsed += diff; + + // Check if ready to execute + if (event.elapsed >= event.delay) + { + ExecuteEvent(event, obj); // Pass object to callback + + // Reset timer for next iteration + event.elapsed = 0; + + // Handle repeat count + if (event.repeats > 0) + { + event.remainingRepeats--; + if (event.remainingRepeats == 0) + { + m_eventsToRemove.push_back(eventId); + } + } + } + } + + // Batch remove expired events + for (uint64 eventId : m_eventsToRemove) + { + RemoveEvent(eventId); + } + } + + void TimedEventManager::ExecuteEvent(TimedEvent& event, WorldObject* obj) + { + try + { + sol::protected_function_result result; + + // Dispatch based on object type + switch (event.objectType) + { + case TimedEventObjectType::GLOBAL: + // Global event: callback(eventId, delay, repeats) + result = event.callback(event.id, event.delay, event.repeats); + break; + + case TimedEventObjectType::PLAYER: + { + if (!obj) + return; + + Player* player = obj->ToPlayer(); + if (!player) + return; + + // Player event: callback(eventId, delay, repeats, player) + result = event.callback(event.id, event.delay, event.repeats, player); + break; + } + + case TimedEventObjectType::CREATURE: + { + if (!obj) + return; + + Creature* creature = obj->ToCreature(); + if (!creature) + return; + + // Creature event: callback(eventId, delay, repeats, creature) + result = event.callback(event.id, event.delay, event.repeats, creature); + break; + } + + case TimedEventObjectType::GAMEOBJECT: + { + if (!obj) + return; + + GameObject* gameobject = obj->ToGameObject(); + if (!gameobject) + return; + + // GameObject event: callback(eventId, delay, repeats, gameobject) + result = event.callback(event.id, event.delay, event.repeats, gameobject); + break; + } + } + + // Check for Lua errors + if (!result.valid()) + { + sol::error err = result; + LOG_ERROR("scripts.eclipse", "Event {} callback error: {}", event.id, err.what()); + } + } + catch (const std::exception& e) + { + LOG_ERROR("scripts.eclipse", "Event {} exception: {}", event.id, e.what()); + } + } + + uint32 TimedEventManager::GetObjectEventCount(ObjectGuid objectGuid) const + { + auto it = m_objectEvents.find(objectGuid); + return it != m_objectEvents.end() ? static_cast(it->second.size()) : 0; + } + + void TimedEventManager::Clear() + { + m_events.clear(); + m_objectEvents.clear(); + m_globalEvents.clear(); + m_eventsToRemove.clear(); + m_nextEventId = 1; + + LOG_DEBUG("scripts.eclipse", "Cleared all timed events (mapId={})", m_mapId); + } + +} // namespace Eclipse::Core diff --git a/src/LuaEngine/Events/TimedEventManager.h b/src/LuaEngine/Events/TimedEventManager.h new file mode 100644 index 0000000000..c2f349a670 --- /dev/null +++ b/src/LuaEngine/Events/TimedEventManager.h @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _ECLIPSE_TIMED_EVENT_MANAGER_H +#define _ECLIPSE_TIMED_EVENT_MANAGER_H + +#include +#include +#include +#include "ObjectGuid.h" +#include "Object.h" + +namespace Eclipse::Core +{ + /** + * @enum TimedEventObjectType + * @brief Defines the type of object associated with a timed event + * + * Used to determine how event callbacks are invoked and what arguments are passed. + */ + enum class TimedEventObjectType : uint8 + { + GLOBAL, ///< Global event, no object association + PLAYER, ///< Player-specific event + CREATURE, ///< Creature-specific event + GAMEOBJECT ///< GameObject-specific event + }; + + /** + * @struct TimedEvent + * @brief Represents a scheduled Lua callback with delay and repeat configuration + * + * Stores all state needed to track and execute a timed event. Events can be: + * - Global: Executed at world-level (CreateLuaEvent) + * - Object-bound: Executed in context of a specific Player/Creature/GameObject + */ + struct TimedEvent + { + uint64 id; ///< Unique event identifier (monotonically increasing) + sol::protected_function callback; ///< Lua callback function (moved, not copied) + uint32 delay; ///< Delay between executions in milliseconds + uint32 repeats; ///< Total repeats (0 = infinite) + uint32 remainingRepeats; ///< Repeats left before expiration + uint32 elapsed; ///< Accumulated time since last execution (ms) + ObjectGuid objectGuid; ///< Associated object GUID (Empty for global) + TimedEventObjectType objectType; ///< Object type discriminator + + /** + * @brief Construct a timed event + * @param eventId Unique event ID + * @param cb Lua callback (moved for performance) + * @param delayMs Delay in milliseconds + * @param repeatCount Number of repeats (0 = infinite) + * @param guid Object GUID (default: Empty for global events) + * @param type Object type (default: GLOBAL) + */ + TimedEvent(uint64 eventId, sol::protected_function&& cb, uint32 delayMs, uint32 repeatCount, ObjectGuid guid = ObjectGuid::Empty, TimedEventObjectType type = TimedEventObjectType::GLOBAL) + : id(eventId), callback(std::move(cb)), delay(delayMs), repeats(repeatCount) + , remainingRepeats(repeatCount), elapsed(0), objectGuid(guid), objectType(type) + { + } + }; + + /** + * @class TimedEventManager + * @brief High-performance timed event scheduler for Lua callbacks + */ + class TimedEventManager + { + public: + explicit TimedEventManager(int32 mapId); + ~TimedEventManager(); + + /** + * @brief Register a global timed event (CreateLuaEvent) + * + * Global events run independently of any game object. Ideal for: + * - World-level timers + * - Periodic server announcements + * - Background cleanup tasks + * + * @param callback Lua function: function(eventId, delay, repeats) + * @param delay Delay in milliseconds between executions + * @param repeats Number of times to execute (0 = infinite) + * @return Unique event ID for cancellation + */ + uint64 RegisterGlobalEvent(sol::protected_function&& callback, uint32 delay, uint32 repeats); + + /** + * @brief Register an object-bound timed event (player:RegisterEvent, etc.) + * + * Object events are executed with the object as context. Used for: + * - Player buffs/debuffs + * - Creature AI timers + * - GameObject state changes + * + * @param objectGuid GUID of the object (Player, Creature, GameObject) + * @param callback Lua function: function(eventId, delay, repeats, object) + * @param delay Delay in milliseconds between executions + * @param repeats Number of times to execute (0 = infinite) + * @param objectType Type discriminator (PLAYER, CREATURE, GAMEOBJECT) + * @return Unique event ID for cancellation + */ + uint64 RegisterObjectEvent(ObjectGuid objectGuid, sol::protected_function&& callback, uint32 delay, uint32 repeats, TimedEventObjectType objectType); + + /** + * @brief Cancel a specific timed event + * @param eventId Event ID returned by Register*Event + * @return true if event existed and was removed, false if not found + */ + bool RemoveEvent(uint64 eventId); + + /** + * @brief Cancel all events associated with an object + * + * Called when object is destroyed or despawned to prevent dangling callbacks. + * + * @param objectGuid GUID of the object to clean up + */ + void RemoveObjectEvents(ObjectGuid objectGuid); + + /** + * @brief Cancel all global events + */ + void RemoveAllGlobalEvents(); + + /** + * @brief Update all global timed events (hot path) + * + * Called every tick from WorldHooks::OnUpdate. + * + * @param diff Time elapsed since last update (milliseconds) + */ + void Update(uint32 diff); + + /** + * @brief Update events for a specific object (hot path) + * + * Called from object-specific hooks (OnPlayerUpdate, OnCreatureUpdate, etc.). + * Object is passed directly. + * + * @param obj WorldObject to update events for + * @param diff Time elapsed since last update (milliseconds) + */ + void UpdateObjectEvents(WorldObject* obj, uint32 diff); + + /** + * @brief Get total number of active timed events + * @return Count of all events (global + object) + */ + uint32 GetActiveEventCount() const { return static_cast(m_events.size()); } + + /** + * @brief Get number of active global events + * @return Count of global events only + */ + uint32 GetGlobalEventCount() const { return static_cast(m_globalEvents.size()); } + + /** + * @brief Get number of events for a specific object + * @param objectGuid GUID to query + * @return Count of events for this object + */ + uint32 GetObjectEventCount(ObjectGuid objectGuid) const; + + /** + * @brief Clear all events (shutdown) + * + * Releases all Lua callback references and clears internal structures. + */ + void Clear(); + + private: + TimedEventManager(const TimedEventManager&) = delete; + TimedEventManager& operator=(const TimedEventManager&) = delete; + TimedEventManager(TimedEventManager&&) = delete; + TimedEventManager& operator=(TimedEventManager&&) = delete; + + /** + * @brief Execute a timed event callback + * @param event Event to execute + * @param obj Object context (nullptr for global events) + */ + void ExecuteEvent(TimedEvent& event, WorldObject* obj = nullptr); + + // Storage: Events by ID for fast lookup/removal + std::unordered_map m_events; + + // Index: Events by object GUID for UpdateObjectEvents + std::unordered_map> m_objectEvents; + + // List: Global event IDs for Update + std::vector m_globalEvents; + + // Reusable buffer: Events to remove + std::vector m_eventsToRemove; + + uint64 m_nextEventId; // < Monotonic counter for unique IDs + int32 m_mapId; // < Map ID this manager belongs to + }; + +} // namespace Eclipse::Core + +#endif // _ECLIPSE_TIMED_EVENT_MANAGER_H diff --git a/src/LuaEngine/HookHelpers.h b/src/LuaEngine/HookHelpers.h deleted file mode 100644 index 557f7531b9..0000000000 --- a/src/LuaEngine/HookHelpers.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * This program is free software licensed under GPL version 3 - * Please see the included DOCS/LICENSE.md for more information - */ - -#ifndef _HOOK_HELPERS_H -#define _HOOK_HELPERS_H - -#include "LuaEngine.h" -#include "ALEUtility.h" - -/* - * Sets up the stack so that event handlers can be called. - * - * Returns the number of functions that were pushed onto the stack. - */ -template -int ALE::SetupStack(BindingMap* bindings1, BindingMap* bindings2, const K1& key1, const K2& key2, int number_of_arguments) -{ - ASSERT(number_of_arguments == this->push_counter); - ASSERT(key1.event_id == key2.event_id); - // Stack: [arguments] - - Push(key1.event_id); - this->push_counter = 0; - ++number_of_arguments; - // Stack: [arguments], event_id - - int arguments_top = lua_gettop(L); - int first_argument_index = arguments_top - number_of_arguments + 1; - ASSERT(arguments_top >= number_of_arguments); - - lua_insert(L, first_argument_index); - // Stack: event_id, [arguments] - - bindings1->PushRefsFor(key1); - if (bindings2) - bindings2->PushRefsFor(key2); - // Stack: event_id, [arguments], [functions] - - int number_of_functions = lua_gettop(L) - arguments_top; - return number_of_functions; -} - -/* - * Replace one of the arguments pushed before `SetupStack` with a new value. - */ -template -void ALE::ReplaceArgument(T value, uint8 index) -{ - ASSERT(index < lua_gettop(L) && index > 0); - // Stack: event_id, [arguments], [functions], [results] - - ALE::Push(L, value); - // Stack: event_id, [arguments], [functions], [results], value - - lua_replace(L, index + 1); - // Stack: event_id, [arguments and value], [functions], [results] -} - -/* - * Call all event handlers registered to the event ID/entry combination and ignore any results. - */ -template -void ALE::CallAllFunctions(BindingMap* bindings1, BindingMap* bindings2, const K1& key1, const K2& key2) -{ - int number_of_arguments = this->push_counter; - // Stack: [arguments] - - int number_of_functions = SetupStack(bindings1, bindings2, key1, key2, number_of_arguments); - // Stack: event_id, [arguments], [functions] - - while (number_of_functions > 0) - { - CallOneFunction(number_of_functions, number_of_arguments, 0); - --number_of_functions; - // Stack: event_id, [arguments], [functions - 1] - } - // Stack: event_id, [arguments] - - CleanUpStack(number_of_arguments); - // Stack: (empty) -} - -/* - * Call all event handlers registered to the event ID/entry combination, - * and returns `default_value` if ALL event handlers returned `default_value`, - * otherwise returns the opposite of `default_value`. - */ -template -bool ALE::CallAllFunctionsBool(BindingMap* bindings1, BindingMap* bindings2, const K1& key1, const K2& key2, bool default_value/* = false*/) -{ - bool result = default_value; - // Note: number_of_arguments here does not count in eventID, which is pushed in SetupStack - int number_of_arguments = this->push_counter; - // Stack: [arguments] - - int number_of_functions = SetupStack(bindings1, bindings2, key1, key2, number_of_arguments); - // Stack: event_id, [arguments], [functions] - - while (number_of_functions > 0) - { - int r = CallOneFunction(number_of_functions, number_of_arguments, 1); - --number_of_functions; - // Stack: event_id, [arguments], [functions - 1], result - - if (lua_isboolean(L, r) && (lua_toboolean(L, r) == 1) != default_value) - result = !default_value; - - lua_pop(L, 1); - // Stack: event_id, [arguments], [functions - 1] - } - // Stack: event_id, [arguments] - - CleanUpStack(number_of_arguments); - // Stack: (empty) - return result; -} - -#endif // _HOOK_HELPERS_H diff --git a/src/LuaEngine/Hooks.h b/src/LuaEngine/Hooks.h deleted file mode 100644 index f871986b2d..0000000000 --- a/src/LuaEngine/Hooks.h +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * This program is free software licensed under GPL version 3 - * Please see the included DOCS/LICENSE.md for more information - */ - -#ifndef _HOOKS_H -#define _HOOKS_H - -/* - * A hook should be written in one of the following forms: - * - * A. If results will be IGNORED: - * - * // Return early if there are no bindings. - * if (!WhateverBindings->HasBindingsFor(SOME_EVENT_TYPE)) - * return; - * - * // Lock out any other threads. - * LOCK_ALE; - * - * // Push extra arguments, if any. - * Push(a); - * Push(b); - * Push(c); - * - * // Call all event handlers. - * CallAllFunctions(WhateverBindings, SOME_EVENT_TYPE); - * - * - * B. If results will be USED: - * - * // Return early if there are no bindings. - * if (!WhateverBindings->HasBindingsFor(SOME_EVENT_TYPE)) - * return; - * - * // Lock out any other threads. - * LOCK_ALE; - * - * // Push extra arguments, if any. - * Push(a); - * Push(b); - * Push(c); - * - * // Setup the stack and get the number of functions pushed. - * // Last argument is 3 because we did 3 Pushes. - * int n = SetupStack(WhateverBindings, SOME_EVENT_TYPE, 3); - * - * // Call each event handler in order and check results. - * while (n > 0) - * { - * // Call an event handler and decrement the function counter afterward. - * // Second-last argument is 3 because we did 3 Pushes. - * // Last argument is 2 because we want 2 results. - * int r = CallOneFunction(n--, 3, 2); - * - * // Results can be popped using `r`. - * int first = CHECKVAL(L, r + 0); - * int second = CHECKVAL(L, r + 1); - * - * // Pop the results off the stack. - * lua_pop(L, 2); - * } - * - * // Clean-up the stack. Argument is 3 because we did 3 Pushes. - * CleanUpStack(3); - */ - -namespace Hooks -{ - 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_BG, - REGTYPE_MAP, - REGTYPE_INSTANCE, - REGTYPE_TICKET, - REGTYPE_SPELL, - REGTYPE_ALL_CREATURE, - REGTYPE_COUNT - }; - - enum PacketEvents - { - PACKET_EVENT_ON_PACKET_RECEIVE = 5, // (event, packet, player) - Player only if accessible. Can return false, newPacket - 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, newPacket - - PACKET_EVENT_COUNT - }; - - 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, newPacket - 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, newPacket - - // World - WORLD_EVENT_ON_OPEN_STATE_CHANGE = 8, // (event, open) - Needs core support on Mangos - WORLD_EVENT_ON_CONFIG_LOAD = 9, // (event, reload) - // UNUSED = 10, - 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) - - // ALE - ALE_EVENT_ON_LUA_STATE_CLOSE = 16, // (event) - triggers just before shutting down ALE (on shutdown and restart) - - // 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) - - // Area trigger - TRIGGER_EVENT_ON_TRIGGER = 24, // (event, player, triggerId) - Can return true - - // Weather - WEATHER_EVENT_ON_CHANGE = 25, // (event, zoneId, state, grade) - - // Auction house - AUCTION_EVENT_ON_ADD = 26, // (event, auctionId, owner, item, expireTime, buyout, startBid, currentBid, bidderGUIDLow) - AUCTION_EVENT_ON_REMOVE = 27, // (event, auctionId, owner, item, expireTime, buyout, startBid, currentBid, bidderGUIDLow) - AUCTION_EVENT_ON_SUCCESSFUL = 28, // (event, auctionId, owner, item, expireTime, buyout, startBid, currentBid, bidderGUIDLow) - AUCTION_EVENT_ON_EXPIRE = 29, // (event, auctionId, owner, item, expireTime, buyout, startBid, currentBid, bidderGUIDLow) - - // AddOns - ADDON_EVENT_ON_MESSAGE = 30, // (event, sender, type, prefix, msg, target) - target can be nil/whisper_target/guild/group/channel. Can return false - - WORLD_EVENT_ON_DELETE_CREATURE = 31, // (event, creature) - WORLD_EVENT_ON_DELETE_GAMEOBJECT = 32, // (event, gameobject) - - // ALE - ALE_EVENT_ON_LUA_STATE_OPEN = 33, // (event) - triggers after all scripts are loaded - - GAME_EVENT_START = 34, // (event, gameeventid) - GAME_EVENT_STOP = 35, // (event, gameeventid) - - SERVER_EVENT_COUNT - }; - - 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, source) - Can return new XP amount - PLAYER_EVENT_ON_LEVEL_CHANGE = 13, // (event, player, oldLevel) - PLAYER_EVENT_ON_MONEY_CHANGE = 14, // (event, player, amount) - Can return new money amount - PLAYER_EVENT_ON_REPUTATION_CHANGE = 15, // (event, player, factionId, standing, incremental) - Can return new standing -> if standing == -1, it will prevent default action (rep gain) - 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, newMessage - PLAYER_EVENT_ON_WHISPER = 19, // (event, player, msg, Type, lang, receiver) - Can return false, newMessage - PLAYER_EVENT_ON_GROUP_CHAT = 20, // (event, player, msg, Type, lang, group) - Can return false, newMessage - PLAYER_EVENT_ON_GUILD_CHAT = 21, // (event, player, msg, Type, lang, guild) - Can return false, newMessage - PLAYER_EVENT_ON_CHANNEL_CHAT = 22, // (event, player, msg, Type, lang, channel) - channel is negative for custom channels. Can return false, newMessage - 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) - - // 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) - Can return InventoryResult enum value - 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) - PLAYER_EVENT_ON_LEARN_TALENTS = 39, // (event, player, talentId, talentRank, spellid) - // UNUSED = 40, // (event, player) - // UNUSED = 41, // (event, player) - PLAYER_EVENT_ON_COMMAND = 42, // (event, player, command, chatHandler) - player is nil if command used from console. Can return false - PLAYER_EVENT_ON_PET_ADDED_TO_WORLD = 43, // (event, player, pet) - PLAYER_EVENT_ON_LEARN_SPELL = 44, // (event, player, spellId) - PLAYER_EVENT_ON_ACHIEVEMENT_COMPLETE = 45, // (event, player, achievement) - PLAYER_EVENT_ON_FFAPVP_CHANGE = 46, // (event, player, hasFfaPvp) - PLAYER_EVENT_ON_UPDATE_AREA = 47, // (event, player, oldArea, newArea) - PLAYER_EVENT_ON_CAN_INIT_TRADE = 48, // (event, player, target) - Can return false to prevent the trade - PLAYER_EVENT_ON_CAN_SEND_MAIL = 49, // (event, player, receiverGuid, mailbox, subject, body, money, cod, item) - Can return false to prevent sending the mail - PLAYER_EVENT_ON_CAN_JOIN_LFG = 50, // (event, player, roles, dungeons, comment) - Can return false to prevent queueing - PLAYER_EVENT_ON_QUEST_REWARD_ITEM = 51, // (event, player, item, count) - PLAYER_EVENT_ON_CREATE_ITEM = 52, // (event, player, item, count) - PLAYER_EVENT_ON_STORE_NEW_ITEM = 53, // (event, player, item, count) - PLAYER_EVENT_ON_COMPLETE_QUEST = 54, // (event, player, quest) - PLAYER_EVENT_ON_CAN_GROUP_INVITE = 55, // (event, player, memberName) - Can return false to prevent inviting - PLAYER_EVENT_ON_GROUP_ROLL_REWARD_ITEM = 56, // (event, player, item, count, voteType, roll) - PLAYER_EVENT_ON_BG_DESERTION = 57, // (event, player, type) - PLAYER_EVENT_ON_PET_KILL = 58, // (event, player, killer) - PLAYER_EVENT_ON_CAN_RESURRECT = 59, // (event, player) - PLAYER_EVENT_ON_CAN_UPDATE_SKILL = 60, // (event, player, skill_id) - Can return true or false - PLAYER_EVENT_ON_BEFORE_UPDATE_SKILL = 61, // (event, player, skill_id, value, max, step) -- Can return new amount - PLAYER_EVENT_ON_UPDATE_SKILL = 62, // (event, player, skill_id, value, max, step, new_value) - PLAYER_EVENT_ON_QUEST_ACCEPT = 63, // (event, player, quest) - PLAYER_EVENT_ON_AURA_APPLY = 64, // (event, player, aura) - PLAYER_EVENT_ON_HEAL = 65, // (event, player, target, gain) - Can return new heal amount - PLAYER_EVENT_ON_DAMAGE = 66, // (event, player, target, damage) - Can return new damage amount - PLAYER_EVENT_ON_AURA_REMOVE = 67, // (event, player, aura, remove_mode) - PLAYER_EVENT_ON_MODIFY_PERIODIC_DAMAGE_AURAS_TICK = 68, // (event, player, target, damage, spellInfo) - Can return new damage amount - PLAYER_EVENT_ON_MODIFY_MELEE_DAMAGE = 69, // (event, player, target, damage) - Can return new damage amount - PLAYER_EVENT_ON_MODIFY_SPELL_DAMAGE_TAKEN = 70, // (event, player, target, damage, spellInfo) - Can return new damage amount - PLAYER_EVENT_ON_MODIFY_HEAL_RECEIVED = 71, // (event, player, target, heal, spellInfo) - Can return new heal amount - PLAYER_EVENT_ON_DEAL_DAMAGE = 72, // (event, player, target, damage, damagetype) - Can return new damage amount - - PLAYER_EVENT_COUNT - }; - - enum GuildEvents - { - // Guild - GUILD_EVENT_ON_ADD_MEMBER = 1, // (event, guild, player, rank) - GUILD_EVENT_ON_REMOVE_MEMBER = 2, // (event, guild, player, 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) - Can return new money amount - GUILD_EVENT_ON_MONEY_DEPOSIT = 8, // (event, guild, player, amount) - Can return new money 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) - - GUILD_EVENT_COUNT - }; - - 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) - - GROUP_EVENT_COUNT - }; - - 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) - - VEHICLE_EVENT_COUNT - }; - - enum CreatureEvents - { - CREATURE_EVENT_ON_ENTER_COMBAT = 1, // (event, creature, target) - Can return true to stop normal action - CREATURE_EVENT_ON_LEAVE_COMBAT = 2, // (event, creature) - Can return true to stop normal action - CREATURE_EVENT_ON_TARGET_DIED = 3, // (event, creature, victim) - Can return true to stop normal action - CREATURE_EVENT_ON_DIED = 4, // (event, creature, killer) - Can return true to stop normal action - CREATURE_EVENT_ON_SPAWN = 5, // (event, creature) - Can return true to stop normal action - CREATURE_EVENT_ON_REACH_WP = 6, // (event, creature, type, id) - Can return true to stop normal action - CREATURE_EVENT_ON_AIUPDATE = 7, // (event, creature, diff) - Can return true to stop normal action - CREATURE_EVENT_ON_RECEIVE_EMOTE = 8, // (event, creature, player, emoteid) - Can return true to stop normal action - CREATURE_EVENT_ON_DAMAGE_TAKEN = 9, // (event, creature, attacker, damage) - Can return true to stop normal action, can return new damage as second return value. - CREATURE_EVENT_ON_PRE_COMBAT = 10, // (event, creature, target) - Can return true to stop normal action - // UNUSED - CREATURE_EVENT_ON_OWNER_ATTACKED = 12, // (event, creature, target) - Can return true to stop normal action // Not on mangos - CREATURE_EVENT_ON_OWNER_ATTACKED_AT = 13, // (event, creature, attacker) - Can return true to stop normal action // Not on mangos - CREATURE_EVENT_ON_HIT_BY_SPELL = 14, // (event, creature, caster, spellid) - Can return true to stop normal action - CREATURE_EVENT_ON_SPELL_HIT_TARGET = 15, // (event, creature, target, spellid) - Can return true to stop normal action - // UNUSED = 16, // (event, creature) - // UNUSED = 17, // (event, creature) - // UNUSED = 18, // (event, creature) - CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE = 19, // (event, creature, summon) - Can return true to stop normal action - CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN = 20, // (event, creature, summon) - Can return true to stop normal action - CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED = 21, // (event, creature, summon, killer) - Can return true to stop normal action // Not on mangos - CREATURE_EVENT_ON_SUMMONED = 22, // (event, creature, summoner) - Can return true to stop normal action - CREATURE_EVENT_ON_RESET = 23, // (event, creature) - CREATURE_EVENT_ON_REACH_HOME = 24, // (event, creature) - Can return true to stop normal action - // UNUSED = 25, // (event, creature) - CREATURE_EVENT_ON_CORPSE_REMOVED = 26, // (event, creature, respawndelay) - Can return true to stop normal action, can return new respawndelay as second return value - CREATURE_EVENT_ON_MOVE_IN_LOS = 27, // (event, creature, unit) - Can return true to stop normal action. Does not actually check LOS, just uses the sight range - // 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) - Can return true - // UNUSED = 32, // (event, creature) - // UNUSED = 33, // (event, creature) - CREATURE_EVENT_ON_QUEST_REWARD = 34, // (event, player, creature, quest, opt) - Can return true - CREATURE_EVENT_ON_DIALOG_STATUS = 35, // (event, player, creature) - CREATURE_EVENT_ON_ADD = 36, // (event, creature) - CREATURE_EVENT_ON_REMOVE = 37, // (event, creature) - CREATURE_EVENT_ON_AURA_APPLY = 38, // (event, creature, aura) - CREATURE_EVENT_ON_HEAL = 39, // (event, creature, target, gain) - Can return new heal amount - CREATURE_EVENT_ON_DAMAGE = 40, // (event, creature, target, damage) - Can return new damage amount - CREATURE_EVENT_ON_AURA_REMOVE = 41, // (event, creature, aura, remove_mode) - CREATURE_EVENT_ON_MODIFY_PERIODIC_DAMAGE_AURAS_TICK = 42, // (event, creature, target, damage, spellInfo) - Can return new damage amount - CREATURE_EVENT_ON_MODIFY_MELEE_DAMAGE = 43, // (event, creature, target, damage) - Can return new damage amount - CREATURE_EVENT_ON_MODIFY_SPELL_DAMAGE_TAKEN = 44, // (event, creature, target, damage, spellInfo) - Can return new damage amount - CREATURE_EVENT_ON_MODIFY_HEAL_RECEIVED = 45, // (event, creature, target, heal, spellInfo) - Can return new heal amount - CREATURE_EVENT_ON_DEAL_DAMAGE = 46, // (event, creature, target, damage, damagetype) - Can return new damage amount - CREATURE_EVENT_COUNT - }; - - 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) - Can return true to stop normal action - GAMEOBJECT_EVENT_ON_QUEST_ACCEPT = 4, // (event, player, go, quest) - Can return true to stop normal action - GAMEOBJECT_EVENT_ON_QUEST_REWARD = 5, // (event, player, go, quest, opt) - Can return true to stop normal action - GAMEOBJECT_EVENT_ON_DIALOG_STATUS = 6, // (event, player, go) - GAMEOBJECT_EVENT_ON_DESTROYED = 7, // (event, go, attacker) - GAMEOBJECT_EVENT_ON_DAMAGED = 8, // (event, go, attacker) - GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE = 9, // (event, go, state) - GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED = 10, // (event, go, state) - // UNUSED = 11, // (event, gameobject) - GAMEOBJECT_EVENT_ON_ADD = 12, // (event, gameobject) - GAMEOBJECT_EVENT_ON_REMOVE = 13, // (event, gameobject) - GAMEOBJECT_EVENT_ON_USE = 14, // (event, go, player) - Can return true to stop normal action - GAMEOBJECT_EVENT_COUNT - }; - - enum ItemEvents - { - ITEM_EVENT_ON_DUMMY_EFFECT = 1, // (event, caster, spellid, effindex, item) - ITEM_EVENT_ON_USE = 2, // (event, player, item, target) - Can return false to stop the spell casting - ITEM_EVENT_ON_QUEST_ACCEPT = 3, // (event, player, item, quest) - Can return true - ITEM_EVENT_ON_EXPIRE = 4, // (event, player, itemid) - Can return true - ITEM_EVENT_ON_REMOVE = 5, // (event, player, item) - Can return true - ITEM_EVENT_COUNT - }; - - enum GossipEvents - { - GOSSIP_EVENT_ON_HELLO = 1, // (event, player, object) - Object is the Creature/GameObject/Item. Can return false to do default action. For item gossip can return false to stop spell casting. - 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. Can return false to do default action. - GOSSIP_EVENT_COUNT - }; - - enum BGEvents - { - BG_EVENT_ON_START = 1, // (event, bg, bgId, instanceId) - Needs to be added to TC - BG_EVENT_ON_END = 2, // (event, bg, bgId, instanceId, winner) - Needs to be added to TC - BG_EVENT_ON_CREATE = 3, // (event, bg, bgId, instanceId) - Needs to be added to TC - BG_EVENT_ON_PRE_DESTROY = 4, // (event, bg, bgId, instanceId) - Needs to be added to TC - BG_EVENT_COUNT - }; - - enum InstanceEvents - { - INSTANCE_EVENT_ON_INITIALIZE = 1, // (event, instance_data, map) - INSTANCE_EVENT_ON_LOAD = 2, // (event, instance_data, map) - INSTANCE_EVENT_ON_UPDATE = 3, // (event, instance_data, map, diff) - INSTANCE_EVENT_ON_PLAYER_ENTER = 4, // (event, instance_data, map, player) - INSTANCE_EVENT_ON_CREATURE_CREATE = 5, // (event, instance_data, map, creature) - INSTANCE_EVENT_ON_GAMEOBJECT_CREATE = 6, // (event, instance_data, map, go) - INSTANCE_EVENT_ON_CHECK_ENCOUNTER_IN_PROGRESS = 7, // (event, instance_data, map) - INSTANCE_EVENT_COUNT - }; - - enum TicketEvents - { - TICKET_EVENT_ON_CREATE = 1, // (event, ticket) - TICKET_EVENT_UPDATE_LAST_CHANGE = 2, // (event, ticket, message) - TICKET_EVENT_ON_CLOSE = 3, // (event, ticket) - TICKET_EVENT_ON_RESOLVE = 4, // (event, ticket) - TICKET_EVENT_COUNT - }; - - enum SpellEvents - { - SPELL_EVENT_ON_PREPARE = 1, // (event, caster, spell) - SPELL_EVENT_ON_CAST = 2, // (event, caster, spell, skipCheck) - 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_ON_AURA_APPLY = 5, // (event, creature, aura) - ALL_CREATURE_EVENT_ON_HEAL = 6, // (event, creature, target, gain) - Can return new heal amount - ALL_CREATURE_EVENT_ON_DAMAGE = 7, // (event, creature, target, damage) - Can return new damage amount - ALL_CREATURE_EVENT_ON_AURA_REMOVE = 8, // (event, creature, aura, remove_mode) - ALL_CREATURE_EVENT_ON_MODIFY_PERIODIC_DAMAGE_AURAS_TICK = 9, // (event, creature, target, damage, spellInfo) - Can return new damage amount - ALL_CREATURE_EVENT_ON_MODIFY_MELEE_DAMAGE = 10, // (event, creature, target, damage) - Can return new damage amount - ALL_CREATURE_EVENT_ON_MODIFY_SPELL_DAMAGE_TAKEN = 11, // (event, creature, target, damage, spellInfo) - Can return new damage amount - ALL_CREATURE_EVENT_ON_MODIFY_HEAL_RECEIVED = 12, // (event, creature, target, heal, spellInfo) - Can return new heal amount - ALL_CREATURE_EVENT_ON_DEAL_DAMAGE = 13, // (event, creature, target, damage, damagetype) - Can return new damage amount - ALL_CREATURE_EVENT_COUNT - }; -}; - -#endif // _HOOKS_H diff --git a/src/LuaEngine/Hooks/PlayerHooks.hpp b/src/LuaEngine/Hooks/PlayerHooks.hpp new file mode 100644 index 0000000000..4e5196b706 --- /dev/null +++ b/src/LuaEngine/Hooks/PlayerHooks.hpp @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _ECLIPSE_PLAYER_HOOKS_H +#define _ECLIPSE_PLAYER_HOOKS_H + +#include "ScriptMgr.h" +#include "Player.h" + +#include "TimedEventManager.h" +#include "EventManager.h" + +namespace Eclipse::Hooks +{ + /** + * @brief Trigger player event helper (template implementation) + * + * Converts enum to uint32 and forwards to EventManager. + * + * @tparam Args Variadic argument types + * @param eventType PlayerEvent enum value + * @param args Arguments to forward to Lua callbacks + */ + template + void TriggerPlayerEvent(Core::PlayerEvent eventType, Args&&... args) + { + // Cast enum to uint32 + uint32 eventId = static_cast(eventType); + + // Trigger event + uint32 executed = Core::EventManager::GetInstance().TriggerGlobalEvent( + eventType, + eventId, + std::forward(args)... + ); + } + + /** + * @class PlayerHooks + * @brief AzerothCore player event interceptor for Eclipse Lua system + * @note Registered in EclipseScriptLoader via sScriptMgr->AddScript() + */ + class PlayerHooks : public PlayerScript + { + public: + /** + * @brief Constructor - registers PlayerHooks with AzerothCore + */ + PlayerHooks() : PlayerScript("Eclipse_PlayerHooks") { } + + /** + * @brief Player login event (PlayerEvent::ON_LOGIN (ID = 2)) + * + * Called when player finishes loading into world. + * Lua signature: function(eventId, player) + * + * @param player + */ + void OnPlayerLogin(Player* player) override + { + TriggerPlayerEvent(Core::PlayerEvent::ON_LOGIN, player); + } + + /** + * @brief Player logout event (PlayerEvent::ON_LOGOUT (ID = 3)) + * + * Called when player disconnects. + * Lua signature: function(eventId, player) + * + * @param player + */ + void OnPlayerLogout(Player* player) override + { + TriggerPlayerEvent(Core::PlayerEvent::ON_LOGOUT, player); + } + + /** + * @brief Level change event (PlayerEvent::ON_LEVEL_CHANGE (ID = 5)) + * + * Called when player gains a level. + * Lua signature: function(eventId, player, oldLevel) + * + * @param player + * @param oldLevel + */ + void OnPlayerLevelChanged(Player* player, uint8 oldLevel) override + { + TriggerPlayerEvent(Core::PlayerEvent::ON_LEVEL_CHANGE, player, oldLevel); + } + + /** + * @brief Money change event (PlayerEvent::ON_MONEY_CHANGE (ID = 6)) + * + * Called before player's money changes. + * Lua signature: function(eventId, player, amount) + * + * @param player + * @param amount + */ + void OnPlayerMoneyChanged(Player* player, int32& amount) override + { + uint32 eventId = static_cast(Core::PlayerEvent::ON_MONEY_CHANGE); + uint32 modifiedAmount = Core::EventManager::GetInstance().TriggerGlobalEventWithReturn( + Core::PlayerEvent::ON_MONEY_CHANGE, + amount, // Default value if no handlers + eventId, + player, + amount + ); + + // Apply modified amount from Lua + amount = modifiedAmount; + } + + /** + * @brief XP gain event (PlayerEvent::ON_GIVE_XP (ID = 7)) + * + * Called when player is about to receive XP. + * Lua can modify amount by reference. + * + * Lua signature: function(eventId, player, amount, victim, xpSource) + * + * @param player + * @param amount + * @param victim + * @param xpSource + */ + void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource) override + { + uint32 eventId = static_cast(Core::PlayerEvent::ON_GIVE_XP); + uint32 modifiedAmount = Core::EventManager::GetInstance().TriggerGlobalEventWithReturn( + Core::PlayerEvent::ON_GIVE_XP, + amount, // Default value if no handlers + eventId, + player, + amount, + victim, + xpSource + ); + + // Apply modified amount from Lua + amount = modifiedAmount; + } + + /** + * @brief Player update tick event (triggers ON_UPDATE) + * + * Called every world tick (typically ~100ms) per player. + * + * Lua signature: function(eventId, player, diff) + * + * @param player Player being updated + * @param diff Time delta since last update (milliseconds) + */ + void OnPlayerUpdate(Player* player, uint32 diff) override + { + // Early exit: player not valid or not in world + if (!player || !player->IsInWorld()) + return; + + auto& stateMgr = Core::StateManager::GetInstance(); + Core::TimedEventManager* mgr = stateMgr.GetTimedEventManager(-1); + + // Execute timed events for this player + if (mgr) + mgr->UpdateObjectEvents(player, diff); + } + }; + +} // namespace Eclipse::Hooks + +#endif // _ECLIPSE_PLAYER_HOOKS_H diff --git a/src/LuaEngine/Hooks/WorldHooks.hpp b/src/LuaEngine/Hooks/WorldHooks.hpp new file mode 100644 index 0000000000..3af7c2840b --- /dev/null +++ b/src/LuaEngine/Hooks/WorldHooks.hpp @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _ECLIPSE_WORLD_HOOKS_H +#define _ECLIPSE_WORLD_HOOKS_H + +#include "ScriptMgr.h" + +#include "TimedEventManager.h" +#include "EventManager.h" +#include "Methods.hpp" + +namespace Eclipse::Hooks +{ + /** + * @brief Trigger Server/World event helper (template implementation) + * + * Converts enum to uint32 and forwards to EventManager. + * + * @tparam Args Variadic argument types + * @param eventType WorldEvent enum value + * @param args Arguments to forward to Lua callbacks + */ + template + void TriggerWorldEvent(uint32 eventId, Args&&... args) + { + auto eventType = static_cast(eventId); + uint32 executed = Core::EventManager::GetInstance().TriggerGlobalEvent( + eventType, + std::forward(args)... + ); + + if (executed > 0) + LOG_DEBUG("eclipse.hooks", "[Eclipse] WorldObject event {} triggered ({} handlers executed)", eventId, executed); + } + + /** + * @class WorldHooks + * @brief AzerothCore world event interceptor for Eclipse Lua system + * @note Registered in EclipseScriptLoader via sScriptMgr->AddScript() + */ + class WorldHooks : public WorldScript + { + public: + /** + * @brief Constructor - registers WorldHooks with AzerothCore + */ + WorldHooks() : WorldScript("Eclipse_WorldHooks") { } + + /** + * @todo Document all overridden hooks + */ + + void OnBeforeConfigLoad(bool reload) override + { + if (!reload) + { + // Initialize the StateManager first + if (!Eclipse::Core::StateManager::GetInstance().Initialize()) + { + LOG_ERROR("eclipse", "[Eclipse] Failed to initialize StateManager!"); + return; + } + + // Get master state + sol::state* masterState = Eclipse::Core::StateManager::GetInstance().GetMasterState(); + if (!masterState) + { + LOG_ERROR("eclipse", "[Eclipse] Failed to create master state!"); + return; + } + + // Initialize EventManager + if (!Eclipse::Core::EventManager::GetInstance().Initialize()) + { + LOG_ERROR("eclipse", "[Eclipse] Failed to initialize EventManager!"); + return; + } + + // Register all Lua methods directly + Eclipse::Core::TimedEventManager* timedEventMgr = Eclipse::Core::StateManager::GetInstance().GetTimedEventManager(-1); + Methods::RegisterAllMethods(*masterState, -1, timedEventMgr); + + try + { + // Start timing script loading + auto startTime = std::chrono::high_resolution_clock::now(); + + // Load all scripts from lua_scripts directory + LOG_INFO("eclipse", "[Eclipse] Scanning and loading scripts from lua_scripts directory..."); + Eclipse::Core::ScriptLoader::GetInstance().SetScriptPath("lua_scripts"); + // uint32 loadedCount = + Eclipse::Core::ScriptLoader::GetInstance().LoadAllScripts(-1); + + // // Calculate elapsed time + // auto endTime = std::chrono::high_resolution_clock::now(); + // auto durationMicro = std::chrono::duration_cast(endTime - startTime).count(); + // auto durationMilli = std::chrono::duration_cast(endTime - startTime).count(); + + // // Get comprehensive statistics from centralized Statistics system + // auto stats = Eclipse::Statistics::EclipseStatistics::GetInstance().GetSnapshot(); + + // // Display comprehensive statistics + // LOG_INFO("server.loading", ""); + // LOG_INFO("server.loading", "========================================"); + // LOG_INFO("server.loading", "[Eclipse] Script Loading Statistics"); + // LOG_INFO("server.loading", "========================================"); + // LOG_INFO("server.loading", "Scripts Discovered : {} total", stats.loadingTotalScripts); + // LOG_INFO("server.loading", " - Ext Scripts : {} (priority)", stats.loadingExtScripts); + // LOG_INFO("server.loading", " - Cout Scripts : {} (pre-compiled)", stats.loadingCoutScripts); + // LOG_INFO("server.loading", " - Lua Scripts : {}", stats.loadingLuaScripts); + // LOG_INFO("server.loading", " - MoonScripts : {}", stats.loadingMoonScripts); + // LOG_INFO("server.loading", ""); + // LOG_INFO("server.loading", "Loading Results :"); + // LOG_INFO("server.loading", " - Successful : {} scripts", stats.loadingSuccessful); + // LOG_INFO("server.loading", " - Failed : {} scripts", stats.loadingFailed); + // LOG_INFO("server.loading", ""); + // LOG_INFO("server.loading", "Bytecode Cache :"); + // LOG_INFO("server.loading", " - Cached Scripts : {}", stats.cacheTotalScripts); + // LOG_INFO("server.loading", " - Cache Hits : {}", stats.cacheHits); + // LOG_INFO("server.loading", " - Cache Misses : {}", stats.cacheMisses); + // LOG_INFO("server.loading", " - Total Size : {} bytes ({:.2f} KB)", + // stats.cacheTotalMemory, + // stats.cacheTotalMemory / 1024.0); + // LOG_INFO("server.loading", ""); + // LOG_INFO("server.loading", "Compilation :"); + // LOG_INFO("server.loading", " - Total Success : {}", stats.compilationSuccess); + // LOG_INFO("server.loading", " - Total Failed : {}", stats.compilationFailed); + // LOG_INFO("server.loading", " - Ext Compiled : {}", stats.compilationExtFiles); + // LOG_INFO("server.loading", " - Cout Loaded : {}", stats.compilationCoutFiles); + // LOG_INFO("server.loading", " - Moon Compiled : {}", stats.compilationMoonScript); + // LOG_INFO("server.loading", " - Bytecode Size : {} bytes", stats.compilationTotalBytecodeSize); + // LOG_INFO("server.loading", ""); + // LOG_INFO("server.loading", "Performance :"); + // LOG_INFO("server.loading", " - Load Time : {} µs ({} ms)", durationMicro, durationMilli); + // if (stats.loadingSuccessful > 0) + // { + // LOG_INFO("server.loading", " - Avg per Script : {:.2f} µs ({:.2f} ms)", + // static_cast(durationMicro) / stats.loadingSuccessful, + // static_cast(durationMilli) / stats.loadingSuccessful); + // } + // LOG_INFO("server.loading", "========================================"); + // LOG_INFO("server.loading", ""); + + // if (stats.loadingFailed > 0) + // { + // LOG_WARN("server.loading", "[Eclipse] Warning: {} script(s) failed to load. Check logs above for details.", + // stats.loadingFailed); + // } + } + catch (const sol::error& e) + { + LOG_ERROR("server.loading", "[Eclipse] Initialization failed: {}", e.what()); + } + } + } + + void OnUpdate(uint32 diff) override + { + auto& stateMgr = Core::StateManager::GetInstance(); + auto stateIds = stateMgr.GetAllStateIds(); + + Core::TimedEventManager* mgr = stateMgr.GetTimedEventManager(-1); + if (mgr) + mgr->Update(diff); + } + }; +} // namespace Eclipse + +#endif // _ECLIPSE_WORLD_OBJECT_HOOKS_H diff --git a/src/LuaEngine/Hooks/WorldObjectHooks.hpp b/src/LuaEngine/Hooks/WorldObjectHooks.hpp new file mode 100644 index 0000000000..d6ed02a92f --- /dev/null +++ b/src/LuaEngine/Hooks/WorldObjectHooks.hpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _ECLIPSE_WORLD_OBJECT_HOOKS_H +#define _ECLIPSE_WORLD_OBJECT_HOOKS_H + +#include "ScriptMgr.h" + +#include "TimedEventManager.h" +#include "EventManager.h" + +namespace Eclipse::Hooks +{ + /** + * @brief Trigger WorldObject event helper (template implementation) + * + * Converts enum to uint32 and forwards to EventManager. + * + * @tparam Args Variadic argument types + * @param eventType WorldObjectEvent enum value + * @param args Arguments to forward to Lua callbacks + */ + template + void TriggerWorldObjectEvent(Core::WorldObjectEvent eventType, Args&&... args) + { + // Cast enum to uint32 + uint32 eventId = static_cast(eventType); + + // Trigger event + uint32 executed = Core::EventManager::GetInstance().TriggerGlobalEvent( + eventType, + eventId, + std::forward(args)... + ); + } + + class WorldObjectHooks : public WorldObjectScript + { + public: + WorldObjectHooks() : WorldObjectScript("Eclipse_WorldObjectHooks") { } + + /** + * todo: Document all overridden hooks + */ + void OnWorldObjectUpdate(WorldObject* object, uint32 diff) override + { + if (!object || !object->IsInWorld()) + return; + + auto& stateMgr = Core::StateManager::GetInstance(); + Core::TimedEventManager* mgr = stateMgr.GetTimedEventManager(-1); + + // Execute timed events for this WorldObject + if (mgr) + mgr->UpdateObjectEvents(object, diff); + } + }; +} // namespace Eclipse + +#endif // _ECLIPSE_WORLD_OBJECT_HOOKS_H diff --git a/src/LuaEngine/HttpManager.cpp b/src/LuaEngine/HttpManager.cpp deleted file mode 100644 index f7079cf3c9..0000000000 --- a/src/LuaEngine/HttpManager.cpp +++ /dev/null @@ -1,275 +0,0 @@ -#include -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -}; - -#define CPPHTTPLIB_OPENSSL_SUPPORT - -#include "libs/httplib.h" -#include "HttpManager.h" -#include "LuaEngine.h" - -HttpWorkItem::HttpWorkItem(int funcRef, const std::string& httpVerb, const std::string& url, const std::string& body, const std::string& contentType, const httplib::Headers& headers) - : funcRef(funcRef), - httpVerb(httpVerb), - url(url), - body(body), - contentType(contentType), - headers(headers) -{ } - -HttpResponse::HttpResponse(int funcRef, int statusCode, const std::string& body, const httplib::Headers& headers) - : funcRef(funcRef), - statusCode(statusCode), - body(body), - headers(headers) -{ } - -HttpManager::HttpManager() - : workQueue(16), - responseQueue(16), - startedWorkerThread(false), - cancelationToken(false), - condVar(), - condVarMutex(), - parseUrlRegex("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?") -{ - StartHttpWorker(); -} - -HttpManager::~HttpManager() -{ - StopHttpWorker(); -} - -void HttpManager::PushRequest(HttpWorkItem* item) -{ - std::unique_lock lock(condVarMutex); - workQueue.push(item); - condVar.notify_one(); -} - -void HttpManager::StartHttpWorker() -{ - ClearQueues(); - - if (!startedWorkerThread) - { - cancelationToken.store(false); - workerThread = std::thread(&HttpManager::HttpWorkerThread, this); - startedWorkerThread = true; - } -} - -void HttpManager::ClearQueues() -{ - while (workQueue.front()) - { - HttpWorkItem* item = *workQueue.front(); - if (item != nullptr) - { - delete item; - } - workQueue.pop(); - } - - while (responseQueue.front()) - { - HttpResponse* item = *responseQueue.front(); - if (item != nullptr) - { - delete item; - } - responseQueue.pop(); - } -} - -void HttpManager::StopHttpWorker() -{ - if (!startedWorkerThread) - { - return; - } - - cancelationToken.store(true); - condVar.notify_one(); - workerThread.join(); - ClearQueues(); - startedWorkerThread = false; -} - -void HttpManager::HttpWorkerThread() -{ - while (true) - { - { - std::unique_lock lock(condVarMutex); - condVar.wait(lock, [&] { return workQueue.front() != nullptr || cancelationToken.load(); }); - } - - if (cancelationToken.load()) - { - break; - } - if (!workQueue.front()) - { - continue; - } - - HttpWorkItem* req = *workQueue.front(); - workQueue.pop(); - if (!req) - { - continue; - } - - try - { - std::string host; - std::string path; - - if (!ParseUrl(req->url, host, path)) { - ALE_LOG_ERROR("[ALE]: Could not parse URL {}", req->url); - continue; - } - - httplib::Client cli(host); - cli.set_connection_timeout(0, 3000000); // 3 seconds - cli.set_read_timeout(5, 0); // 5 seconds - cli.set_write_timeout(5, 0); // 5 seconds - - httplib::Result res = DoRequest(cli, req, path); - httplib::Error err = res.error(); - if (err != httplib::Error::Success) - { - ALE_LOG_ERROR("[ALE]: HTTP request error: {}", httplib::to_string(err)); - continue; - } - - if (res->status == 301) - { - std::string location = res->get_header_value("Location"); - std::string host; - std::string path; - - if (!ParseUrl(location, host, path)) - { - ALE_LOG_ERROR("[ALE]: Could not parse URL after redirect: {}", location); - continue; - } - httplib::Client cli2(host); - cli2.set_connection_timeout(0, 3000000); // 3 seconds - cli2.set_read_timeout(5, 0); // 5 seconds - cli2.set_write_timeout(5, 0); // 5 seconds - res = DoRequest(cli2, req, path); - } - - responseQueue.push(new HttpResponse(req->funcRef, res->status, res->body, res->headers)); - } - catch (const std::exception& ex) - { - ALE_LOG_ERROR("[ALE]: HTTP request error: {}", ex.what()); - } - - delete req; - } -} - -httplib::Result HttpManager::DoRequest(httplib::Client& client, HttpWorkItem* req, const std::string& urlPath) -{ - const char* path = urlPath.c_str(); - if (req->httpVerb == "GET") - { - return client.Get(path, req->headers); - } - if (req->httpVerb == "HEAD") - { - return client.Head(path, req->headers); - } - if (req->httpVerb == "POST") - { - return client.Post(path, req->headers, req->body, req->contentType.c_str()); - } - if (req->httpVerb == "PUT") - { - return client.Put(path, req->headers, req->body, req->contentType.c_str()); - } - if (req->httpVerb == "PATCH") - { - return client.Patch(path, req->headers, req->body, req->contentType.c_str()); - } - if (req->httpVerb == "DELETE") - { - return client.Delete(path, req->headers); - } - if (req->httpVerb == "OPTIONS") - { - return client.Options(path, req->headers); - } - - ALE_LOG_ERROR("[ALE]: HTTP request error: invalid HTTP verb {}", req->httpVerb); - return client.Get(path, req->headers); -} - -bool HttpManager::ParseUrl(const std::string& url, std::string& host, std::string& path) -{ - std::smatch matches; - - if (!std::regex_search(url, matches, parseUrlRegex)) - { - return false; - } - - std::string scheme = matches[2]; - std::string authority = matches[4]; - std::string query = matches[7]; - host = scheme + "://" + authority; - path = matches[5]; - if (path.empty()) - { - path = "/"; - } - path += (query.empty() ? "" : "?") + query; - - return true; -} - -void HttpManager::HandleHttpResponses() -{ - while (!responseQueue.empty()) - { - HttpResponse* res = *responseQueue.front(); - responseQueue.pop(); - - if (res == nullptr) - { - continue; - } - - LOCK_ALE; - - lua_State* L = ALE::GALE->L; - - // Get function - lua_rawgeti(L, LUA_REGISTRYINDEX, res->funcRef); - - // Push parameters - ALE::Push(L, res->statusCode); - ALE::Push(L, res->body); - lua_newtable(L); - for (const auto& item : res->headers) { - ALE::Push(L, item.first); - ALE::Push(L, item.second); - lua_settable(L, -3); - } - - // Call function - ALE::GALE->ExecuteCall(3, 0); - - luaL_unref(L, LUA_REGISTRYINDEX, res->funcRef); - - delete res; - } -} diff --git a/src/LuaEngine/HttpManager.h b/src/LuaEngine/HttpManager.h deleted file mode 100644 index cab17a4466..0000000000 --- a/src/LuaEngine/HttpManager.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef ALE_HTTP_MANAGER_H -#define ALE_HTTP_MANAGER_H - -#include - -#include "libs/httplib.h" -#include "libs/rigtorp/SPSCQueue.h" - -struct HttpWorkItem -{ -public: - HttpWorkItem(int funcRef, const std::string& httpVerb, const std::string& url, const std::string& body, const std::string &contentType, const httplib::Headers& headers); - - int funcRef; - std::string httpVerb; - std::string url; - std::string body; - std::string contentType; - httplib::Headers headers; -}; - -struct HttpResponse -{ -public: - HttpResponse(int funcRef, int statusCode, const std::string& body, const httplib::Headers& headers); - - int funcRef; - int statusCode; - std::string body; - httplib::Headers headers; -}; - - -class HttpManager -{ -public: - HttpManager(); - ~HttpManager(); - - void StartHttpWorker(); - void StopHttpWorker(); - void PushRequest(HttpWorkItem* item); - void HandleHttpResponses(); - -private: - void ClearQueues(); - void HttpWorkerThread(); - bool ParseUrl(const std::string& url, std::string& host, std::string& path); - httplib::Result DoRequest(httplib::Client& client, HttpWorkItem* req, const std::string& path); - - rigtorp::SPSCQueue workQueue; - rigtorp::SPSCQueue responseQueue; - std::thread workerThread; - bool startedWorkerThread; - std::atomic_bool cancelationToken; - std::condition_variable condVar; - std::mutex condVarMutex; - std::regex parseUrlRegex; -}; - -#endif // #ifndef ALE_HTTP_MANAGER_H diff --git a/src/LuaEngine/Loading/EclipseScriptLoader.cpp b/src/LuaEngine/Loading/EclipseScriptLoader.cpp new file mode 100644 index 0000000000..fb6a0307d7 --- /dev/null +++ b/src/LuaEngine/Loading/EclipseScriptLoader.cpp @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#include "EclipseScriptLoader.h" +#include "StateManager.h" +#include "ScriptCompiler.h" +#include "Log.h" +#include +#include // For std::sort + +#ifdef _WIN32 +#include +#endif + +namespace fs = boost::filesystem; + +namespace Eclipse::Core +{ + /** + * @brief Get ScriptLoader singleton instance + * + * Thread-safe initialization (C++11 magic statics). + * + * @return Reference to the global ScriptLoader + */ + ScriptLoader& ScriptLoader::GetInstance() + { + static ScriptLoader instance; + return instance; + } + + /** + * @brief Constructor - initializes default script path + */ + ScriptLoader::ScriptLoader() + : m_scriptPath("lua_scripts") + { + LOG_DEBUG("server.loading", "[Eclipse] ScriptLoader - Creating script loader"); + } + + /** + * @brief Destructor + */ + ScriptLoader::~ScriptLoader() + { + } + + /** + * @brief Set script directory path + * + * Changes the root directory for script scanning. + * + * @param path Path to lua_scripts directory + */ + void ScriptLoader::SetScriptPath(const std::string& path) + { + m_scriptPath = path; + LOG_INFO("eclipse.loader", "[Eclipse] ScriptLoader - Script path set to: {}", path); + } + + /** + * @brief Check if file is a valid script file + * + * Accepts: .ext, .lua, .moon, .cout + * + * @param filename Filename to check + * @param extension Output: extracted extension if valid + * @return true if valid script extension + */ + bool ScriptLoader::IsScriptFile(const std::string& filename, std::string& extension) + { + size_t dotPos = filename.rfind('.'); + if (dotPos == std::string::npos) + return false; + + extension = filename.substr(dotPos); + return extension == ".ext" || extension == ".lua" || extension == ".moon" || extension == ".cout"; + } + + sol::state* ScriptLoader::GetStateOrNull(int32 stateId, const char* callerName) + { + sol::state* state = nullptr; + + if (stateId == -1) + state = StateManager::GetInstance().GetMasterState(); + else + state = StateManager::GetInstance().GetOrCreateState(stateId); + + if (!state) + { + LOG_ERROR("eclipse.loader", "[Eclipse] ScriptLoader::{} - Failed to get state {}", + callerName, stateId); + return nullptr; + } + + return state; + } + + /** + * @brief Recursively scan directory for scripts + * + * Uses boost::filesystem::recursive_directory_iterator. + * Skips hidden files (Windows: FILE_ATTRIBUTE_HIDDEN, Unix: starts with '.'). + * + * @param directory Directory to scan + * @param scripts Output vector (scripts appended) + */ + void ScriptLoader::ScanDirectory(const std::string& directory, std::vector& scripts) + { + try + { + if (!fs::exists(directory)) + { + LOG_WARN("eclipse.loader", "[Eclipse] ScriptLoader - Directory does not exist: {}", directory); + return; + } + + fs::recursive_directory_iterator end_iter; + for (fs::recursive_directory_iterator dir_iter(directory); dir_iter != end_iter; ++dir_iter) + { + std::string filepath = dir_iter->path().generic_string(); + + // Check for hidden files (platform-specific) +#ifdef _WIN32 + DWORD dwAttrib = GetFileAttributes(filepath.c_str()); + if (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_HIDDEN)) + continue; +#else + std::string name = dir_iter->path().filename().generic_string(); + if (!name.empty() && name[0] == '.') + continue; +#endif + + if (fs::is_regular_file(dir_iter->status())) + { + std::string filename = dir_iter->path().filename().generic_string(); + std::string extension; + + if (IsScriptFile(filename, extension)) + scripts.emplace_back(filename, filepath, extension); + } + } + } + catch (const fs::filesystem_error& e) + { + LOG_ERROR("eclipse.loader", "[Eclipse] ScriptLoader - Filesystem error: {}", e.what()); + } + } + + /** + * @brief Scan directory for .lua and .moon files + * + * Recursively scans lua_scripts directory tree. + * Resets statistics before scanning. + * + * @return Vector of discovered script files + */ + std::vector ScriptLoader::ScanScripts() + { + LOG_INFO("eclipse.loader", "[Eclipse] ScriptLoader - Scanning directory: {}", m_scriptPath); + + // Build require paths (currently unused, reserved for future) + m_requirePath.clear(); + m_requireCPath.clear(); + + std::vector scripts; + ScanDirectory(m_scriptPath, scripts); + + // Sort scripts by priority: .ext (0) first, then .cout (1), .moon (2), .lua (3) + std::sort(scripts.begin(), scripts.end()); + + // Count file types and update statistics + uint32 extScripts = 0, coutScripts = 0, luaScripts = 0, moonScripts = 0; + for (const auto& script : scripts) + { + if (script.extension == ".ext") extScripts++; + else if (script.extension == ".cout") coutScripts++; + else if (script.extension == ".lua") luaScripts++; + else if (script.extension == ".moon") moonScripts++; + } + + auto& stats = Statistics::EclipseStatistics::GetInstance(); + stats.SetLoadingExtScripts(extScripts); + stats.SetLoadingCoutScripts(coutScripts); + stats.SetLoadingLuaScripts(luaScripts); + stats.SetLoadingMoonScripts(moonScripts); + stats.SetLoadingTotalScripts(scripts.size()); + + LOG_INFO("eclipse.loader", "[Eclipse] ScriptLoader - Found {} scripts ({} Ext, {} Cout, {} Lua, {} MoonScript)", + scripts.size(), extScripts, coutScripts, luaScripts, moonScripts); + + return scripts; + } + + /** + * @brief Setup require paths for a Lua state + * + * Configures package.path and package.cpath to allow require() from subdirectories. + * Adds all subdirectories recursively. + * + * Example paths added: + * - lua_scripts/?.lua + * - lua_scripts/subdir/?.lua + * - lua_scripts/?.dll (Windows) or ?.so (Unix) + * + * @param state Lua state to configure + */ + void ScriptLoader::SetupRequirePaths(sol::state& state) + { + // Build require paths recursively for all subdirectories + if (!fs::exists(m_scriptPath)) + return; + + std::string luaPath; + std::string luaCPath; + + try + { + fs::recursive_directory_iterator end_iter; + for (fs::recursive_directory_iterator dir_iter(m_scriptPath); dir_iter != end_iter; ++dir_iter) + { + if (fs::is_directory(dir_iter->status())) + { + std::string dirPath = dir_iter->path().generic_string(); + luaPath += dirPath + "/?.lua;" + dirPath + "/?.moon;" + dirPath + "/?.ext;"; +#ifdef _WIN32 + luaCPath += dirPath + "/?.dll;"; +#else + luaCPath += dirPath + "/?.so;"; +#endif + } + } + + // Add base path + luaPath = m_scriptPath + "/?.lua;" + m_scriptPath + "/?.moon;" + m_scriptPath + "/?.ext;" + luaPath; +#ifdef _WIN32 + luaCPath = m_scriptPath + "/?.dll;" + luaCPath; +#else + luaCPath = m_scriptPath + "/?.so;" + luaCPath; +#endif + + // Get current package.path and append + sol::optional currentPath = state["package"]["path"]; + if (currentPath) + luaPath += *currentPath; + + sol::optional currentCPath = state["package"]["cpath"]; + if (currentCPath) + luaCPath += *currentCPath; + + state["package"]["path"] = luaPath; + state["package"]["cpath"] = luaCPath; + + LOG_DEBUG("eclipse.loader", "[Eclipse] ScriptLoader - Configured require paths for state"); + } + catch (const fs::filesystem_error& e) + { + LOG_ERROR("eclipse.loader", "[Eclipse] ScriptLoader - Error setting up require paths: {}", e.what()); + } + } + + /** + * @brief Load a specific script file + * + * Workflow: + * 1. Get Lua state (master or per-map) + * 2. Compile script via ScriptCompiler (uses BytecodeCache) + * 3. Load bytecode into state + * 4. Execute loaded function + * + * @param scriptFile Script file metadata + * @param stateId State ID to load into (-1 for master) + * @return true if loaded and executed successfully + */ + bool ScriptLoader::LoadScript(const ScriptFile& scriptFile, int32 stateId) + { + LOG_DEBUG("eclipse.loader", "[Eclipse] ScriptLoader - Loading script: {}", scriptFile.filepath); + + // Get the state to load into (DRY - uses helper) + sol::state* state = GetStateOrNull(stateId, "LoadScript"); + if (!state) + { + Statistics::EclipseStatistics::GetInstance().IncrementLoadingFailed(); + return false; + } + + try + { + // Compile to bytecode (via BytecodeCache) + API::CompileOptions opts; + opts.allowMoonScript = true; + + auto bytecode = API::ScriptCompiler::GetInstance().CompileFile(scriptFile.filepath, opts); + + if (!bytecode || !bytecode->isValid()) + { + LOG_ERROR("eclipse.loader", "[Eclipse] ScriptLoader - Failed to compile script: {}", + scriptFile.filepath); + Statistics::EclipseStatistics::GetInstance().IncrementLoadingFailed(); + return false; + } + + // Load bytecode into state (direct sol2 call) + auto result = state->load(bytecode->bytecode.as_string_view(), scriptFile.filename); + + if (!result.valid()) + { + sol::error err = result; + LOG_ERROR("eclipse.loader", "[Eclipse] ScriptLoader - Failed to load script: {} - Error: {}", + scriptFile.filepath, err.what()); + Statistics::EclipseStatistics::GetInstance().IncrementLoadingFailed(); + return false; + } + + // Execute the loaded script + sol::protected_function scriptFunc = result; + auto execResult = scriptFunc(); + + if (!execResult.valid()) + { + sol::error err = execResult; + LOG_ERROR("eclipse.loader", "[Eclipse] ScriptLoader - Error executing script: {} - Error: {}", + scriptFile.filepath, err.what()); + Statistics::EclipseStatistics::GetInstance().IncrementLoadingFailed(); + return false; + } + + LOG_INFO("eclipse.loader", "[Eclipse] ScriptLoader - Successfully loaded: {}", scriptFile.filename); + Statistics::EclipseStatistics::GetInstance().IncrementLoadingSuccessful(); + return true; + } + catch (const sol::error& e) + { + LOG_ERROR("eclipse.loader", "[Eclipse] ScriptLoader - Exception loading script: {} - Error: {}", + scriptFile.filepath, e.what()); + Statistics::EclipseStatistics::GetInstance().IncrementLoadingFailed(); + return false; + } + } + + /** + * @brief Load all scripts from directory + * + * Main script loading workflow: + * 1. Get or create Lua state + * 2. Setup require paths + * 3. Scan for scripts + * 4. Load each script + * + * @param stateId State ID to load scripts into (-1 for master) + * @return Number of scripts successfully loaded + */ + uint32 ScriptLoader::LoadAllScripts(int32 stateId) + { + LOG_INFO("eclipse.loader", "[Eclipse] ScriptLoader - Loading all scripts into state {}", stateId); + + // Get the state and setup require paths first (DRY - uses helper) + sol::state* state = GetStateOrNull(stateId, "LoadAllScripts"); + if (!state) + return 0; + + // Setup require paths before loading scripts + SetupRequirePaths(*state); + + auto scripts = ScanScripts(); + if (scripts.empty()) + { + LOG_WARN("eclipse.loader", "[Eclipse] ScriptLoader - No scripts found in: {}", m_scriptPath); + return 0; + } + + // Track loading stats + uint32 successCount = 0; + for (const auto& script : scripts) + { + if (LoadScript(script, stateId)) + successCount++; + } + + auto stats = Statistics::EclipseStatistics::GetInstance().GetSnapshot(); + LOG_INFO("eclipse.loader", "[Eclipse] ScriptLoader - Loaded {}/{} scripts ({} failed)", stats.loadingSuccessful, scripts.size(), stats.loadingFailed); + + return successCount; + } + + /** + * @brief Reload all scripts (clear cache + reload) + * + * Full reload workflow: + * 1. Remove and recreate state (if per-map state) + * 2. LoadAllScripts() + * + * @param stateId State ID to reload scripts for (-1 for master) + * @return Number of scripts successfully reloaded + */ + uint32 ScriptLoader::ReloadAllScripts(int32 stateId) + { + LOG_INFO("eclipse.loader", "[Eclipse] ScriptLoader - Reloading all scripts for state {}", stateId); + + // Remove and recreate the state (if per-map state) + if (stateId >= 0) + StateManager::GetInstance().RemoveState(stateId); + + // Reload scripts + return LoadAllScripts(stateId); + } + +} // namespace Eclipse::Core diff --git a/src/LuaEngine/Loading/EclipseScriptLoader.h b/src/LuaEngine/Loading/EclipseScriptLoader.h new file mode 100644 index 0000000000..e9de3af528 --- /dev/null +++ b/src/LuaEngine/Loading/EclipseScriptLoader.h @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _ECLIPSE_SCRIPT_LOADER_H +#define _ECLIPSE_SCRIPT_LOADER_H + +#include +#include +#include +#include +#include "Common.h" + +namespace Eclipse::Core +{ + /** + * @struct ScriptFile + * @brief Metadata for discovered script files + * + * Supports: .ext (priority), .lua, .moon, .cout (pre-compiled) + * - filename: Just the name (e.g., "test.lua") + * - filepath: Full path (e.g., "lua_scripts/test.lua") + * - extension: File extension (".ext", ".lua", ".moon", ".cout") + * - priority: Load order (0 = highest priority) + */ + struct ScriptFile + { + std::string filename; ///< Filename only + std::string filepath; ///< Full path + std::string extension; ///< File extension + int priority; ///< Load priority (0=.ext, 1=.cout, 2=.moon, 3=.lua) + + /** + * @brief Default constructor + */ + ScriptFile() : priority(3) {} + + /** + * @brief Constructor + * @param name Filename + * @param path Full filepath + * @param ext File extension + */ + ScriptFile(const std::string& name, const std::string& path, const std::string& ext) + : filename(name), filepath(path), extension(ext) + { + // Set priority: .ext > .cout > .moon > .lua + if (ext == ".ext") + priority = 0; + else if (ext == ".cout") + priority = 1; + else if (ext == ".moon") + priority = 2; + else // .lua + priority = 3; + } + + // Comparator for sorting by priority + bool operator<(const ScriptFile& other) const + { + return priority < other.priority; + } + }; + + /** + * @class ScriptLoader + * @brief Discovers, compiles, and executes Lua/MoonScript files + * + * **Purpose:** + * Scans lua_scripts directory, compiles scripts to bytecode via BytecodeCache, + * and executes them in the appropriate Lua state. + * + * **Architecture:** + * - Singleton for global script management + * - Recursive directory scanning (finds scripts in subdirectories) + * - Bytecode caching for fast reload + * - Package.path/cpath configuration for require() + * + * **Workflow:** + * 1. ScanScripts(): Recursively scan lua_scripts directory + * 2. SetupRequirePaths(): Configure Lua package paths + * 3. LoadScript(): Compile via BytecodeCache, load, execute + * 4. ReloadAllScripts(): Clear cache, reload all + * + * **Current Behavior (State -1):** + * - All scripts loaded into master state (-1) + * - Called once during server startup + * - No runtime script loading + * + * **Future Behavior (Multistate):** + * - Master state: Shared libraries/utilities + * - Per-map states: Map-specific scripts + * - Dynamic loading when maps created + * + * **Performance:** + * - ScanScripts: O(n) where n = files in directory tree + * - LoadScript: O(1) if bytecode cached, O(m) if compiling (m = script size) + * - ReloadAllScripts: O(n*m) full recompilation + * + * **Hidden File Handling:** + * - Windows: Skips FILE_ATTRIBUTE_HIDDEN files + * - Unix: Skips files starting with '.' + * + * **Thread-Safety:** + * - NOT thread-safe (initialization only) + * - Called from single thread during server startup + * + * @note Uses boost::filesystem for cross-platform file operations + */ + class ScriptLoader + { + public: + /** + * @brief Default constructor + */ + ScriptLoader(); + + /** + * @brief Destructor + */ + ~ScriptLoader(); + + // Non-copyable, non-movable (singleton pattern) + ScriptLoader(const ScriptLoader&) = delete; + ScriptLoader& operator=(const ScriptLoader&) = delete; + ScriptLoader(ScriptLoader&&) = delete; + ScriptLoader& operator=(ScriptLoader&&) = delete; + + /** + * @brief Get singleton instance + * @return Reference to the global ScriptLoader + */ + static ScriptLoader& GetInstance(); + + /** + * @brief Set script directory path + * + * Sets the root directory for script scanning. + * Default: "lua_scripts" + * + * @param path Path to lua_scripts directory (absolute or relative) + */ + void SetScriptPath(const std::string& path); + + /** + * @brief Get current script path + * @return Script directory path + */ + const std::string& GetScriptPath() const { return m_scriptPath; } + + /** + * @brief Scan directory for .lua and .moon files + * + * Recursively scans lua_scripts directory tree. + * Skips hidden files (Windows: FILE_ATTRIBUTE_HIDDEN, Unix: starts with '.'). + * + * Performance: O(n) where n = total files in directory tree. + * + * @return Vector of discovered script files + */ + std::vector ScanScripts(); + + /** + * @brief Load all scripts from directory + * + * Workflow: + * 1. Get or create Lua state + * 2. Setup require paths + * 3. Scan for scripts + * 4. Load each script (compile + execute) + * + * Current: Loads all into master state (-1). + * Future: Can specify per-map state ID. + * + * @param stateId State ID to load scripts into (-1 for master, >=0 for per-map) + * @return Number of scripts successfully loaded + */ + uint32 LoadAllScripts(int32 stateId = -1); + + /** + * @brief Load a specific script file + * + * Loads single script: + * 1. Get bytecode from BytecodeCache (compile if needed) + * 2. Load bytecode into state + * 3. Execute loaded function + * + * Performance: O(1) if bytecode cached, O(n) if compiling. + * + * @param scriptFile Script file metadata + * @param stateId State ID to load into (-1 for master) + * @return true if loaded and executed successfully + */ + bool LoadScript(const ScriptFile& scriptFile, int32 stateId = -1); + + /** + * @brief Reload all scripts (clear cache + reload) + * + * Full reload workflow: + * 1. Clear BytecodeCache (force recompilation) + * 2. Destroy and recreate state (if per-map state) + * 3. LoadAllScripts() + * + * Performance: O(n*m) where n = scripts, m = avg script size. + * + * @param stateId State ID to reload scripts for (-1 for master) + * @return Number of scripts successfully reloaded + */ + uint32 ReloadAllScripts(int32 stateId = -1); + + /** + * @brief Setup require paths for a Lua state + * + * Configures package.path and package.cpath for require(). + * Adds all subdirectories recursively to search paths. + * + * Example paths added: + * - lua_scripts/?.lua + * - lua_scripts/?/init.lua + * - lua_scripts/subdir/?.lua + * - lua_scripts/?.dll (Windows) or ?.so (Unix) + * + * @param state Lua state to configure + */ + void SetupRequirePaths(sol::state& state); + + private: + std::string m_scriptPath; ///< Root script directory path + std::string m_requirePath; ///< Cached Lua require path (unused currently) + std::string m_requireCPath; ///< Cached Lua require cpath (unused currently) + // NOTE: All statistics tracked in Eclipse::Statistics::EclipseStatistics + + /** + * @brief Recursively scan directory for scripts + * + * Internal recursive helper for ScanScripts(). + * + * @param directory Directory to scan + * @param scripts Output vector (appended to) + */ + void ScanDirectory(const std::string& directory, std::vector& scripts); + + /** + * @brief Check if file is a valid script file + * + * Accepts: .ext, .lua, .moon, .cout + * + * @param filename Filename to check + * @param extension Output: extracted extension if valid + * @return true if valid script file extension + */ + bool IsScriptFile(const std::string& filename, std::string& extension); + + /** + * @brief Get Lua state with validation + * @param stateId State ID (-1 for master, >=0 for per-map) + * @param callerName Caller function name for error logging + * @return Pointer to state, or nullptr if unavailable (logs error) + */ + sol::state* GetStateOrNull(int32 stateId, const char* callerName); + }; + +} // namespace Eclipse::Core + +#endif // _ECLIPSE_SCRIPT_LOADER_H diff --git a/src/LuaEngine/LuaEngine.cpp b/src/LuaEngine/LuaEngine.cpp deleted file mode 100644 index c647d689a5..0000000000 --- a/src/LuaEngine/LuaEngine.cpp +++ /dev/null @@ -1,1722 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#include "Hooks.h" -#include "LuaEngine.h" -#include "BindingMap.h" -#include "Chat.h" -#include "ALECompat.h" -#include "ALEEventMgr.h" -#include "ALEIncludes.h" -#include "ALETemplate.h" -#include "ALEUtility.h" -#include "ALECreatureAI.h" -#include "ALEInstanceAI.h" - -#if AC_PLATFORM == AC_PLATFORM_WINDOWS -#define ALE_WINDOWS -#endif - -// Some dummy includes containing BOOST_VERSION: -// ObjectAccessor.h Config.h Log.h -#define USING_BOOST - -#include -#include -#include -#include -#include -#include - -extern "C" -{ -// Base lua libraries -#include "lua.h" -#include "lualib.h" -#include "lauxlib.h" - -// Additional lua libraries -}; - -ALE::ScriptList ALE::lua_scripts; -ALE::ScriptList ALE::lua_extensions; -std::string ALE::lua_folderpath; -std::string ALE::lua_requirepath; -std::string ALE::lua_requirecpath; -ALE* ALE::GALE = NULL; -bool ALE::reload = false; -bool ALE::initialized = false; -ALE::LockType ALE::lock; -std::unique_ptr ALE::fileWatcher; - -// Global bytecode cache that survives ALE reloads -static std::unordered_map globalBytecodeCache; -static std::unordered_map timestampCache; -static std::mutex globalCacheMutex; - -extern void RegisterFunctions(ALE* E); - -void ALE::Initialize() -{ - LOCK_ALE; - ASSERT(!IsInitialized()); - - // For instance data the data column needs to be able to hold more than 255 characters (tinytext) - // so we change it to TEXT automatically on startup - CharacterDatabase.DirectExecute("ALTER TABLE `instance` CHANGE COLUMN `data` `data` TEXT NOT NULL"); - - LoadScriptPaths(); - - // Must be before creating GALE - // This is checked on ALE creation - initialized = true; - - // Create global ALE - GALE = new ALE(); - - // Start file watcher if enabled - if (ALEConfig::GetInstance().IsAutoReloadEnabled()) - { - uint32 watchInterval = eConfigMgr->GetOption("ALE.AutoReloadInterval", 1); - fileWatcher = std::make_unique(); - fileWatcher->StartWatching(lua_folderpath, watchInterval); - } -} - -void ALE::Uninitialize() -{ - LOCK_ALE; - ASSERT(IsInitialized()); - - // Stop file watcher - if (fileWatcher) - { - fileWatcher->StopWatching(); - fileWatcher.reset(); - } - - delete GALE; - GALE = NULL; - - lua_scripts.clear(); - lua_extensions.clear(); - - // Clear global cache on shutdown - ClearGlobalCache(); - - initialized = false; -} - -void ALE::LoadScriptPaths() -{ - uint32 oldMSTime = ALEUtil::GetCurrTime(); - - lua_scripts.clear(); - lua_extensions.clear(); - - lua_folderpath = ALEConfig::GetInstance().GetScriptPath(); - const std::string& lua_path_extra = static_cast(ALEConfig::GetInstance().GetRequirePath()); - const std::string& lua_cpath_extra = static_cast(ALEConfig::GetInstance().GetRequireCPath()); - -#ifndef ALE_WINDOWS - if (lua_folderpath[0] == '~') - if (const char* home = getenv("HOME")) - lua_folderpath.replace(0, 1, home); -#endif - ALE_LOG_INFO("[ALE]: Searching scripts from `{}`", lua_folderpath); - - // clear all cache variables - lua_requirepath.clear(); - lua_requirecpath.clear(); - - GetScripts(lua_folderpath); - - // append our custom require paths and cpaths if the config variables are not empty - if (!lua_path_extra.empty()) - lua_requirepath += lua_path_extra; - - if (!lua_cpath_extra.empty()) - lua_requirecpath += lua_cpath_extra; - - // Erase last ; - if (!lua_requirepath.empty()) - lua_requirepath.erase(lua_requirepath.end() - 1); - - if (!lua_requirecpath.empty()) - lua_requirecpath.erase(lua_requirecpath.end() - 1); - - ALE_LOG_DEBUG("[ALE]: Loaded {} scripts in {} ms", lua_scripts.size() + lua_extensions.size(), ALEUtil::GetTimeDiff(oldMSTime)); -} - -void ALE::_ReloadALE() -{ - LOCK_ALE; - ASSERT(IsInitialized()); - - if (eConfigMgr->GetOption("ALE.PlayerAnnounceReload", false)) - eWorldSessionMgr->SendServerMessage(SERVER_MSG_STRING, "Reloading ALE..."); - else - ChatHandler(nullptr).SendGMText(SERVER_MSG_STRING, "Reloading ALE..."); - - // Remove all timed events - sALE->eventMgr->SetStates(LUAEVENT_STATE_ERASE); - - // Close lua - sALE->CloseLua(); - - // Reload script paths - LoadScriptPaths(); - - // Open new lua and libaraies - sALE->OpenLua(); - - // Run scripts from laoded paths - sALE->RunScripts(); - - reload = false; -} - -ALE::ALE() : -event_level(0), -push_counter(0), - -L(NULL), -eventMgr(NULL), -httpManager(), -queryProcessor(), - -ServerEventBindings(NULL), -PlayerEventBindings(NULL), -GuildEventBindings(NULL), -GroupEventBindings(NULL), -VehicleEventBindings(NULL), -BGEventBindings(NULL), -AllCreatureEventBindings(NULL), - -PacketEventBindings(NULL), -CreatureEventBindings(NULL), -CreatureGossipBindings(NULL), -GameObjectEventBindings(NULL), -GameObjectGossipBindings(NULL), -ItemEventBindings(NULL), -ItemGossipBindings(NULL), -PlayerGossipBindings(NULL), -MapEventBindings(NULL), -InstanceEventBindings(NULL), -TicketEventBindings(NULL), -SpellEventBindings(NULL), - -CreatureUniqueBindings(NULL) -{ - ASSERT(IsInitialized()); - - OpenLua(); - - // Replace this with map insert if making multithread version - - // Set event manager. Must be after setting sALE - // on multithread have a map of state pointers and here insert this pointer to the map and then save a pointer of that pointer to the EventMgr - eventMgr = new EventMgr(&ALE::GALE); -} - -ALE::~ALE() -{ - ASSERT(IsInitialized()); - - CloseLua(); - - delete eventMgr; - eventMgr = NULL; -} - -void ALE::CloseLua() -{ - OnLuaStateClose(); - - DestroyBindStores(); - - // Must close lua state after deleting stores and mgr - if (L) - lua_close(L); - L = NULL; - - instanceDataRefs.clear(); - continentDataRefs.clear(); -} - -void ALE::OpenLua() -{ - if (!ALEConfig::GetInstance().IsALEEnabled()) - { - ALE_LOG_INFO("[ALE]: ALE is disabled in config"); - return; - } - - L = luaL_newstate(); - - lua_pushlightuserdata(L, this); - lua_setfield(L, LUA_REGISTRYINDEX, ALE_STATE_PTR); - - CreateBindStores(); - - // open base lua libraries - luaL_openlibs(L); - - // open additional lua libraries - - // Register methods and functions - RegisterFunctions(this); - - // Set lua require folder paths (scripts folder structure) - lua_getglobal(L, "package"); - lua_pushstring(L, GetRequirePath().c_str()); - lua_setfield(L, -2, "path"); - lua_pushstring(L, GetRequireCPath().c_str()); - lua_setfield(L, -2, "cpath"); - - // Set package.loaders loader for precompiled scripts - lua_getfield(L, -1, "loaders"); - if (lua_isnil(L, -1)) { - // Lua 5.2+ uses searchers instead of loaders - lua_pop(L, 1); - lua_getfield(L, -1, "searchers"); - } - - lua_pop(L, 1); -} - -void ALE::CreateBindStores() -{ - DestroyBindStores(); - - ServerEventBindings = new BindingMap< EventKey >(L); - PlayerEventBindings = new BindingMap< EventKey >(L); - GuildEventBindings = new BindingMap< EventKey >(L); - GroupEventBindings = new BindingMap< EventKey >(L); - VehicleEventBindings = new BindingMap< EventKey >(L); - BGEventBindings = new BindingMap< EventKey >(L); - TicketEventBindings = new BindingMap< EventKey >(L); - AllCreatureEventBindings = new BindingMap< EventKey >(L); - - PacketEventBindings = new BindingMap< EntryKey >(L); - CreatureEventBindings = new BindingMap< EntryKey >(L); - CreatureGossipBindings = new BindingMap< EntryKey >(L); - GameObjectEventBindings = new BindingMap< EntryKey >(L); - GameObjectGossipBindings = new BindingMap< EntryKey >(L); - ItemEventBindings = new BindingMap< EntryKey >(L); - ItemGossipBindings = new BindingMap< EntryKey >(L); - PlayerGossipBindings = new BindingMap< EntryKey >(L); - MapEventBindings = new BindingMap< EntryKey >(L); - InstanceEventBindings = new BindingMap< EntryKey >(L); - SpellEventBindings = new BindingMap< EntryKey >(L); - - CreatureUniqueBindings = new BindingMap< UniqueObjectKey >(L); -} - -void ALE::DestroyBindStores() -{ - delete ServerEventBindings; - delete PlayerEventBindings; - delete GuildEventBindings; - delete GroupEventBindings; - delete VehicleEventBindings; - delete AllCreatureEventBindings; - - delete PacketEventBindings; - delete CreatureEventBindings; - delete CreatureGossipBindings; - delete GameObjectEventBindings; - delete GameObjectGossipBindings; - delete ItemEventBindings; - delete ItemGossipBindings; - delete PlayerGossipBindings; - delete BGEventBindings; - delete MapEventBindings; - delete InstanceEventBindings; - delete SpellEventBindings; - - delete CreatureUniqueBindings; - - ServerEventBindings = NULL; - PlayerEventBindings = NULL; - GuildEventBindings = NULL; - GroupEventBindings = NULL; - VehicleEventBindings = NULL; - AllCreatureEventBindings = NULL; - - PacketEventBindings = NULL; - CreatureEventBindings = NULL; - CreatureGossipBindings = NULL; - GameObjectEventBindings = NULL; - GameObjectGossipBindings = NULL; - ItemEventBindings = NULL; - ItemGossipBindings = NULL; - PlayerGossipBindings = NULL; - BGEventBindings = NULL; - MapEventBindings = NULL; - InstanceEventBindings = NULL; - SpellEventBindings = NULL; - - CreatureUniqueBindings = NULL; -} - -void ALE::AddScriptPath(std::string filename, const std::string& fullpath) -{ - ALE_LOG_DEBUG("[ALE]: AddScriptPath Checking file `{}`", fullpath); - - // split file name - std::size_t extDot = filename.find_last_of('.'); - if (extDot == std::string::npos) - return; - std::string ext = filename.substr(extDot); - filename = filename.substr(0, extDot); - - // check extension and add path to scripts to load - if (ext != ".lua" && ext != ".dll" && ext != ".so" && ext != ".ext" && ext !=".moon" && ext != ".out") - return; - bool extension = ext == ".ext"; - - LuaScript script; - script.fileext = ext; - script.filename = filename; - script.filepath = fullpath; - script.modulepath = fullpath.substr(0, fullpath.length() - filename.length() - ext.length()); - if (extension) - lua_extensions.push_back(script); - else - lua_scripts.push_back(script); - ALE_LOG_DEBUG("[ALE]: AddScriptPath add path `{}`", fullpath); -} - -std::time_t ALE::GetFileModTime(const std::string& filepath) -{ - struct stat fileInfo; - if (stat(filepath.c_str(), &fileInfo) == 0) - return fileInfo.st_mtime; - return 0; -} - -std::time_t ALE::GetFileModTimeWithCache(const std::string& filepath) -{ - auto it = timestampCache.find(filepath); - if (it != timestampCache.end()) - return it->second; - - std::time_t modTime = GetFileModTime(filepath); - timestampCache[filepath] = modTime; - return modTime; -} - -bool ALE::CompileScriptToGlobalCache(const std::string& filepath) -{ - std::lock_guard lock(globalCacheMutex); - - lua_State* tempL = luaL_newstate(); - if (!tempL) - return false; - - int result = luaL_loadfile(tempL, filepath.c_str()); - if (result != LUA_OK) - { - lua_close(tempL); - return false; - } - - std::time_t modTime = GetFileModTime(filepath); - - auto& cacheEntry = globalBytecodeCache[filepath]; - cacheEntry.last_modified = modTime; - cacheEntry.filepath = filepath; - cacheEntry.bytecode.clear(); - cacheEntry.bytecode.reserve(1024); - - struct BytecodeWriter { - BytecodeBuffer* buffer; - static int writer(lua_State*, const void* p, size_t sz, void* ud) { - BytecodeWriter* w = static_cast(ud); - const uint8* bytes = static_cast(p); - w->buffer->insert(w->buffer->end(), bytes, bytes + sz); - return 0; - } - }; - - BytecodeWriter writer; - writer.buffer = &cacheEntry.bytecode; - - int dumpResult = lua_dump(tempL, BytecodeWriter::writer, &writer); - if (dumpResult != LUA_OK || cacheEntry.bytecode.empty()) - { - globalBytecodeCache.erase(filepath); - lua_close(tempL); - return false; - } - - lua_close(tempL); - return true; -} - -bool ALE::CompileMoonScriptToGlobalCache(const std::string& filepath) -{ - std::lock_guard lock(globalCacheMutex); - - lua_State* tempL = luaL_newstate(); - if (!tempL) - return false; - - luaL_openlibs(tempL); - - std::string moonscriptLoader = "return require('moonscript').loadfile([[" + filepath + "]])"; - int result = luaL_loadstring(tempL, moonscriptLoader.c_str()); - if (result != LUA_OK) - { - lua_close(tempL); - return false; - } - - result = lua_pcall(tempL, 0, 1, 0); - if (result != LUA_OK) - { - lua_close(tempL); - return false; - } - - std::time_t modTime = GetFileModTime(filepath); - - auto& cacheEntry = globalBytecodeCache[filepath]; - cacheEntry.last_modified = modTime; - cacheEntry.filepath = filepath; - cacheEntry.bytecode.clear(); - cacheEntry.bytecode.reserve(2048); - - struct BytecodeWriter { - BytecodeBuffer* buffer; - static int writer(lua_State*, const void* p, size_t sz, void* ud) { - BytecodeWriter* w = static_cast(ud); - const uint8* bytes = static_cast(p); - w->buffer->insert(w->buffer->end(), bytes, bytes + sz); - return 0; - } - }; - - BytecodeWriter writer; - writer.buffer = &cacheEntry.bytecode; - - int dumpResult = lua_dump(tempL, BytecodeWriter::writer, &writer); - if (dumpResult != LUA_OK || cacheEntry.bytecode.empty()) - { - globalBytecodeCache.erase(filepath); - lua_close(tempL); - return false; - } - - lua_close(tempL); - return true; -} - -int ALE::TryLoadFromGlobalCache(lua_State* L, const std::string& filepath) -{ - std::lock_guard lock(globalCacheMutex); - - auto it = globalBytecodeCache.find(filepath); - if (it == globalBytecodeCache.end() || it->second.bytecode.empty()) - return LUA_ERRFILE; - - std::time_t currentModTime = GetFileModTimeWithCache(filepath); - if (it->second.last_modified != currentModTime || currentModTime == 0) - return LUA_ERRFILE; - - return luaL_loadbuffer(L, reinterpret_cast(it->second.bytecode.data()), it->second.bytecode.size(), filepath.c_str()); -} - -int ALE::LoadScriptWithCache(lua_State* L, const std::string& filepath, bool isMoonScript, uint32* compiledCount, uint32* cachedCount) -{ - bool cacheEnabled = ALEConfig::GetInstance().IsByteCodeCacheEnabled(); - - if (cacheEnabled) - { - int result = TryLoadFromGlobalCache(L, filepath); - if (result == LUA_OK) - { - if (cachedCount) (*cachedCount)++; - return LUA_OK; - } - - bool compileSuccess = isMoonScript ? - CompileMoonScriptToGlobalCache(filepath) : - CompileScriptToGlobalCache(filepath); - - if (compileSuccess) - { - if (compiledCount) (*compiledCount)++; - std::lock_guard lock(globalCacheMutex); - auto it = globalBytecodeCache.find(filepath); - if (it != globalBytecodeCache.end() && !it->second.bytecode.empty()) - { - result = luaL_loadbuffer(L, reinterpret_cast(it->second.bytecode.data()), it->second.bytecode.size(), filepath.c_str()); - if (result == LUA_OK) - return LUA_OK; - } - } - } - - if (isMoonScript) - { - std::string str = "return require('moonscript').loadfile([[" + filepath + "]])"; - int result = luaL_loadstring(L, str.c_str()); - if (result != LUA_OK) - return result; - return lua_pcall(L, 0, LUA_MULTRET, 0); - } - else - { - return luaL_loadfile(L, filepath.c_str()); - } -} - -void ALE::ClearGlobalCache() -{ - std::lock_guard lock(globalCacheMutex); - globalBytecodeCache.clear(); - timestampCache.clear(); - ALE_LOG_INFO("[ALE]: Global bytecode cache cleared"); -} - -void ALE::ClearTimestampCache() -{ - std::lock_guard lock(globalCacheMutex); - timestampCache.clear(); -} - -size_t ALE::GetGlobalCacheSize() -{ - std::lock_guard lock(globalCacheMutex); - return globalBytecodeCache.size(); -} - -int ALE::LoadCompiledScript(lua_State* L, const std::string& filepath) -{ - std::ifstream file(filepath, std::ios::binary); - if (!file.is_open()) - return LUA_ERRFILE; - - file.seekg(0, std::ios::end); - size_t fileSize = file.tellg(); - file.seekg(0, std::ios::beg); - - std::vector buffer(fileSize); - file.read(buffer.data(), fileSize); - file.close(); - - return luaL_loadbuffer(L, buffer.data(), fileSize, filepath.c_str()); -} - -// Finds lua script files from given path (including subdirectories) and pushes them to scripts -void ALE::GetScripts(std::string path) -{ - ALE_LOG_DEBUG("[ALE]: GetScripts from path `{}`", path); - - boost::filesystem::path someDir(path); - boost::filesystem::directory_iterator end_iter; - - if (boost::filesystem::exists(someDir) && boost::filesystem::is_directory(someDir)) - { - lua_requirepath += - path + "/?.lua;" + - path + "/?.moon;" + - path + "/?.ext;"; - - lua_requirecpath += - path + "/?.dll;" + - path + "/?.so;"; - - for (boost::filesystem::directory_iterator dir_iter(someDir); dir_iter != end_iter; ++dir_iter) - { - std::string fullpath = dir_iter->path().generic_string(); - - // Check if file is hidden -#ifdef ALE_WINDOWS - DWORD dwAttrib = GetFileAttributes(fullpath.c_str()); - if (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_HIDDEN)) - continue; -#else - std::string name = dir_iter->path().filename().generic_string().c_str(); - if (name[0] == '.') - continue; -#endif - - // load subfolder - if (boost::filesystem::is_directory(dir_iter->status())) - { - GetScripts(fullpath); - continue; - } - - if (boost::filesystem::is_regular_file(dir_iter->status())) - { - // was file, try add - std::string filename = dir_iter->path().filename().generic_string(); - AddScriptPath(filename, fullpath); - } - } - } -} - -static bool ScriptPathComparator(const LuaScript& first, const LuaScript& second) -{ - return first.filepath < second.filepath; -} - -void ALE::RunScripts() -{ - LOCK_ALE; - if (!ALEConfig::GetInstance().IsALEEnabled()) - return; - - uint32 oldMSTime = ALEUtil::GetCurrTime(); - uint32 count = 0; - uint32 compiledCount = 0; - uint32 cachedCount = 0; - uint32 precompiledCount = 0; - bool cacheEnabled = eConfigMgr->GetOption("ALE.BytecodeCache", true); - - if (cacheEnabled) - ClearTimestampCache(); - - ScriptList scripts; - lua_extensions.sort(ScriptPathComparator); - lua_scripts.sort(ScriptPathComparator); - scripts.insert(scripts.end(), lua_extensions.begin(), lua_extensions.end()); - scripts.insert(scripts.end(), lua_scripts.begin(), lua_scripts.end()); - - std::unordered_map loaded; // filename, path - - lua_getglobal(L, "package"); - // Stack: package - luaL_getsubtable(L, -1, "loaded"); - // Stack: package, modules - int modules = lua_gettop(L); - for (ScriptList::iterator it = scripts.begin(); it != scripts.end(); ++it) - { - // Check that no duplicate names exist - if (loaded.find(it->filename) != loaded.end()) - { - ALE_LOG_ERROR("[ALE]: Error loading `{}`. File with same name already loaded from `{}`, rename either file", it->filepath, loaded[it->filename]); - continue; - } - loaded[it->filename] = it->filepath; - - lua_getfield(L, modules, it->filename.c_str()); - // Stack: package, modules, module - if (!lua_isnoneornil(L, -1)) - { - lua_pop(L, 1); - ALE_LOG_DEBUG("[ALE]: `{}` was already loaded or required", it->filepath); - continue; - } - lua_pop(L, 1); - // Stack: package, modules - - if (it->fileext == ".moon") - { - if (LoadScriptWithCache(L, it->filepath, true, &compiledCount, &cachedCount)) - { - // Stack: package, modules, errmsg - ALE_LOG_ERROR("[ALE]: Error loading MoonScript `{}`", it->filepath); - Report(L); - // Stack: package, modules - continue; - } - } - else if (it->fileext == ".out") - { - if (LoadCompiledScript(L, it->filepath)) - { - // Stack: package, modules, errmsg - ALE_LOG_ERROR("[ALE]: Error loading compiled script `{}`", it->filepath); - Report(L); - // Stack: package, modules - continue; - } - precompiledCount++; - } - else if (it->fileext == ".lua" || it->fileext == ".ext") - { - if (LoadScriptWithCache(L, it->filepath, false, &compiledCount, &cachedCount)) - { - // Stack: package, modules, errmsg - ALE_LOG_ERROR("[ALE]: Error loading `{}`", it->filepath); - Report(L); - // Stack: package, modules - continue; - } - } - else - { - if (luaL_loadfile(L, it->filepath.c_str())) - { - // Stack: package, modules, errmsg - ALE_LOG_ERROR("[ALE]: Error loading `{}`", it->filepath); - Report(L); - // Stack: package, modules - continue; - } - } - - // Stack: package, modules, filefunc - if (ExecuteCall(0, 1)) - { - // Stack: package, modules, result - if (lua_isnoneornil(L, -1) || (lua_isboolean(L, -1) && !lua_toboolean(L, -1))) - { - // if result evaluates to false, change it to true - lua_pop(L, 1); - Push(L, true); - } - lua_setfield(L, modules, it->filename.c_str()); - // Stack: package, modules - - // successfully loaded and ran file - ALE_LOG_DEBUG("[ALE]: Successfully loaded `{}`", it->filepath); - ++count; - continue; - } - } - // Stack: package, modules - lua_pop(L, 2); - - std::string details = ""; - if (cacheEnabled && (compiledCount > 0 || cachedCount > 0 || precompiledCount > 0)) - { - details = fmt::format("({} compiled, {} cached, {} pre-compiled)", compiledCount, cachedCount, precompiledCount); - } - ALE_LOG_INFO("[ALE]: Executed {} Lua scripts in {} ms {}", count, ALEUtil::GetTimeDiff(oldMSTime), details); - - OnLuaStateOpen(); -} - -void ALE::InvalidateObjects() -{ - ++callstackid; - ASSERT(callstackid && "Callstackid overflow"); -} - -void ALE::Report(lua_State* _L) -{ - const char* msg = lua_tostring(_L, -1); - ALE_LOG_ERROR("{}", msg); - lua_pop(_L, 1); -} - -// Borrowed from http://stackoverflow.com/questions/12256455/print-stacktrace-from-c-code-with-embedded-lua -int ALE::StackTrace(lua_State *_L) -{ - // Stack: errmsg - if (!lua_isstring(_L, -1)) /* 'message' not a string? */ - return 1; /* keep it intact */ - // Stack: errmsg, debug - lua_getglobal(_L, "debug"); - if (!lua_istable(_L, -1)) - { - lua_pop(_L, 1); - return 1; - } - // Stack: errmsg, debug, traceback - lua_getfield(_L, -1, "traceback"); - if (!lua_isfunction(_L, -1)) - { - lua_pop(_L, 2); - return 1; - } - lua_pushvalue(_L, -3); /* pass error message */ - lua_pushinteger(_L, 1); /* skip this function and traceback */ - // Stack: errmsg, debug, traceback, errmsg, 2 - lua_call(_L, 2, 1); /* call debug.traceback */ - - // dirty stack? - // Stack: errmsg, debug, tracemsg - sALE->OnError(std::string(lua_tostring(_L, -1))); - return 1; -} - -bool ALE::ExecuteCall(int params, int res) -{ - int top = lua_gettop(L); - int base = top - params; - - // Expected: function, [parameters] - ASSERT(base > 0); - - // Check function type - if (!lua_isfunction(L, base)) - { - ALE_LOG_ERROR("[ALE]: Cannot execute call: registered value is {}, not a function.", luaL_tolstring(L, base, NULL)); - ASSERT(false); // stack probably corrupt - } - - bool usetrace = ALEConfig::GetInstance().IsTraceBackEnabled(); - if (usetrace) - { - lua_pushcfunction(L, &StackTrace); - // Stack: function, [parameters], traceback - lua_insert(L, base); - // Stack: traceback, function, [parameters] - } - - // Objects are invalidated when event_level hits 0 - ++event_level; - int result = lua_pcall(L, params, res, usetrace ? base : 0); - --event_level; - - if (usetrace) - { - // Stack: traceback, [results or errmsg] - lua_remove(L, base); - } - // Stack: [results or errmsg] - - // lua_pcall returns 0 on success. - // On error print the error and push nils for expected amount of returned values - if (result) - { - // Stack: errmsg - Report(L); - - // Force garbage collect - lua_gc(L, LUA_GCCOLLECT, 0); - - // Push nils for expected amount of results - for (int i = 0; i < res; ++i) - lua_pushnil(L); - // Stack: [nils] - return false; - } - - // Stack: [results] - return true; -} - -void ALE::Push(lua_State* luastate) -{ - lua_pushnil(luastate); -} -void ALE::Push(lua_State* luastate, const long long l) -{ - ALETemplate::Push(luastate, new long long(l)); -} -void ALE::Push(lua_State* luastate, const unsigned long long l) -{ - ALETemplate::Push(luastate, new unsigned long long(l)); -} -void ALE::Push(lua_State* luastate, const long l) -{ - Push(luastate, static_cast(l)); -} -void ALE::Push(lua_State* luastate, const unsigned long l) -{ - Push(luastate, static_cast(l)); -} -void ALE::Push(lua_State* luastate, const int i) -{ - lua_pushinteger(luastate, i); -} -void ALE::Push(lua_State* luastate, const unsigned int u) -{ - lua_pushunsigned(luastate, u); -} -void ALE::Push(lua_State* luastate, const double d) -{ - lua_pushnumber(luastate, d); -} -void ALE::Push(lua_State* luastate, const float f) -{ - lua_pushnumber(luastate, f); -} -void ALE::Push(lua_State* luastate, const bool b) -{ - lua_pushboolean(luastate, b); -} -void ALE::Push(lua_State* luastate, const std::string& str) -{ - lua_pushstring(luastate, str.c_str()); -} -void ALE::Push(lua_State* luastate, const char* str) -{ - lua_pushstring(luastate, str); -} -void ALE::Push(lua_State* luastate, Pet const* pet) -{ - Push(luastate, pet); -} -void ALE::Push(lua_State* luastate, TempSummon const* summon) -{ - Push(luastate, summon); -} -void ALE::Push(lua_State* luastate, Unit const* unit) -{ - if (!unit) - { - Push(luastate); - return; - } - switch (unit->GetTypeId()) - { - case TYPEID_UNIT: - Push(luastate, unit->ToCreature()); - break; - case TYPEID_PLAYER: - Push(luastate, unit->ToPlayer()); - break; - default: - ALETemplate::Push(luastate, unit); - } -} -void ALE::Push(lua_State* luastate, WorldObject const* obj) -{ - if (!obj) - { - Push(luastate); - return; - } - switch (obj->GetTypeId()) - { - case TYPEID_UNIT: - Push(luastate, obj->ToCreature()); - break; - case TYPEID_PLAYER: - Push(luastate, obj->ToPlayer()); - break; - case TYPEID_GAMEOBJECT: - Push(luastate, obj->ToGameObject()); - break; - case TYPEID_CORPSE: - Push(luastate, obj->ToCorpse()); - break; - default: - ALETemplate::Push(luastate, obj); - } -} -void ALE::Push(lua_State* luastate, Object const* obj) -{ - if (!obj) - { - Push(luastate); - return; - } - switch (obj->GetTypeId()) - { - case TYPEID_UNIT: - Push(luastate, obj->ToCreature()); - break; - case TYPEID_PLAYER: - Push(luastate, obj->ToPlayer()); - break; - case TYPEID_GAMEOBJECT: - Push(luastate, obj->ToGameObject()); - break; - case TYPEID_CORPSE: - Push(luastate, obj->ToCorpse()); - break; - default: - ALETemplate::Push(luastate, obj); - } -} -void ALE::Push(lua_State* luastate, ObjectGuid const guid) -{ - ALETemplate::Push(luastate, new unsigned long long(guid.GetRawValue())); -} - -void ALE::Push(lua_State* luastate, GemPropertiesEntry const& gemProperties) -{ - Push(luastate, &gemProperties); -} - -void ALE::Push(lua_State* luastate, SpellEntry const& spell) -{ - Push(luastate, &spell); -} - -void ALE::Push(lua_State* luastate, CreatureTemplate const* creatureTemplate) -{ - Push(luastate, creatureTemplate); -} - -std::string ALE::FormatQuery(lua_State* L, const char* query) -{ - int numArgs = lua_gettop(L); - std::string formattedQuery = query; - - size_t position = 0; - for (int i = 2; i <= numArgs; ++i) - { - std::string arg; - - if (lua_isnumber(L, i)) - { - arg = std::to_string(lua_tonumber(L, i)); - } - else if (lua_isstring(L, i)) - { - std::string value = lua_tostring(L, i); - for (size_t pos = 0; (pos = value.find('\'', pos)) != std::string::npos; pos += 2) - { - value.insert(pos, "'"); - } - arg = "'" + value + "'"; - } - else - { - luaL_error(L, "Unsupported argument type. Only numbers and strings are supported."); - return ""; - } - - position = formattedQuery.find("?", position); - if (position == std::string::npos) - { - luaL_error(L, "Mismatch between placeholders and arguments."); - return ""; - } - formattedQuery.replace(position, 1, arg); - position += arg.length(); - } - - return formattedQuery; -} - -static int CheckIntegerRange(lua_State* luastate, int narg, int min, int max) -{ - double value = luaL_checknumber(luastate, narg); - char error_buffer[64]; - - if (value > max) - { - snprintf(error_buffer, 64, "value must be less than or equal to %i", max); - return luaL_argerror(luastate, narg, error_buffer); - } - - if (value < min) - { - snprintf(error_buffer, 64, "value must be greater than or equal to %i", min); - return luaL_argerror(luastate, narg, error_buffer); - } - - return static_cast(value); -} - -static unsigned int CheckUnsignedRange(lua_State* luastate, int narg, unsigned int max) -{ - double value = luaL_checknumber(luastate, narg); - - if (value < 0) - return luaL_argerror(luastate, narg, "value must be greater than or equal to 0"); - - if (value > max) - { - char error_buffer[64]; - snprintf(error_buffer, 64, "value must be less than or equal to %u", max); - return luaL_argerror(luastate, narg, error_buffer); - } - - return static_cast(value); -} - -template<> bool ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return lua_toboolean(luastate, narg) != 0; -} -template<> float ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return static_cast(luaL_checknumber(luastate, narg)); -} -template<> double ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return luaL_checknumber(luastate, narg); -} -template<> signed char ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return CheckIntegerRange(luastate, narg, SCHAR_MIN, SCHAR_MAX); -} -template<> unsigned char ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return CheckUnsignedRange(luastate, narg, UCHAR_MAX); -} -template<> short ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return CheckIntegerRange(luastate, narg, SHRT_MIN, SHRT_MAX); -} -template<> unsigned short ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return CheckUnsignedRange(luastate, narg, USHRT_MAX); -} -template<> int ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return CheckIntegerRange(luastate, narg, INT_MIN, INT_MAX); -} -template<> unsigned int ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return CheckUnsignedRange(luastate, narg, UINT_MAX); -} -template<> const char* ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return luaL_checkstring(luastate, narg); -} -template<> std::string ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return luaL_checkstring(luastate, narg); -} -template<> long long ALE::CHECKVAL(lua_State* luastate, int narg) -{ - if (lua_isnumber(luastate, narg)) - return static_cast(CHECKVAL(luastate, narg)); - return *(ALE::CHECKOBJ(luastate, narg, true)); -} -template<> unsigned long long ALE::CHECKVAL(lua_State* luastate, int narg) -{ - if (lua_isnumber(luastate, narg)) - return static_cast(CHECKVAL(luastate, narg)); - return *(ALE::CHECKOBJ(luastate, narg, true)); -} -template<> long ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return static_cast(CHECKVAL(luastate, narg)); -} -template<> unsigned long ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return static_cast(CHECKVAL(luastate, narg)); -} -template<> ObjectGuid ALE::CHECKVAL(lua_State* luastate, int narg) -{ - return ObjectGuid(uint64((CHECKVAL(luastate, narg)))); -} - -template<> Object* ALE::CHECKOBJ(lua_State* luastate, int narg, bool error) -{ - Object* obj = CHECKOBJ(luastate, narg, false); - if (!obj) - obj = CHECKOBJ(luastate, narg, false); - if (!obj) - obj = ALETemplate::Check(luastate, narg, error); - return obj; -} -template<> WorldObject* ALE::CHECKOBJ(lua_State* luastate, int narg, bool error) -{ - WorldObject* obj = CHECKOBJ(luastate, narg, false); - if (!obj) - obj = CHECKOBJ(luastate, narg, false); - if (!obj) - obj = CHECKOBJ(luastate, narg, false); - if (!obj) - obj = ALETemplate::Check(luastate, narg, error); - return obj; -} -template<> Unit* ALE::CHECKOBJ(lua_State* luastate, int narg, bool error) -{ - Unit* obj = CHECKOBJ(luastate, narg, false); - if (!obj) - obj = CHECKOBJ(luastate, narg, false); - if (!obj) - obj = ALETemplate::Check(luastate, narg, error); - return obj; -} - -template<> ALEObject* ALE::CHECKOBJ(lua_State* luastate, int narg, bool error) -{ - return CHECKTYPE(luastate, narg, NULL, error); -} - -ALEObject* ALE::CHECKTYPE(lua_State* luastate, int narg, const char* tname, bool error) -{ - if (lua_islightuserdata(luastate, narg)) - { - if (error) - luaL_argerror(luastate, narg, "bad argument : userdata expected, got lightuserdata"); - return NULL; - } - - ALEObject** ptrHold = static_cast(lua_touserdata(luastate, narg)); - - if (!ptrHold || (tname && (*ptrHold)->GetTypeName() != tname)) - { - if (error) - { - char buff[256]; - snprintf(buff, 256, "bad argument : %s expected, got %s", tname ? tname : "ALEObject", ptrHold ? (*ptrHold)->GetTypeName() : luaL_typename(luastate, narg)); - luaL_argerror(luastate, narg, buff); - } - return NULL; - } - return *ptrHold; -} - -template -static int cancelBinding(lua_State *L) -{ - uint64 bindingID = ALE::CHECKVAL(L, lua_upvalueindex(1)); - - BindingMap* bindings = (BindingMap*)lua_touserdata(L, lua_upvalueindex(2)); - ASSERT(bindings != NULL); - - bindings->Remove(bindingID); - - return 0; -} - -template -static void createCancelCallback(lua_State* L, uint64 bindingID, BindingMap* bindings) -{ - ALE::Push(L, bindingID); - lua_pushlightuserdata(L, bindings); - // Stack: bindingID, bindings - - lua_pushcclosure(L, &cancelBinding, 2); - // Stack: cancel_callback -} - -// Saves the function reference ID given to the register type's store for given entry under the given event -int ALE::Register(lua_State* L, uint8 regtype, uint32 entry, ObjectGuid guid, uint32 instanceId, uint32 event_id, int functionRef, uint32 shots) -{ - uint64 bindingID; - - switch (regtype) - { - case Hooks::REGTYPE_SERVER: - if (event_id < Hooks::SERVER_EVENT_COUNT) - { - auto key = EventKey((Hooks::ServerEvents)event_id); - bindingID = ServerEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, ServerEventBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_PLAYER: - if (event_id < Hooks::PLAYER_EVENT_COUNT) - { - auto key = EventKey((Hooks::PlayerEvents)event_id); - bindingID = PlayerEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, PlayerEventBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_GUILD: - if (event_id < Hooks::GUILD_EVENT_COUNT) - { - auto key = EventKey((Hooks::GuildEvents)event_id); - bindingID = GuildEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, GuildEventBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_GROUP: - if (event_id < Hooks::GROUP_EVENT_COUNT) - { - auto key = EventKey((Hooks::GroupEvents)event_id); - bindingID = GroupEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, GroupEventBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_VEHICLE: - if (event_id < Hooks::VEHICLE_EVENT_COUNT) - { - auto key = EventKey((Hooks::VehicleEvents)event_id); - bindingID = VehicleEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, VehicleEventBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_BG: - if (event_id < Hooks::BG_EVENT_COUNT) - { - auto key = EventKey((Hooks::BGEvents)event_id); - bindingID = BGEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, BGEventBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_PACKET: - if (event_id < Hooks::PACKET_EVENT_COUNT) - { - if (entry >= NUM_MSG_TYPES) - { - luaL_unref(L, LUA_REGISTRYINDEX, functionRef); - luaL_error(L, "Couldn't find a creature with (ID: %d)!", entry); - return 0; // Stack: (empty) - } - - auto key = EntryKey((Hooks::PacketEvents)event_id, entry); - bindingID = PacketEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, PacketEventBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_CREATURE: - if (event_id < Hooks::CREATURE_EVENT_COUNT) - { - if (entry != 0) - { - if (!eObjectMgr->GetCreatureTemplate(entry)) - { - luaL_unref(L, LUA_REGISTRYINDEX, functionRef); - luaL_error(L, "Couldn't find a creature with (ID: %d)!", entry); - return 0; // Stack: (empty) - } - - auto key = EntryKey((Hooks::CreatureEvents)event_id, entry); - bindingID = CreatureEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, CreatureEventBindings); - } - else - { - if (guid.IsEmpty()) - { - luaL_unref(L, LUA_REGISTRYINDEX, functionRef); - luaL_error(L, "guid was 0!"); - return 0; // Stack: (empty) - } - - auto key = UniqueObjectKey((Hooks::CreatureEvents)event_id, guid, instanceId); - bindingID = CreatureUniqueBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, CreatureUniqueBindings); - } - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_CREATURE_GOSSIP: - if (event_id < Hooks::GOSSIP_EVENT_COUNT) - { - if (!eObjectMgr->GetCreatureTemplate(entry)) - { - luaL_unref(L, LUA_REGISTRYINDEX, functionRef); - luaL_error(L, "Couldn't find a creature with (ID: %d)!", entry); - return 0; // Stack: (empty) - } - - auto key = EntryKey((Hooks::GossipEvents)event_id, entry); - bindingID = CreatureGossipBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, CreatureGossipBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_GAMEOBJECT: - if (event_id < Hooks::GAMEOBJECT_EVENT_COUNT) - { - if (!eObjectMgr->GetGameObjectTemplate(entry)) - { - luaL_unref(L, LUA_REGISTRYINDEX, functionRef); - luaL_error(L, "Couldn't find a gameobject with (ID: %d)!", entry); - return 0; // Stack: (empty) - } - - auto key = EntryKey((Hooks::GameObjectEvents)event_id, entry); - bindingID = GameObjectEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, GameObjectEventBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_GAMEOBJECT_GOSSIP: - if (event_id < Hooks::GOSSIP_EVENT_COUNT) - { - if (!eObjectMgr->GetGameObjectTemplate(entry)) - { - luaL_unref(L, LUA_REGISTRYINDEX, functionRef); - luaL_error(L, "Couldn't find a gameobject with (ID: %d)!", entry); - return 0; // Stack: (empty) - } - - auto key = EntryKey((Hooks::GossipEvents)event_id, entry); - bindingID = GameObjectGossipBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, GameObjectGossipBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_ITEM: - if (event_id < Hooks::ITEM_EVENT_COUNT) - { - if (!eObjectMgr->GetItemTemplate(entry)) - { - luaL_unref(L, LUA_REGISTRYINDEX, functionRef); - luaL_error(L, "Couldn't find a item with (ID: %d)!", entry); - return 0; // Stack: (empty) - } - - auto key = EntryKey((Hooks::ItemEvents)event_id, entry); - bindingID = ItemEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, ItemEventBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_ITEM_GOSSIP: - if (event_id < Hooks::GOSSIP_EVENT_COUNT) - { - if (!eObjectMgr->GetItemTemplate(entry)) - { - luaL_unref(L, LUA_REGISTRYINDEX, functionRef); - luaL_error(L, "Couldn't find a item with (ID: %d)!", entry); - return 0; // Stack: (empty) - } - - auto key = EntryKey((Hooks::GossipEvents)event_id, entry); - bindingID = ItemGossipBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, ItemGossipBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_PLAYER_GOSSIP: - if (event_id < Hooks::GOSSIP_EVENT_COUNT) - { - auto key = EntryKey((Hooks::GossipEvents)event_id, entry); - bindingID = PlayerGossipBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, PlayerGossipBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_MAP: - if (event_id < Hooks::INSTANCE_EVENT_COUNT) - { - auto key = EntryKey((Hooks::InstanceEvents)event_id, entry); - bindingID = MapEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, MapEventBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_INSTANCE: - if (event_id < Hooks::INSTANCE_EVENT_COUNT) - { - auto key = EntryKey((Hooks::InstanceEvents)event_id, entry); - bindingID = InstanceEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, InstanceEventBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_TICKET: - if (event_id < Hooks::TICKET_EVENT_COUNT) - { - auto key = EventKey((Hooks::TicketEvents)event_id); - bindingID = TicketEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, TicketEventBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_SPELL: - if (event_id < Hooks::SPELL_EVENT_COUNT) - { - if (!sSpellMgr->GetSpellInfo(entry)) - { - luaL_unref(L, LUA_REGISTRYINDEX, functionRef); - luaL_error(L, "Couldn't find a spell with (ID: %d)!", entry); - return 0; // Stack: (empty) - } - - auto key = EntryKey((Hooks::SpellEvents)event_id, entry); - bindingID = SpellEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, SpellEventBindings); - return 1; // Stack: callback - } - break; - - case Hooks::REGTYPE_ALL_CREATURE: - if (event_id < Hooks::ALL_CREATURE_EVENT_COUNT) - { - auto key = EventKey((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; - oss << "regtype " << static_cast(regtype) << ", event " << event_id << ", entry " << entry << ", guid " << guid.GetRawValue() << ", instance " << instanceId; - luaL_error(L, "Unknown event type (%s)", oss.str().c_str()); - return 0; -} - -/* - * Cleans up the stack, effectively undoing all Push calls and the Setup call. - */ -void ALE::CleanUpStack(int number_of_arguments) -{ - // Stack: event_id, [arguments] - - lua_pop(L, number_of_arguments + 1); // Add 1 because the caller doesn't know about `event_id`. - // Stack: (empty) - - if (event_level == 0) - InvalidateObjects(); -} - -/* - * Call a single event handler that was put on the stack with `Setup` and removes it from the stack. - * - * The caller is responsible for keeping track of how many times this should be called. - */ -int ALE::CallOneFunction(int number_of_functions, int number_of_arguments, int number_of_results) -{ - ++number_of_arguments; // Caller doesn't know about `event_id`. - ASSERT(number_of_functions > 0 && number_of_arguments > 0 && number_of_results >= 0); - // Stack: event_id, [arguments], [functions] - - int functions_top = lua_gettop(L); - int first_function_index = functions_top - number_of_functions + 1; - int arguments_top = first_function_index - 1; - int first_argument_index = arguments_top - number_of_arguments + 1; - - // Copy the arguments from the bottom of the stack to the top. - for (int argument_index = first_argument_index; argument_index <= arguments_top; ++argument_index) - { - lua_pushvalue(L, argument_index); - } - // Stack: event_id, [arguments], [functions], event_id, [arguments] - - ExecuteCall(number_of_arguments, number_of_results); - --functions_top; - // Stack: event_id, [arguments], [functions - 1], [results] - - return functions_top + 1; // Return the location of the first result (if any exist). -} - -CreatureAI* ALE::GetAI(Creature* creature) -{ - if (!ALEConfig::GetInstance().IsALEEnabled()) - return NULL; - - for (int i = 1; i < Hooks::CREATURE_EVENT_COUNT; ++i) - { - Hooks::CreatureEvents event_id = (Hooks::CreatureEvents)i; - - auto entryKey = EntryKey(event_id, creature->GetEntry()); - auto uniqueKey = UniqueObjectKey(event_id, creature->GET_GUID(), creature->GetInstanceId()); - - if (CreatureEventBindings->HasBindingsFor(entryKey) || - CreatureUniqueBindings->HasBindingsFor(uniqueKey)) - return new ALECreatureAI(creature); - } - - return NULL; -} - -InstanceData* ALE::GetInstanceData(Map* map) -{ - if (!ALEConfig::GetInstance().IsALEEnabled()) - return NULL; - - for (int i = 1; i < Hooks::INSTANCE_EVENT_COUNT; ++i) - { - Hooks::InstanceEvents event_id = (Hooks::InstanceEvents)i; - - auto key = EntryKey(event_id, map->GetId()); - - if (MapEventBindings->HasBindingsFor(key) || - InstanceEventBindings->HasBindingsFor(key)) - return new ALEInstanceAI(map); - } - - return NULL; -} - -bool ALE::HasInstanceData(Map const* map) -{ - if (!map->Instanceable()) - return continentDataRefs.find(map->GetId()) != continentDataRefs.end(); - else - return instanceDataRefs.find(map->GetInstanceId()) != instanceDataRefs.end(); -} - -void ALE::CreateInstanceData(Map const* map) -{ - ASSERT(lua_istable(L, -1)); - int ref = luaL_ref(L, LUA_REGISTRYINDEX); - - if (!map->Instanceable()) - { - uint32 mapId = map->GetId(); - - // If there's another table that was already stored for the map, unref it. - auto mapRef = continentDataRefs.find(mapId); - if (mapRef != continentDataRefs.end()) - { - luaL_unref(L, LUA_REGISTRYINDEX, mapRef->second); - } - - continentDataRefs[mapId] = ref; - } - else - { - uint32 instanceId = map->GetInstanceId(); - - // If there's another table that was already stored for the instance, unref it. - auto instRef = instanceDataRefs.find(instanceId); - if (instRef != instanceDataRefs.end()) - { - luaL_unref(L, LUA_REGISTRYINDEX, instRef->second); - } - - instanceDataRefs[instanceId] = ref; - } -} - -/* - * Unrefs the instanceId related events and data - * Does all required actions for when an instance is freed. - */ -void ALE::FreeInstanceId(uint32 instanceId) -{ - LOCK_ALE; - - if (!ALEConfig::GetInstance().IsALEEnabled()) - return; - - for (int i = 1; i < Hooks::INSTANCE_EVENT_COUNT; ++i) - { - auto key = EntryKey((Hooks::InstanceEvents)i, instanceId); - - if (MapEventBindings->HasBindingsFor(key)) - MapEventBindings->Clear(key); - - if (InstanceEventBindings->HasBindingsFor(key)) - InstanceEventBindings->Clear(key); - - if (instanceDataRefs.find(instanceId) != instanceDataRefs.end()) - { - luaL_unref(L, LUA_REGISTRYINDEX, instanceDataRefs[instanceId]); - instanceDataRefs.erase(instanceId); - } - } -} - -void ALE::PushInstanceData(lua_State* L, ALEInstanceAI* ai, bool incrementCounter) -{ - // Check if the instance data is missing (i.e. someone reloaded ALE). - if (!HasInstanceData(ai->instance)) - ai->Reload(); - - // Get the instance data table from the registry. - if (!ai->instance->Instanceable()) - lua_rawgeti(L, LUA_REGISTRYINDEX, continentDataRefs[ai->instance->GetId()]); - else - lua_rawgeti(L, LUA_REGISTRYINDEX, instanceDataRefs[ai->instance->GetInstanceId()]); - - ASSERT(lua_istable(L, -1)); - - if (incrementCounter) - ++push_counter; -} diff --git a/src/LuaEngine/LuaEngine.h b/src/LuaEngine/LuaEngine.h deleted file mode 100644 index 3db6bb4411..0000000000 --- a/src/LuaEngine/LuaEngine.h +++ /dev/null @@ -1,626 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef _LUA_ENGINE_H -#define _LUA_ENGINE_H - -#include "Common.h" -#include "SharedDefines.h" -#include "DBCEnums.h" - -#include "Group.h" -#include "Item.h" -#include "Chat.h" -#include "Player.h" -#include "Weather.h" -#include "World.h" -#include "Hooks.h" -#include "LFG.h" -#include "ALEUtility.h" -#include "HttpManager.h" -#include "EventEmitter.h" -#include "TicketMgr.h" -#include "LootMgr.h" -#include "ALEFileWatcher.h" -#include "ALEConfig.h" -#include -#include -#include -#include -#include - -extern "C" -{ -#include -}; - -struct ItemTemplate; -typedef BattlegroundTypeId BattleGroundTypeId; -typedef AreaTrigger AreaTriggerEntry; -class AuctionHouseObject; -struct AuctionEntry; -class Battleground; -typedef Battleground BattleGround; -class Channel; -class Corpse; -class Creature; -class CreatureAI; -class GameObject; -class GameObjectAI; -class Guild; -class Group; -class InstanceScript; -typedef InstanceScript InstanceData; -class ALEInstanceAI; -class Item; -class Pet; -class Player; -class Quest; -class Spell; -class SpellCastTargets; -class TempSummon; -// class Transport; -class Unit; -class Weather; -class WorldPacket; -class Vehicle; - -struct lua_State; -class EventMgr; -class ALEObject; -template class ALETemplate; - -template class BindingMap; -template struct EventKey; -template struct EntryKey; -template struct UniqueObjectKey; - -// Type definition for bytecode buffer -typedef std::vector BytecodeBuffer; - -// Global bytecode cache entry -struct GlobalCacheEntry -{ - BytecodeBuffer bytecode; - std::time_t last_modified; - std::string filepath; - - GlobalCacheEntry() : last_modified(0) {} - GlobalCacheEntry(const BytecodeBuffer& code, std::time_t modTime, const std::string& path) - : bytecode(code), last_modified(modTime), filepath(path) {} -}; - -struct LuaScript -{ - std::string fileext; - std::string filename; - std::string filepath; - std::string modulepath; - LuaScript() {} -}; - -#define ALE_STATE_PTR "ALE State Ptr" -#define LOCK_ALE ALE::Guard __guard(ALE::GetLock()) - -#define ALE_GAME_API AC_GAME_API - -class ALE_GAME_API ALE -{ -public: - typedef std::list ScriptList; - - typedef std::recursive_mutex LockType; - typedef std::lock_guard Guard; - - const std::string& GetRequirePath() const { return lua_requirepath; } - const std::string& GetRequireCPath() const { return lua_requirecpath; } - -private: - static bool reload; - static bool initialized; - static LockType lock; - static std::unique_ptr fileWatcher; - - // Lua script locations - static ScriptList lua_scripts; - static ScriptList lua_extensions; - - // Lua script folder path - static std::string lua_folderpath; - // lua path variable for require() function - static std::string lua_requirepath; - static std::string lua_requirecpath; - - // A counter for lua event stacks that occur (see event_level). - // This is used to determine whether an object belongs to the current call stack or not. - // 0 is reserved for always belonging to the call stack - // 1 is reserved for a non valid callstackid - uint64 callstackid = 2; - // A counter for the amount of nested events. When the event_level - // reaches 0 we are about to return back to C++. At this point the - // objects used during the event stack are invalidated. - uint32 event_level; - // When a hook pushes arguments to be passed to event handlers, - // this is used to keep track of how many arguments were pushed. - uint8 push_counter; - - // Map from instance ID -> Lua table ref - std::unordered_map instanceDataRefs; - // Map from map ID -> Lua table ref - std::unordered_map continentDataRefs; - - ALE(); - ~ALE(); - - // Prevent copy - ALE(ALE const&) = delete; - ALE& operator=(const ALE&) = delete; - - void OpenLua(); - void CloseLua(); - void DestroyBindStores(); - void CreateBindStores(); - void InvalidateObjects(); - - // Use ReloadALE() to make ALE reload - // This is called on world update to reload ALE - static void _ReloadALE(); - static void LoadScriptPaths(); - static void GetScripts(std::string path); - static void AddScriptPath(std::string filename, const std::string& fullpath); - static int LoadCompiledScript(lua_State* L, const std::string& filepath); - static std::time_t GetFileModTime(const std::string& filepath); - static std::time_t GetFileModTimeWithCache(const std::string& filepath); - - // Global cache management - static bool CompileScriptToGlobalCache(const std::string& filepath); - static bool CompileMoonScriptToGlobalCache(const std::string& filepath); - static int TryLoadFromGlobalCache(lua_State* L, const std::string& filepath); - static int LoadScriptWithCache(lua_State* L, const std::string& filepath, bool isMoonScript, uint32* compiledCount = nullptr, uint32* cachedCount = nullptr); - static void ClearGlobalCache(); - static void ClearTimestampCache(); - static size_t GetGlobalCacheSize(); - - static int StackTrace(lua_State *_L); - static void Report(lua_State* _L); - - // Some helpers for hooks to call event handlers. - // The bodies of the templates are in HookHelpers.h, so if you want to use them you need to #include "HookHelpers.h". - template int SetupStack(BindingMap* bindings1, BindingMap* bindings2, const K1& key1, const K2& key2, int number_of_arguments); - int CallOneFunction(int number_of_functions, int number_of_arguments, int number_of_results); - void CleanUpStack(int number_of_arguments); - template void ReplaceArgument(T value, uint8 index); - template void CallAllFunctions(BindingMap* bindings1, BindingMap* bindings2, const K1& key1, const K2& key2); - template bool CallAllFunctionsBool(BindingMap* bindings1, BindingMap* bindings2, const K1& key1, const K2& key2, bool default_value = false); - - // Same as above but for only one binding instead of two. - // `key` is passed twice because there's no NULL for references, but it's not actually used if `bindings2` is NULL. - template int SetupStack(BindingMap* bindings, const K& key, int number_of_arguments) - { - return SetupStack(bindings, NULL, key, key, number_of_arguments); - } - template void CallAllFunctions(BindingMap* bindings, const K& key) - { - CallAllFunctions(bindings, NULL, key, key); - } - template bool CallAllFunctionsBool(BindingMap* bindings, const K& key, bool default_value = false) - { - return CallAllFunctionsBool(bindings, NULL, key, key, default_value); - } - - // Non-static pushes, to be used in hooks. - // These just call the correct static version with the main thread's Lua state. - void Push() { Push(L); ++push_counter; } - void Push(const long long value) { Push(L, value); ++push_counter; } - void Push(const unsigned long long value) { Push(L, value); ++push_counter; } - void Push(const long value) { Push(L, value); ++push_counter; } - void Push(const unsigned long value) { Push(L, value); ++push_counter; } - void Push(const int value) { Push(L, value); ++push_counter; } - void Push(const unsigned int value) { Push(L, value); ++push_counter; } - void Push(const bool value) { Push(L, value); ++push_counter; } - void Push(const float value) { Push(L, value); ++push_counter; } - void Push(const double value) { Push(L, value); ++push_counter; } - 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 - void Push(T const* ptr) { Push(L, ptr); ++push_counter; } - -public: - static ALE* GALE; - - lua_State* L; - EventMgr* eventMgr; - HttpManager httpManager; - QueryCallbackProcessor queryProcessor; - EventEmitter OnError; - - BindingMap< EventKey >* ServerEventBindings; - BindingMap< EventKey >* PlayerEventBindings; - BindingMap< EventKey >* GuildEventBindings; - BindingMap< EventKey >* GroupEventBindings; - BindingMap< EventKey >* VehicleEventBindings; - BindingMap< EventKey >* BGEventBindings; - BindingMap< EventKey >* AllCreatureEventBindings; - - BindingMap< EntryKey >* PacketEventBindings; - BindingMap< EntryKey >* CreatureEventBindings; - BindingMap< EntryKey >* CreatureGossipBindings; - BindingMap< EntryKey >* GameObjectEventBindings; - BindingMap< EntryKey >* GameObjectGossipBindings; - BindingMap< EntryKey >* ItemEventBindings; - BindingMap< EntryKey >* ItemGossipBindings; - BindingMap< EntryKey >* PlayerGossipBindings; - BindingMap< EntryKey >* MapEventBindings; - BindingMap< EntryKey >* InstanceEventBindings; - BindingMap< EventKey >* TicketEventBindings; - BindingMap< EntryKey >* SpellEventBindings; - - BindingMap< UniqueObjectKey >* CreatureUniqueBindings; - - static void Initialize(); - static void Uninitialize(); - // This function is used to make ALE reload - static void ReloadALE() { LOCK_ALE; reload = true; } - static LockType& GetLock() { return lock; }; - static bool IsInitialized() { return initialized; } - // Never returns nullptr - static ALE* GetALE(lua_State* L) - { - lua_pushstring(L, ALE_STATE_PTR); - lua_rawget(L, LUA_REGISTRYINDEX); - ASSERT(lua_islightuserdata(L, -1)); - ALE* E = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); - ASSERT(E); - return E; - } - - // Static pushes, can be used by anything, including methods. - static void Push(lua_State* luastate); // nil - static void Push(lua_State* luastate, const long long); - static void Push(lua_State* luastate, const unsigned long long); - static void Push(lua_State* luastate, const long); - static void Push(lua_State* luastate, const unsigned long); - static void Push(lua_State* luastate, const int); - static void Push(lua_State* luastate, const unsigned int); - static void Push(lua_State* luastate, const bool); - static void Push(lua_State* luastate, const float); - static void Push(lua_State* luastate, const double); - static void Push(lua_State* luastate, const std::string&); - static void Push(lua_State* luastate, const char*); - static void Push(lua_State* luastate, Object const* obj); - static void Push(lua_State* luastate, WorldObject const* obj); - static void Push(lua_State* luastate, Unit const* unit); - static void Push(lua_State* luastate, Pet const* pet); - static void Push(lua_State* luastate, TempSummon const* summon); - 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 - static void Push(lua_State* luastate, T const* ptr) - { - ALETemplate::Push(luastate, ptr); - } - - static std::string FormatQuery(lua_State* L, const char* query); - - bool ExecuteCall(int params, int res); - - /* - * Returns `true` if ALE has instance data for `map`. - */ - bool HasInstanceData(Map const* map); - - /* - * Use the top element of the stack as the instance data table for `map`, - * then pops it off the stack. - */ - void CreateInstanceData(Map const* map); - - /* - * Retrieve the instance data for the `Map` scripted by `ai` and push it - * onto the stack. - * - * An `ALEInstanceAI` is needed because the instance data might - * not exist (i.e. ALE has been reloaded). - * - * In that case, the AI is "reloaded" (new instance data table is created - * and loaded with the last known save state, and `Load`/`Initialize` - * hooks are called). - */ - void PushInstanceData(lua_State* L, ALEInstanceAI* ai, bool incrementCounter = true); - - void RunScripts(); - bool ShouldReload() const { return reload; } - bool HasLuaState() const { return L != NULL; } - uint64 GetCallstackId() const { return callstackid; } - int Register(lua_State* L, uint8 reg, uint32 entry, ObjectGuid guid, uint32 instanceId, uint32 event_id, int functionRef, uint32 shots); - - // Checks - template static T CHECKVAL(lua_State* luastate, int narg); - template static T CHECKVAL(lua_State* luastate, int narg, T def) - { - return lua_isnoneornil(luastate, narg) ? def : CHECKVAL(luastate, narg); - } - template static T* CHECKOBJ(lua_State* luastate, int narg, bool error = true) - { - return ALETemplate::Check(luastate, narg, error); - } - static ALEObject* CHECKTYPE(lua_State* luastate, int narg, const char *tname, bool error = true); - - CreatureAI* GetAI(Creature* creature); - InstanceData* GetInstanceData(Map* map); - void FreeInstanceId(uint32 instanceId); - - /* Custom */ - void OnTimedEvent(int funcRef, uint32 delay, uint32 calls, WorldObject* obj); - bool OnCommand(ChatHandler& handler, const char* text); - void OnWorldUpdate(uint32 diff); - void OnLootItem(Player* pPlayer, Item* pItem, uint32 count, ObjectGuid guid); - void OnLootMoney(Player* pPlayer, uint32 amount); - void OnFirstLogin(Player* pPlayer); - void OnEquip(Player* pPlayer, Item* pItem, uint8 bag, uint8 slot); - void OnRepop(Player* pPlayer); - void OnResurrect(Player* pPlayer); - void OnQuestAbandon(Player* pPlayer, uint32 questId); - void OnLearnTalents(Player* pPlayer, uint32 talentId, uint32 talentRank, uint32 spellid); - InventoryResult OnCanUseItem(const Player* pPlayer, uint32 itemEntry); - void OnLuaStateClose(); - void OnLuaStateOpen(); - bool OnAddonMessage(Player* sender, uint32 type, std::string& msg, Player* receiver, Guild* guild, Group* group, Channel* channel); - void OnPetAddedToWorld(Player* player, Creature* pet); - void OnQuestRewardItem(Player* player, Item* item, uint32 count); - void OnCreateItem(Player* player, Item* item, uint32 count); - void OnStoreNewItem(Player* player, Item* item, uint32 count); - void OnPlayerCompleteQuest(Player* player, Quest const* quest); - - /* Item */ - void OnDummyEffect(WorldObject* pCaster, uint32 spellId, SpellEffIndex effIndex, Item* pTarget); - bool OnQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest); - bool OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets); - bool OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets); - bool OnItemGossip(Player* pPlayer, Item* pItem, SpellCastTargets const& targets); - bool OnExpire(Player* pPlayer, ItemTemplate const* pProto); - bool OnRemove(Player* pPlayer, Item* item); - void HandleGossipSelectOption(Player* pPlayer, Item* item, uint32 sender, uint32 action, const std::string& code); - - /* Creature */ - void OnDummyEffect(WorldObject* pCaster, uint32 spellId, SpellEffIndex effIndex, Creature* pTarget); - bool OnGossipHello(Player* pPlayer, Creature* pCreature); - bool OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action); - bool OnGossipSelectCode(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action, const char* code); - bool OnQuestAccept(Player* pPlayer, Creature* pCreature, Quest const* pQuest); - bool OnQuestReward(Player* pPlayer, Creature* pCreature, Quest const* pQuest, uint32 opt); - void GetDialogStatus(const Player* pPlayer, const Creature* pCreature); - - bool OnSummoned(Creature* creature, Unit* summoner); - bool UpdateAI(Creature* me, const uint32 diff); - bool EnterCombat(Creature* me, Unit* target); - bool DamageTaken(Creature* me, Unit* attacker, uint32& damage); - bool JustDied(Creature* me, Unit* killer); - bool KilledUnit(Creature* me, Unit* victim); - bool JustSummoned(Creature* me, Creature* summon); - bool SummonedCreatureDespawn(Creature* me, Creature* summon); - bool MovementInform(Creature* me, uint32 type, uint32 id); - bool AttackStart(Creature* me, Unit* target); - bool EnterEvadeMode(Creature* me); - bool JustRespawned(Creature* me); - bool JustReachedHome(Creature* me); - bool ReceiveEmote(Creature* me, Player* player, uint32 emoteId); - bool CorpseRemoved(Creature* me, uint32& respawnDelay); - bool MoveInLineOfSight(Creature* me, Unit* who); - bool SpellHit(Creature* me, WorldObject* caster, SpellInfo const* spell); - bool SpellHitTarget(Creature* me, WorldObject* target, SpellInfo const* spell); - bool SummonedCreatureDies(Creature* me, Creature* summon, Unit* killer); - bool OwnerAttackedBy(Creature* me, Unit* attacker); - bool OwnerAttacked(Creature* me, Unit* target); - void On_Reset(Creature* me); - void OnCreatureAuraApply(Creature* me, Aura* aura); - void OnCreatureHeal(Creature* me, Unit* target, uint32& gain); - void OnCreatureDamage(Creature* me, Unit* target, uint32& gain); - void OnCreatureAuraRemove(Creature* me, Aura* aura, AuraRemoveMode mode); - void OnCreatureModifyPeriodicDamageAurasTick(Creature* me, Unit* target, uint32& damage, SpellInfo const* spellInfo); - void OnCreatureModifyMeleeDamage(Creature* me, Unit* target, uint32& damage); - void OnCreatureModifySpellDamageTaken(Creature* me, Unit* target, int32& damage, SpellInfo const* spellInfo); - void OnCreatureModifyHealReceived(Creature* me, Unit* target, uint32& heal, SpellInfo const* spellInfo); - uint32 OnCreatureDealDamage(Creature* me, Unit* pVictim, uint32 damage, DamageEffectType damagetype); - - /* GameObject */ - void OnDummyEffect(WorldObject* pCaster, uint32 spellId, SpellEffIndex effIndex, GameObject* pTarget); - bool OnGameObjectUse(Player* pPlayer, GameObject* pGameObject); - bool OnGossipHello(Player* pPlayer, GameObject* pGameObject); - bool OnGossipSelect(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action); - bool OnGossipSelectCode(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action, const char* code); - bool OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest); - bool OnQuestReward(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest, uint32 opt); - void GetDialogStatus(const Player* pPlayer, const GameObject* pGameObject); - void OnDestroyed(GameObject* pGameObject, WorldObject* attacker); - void OnDamaged(GameObject* pGameObject, WorldObject* attacker); - void OnLootStateChanged(GameObject* pGameObject, uint32 state); - void OnGameObjectStateChanged(GameObject* pGameObject, uint32 state); - void UpdateAI(GameObject* pGameObject, uint32 diff); - void OnSpawn(GameObject* gameobject); - - /* Packet */ - bool OnPacketSend(WorldSession* session, const WorldPacket& packet); - void OnPacketSendAny(Player* player, const WorldPacket& packet, bool& result); - void OnPacketSendOne(Player* player, const WorldPacket& packet, bool& result); - bool OnPacketReceive(WorldSession* session, WorldPacket& packet); - void OnPacketReceiveAny(Player* player, WorldPacket& packet, bool& result); - void OnPacketReceiveOne(Player* player, WorldPacket& packet, bool& result); - - /* Player */ - void OnPlayerEnterCombat(Player* pPlayer, Unit* pEnemy); - void OnPlayerLeaveCombat(Player* pPlayer); - void OnPVPKill(Player* pKiller, Player* pKilled); - void OnCreatureKill(Player* pKiller, Creature* pKilled); - void OnPlayerKilledByCreature(Creature* pKiller, Player* pKilled); - void OnLevelChanged(Player* pPlayer, uint8 oldLevel); - void OnFreeTalentPointsChanged(Player* pPlayer, uint32 newPoints); - void OnTalentsReset(Player* pPlayer, bool noCost); - void OnMoneyChanged(Player* pPlayer, int32& amount); - void OnGiveXP(Player* pPlayer, uint32& amount, Unit* pVictim, uint8 xpSource); - bool OnReputationChange(Player* pPlayer, uint32 factionID, int32& standing, bool incremental); - void OnDuelRequest(Player* pTarget, Player* pChallenger); - void OnDuelStart(Player* pStarter, Player* pChallenger); - void OnDuelEnd(Player* pWinner, Player* pLoser, DuelCompleteType type); - bool OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg); - bool OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Group* pGroup); - bool OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Guild* pGuild); - bool OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Channel* pChannel); - bool OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Player* pReceiver); - void OnEmote(Player* pPlayer, uint32 emote); - void OnTextEmote(Player* pPlayer, uint32 textEmote, uint32 emoteNum, ObjectGuid guid); - void OnPlayerSpellCast(Player* pPlayer, Spell* pSpell, bool skipCheck); - void OnLogin(Player* pPlayer); - void OnLogout(Player* pPlayer); - void OnCreate(Player* pPlayer); - void OnDelete(uint32 guid); - void OnSave(Player* pPlayer); - void OnBindToInstance(Player* pPlayer, Difficulty difficulty, uint32 mapid, bool permanent); - void OnUpdateArea(Player* pPlayer, uint32 oldArea, uint32 newArea); - void OnUpdateZone(Player* pPlayer, uint32 newZone, uint32 newArea); - void OnMapChanged(Player* pPlayer); - void HandleGossipSelectOption(Player* pPlayer, uint32 menuId, uint32 sender, uint32 action, const std::string& code); - void OnLearnSpell(Player* player, uint32 spellId); - void OnAchiComplete(Player* player, AchievementEntry const* achievement); - void OnFfaPvpStateUpdate(Player* player, bool hasFfaPvp); - bool OnCanInitTrade(Player* player, Player* target); - bool OnCanSendMail(Player* player, ObjectGuid receiverGuid, ObjectGuid mailbox, std::string& subject, std::string& body, uint32 money, uint32 cod, Item* item); - bool OnCanJoinLfg(Player* player, uint8 roles, lfg::LfgDungeonSet& dungeons, const std::string& comment); - bool OnCanGroupInvite(Player* player, std::string& memberName); - void OnGroupRollRewardItem(Player* player, Item* item, uint32 count, RollVote voteType, Roll* roll); - void OnBattlegroundDesertion(Player* player, const BattlegroundDesertionType type); - void OnCreatureKilledByPet(Player* player, Creature* killed); - bool OnPlayerCanUpdateSkill(Player* player, uint32 skill_id); - void OnPlayerBeforeUpdateSkill(Player* player, uint32 skill_id, uint32& value, uint32 max, uint32 step); - void OnPlayerUpdateSkill(Player* player, uint32 skill_id, uint32 value, uint32 max, uint32 step, uint32 new_value); - bool CanPlayerResurrect(Player* player); - void OnPlayerQuestAccept(Player* player, Quest const* quest); - void OnPlayerAuraApply(Player* player, Aura* aura); - void OnPlayerAuraRemove(Player* player, Aura* aura, AuraRemoveMode mode); - void OnPlayerHeal(Player* player, Unit* target, uint32& gain); - void OnPlayerDamage(Player* player, Unit* target, uint32& damage); - void OnPlayerModifyPeriodicDamageAurasTick(Player* player, Unit* target, uint32& damage, SpellInfo const* spellInfo); - void OnPlayerModifyMeleeDamage(Player* player, Unit* target, uint32& damage); - void OnPlayerModifySpellDamageTaken(Player* player, Unit* target, int32& damage, SpellInfo const* spellInfo); - void OnPlayerModifyHealReceived(Player* player, Unit* target, uint32& heal, SpellInfo const* spellInfo); - uint32 OnPlayerDealDamage(Player* player, Unit* pVictim, uint32 damage, DamageEffectType damagetype); - - /* Vehicle */ - void OnInstall(Vehicle* vehicle); - void OnUninstall(Vehicle* vehicle); - void OnInstallAccessory(Vehicle* vehicle, Creature* accessory); - void OnAddPassenger(Vehicle* vehicle, Unit* passenger, int8 seatId); - void OnRemovePassenger(Vehicle* vehicle, Unit* passenger); - - /* AreaTrigger */ - bool OnAreaTrigger(Player* pPlayer, AreaTriggerEntry const* pTrigger); - - /* Weather */ - void OnChange(Weather* weather, uint32 zone, WeatherState state, float grade); - - /* Auction House */ - void OnAdd(AuctionHouseObject* ah, AuctionEntry* entry); - void OnRemove(AuctionHouseObject* ah, AuctionEntry* entry); - void OnSuccessful(AuctionHouseObject* ah, AuctionEntry* entry); - void OnExpire(AuctionHouseObject* ah, AuctionEntry* entry); - - /* Guild */ - void OnAddMember(Guild* guild, Player* player, uint32 plRank); - void OnRemoveMember(Guild* guild, Player* player, bool isDisbanding); - void OnMOTDChanged(Guild* guild, const std::string& newMotd); - void OnInfoChanged(Guild* guild, const std::string& newInfo); - void OnCreate(Guild* guild, Player* leader, const std::string& name); - void OnDisband(Guild* guild); - void OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, bool isRepair); - void OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount); - void OnItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId, bool isDestBank, uint8 destContainer, uint8 destSlotId); - void OnEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank); - void OnBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId); - - /* Group */ - void OnAddMember(Group* group, ObjectGuid guid); - void OnInviteMember(Group* group, ObjectGuid guid); - void OnRemoveMember(Group* group, ObjectGuid guid, uint8 method); - void OnChangeLeader(Group* group, ObjectGuid newLeaderGuid, ObjectGuid oldLeaderGuid); - void OnDisband(Group* group); - void OnCreate(Group* group, ObjectGuid leaderGuid, GroupType groupType); - - /* Map */ - void OnCreate(Map* map); - void OnDestroy(Map* map); - void OnPlayerEnter(Map* map, Player* player); - void OnPlayerLeave(Map* map, Player* player); - void OnUpdate(Map* map, uint32 diff); - void OnAddToWorld(Creature* creature); - void OnRemoveFromWorld(Creature* creature); - void OnAddToWorld(GameObject* gameobject); - void OnRemoveFromWorld(GameObject* gameobject); - void OnRemove(Creature* creature); - void OnRemove(GameObject* gameobject); - - /* Instance */ - void OnInitialize(ALEInstanceAI* ai); - void OnLoad(ALEInstanceAI* ai); - void OnUpdateInstance(ALEInstanceAI* ai, uint32 diff); - void OnPlayerEnterInstance(ALEInstanceAI* ai, Player* player); - void OnCreatureCreate(ALEInstanceAI* ai, Creature* creature); - void OnGameObjectCreate(ALEInstanceAI* ai, GameObject* gameobject); - bool OnCheckEncounterInProgress(ALEInstanceAI* ai); - - /* World */ - void OnOpenStateChange(bool open); - void OnConfigLoad(bool reload, bool isBefore); - void OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask); - void OnShutdownCancel(); - void OnStartup(); - void OnShutdown(); - void OnGameEventStart(uint32 eventid); - void OnGameEventStop(uint32 eventid); - - /* Battle Ground */ - void OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId); - void OnBGEnd(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId, TeamId winner); - void OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId); - void OnBGDestroy(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId); - - /* Ticket */ - void OnTicketCreate(GmTicket* ticket); - void OnTicketClose(GmTicket* ticket); - void OnTicketUpdateLastChange(GmTicket* ticket); - void OnTicketResolve(GmTicket* ticket); - - /* Spell */ - 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); - void OnAllCreatureAuraApply(Creature* me, Aura* aura); - void OnAllCreatureHeal(Creature* me, Unit* target, uint32& gain); - void OnAllCreatureDamage(Creature* me, Unit* target, uint32& gain); - void OnAllCreatureAuraRemove(Creature* me, Aura* aura, AuraRemoveMode mode); - void OnAllCreatureModifyPeriodicDamageAurasTick(Creature* me, Unit* target, uint32& damage, SpellInfo const* spellInfo); - void OnAllCreatureModifyMeleeDamage(Creature* me, Unit* target, uint32& damage); - void OnAllCreatureModifySpellDamageTaken(Creature* me, Unit* target, int32& damage, SpellInfo const* spellInfo); - void OnAllCreatureModifyHealReceived(Creature* me, Unit* target, uint32& heal, SpellInfo const* spellInfo); - uint32 OnAllCreatureDealDamage(Creature* me, Unit* pVictim, uint32 damage, DamageEffectType damagetype); -}; -template<> Unit* ALE::CHECKOBJ(lua_State* L, int narg, bool error); -template<> Object* ALE::CHECKOBJ(lua_State* L, int narg, bool error); -template<> WorldObject* ALE::CHECKOBJ(lua_State* L, int narg, bool error); -template<> ALEObject* ALE::CHECKOBJ(lua_State* L, int narg, bool error); - -#define sALE ALE::GALE -#endif diff --git a/src/LuaEngine/LuaFunctions.cpp b/src/LuaEngine/LuaFunctions.cpp deleted file mode 100644 index 0ebe274acc..0000000000 --- a/src/LuaEngine/LuaFunctions.cpp +++ /dev/null @@ -1,1958 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -extern "C" -{ -#include "lua.h" -}; - -// ALE -#include "LuaEngine.h" -#include "ALEEventMgr.h" -#include "ALEIncludes.h" -#include "ALETemplate.h" -#include "ALEUtility.h" - -// Method includes -#include "GlobalMethods.h" -#include "ObjectMethods.h" -#include "WorldObjectMethods.h" -#include "UnitMethods.h" -#include "PlayerMethods.h" -#include "CreatureMethods.h" -#include "GroupMethods.h" -#include "GuildMethods.h" -#include "GameObjectMethods.h" -#include "ALEQueryMethods.h" -#include "AuraMethods.h" -#include "ItemMethods.h" -#include "WorldPacketMethods.h" -#include "SpellMethods.h" -#include "QuestMethods.h" -#include "MapMethods.h" -#include "CorpseMethods.h" -#include "VehicleMethods.h" -#include "BattleGroundMethods.h" -#include "ChatHandlerMethods.h" -#include "AchievementMethods.h" -#include "ItemTemplateMethods.h" -#include "RollMethods.h" -#include "TicketMethods.h" -#include "SpellInfoMethods.h" -#include "PetMethods.h" -#include "LootMethods.h" - -// DBCStores includes -#include "GemPropertiesEntryMethods.h" -#include "SpellEntryMethods.h" - -luaL_Reg GlobalMethods[] = -{ - // Hooks - { "RegisterPacketEvent", &LuaGlobalFunctions::RegisterPacketEvent }, - { "RegisterServerEvent", &LuaGlobalFunctions::RegisterServerEvent }, - { "RegisterPlayerEvent", &LuaGlobalFunctions::RegisterPlayerEvent }, - { "RegisterGuildEvent", &LuaGlobalFunctions::RegisterGuildEvent }, - { "RegisterGroupEvent", &LuaGlobalFunctions::RegisterGroupEvent }, - { "RegisterCreatureEvent", &LuaGlobalFunctions::RegisterCreatureEvent }, - { "RegisterUniqueCreatureEvent", &LuaGlobalFunctions::RegisterUniqueCreatureEvent }, - { "RegisterCreatureGossipEvent", &LuaGlobalFunctions::RegisterCreatureGossipEvent }, - { "RegisterGameObjectEvent", &LuaGlobalFunctions::RegisterGameObjectEvent }, - { "RegisterGameObjectGossipEvent", &LuaGlobalFunctions::RegisterGameObjectGossipEvent }, - { "RegisterItemEvent", &LuaGlobalFunctions::RegisterItemEvent }, - { "RegisterItemGossipEvent", &LuaGlobalFunctions::RegisterItemGossipEvent }, - { "RegisterPlayerGossipEvent", &LuaGlobalFunctions::RegisterPlayerGossipEvent }, - { "RegisterBGEvent", &LuaGlobalFunctions::RegisterBGEvent }, - { "RegisterMapEvent", &LuaGlobalFunctions::RegisterMapEvent }, - { "RegisterInstanceEvent", &LuaGlobalFunctions::RegisterInstanceEvent }, - { "RegisterTicketEvent", &LuaGlobalFunctions::RegisterTicketEvent }, - { "RegisterSpellEvent", &LuaGlobalFunctions::RegisterSpellEvent }, - { "RegisterAllCreatureEvent", &LuaGlobalFunctions::RegisterAllCreatureEvent }, - - - { "ClearBattleGroundEvents", &LuaGlobalFunctions::ClearBattleGroundEvents }, - { "ClearCreatureEvents", &LuaGlobalFunctions::ClearCreatureEvents }, - { "ClearUniqueCreatureEvents", &LuaGlobalFunctions::ClearUniqueCreatureEvents }, - { "ClearCreatureGossipEvents", &LuaGlobalFunctions::ClearCreatureGossipEvents }, - { "ClearGameObjectEvents", &LuaGlobalFunctions::ClearGameObjectEvents }, - { "ClearGameObjectGossipEvents", &LuaGlobalFunctions::ClearGameObjectGossipEvents }, - { "ClearGroupEvents", &LuaGlobalFunctions::ClearGroupEvents }, - { "ClearGuildEvents", &LuaGlobalFunctions::ClearGuildEvents }, - { "ClearItemEvents", &LuaGlobalFunctions::ClearItemEvents }, - { "ClearItemGossipEvents", &LuaGlobalFunctions::ClearItemGossipEvents }, - { "ClearPacketEvents", &LuaGlobalFunctions::ClearPacketEvents }, - { "ClearPlayerEvents", &LuaGlobalFunctions::ClearPlayerEvents }, - { "ClearPlayerGossipEvents", &LuaGlobalFunctions::ClearPlayerGossipEvents }, - { "ClearServerEvents", &LuaGlobalFunctions::ClearServerEvents }, - { "ClearMapEvents", &LuaGlobalFunctions::ClearMapEvents }, - { "ClearInstanceEvents", &LuaGlobalFunctions::ClearInstanceEvents }, - { "ClearTicketEvents", &LuaGlobalFunctions::ClearTicketEvents }, - { "ClearSpellEvents", &LuaGlobalFunctions::ClearSpellEvents }, - { "ClearAllCreatureEvents", &LuaGlobalFunctions::ClearAllCreatureEvents }, - - // Getters - { "GetLuaEngine", &LuaGlobalFunctions::GetLuaEngine }, - { "GetCoreName", &LuaGlobalFunctions::GetCoreName }, - { "GetConfigValue", &LuaGlobalFunctions::GetConfigValue }, - { "GetRealmID", &LuaGlobalFunctions::GetRealmID }, - { "GetCoreVersion", &LuaGlobalFunctions::GetCoreVersion }, - { "GetCoreExpansion", &LuaGlobalFunctions::GetCoreExpansion }, - { "GetStateMap", &LuaGlobalFunctions::GetStateMap }, - { "GetStateMapId", &LuaGlobalFunctions::GetStateMapId }, - { "GetStateInstanceId", &LuaGlobalFunctions::GetStateInstanceId }, - { "GetQuest", &LuaGlobalFunctions::GetQuest }, - { "GetPlayerByGUID", &LuaGlobalFunctions::GetPlayerByGUID }, - { "GetPlayerByName", &LuaGlobalFunctions::GetPlayerByName }, - { "GetGameTime", &LuaGlobalFunctions::GetGameTime }, - { "GetPlayersInWorld", &LuaGlobalFunctions::GetPlayersInWorld }, - { "GetGuildByName", &LuaGlobalFunctions::GetGuildByName }, - { "GetGuildByLeaderGUID", &LuaGlobalFunctions::GetGuildByLeaderGUID }, - { "GetPlayerCount", &LuaGlobalFunctions::GetPlayerCount }, - { "GetPlayerGUID", &LuaGlobalFunctions::GetPlayerGUID }, - { "GetItemGUID", &LuaGlobalFunctions::GetItemGUID }, - { "GetItemTemplate", &LuaGlobalFunctions::GetItemTemplate }, - { "GetObjectGUID", &LuaGlobalFunctions::GetObjectGUID }, - { "GetUnitGUID", &LuaGlobalFunctions::GetUnitGUID }, - { "GetGUIDLow", &LuaGlobalFunctions::GetGUIDLow }, - { "GetGUIDType", &LuaGlobalFunctions::GetGUIDType }, - { "GetGUIDEntry", &LuaGlobalFunctions::GetGUIDEntry }, - { "GetPackedGUIDSize", &LuaGlobalFunctions::GetPackedGUIDSize }, - { "GetAreaName", &LuaGlobalFunctions::GetAreaName }, - { "GetOwnerHalaa", &LuaGlobalFunctions::GetOwnerHalaa }, - { "bit_not", &LuaGlobalFunctions::bit_not }, - { "bit_xor", &LuaGlobalFunctions::bit_xor }, - { "bit_rshift", &LuaGlobalFunctions::bit_rshift }, - { "bit_lshift", &LuaGlobalFunctions::bit_lshift }, - { "bit_or", &LuaGlobalFunctions::bit_or }, - { "bit_and", &LuaGlobalFunctions::bit_and }, - { "GetItemLink", &LuaGlobalFunctions::GetItemLink }, - { "GetMapById", &LuaGlobalFunctions::GetMapById }, - { "GetCurrTime", &LuaGlobalFunctions::GetCurrTime }, - { "GetTimeDiff", &LuaGlobalFunctions::GetTimeDiff }, - { "PrintInfo", &LuaGlobalFunctions::PrintInfo }, - { "PrintError", &LuaGlobalFunctions::PrintError }, - { "PrintDebug", &LuaGlobalFunctions::PrintDebug }, - { "GetActiveGameEvents", &LuaGlobalFunctions::GetActiveGameEvents }, - { "GetGossipMenuOptionLocale", &LuaGlobalFunctions::GetGossipMenuOptionLocale }, - { "GetMapEntrance", &LuaGlobalFunctions::GetMapEntrance }, - { "GetSpellInfo", &LuaGlobalFunctions::GetSpellInfo }, - - // Boolean - { "IsCompatibilityMode", &LuaGlobalFunctions::IsCompatibilityMode }, - { "IsInventoryPos", &LuaGlobalFunctions::IsInventoryPos }, - { "IsEquipmentPos", &LuaGlobalFunctions::IsEquipmentPos }, - { "IsBankPos", &LuaGlobalFunctions::IsBankPos }, - { "IsBagPos", &LuaGlobalFunctions::IsBagPos }, - { "IsGameEventActive", &LuaGlobalFunctions::IsGameEventActive }, - - // Other - { "ReloadALE", &LuaGlobalFunctions::ReloadALE }, - { "RunCommand", &LuaGlobalFunctions::RunCommand }, - { "SendWorldMessage", &LuaGlobalFunctions::SendWorldMessage }, - { "WorldDBQuery", &LuaGlobalFunctions::WorldDBQuery }, - { "WorldDBQueryAsync", &LuaGlobalFunctions::WorldDBQueryAsync }, - { "WorldDBExecute", &LuaGlobalFunctions::WorldDBExecute }, - { "CharDBQuery", &LuaGlobalFunctions::CharDBQuery }, - { "CharDBQueryAsync", &LuaGlobalFunctions::CharDBQueryAsync }, - { "CharDBExecute", &LuaGlobalFunctions::CharDBExecute }, - { "AuthDBQuery", &LuaGlobalFunctions::AuthDBQuery }, - { "AuthDBQueryAsync", &LuaGlobalFunctions::AuthDBQueryAsync }, - { "AuthDBExecute", &LuaGlobalFunctions::AuthDBExecute }, - { "CreateLuaEvent", &LuaGlobalFunctions::CreateLuaEvent }, - { "RemoveEventById", &LuaGlobalFunctions::RemoveEventById }, - { "RemoveEvents", &LuaGlobalFunctions::RemoveEvents }, - { "PerformIngameSpawn", &LuaGlobalFunctions::PerformIngameSpawn }, - { "CreatePacket", &LuaGlobalFunctions::CreatePacket }, - { "AddVendorItem", &LuaGlobalFunctions::AddVendorItem }, - { "VendorRemoveItem", &LuaGlobalFunctions::VendorRemoveItem }, - { "VendorRemoveAllItems", &LuaGlobalFunctions::VendorRemoveAllItems }, - { "Kick", &LuaGlobalFunctions::Kick }, - { "Ban", &LuaGlobalFunctions::Ban }, - { "SaveAllPlayers", &LuaGlobalFunctions::SaveAllPlayers }, - { "SendMail", &LuaGlobalFunctions::SendMail }, - { "AddTaxiPath", &LuaGlobalFunctions::AddTaxiPath }, - { "CreateInt64", &LuaGlobalFunctions::CreateLongLong }, - { "CreateUint64", &LuaGlobalFunctions::CreateULongLong }, - { "StartGameEvent", &LuaGlobalFunctions::StartGameEvent }, - { "StopGameEvent", &LuaGlobalFunctions::StopGameEvent }, - { "HttpRequest", &LuaGlobalFunctions::HttpRequest }, - { "SetOwnerHalaa", &LuaGlobalFunctions::SetOwnerHalaa }, - { "LookupEntry", &LuaGlobalFunctions::LookupEntry }, - - { NULL, NULL } -}; - -ALERegister ObjectMethods[] = -{ - // Getters - { "GetEntry", &LuaObject::GetEntry }, - { "GetGUID", &LuaObject::GetGUID }, - { "GetGUIDLow", &LuaObject::GetGUIDLow }, - { "GetInt32Value", &LuaObject::GetInt32Value }, - { "GetUInt32Value", &LuaObject::GetUInt32Value }, - { "GetFloatValue", &LuaObject::GetFloatValue }, - { "GetByteValue", &LuaObject::GetByteValue }, - { "GetUInt16Value", &LuaObject::GetUInt16Value }, - { "GetUInt64Value", &LuaObject::GetUInt64Value }, - { "GetScale", &LuaObject::GetScale }, - { "GetTypeId", &LuaObject::GetTypeId }, - - // Setters - { "SetInt32Value", &LuaObject::SetInt32Value }, - { "SetUInt32Value", &LuaObject::SetUInt32Value }, - { "UpdateUInt32Value", &LuaObject::UpdateUInt32Value }, - { "SetFloatValue", &LuaObject::SetFloatValue }, - { "SetByteValue", &LuaObject::SetByteValue }, - { "SetUInt16Value", &LuaObject::SetUInt16Value }, - { "SetInt16Value", &LuaObject::SetInt16Value }, - { "SetUInt64Value", &LuaObject::SetUInt64Value }, - { "SetScale", &LuaObject::SetScale }, - { "SetFlag", &LuaObject::SetFlag }, - - // Boolean - { "IsInWorld", &LuaObject::IsInWorld }, - { "IsPlayer", &LuaObject::IsPlayer }, - { "HasFlag", &LuaObject::HasFlag }, - - // Other - { "ToGameObject", &LuaObject::ToGameObject }, - { "ToUnit", &LuaObject::ToUnit }, - { "ToCreature", &LuaObject::ToCreature }, - { "ToPlayer", &LuaObject::ToPlayer }, - { "ToCorpse", &LuaObject::ToCorpse }, - { "RemoveFlag", &LuaObject::RemoveFlag }, - - { NULL, NULL } -}; - -ALERegister WorldObjectMethods[] = -{ - // Getters - { "GetName", &LuaWorldObject::GetName }, - { "GetMap", &LuaWorldObject::GetMap }, - { "GetPhaseMask", &LuaWorldObject::GetPhaseMask }, - { "SetPhaseMask", &LuaWorldObject::SetPhaseMask }, - { "GetInstanceId", &LuaWorldObject::GetInstanceId }, - { "GetAreaId", &LuaWorldObject::GetAreaId }, - { "GetZoneId", &LuaWorldObject::GetZoneId }, - { "GetMapId", &LuaWorldObject::GetMapId }, - { "GetX", &LuaWorldObject::GetX }, - { "GetY", &LuaWorldObject::GetY }, - { "GetZ", &LuaWorldObject::GetZ }, - { "GetO", &LuaWorldObject::GetO }, - { "GetLocation", &LuaWorldObject::GetLocation }, - { "GetPlayersInRange", &LuaWorldObject::GetPlayersInRange }, - { "GetCreaturesInRange", &LuaWorldObject::GetCreaturesInRange }, - { "GetGameObjectsInRange", &LuaWorldObject::GetGameObjectsInRange }, - { "GetNearestPlayer", &LuaWorldObject::GetNearestPlayer }, - { "GetNearestGameObject", &LuaWorldObject::GetNearestGameObject }, - { "GetNearestCreature", &LuaWorldObject::GetNearestCreature }, - { "GetNearObject", &LuaWorldObject::GetNearObject }, - { "GetNearObjects", &LuaWorldObject::GetNearObjects }, - { "GetDistance", &LuaWorldObject::GetDistance }, - { "GetExactDistance", &LuaWorldObject::GetExactDistance }, - { "GetDistance2d", &LuaWorldObject::GetDistance2d }, - { "GetExactDistance2d", &LuaWorldObject::GetExactDistance2d }, - { "GetRelativePoint", &LuaWorldObject::GetRelativePoint }, - { "GetAngle", &LuaWorldObject::GetAngle }, - - // Boolean - { "IsWithinLoS", &LuaWorldObject::IsWithinLoS }, - { "IsInMap", &LuaWorldObject::IsInMap }, - { "IsWithinDist3d", &LuaWorldObject::IsWithinDist3d }, - { "IsWithinDist2d", &LuaWorldObject::IsWithinDist2d }, - { "IsWithinDist", &LuaWorldObject::IsWithinDist }, - { "IsWithinDistInMap", &LuaWorldObject::IsWithinDistInMap }, - { "IsInRange", &LuaWorldObject::IsInRange }, - { "IsInRange2d", &LuaWorldObject::IsInRange2d }, - { "IsInRange3d", &LuaWorldObject::IsInRange3d }, - { "IsInFront", &LuaWorldObject::IsInFront }, - { "IsInBack", &LuaWorldObject::IsInBack }, - - // Other - { "SummonGameObject", &LuaWorldObject::SummonGameObject }, - { "SpawnCreature", &LuaWorldObject::SpawnCreature }, - { "SendPacket", &LuaWorldObject::SendPacket }, - { "RegisterEvent", &LuaWorldObject::RegisterEvent }, - { "RemoveEventById", &LuaWorldObject::RemoveEventById }, - { "RemoveEvents", &LuaWorldObject::RemoveEvents }, - { "PlayMusic", &LuaWorldObject::PlayMusic }, - { "PlayDirectSound", &LuaWorldObject::PlayDirectSound }, - { "PlayDistanceSound", &LuaWorldObject::PlayDistanceSound }, - - { NULL, NULL } -}; - -ALERegister UnitMethods[] = -{ - // Getters - { "GetLevel", &LuaUnit::GetLevel }, - { "GetHealth", &LuaUnit::GetHealth }, - { "GetDisplayId", &LuaUnit::GetDisplayId }, - { "GetNativeDisplayId", &LuaUnit::GetNativeDisplayId }, - { "GetPower", &LuaUnit::GetPower }, - { "GetMaxPower", &LuaUnit::GetMaxPower }, - { "GetPowerType", &LuaUnit::GetPowerType }, - { "GetMaxHealth", &LuaUnit::GetMaxHealth }, - { "GetHealthPct", &LuaUnit::GetHealthPct }, - { "GetPowerPct", &LuaUnit::GetPowerPct }, - { "GetGender", &LuaUnit::GetGender }, - { "GetRace", &LuaUnit::GetRace }, - { "GetClass", &LuaUnit::GetClass }, - { "GetRaceMask", &LuaUnit::GetRaceMask }, - { "GetClassMask", &LuaUnit::GetClassMask }, - { "GetRaceAsString", &LuaUnit::GetRaceAsString }, - { "GetClassAsString", &LuaUnit::GetClassAsString }, - { "GetAura", &LuaUnit::GetAura }, - { "GetFaction", &LuaUnit::GetFaction }, - { "GetCurrentSpell", &LuaUnit::GetCurrentSpell }, - { "GetCreatureType", &LuaUnit::GetCreatureType }, - { "GetMountId", &LuaUnit::GetMountId }, - { "GetOwner", &LuaUnit::GetOwner }, - { "GetFriendlyUnitsInRange", &LuaUnit::GetFriendlyUnitsInRange }, - { "GetUnfriendlyUnitsInRange", &LuaUnit::GetUnfriendlyUnitsInRange }, - { "GetOwnerGUID", &LuaUnit::GetOwnerGUID }, - { "GetCreatorGUID", &LuaUnit::GetCreatorGUID }, - { "GetMinionGUID", &LuaUnit::GetPetGUID }, - { "GetCharmerGUID", &LuaUnit::GetCharmerGUID }, - { "GetCharmGUID", &LuaUnit::GetCharmGUID }, - { "GetPetGUID", &LuaUnit::GetPetGUID }, - { "GetCritterGUID", &LuaUnit::GetCritterGUID }, - { "GetControllerGUID", &LuaUnit::GetControllerGUID }, - { "GetControllerGUIDS", &LuaUnit::GetControllerGUIDS }, - { "GetStandState", &LuaUnit::GetStandState }, - { "GetVictim", &LuaUnit::GetVictim }, - { "GetSpeed", &LuaUnit::GetSpeed }, - { "GetSpeedRate", &LuaUnit::GetSpeedRate }, - { "GetStat", &LuaUnit::GetStat }, - { "GetBaseSpellPower", &LuaUnit::GetBaseSpellPower }, - { "GetVehicleKit", &LuaUnit::GetVehicleKit }, - // {"GetVehicle", &LuaUnit::GetVehicle}, // :GetVehicle() - UNDOCUMENTED - Gets the Vehicle kit of the vehicle the unit is on - { "GetMovementType", &LuaUnit::GetMovementType }, - { "GetAttackers", &LuaUnit::GetAttackers }, - { "GetThreat", &LuaUnit::GetThreat }, - - // Setters - { "SetFaction", &LuaUnit::SetFaction }, - { "SetLevel", &LuaUnit::SetLevel }, - { "SetHealth", &LuaUnit::SetHealth }, - { "SetMaxHealth", &LuaUnit::SetMaxHealth }, - { "SetPower", &LuaUnit::SetPower }, - { "SetMaxPower", &LuaUnit::SetMaxPower }, - { "SetPowerType", &LuaUnit::SetPowerType }, - { "SetDisplayId", &LuaUnit::SetDisplayId }, - { "SetNativeDisplayId", &LuaUnit::SetNativeDisplayId }, - { "SetFacing", &LuaUnit::SetFacing }, - { "SetFacingToObject", &LuaUnit::SetFacingToObject }, - { "SetSpeed", &LuaUnit::SetSpeed }, - { "SetSpeedRate", &LuaUnit::SetSpeedRate }, - // {"SetStunned", &LuaUnit::SetStunned}, // :SetStunned([enable]) - UNDOCUMENTED - Stuns or removes stun - {"SetRooted", &LuaUnit::SetRooted}, - {"SetConfused", &LuaUnit::SetConfused}, - {"SetFeared", &LuaUnit::SetFeared}, - { "SetPvP", &LuaUnit::SetPvP }, - { "SetFFA", &LuaUnit::SetFFA }, - { "SetSanctuary", &LuaUnit::SetSanctuary }, - // {"SetCanFly", &LuaUnit::SetCanFly}, // :SetCanFly(apply) - UNDOCUMENTED - // {"SetVisible", &LuaUnit::SetVisible}, // :SetVisible(x) - UNDOCUMENTED - { "SetOwnerGUID", &LuaUnit::SetOwnerGUID }, - { "SetName", &LuaUnit::SetName }, - { "SetSheath", &LuaUnit::SetSheath }, - { "SetCreatorGUID", &LuaUnit::SetCreatorGUID }, - { "SetMinionGUID", &LuaUnit::SetPetGUID }, - { "SetPetGUID", &LuaUnit::SetPetGUID }, - { "SetCritterGUID", &LuaUnit::SetCritterGUID }, - { "SetWaterWalk", &LuaUnit::SetWaterWalk }, - { "SetStandState", &LuaUnit::SetStandState }, - { "SetInCombatWith", &LuaUnit::SetInCombatWith }, - { "ModifyPower", &LuaUnit::ModifyPower }, - { "SetImmuneTo", &LuaUnit::SetImmuneTo }, - - // Boolean - { "IsAlive", &LuaUnit::IsAlive }, - { "IsDead", &LuaUnit::IsDead }, - { "IsDying", &LuaUnit::IsDying }, - { "IsPvPFlagged", &LuaUnit::IsPvPFlagged }, - { "IsInCombat", &LuaUnit::IsInCombat }, - { "IsBanker", &LuaUnit::IsBanker }, - { "IsBattleMaster", &LuaUnit::IsBattleMaster }, - { "IsCharmed", &LuaUnit::IsCharmed }, - { "IsArmorer", &LuaUnit::IsArmorer }, - { "IsAttackingPlayer", &LuaUnit::IsAttackingPlayer }, - { "IsInWater", &LuaUnit::IsInWater }, - { "IsUnderWater", &LuaUnit::IsUnderWater }, - { "IsAuctioneer", &LuaUnit::IsAuctioneer }, - { "IsGuildMaster", &LuaUnit::IsGuildMaster }, - { "IsInnkeeper", &LuaUnit::IsInnkeeper }, - { "IsTrainer", &LuaUnit::IsTrainer }, - { "IsGossip", &LuaUnit::IsGossip }, - { "IsTaxi", &LuaUnit::IsTaxi }, - { "IsSpiritHealer", &LuaUnit::IsSpiritHealer }, - { "IsSpiritGuide", &LuaUnit::IsSpiritGuide }, - { "IsTabardDesigner", &LuaUnit::IsTabardDesigner }, - { "IsServiceProvider", &LuaUnit::IsServiceProvider }, - { "IsSpiritService", &LuaUnit::IsSpiritService }, - { "HealthBelowPct", &LuaUnit::HealthBelowPct }, - { "HealthAbovePct", &LuaUnit::HealthAbovePct }, - { "IsMounted", &LuaUnit::IsMounted }, - { "AttackStop", &LuaUnit::AttackStop }, - { "Attack", &LuaUnit::Attack }, - // {"IsVisible", &LuaUnit::IsVisible}, // :IsVisible() - UNDOCUMENTED - // {"IsMoving", &LuaUnit::IsMoving}, // :IsMoving() - UNDOCUMENTED - // {"IsFlying", &LuaUnit::IsFlying}, // :IsFlying() - UNDOCUMENTED - { "IsStopped", &LuaUnit::IsStopped }, - { "HasUnitState", &LuaUnit::HasUnitState }, - { "IsQuestGiver", &LuaUnit::IsQuestGiver }, - { "IsInAccessiblePlaceFor", &LuaUnit::IsInAccessiblePlaceFor }, - { "IsVendor", &LuaUnit::IsVendor }, - { "IsRooted", &LuaUnit::IsRooted }, - { "IsFullHealth", &LuaUnit::IsFullHealth }, - { "HasAura", &LuaUnit::HasAura }, - { "IsCasting", &LuaUnit::IsCasting }, - { "IsStandState", &LuaUnit::IsStandState }, - { "IsOnVehicle", &LuaUnit::IsOnVehicle }, - - // Other - { "HandleStatFlatModifier", &LuaUnit::HandleStatFlatModifier }, - { "AddAura", &LuaUnit::AddAura }, - { "RemoveAura", &LuaUnit::RemoveAura }, - { "RemoveAllAuras", &LuaUnit::RemoveAllAuras }, - { "RemoveArenaAuras", &LuaUnit::RemoveArenaAuras }, - { "ClearInCombat", &LuaUnit::ClearInCombat }, - { "DeMorph", &LuaUnit::DeMorph }, - { "SendUnitWhisper", &LuaUnit::SendUnitWhisper }, - { "SendUnitEmote", &LuaUnit::SendUnitEmote }, - { "SendUnitSay", &LuaUnit::SendUnitSay }, - { "SendUnitYell", &LuaUnit::SendUnitYell }, - { "CastSpell", &LuaUnit::CastSpell }, - { "CastCustomSpell", &LuaUnit::CastCustomSpell }, - { "CastSpellAoF", &LuaUnit::CastSpellAoF }, - { "Kill", &LuaUnit::Kill }, - { "StopSpellCast", &LuaUnit::StopSpellCast }, - { "InterruptSpell", &LuaUnit::InterruptSpell }, - { "SendChatMessageToPlayer", &LuaUnit::SendChatMessageToPlayer }, - { "PerformEmote", &LuaUnit::PerformEmote }, - { "EmoteState", &LuaUnit::EmoteState }, - { "CountPctFromCurHealth", &LuaUnit::CountPctFromCurHealth }, - { "CountPctFromMaxHealth", &LuaUnit::CountPctFromMaxHealth }, - { "Dismount", &LuaUnit::Dismount }, - { "Mount", &LuaUnit::Mount }, - // {"RestoreDisplayId", &LuaUnit::RestoreDisplayId}, // :RestoreDisplayId() - UNDOCUMENTED - // {"RestoreFaction", &LuaUnit::RestoreFaction}, // :RestoreFaction() - UNDOCUMENTED - // {"RemoveBindSightAuras", &LuaUnit::RemoveBindSightAuras}, // :RemoveBindSightAuras() - UNDOCUMENTED - // {"RemoveCharmAuras", &LuaUnit::RemoveCharmAuras}, // :RemoveCharmAuras() - UNDOCUMENTED - { "ClearThreatList", &LuaUnit::ClearThreatList }, - { "GetThreatList", &LuaUnit::GetThreatList }, - { "ClearUnitState", &LuaUnit::ClearUnitState }, - { "AddUnitState", &LuaUnit::AddUnitState }, - // {"DisableMelee", &LuaUnit::DisableMelee}, // :DisableMelee([disable]) - UNDOCUMENTED - if true, enables - // {"SummonGuardian", &LuaUnit::SummonGuardian}, // :SummonGuardian(entry, x, y, z, o[, duration]) - UNDOCUMENTED - summons a guardian to location. Scales with summoner, is friendly to him and guards him. - { "NearTeleport", &LuaUnit::NearTeleport }, - { "MoveIdle", &LuaUnit::MoveIdle }, - { "MoveRandom", &LuaUnit::MoveRandom }, - { "MoveHome", &LuaUnit::MoveHome }, - { "MoveFollow", &LuaUnit::MoveFollow }, - { "MoveChase", &LuaUnit::MoveChase }, - { "MoveConfused", &LuaUnit::MoveConfused }, - { "MoveFleeing", &LuaUnit::MoveFleeing }, - { "MoveTo", &LuaUnit::MoveTo }, - { "MoveJump", &LuaUnit::MoveJump }, - { "MoveStop", &LuaUnit::MoveStop }, - { "MoveExpire", &LuaUnit::MoveExpire }, - { "MoveClear", &LuaUnit::MoveClear }, - { "DealDamage", &LuaUnit::DealDamage }, - { "DealHeal", &LuaUnit::DealHeal }, - { "AddThreat", &LuaUnit::AddThreat }, - { "ModifyThreatPct", &LuaUnit::ModifyThreatPct }, - { "ClearThreat", &LuaUnit::ClearThreat }, - { "ResetAllThreat", &LuaUnit::ResetAllThreat }, - - { NULL, NULL } -}; - -ALERegister PlayerMethods[] = -{ - // Getters - { "GetSelection", &LuaPlayer::GetSelection }, - { "GetGMRank", &LuaPlayer::GetGMRank }, - { "GetGuildId", &LuaPlayer::GetGuildId }, - { "GetCoinage", &LuaPlayer::GetCoinage }, - { "GetTeam", &LuaPlayer::GetTeam }, - { "GetItemCount", &LuaPlayer::GetItemCount }, - { "GetGroup", &LuaPlayer::GetGroup }, - { "GetGuild", &LuaPlayer::GetGuild }, - { "GetAccountId", &LuaPlayer::GetAccountId }, - { "GetAccountName", &LuaPlayer::GetAccountName }, - { "GetCompletedQuestsCount", &LuaPlayer::GetCompletedQuestsCount }, - { "GetArenaPoints", &LuaPlayer::GetArenaPoints }, - { "GetHonorPoints", &LuaPlayer::GetHonorPoints }, - { "GetLifetimeKills", &LuaPlayer::GetLifetimeKills }, - { "GetPlayerIP", &LuaPlayer::GetPlayerIP }, - { "GetLevelPlayedTime", &LuaPlayer::GetLevelPlayedTime }, - { "GetTotalPlayedTime", &LuaPlayer::GetTotalPlayedTime }, - { "GetItemByPos", &LuaPlayer::GetItemByPos }, - { "GetItemByEntry", &LuaPlayer::GetItemByEntry }, - { "GetItemByGUID", &LuaPlayer::GetItemByGUID }, - { "GetMailCount", &LuaPlayer::GetMailCount }, - { "GetMailItem", &LuaPlayer::GetMailItem }, - { "GetReputation", &LuaPlayer::GetReputation }, - { "GetEquippedItemBySlot", &LuaPlayer::GetEquippedItemBySlot }, - { "GetQuestLevel", &LuaPlayer::GetQuestLevel }, - { "GetChatTag", &LuaPlayer::GetChatTag }, - { "GetRestBonus", &LuaPlayer::GetRestBonus }, - { "GetPhaseMaskForSpawn", &LuaPlayer::GetPhaseMaskForSpawn }, - { "GetAchievementPoints", &LuaPlayer::GetAchievementPoints }, - { "GetCompletedAchievementsCount", &LuaPlayer::GetCompletedAchievementsCount }, - { "GetReqKillOrCastCurrentCount", &LuaPlayer::GetReqKillOrCastCurrentCount }, - { "GetQuestStatus", &LuaPlayer::GetQuestStatus }, - { "GetInGameTime", &LuaPlayer::GetInGameTime }, - { "GetComboPoints", &LuaPlayer::GetComboPoints }, - { "GetComboTarget", &LuaPlayer::GetComboTarget }, - { "GetGuildName", &LuaPlayer::GetGuildName }, - { "GetFreeTalentPoints", &LuaPlayer::GetFreeTalentPoints }, - { "GetActiveSpec", &LuaPlayer::GetActiveSpec }, - { "GetSpecsCount", &LuaPlayer::GetSpecsCount }, - { "GetSpellCooldownDelay", &LuaPlayer::GetSpellCooldownDelay }, - { "GetGuildRank", &LuaPlayer::GetGuildRank }, - { "GetDifficulty", &LuaPlayer::GetDifficulty }, - { "GetHealthBonusFromStamina", &LuaPlayer::GetHealthBonusFromStamina }, - { "GetManaBonusFromIntellect", &LuaPlayer::GetManaBonusFromIntellect }, - { "GetMaxSkillValue", &LuaPlayer::GetMaxSkillValue }, - { "GetPureMaxSkillValue", &LuaPlayer::GetPureMaxSkillValue }, - { "GetSkillValue", &LuaPlayer::GetSkillValue }, - { "GetBaseSkillValue", &LuaPlayer::GetBaseSkillValue }, - { "GetPureSkillValue", &LuaPlayer::GetPureSkillValue }, - { "GetSkillPermBonusValue", &LuaPlayer::GetSkillPermBonusValue }, - { "GetSkillTempBonusValue", &LuaPlayer::GetSkillTempBonusValue }, - { "GetReputationRank", &LuaPlayer::GetReputationRank }, - { "GetDrunkValue", &LuaPlayer::GetDrunkValue }, - { "GetBattlegroundId", &LuaPlayer::GetBattlegroundId }, - { "GetBattlegroundTypeId", &LuaPlayer::GetBattlegroundTypeId }, - { "GetXP", &LuaPlayer::GetXP }, - { "GetXPRestBonus", &LuaPlayer::GetXPRestBonus }, - { "GetGroupInvite", &LuaPlayer::GetGroupInvite }, - { "GetSubGroup", &LuaPlayer::GetSubGroup }, - { "GetNextRandomRaidMember", &LuaPlayer::GetNextRandomRaidMember }, - { "GetOriginalGroup", &LuaPlayer::GetOriginalGroup }, - { "GetOriginalSubGroup", &LuaPlayer::GetOriginalSubGroup }, - { "GetChampioningFaction", &LuaPlayer::GetChampioningFaction }, - { "GetLatency", &LuaPlayer::GetLatency }, - // {"GetRecruiterId", &LuaPlayer::GetRecruiterId}, // :GetRecruiterId() - UNDOCUMENTED - Returns player's recruiter's ID - { "GetDbLocaleIndex", &LuaPlayer::GetDbLocaleIndex }, - { "GetDbcLocale", &LuaPlayer::GetDbcLocale }, - { "GetCorpse", &LuaPlayer::GetCorpse }, - { "GetGossipTextId", &LuaPlayer::GetGossipTextId }, - { "GetQuestRewardStatus", &LuaPlayer::GetQuestRewardStatus }, - { "GetShieldBlockValue", &LuaPlayer::GetShieldBlockValue }, - { "GetPlayerSettingValue", &LuaPlayer::GetPlayerSettingValue }, - { "GetTrader", &LuaPlayer::GetTrader }, - { "GetBonusTalentCount", &LuaPlayer::GetBonusTalentCount }, - { "GetKnownTaxiNodes", &LuaPlayer::GetKnownTaxiNodes }, - { "GetPet", &LuaPlayer::GetPet }, - { "GetTemporaryUnsummonedPetNumber", &LuaPlayer::GetTemporaryUnsummonedPetNumber }, - { "GetLastPetNumber", &LuaPlayer::GetLastPetNumber }, - { "GetLastPetSpell", &LuaPlayer::GetLastPetSpell }, - { "GetQuestSlotQuestId", &LuaPlayer::GetQuestSlotQuestId }, - - // Setters - { "SetTemporaryUnsummonedPetNumber", &LuaPlayer::SetTemporaryUnsummonedPetNumber }, - { "SetLastPetNumber", &LuaPlayer::SetLastPetNumber }, - { "SetLastPetSpell", &LuaPlayer::SetLastPetSpell }, - { "SetShowDKPet", &LuaPlayer::SetShowDKPet }, - { "AdvanceSkillsToMax", &LuaPlayer::AdvanceSkillsToMax }, - { "AdvanceSkill", &LuaPlayer::AdvanceSkill }, - { "AdvanceAllSkills", &LuaPlayer::AdvanceAllSkills }, - { "AddLifetimeKills", &LuaPlayer::AddLifetimeKills }, - { "SetCoinage", &LuaPlayer::SetCoinage }, - { "SetKnownTitle", &LuaPlayer::SetKnownTitle }, - { "UnsetKnownTitle", &LuaPlayer::UnsetKnownTitle }, - { "SetBindPoint", &LuaPlayer::SetBindPoint }, - { "SetArenaPoints", &LuaPlayer::SetArenaPoints }, - { "SetHonorPoints", &LuaPlayer::SetHonorPoints }, - { "SetSpellPower", &LuaPlayer::SetSpellPower }, - { "SetLifetimeKills", &LuaPlayer::SetLifetimeKills }, - { "SetGameMaster", &LuaPlayer::SetGameMaster }, - { "SetGMChat", &LuaPlayer::SetGMChat }, - { "SetKnownTaxiNodes", &LuaPlayer::SetKnownTaxiNodes }, - { "SetTaxiCheat", &LuaPlayer::SetTaxiCheat }, - { "SetGMVisible", &LuaPlayer::SetGMVisible }, - { "SetPvPDeath", &LuaPlayer::SetPvPDeath }, - { "SetAcceptWhispers", &LuaPlayer::SetAcceptWhispers }, - { "SetRestBonus", &LuaPlayer::SetRestBonus }, - { "SetQuestStatus", &LuaPlayer::SetQuestStatus }, - { "SetReputation", &LuaPlayer::SetReputation }, - { "SetFreeTalentPoints", &LuaPlayer::SetFreeTalentPoints }, - { "SetGuildRank", &LuaPlayer::SetGuildRank }, - // {"SetMovement", &LuaPlayer::SetMovement}, // :SetMovement(type) - UNDOCUMENTED - Sets player's movement type - { "SetSkill", &LuaPlayer::SetSkill }, - { "SetFactionForRace", &LuaPlayer::SetFactionForRace }, - { "SetDrunkValue", &LuaPlayer::SetDrunkValue }, - { "SetAtLoginFlag", &LuaPlayer::SetAtLoginFlag }, - { "SetPlayerLock", &LuaPlayer::SetPlayerLock }, - { "SetGender", &LuaPlayer::SetGender }, - { "SetSheath", &LuaPlayer::SetSheath }, - { "SetBonusTalentCount", &LuaPlayer::SetBonusTalentCount }, - { "AddBonusTalent", &LuaPlayer::AddBonusTalent }, - { "RemoveBonusTalent", &LuaPlayer::RemoveBonusTalent }, - { "GetHomebind", &LuaPlayer::GetHomebind }, - { "GetSpells", &LuaPlayer::GetSpells }, - { "GetAverageItemLevel", &LuaPlayer::GetAverageItemLevel }, - { "GetBarberShopCost", &LuaPlayer::GetBarberShopCost }, - { "GetSightRange", &LuaPlayer::GetSightRange }, - { "GetWeaponProficiency", &LuaPlayer::GetWeaponProficiency }, - { "GetArmorProficiency", &LuaPlayer::GetArmorProficiency }, - { "GetAmmoDPS", &LuaPlayer::GetAmmoDPS }, - { "GetShield", &LuaPlayer::GetShield }, - { "GetRunesState", &LuaPlayer::GetRunesState }, - { "GetViewpoint", &LuaPlayer::GetViewpoint }, - { "GetDodgeFromAgility", &LuaPlayer::GetDodgeFromAgility }, - { "GetMeleeCritFromAgility", &LuaPlayer::GetMeleeCritFromAgility }, - { "GetSpellCritFromIntellect", &LuaPlayer::GetSpellCritFromIntellect }, - { "GetInventoryItem", &LuaPlayer::GetInventoryItem }, - { "GetBankItem", &LuaPlayer::GetBankItem }, - { "GetCreationTime", &LuaPlayer::GetCreationTime }, - { "SetCanFly", &LuaPlayer::SetCanFly }, - - // Boolean - { "HasTankSpec", &LuaPlayer::HasTankSpec }, - { "HasMeleeSpec", &LuaPlayer::HasMeleeSpec }, - { "HasCasterSpec", &LuaPlayer::HasCasterSpec }, - { "HasHealSpec", &LuaPlayer::HasHealSpec }, - { "IsInGroup", &LuaPlayer::IsInGroup }, - { "IsInGuild", &LuaPlayer::IsInGuild }, - { "IsGM", &LuaPlayer::IsGM }, - { "IsImmuneToDamage", &LuaPlayer::IsImmuneToDamage }, - { "IsAlliance", &LuaPlayer::IsAlliance }, - { "IsHorde", &LuaPlayer::IsHorde }, - { "HasTitle", &LuaPlayer::HasTitle }, - { "HasItem", &LuaPlayer::HasItem }, - { "Teleport", &LuaPlayer::Teleport }, - { "AddItem", &LuaPlayer::AddItem }, - { "IsInArenaTeam", &LuaPlayer::IsInArenaTeam }, - { "CanRewardQuest", &LuaPlayer::CanRewardQuest }, - { "CanCompleteRepeatableQuest", &LuaPlayer::CanCompleteRepeatableQuest }, - { "CanCompleteQuest", &LuaPlayer::CanCompleteQuest }, - { "CanEquipItem", &LuaPlayer::CanEquipItem }, - { "IsFalling", &LuaPlayer::IsFalling }, - { "ToggleAFK", &LuaPlayer::ToggleAFK }, - { "ToggleDND", &LuaPlayer::ToggleDND }, - { "IsAFK", &LuaPlayer::IsAFK }, - { "IsDND", &LuaPlayer::IsDND }, - { "IsAcceptingWhispers", &LuaPlayer::IsAcceptingWhispers }, - { "IsGMChat", &LuaPlayer::IsGMChat }, - { "IsTaxiCheater", &LuaPlayer::IsTaxiCheater }, - { "IsGMVisible", &LuaPlayer::IsGMVisible }, - { "HasQuest", &LuaPlayer::HasQuest }, - { "InBattlegroundQueue", &LuaPlayer::InBattlegroundQueue }, - // {"IsImmuneToEnvironmentalDamage", &LuaPlayer::IsImmuneToEnvironmentalDamage}, // :IsImmuneToEnvironmentalDamage() - UNDOCUMENTED - Returns true if the player is immune to environmental damage - { "CanSpeak", &LuaPlayer::CanSpeak }, - { "HasAtLoginFlag", &LuaPlayer::HasAtLoginFlag }, - // {"InRandomLfgDungeon", &LuaPlayer::InRandomLfgDungeon}, // :InRandomLfgDungeon() - UNDOCUMENTED - Returns true if the player is in a random LFG dungeon - // {"HasPendingBind", &LuaPlayer::HasPendingBind}, // :HasPendingBind() - UNDOCUMENTED - Returns true if the player has a pending instance bind - { "HasAchieved", &LuaPlayer::HasAchieved }, - { "GetAchievementCriteriaProgress", &LuaPlayer::GetAchievementCriteriaProgress }, - { "SetAchievement", &LuaPlayer::SetAchievement }, - { "CanUninviteFromGroup", &LuaPlayer::CanUninviteFromGroup }, - { "IsRested", &LuaPlayer::IsRested }, - // {"CanFlyInZone", &LuaPlayer::CanFlyInZone}, // :CanFlyInZone(mapid, zone) - UNDOCUMENTED - Returns true if the player can fly in the area - // {"IsNeverVisible", &LuaPlayer::IsNeverVisible}, // :IsNeverVisible() - UNDOCUMENTED - Returns true if the player is never visible - { "IsVisibleForPlayer", &LuaPlayer::IsVisibleForPlayer }, - // {"IsUsingLfg", &LuaPlayer::IsUsingLfg}, // :IsUsingLfg() - UNDOCUMENTED - Returns true if the player is using LFG - { "HasQuestForItem", &LuaPlayer::HasQuestForItem }, - { "HasQuestForGO", &LuaPlayer::HasQuestForGO }, - { "CanShareQuest", &LuaPlayer::CanShareQuest }, - // {"HasReceivedQuestReward", &LuaPlayer::HasReceivedQuestReward}, // :HasReceivedQuestReward(entry) - UNDOCUMENTED - Returns true if the player has recieved the quest's reward - { "HasTalent", &LuaPlayer::HasTalent }, - { "IsInSameGroupWith", &LuaPlayer::IsInSameGroupWith }, - { "IsInSameRaidWith", &LuaPlayer::IsInSameRaidWith }, - { "IsGroupVisibleFor", &LuaPlayer::IsGroupVisibleFor }, - { "HasSkill", &LuaPlayer::HasSkill }, - { "IsHonorOrXPTarget", &LuaPlayer::IsHonorOrXPTarget }, - { "CanParry", &LuaPlayer::CanParry }, - { "CanBlock", &LuaPlayer::CanBlock }, - { "CanTitanGrip", &LuaPlayer::CanTitanGrip }, - { "InBattleground", &LuaPlayer::InBattleground }, - { "InArena", &LuaPlayer::InArena }, - // {"IsOutdoorPvPActive", &LuaPlayer::IsOutdoorPvPActive}, // :IsOutdoorPvPActive() - UNDOCUMENTED - Returns true if the player is outdoor pvp active - // {"IsARecruiter", &LuaPlayer::IsARecruiter}, // :IsARecruiter() - UNDOCUMENTED - Returns true if the player is a recruiter - { "CanUseItem", &LuaPlayer::CanUseItem }, - { "HasSpell", &LuaPlayer::HasSpell }, - { "HasSpellCooldown", &LuaPlayer::HasSpellCooldown }, - { "IsInWater", &LuaPlayer::IsInWater }, - { "CanFly", &LuaPlayer::CanFly }, - { "IsMoving", &LuaPlayer::IsMoving }, - { "IsFlying", &LuaPlayer::IsFlying }, - { "CanPetResurrect", &LuaPlayer::CanPetResurrect }, - { "IsExistPet", &LuaPlayer::IsExistPet }, - { "CanTameExoticPets", &LuaPlayer::CanTameExoticPets }, - { "IsPetNeedBeTemporaryUnsummoned", &LuaPlayer::IsPetNeedBeTemporaryUnsummoned }, - { "CanResummonPet", &LuaPlayer::CanResummonPet }, - { "CanSeeDKPet", &LuaPlayer::CanSeeDKPet }, - { "IsMaxLevel", &LuaPlayer::IsMaxLevel }, - { "IsDailyQuestDone", &LuaPlayer::IsDailyQuestDone }, - { "IsPvP", &LuaPlayer::IsPvP }, - { "IsFFAPvP", &LuaPlayer::IsFFAPvP }, - { "IsUsingLfg", &LuaPlayer::IsUsingLfg }, - { "InRandomLfgDungeon", &LuaPlayer::InRandomLfgDungeon }, - { "CanInteractWithQuestGiver", &LuaPlayer::CanInteractWithQuestGiver }, - { "CanSeeStartQuest", &LuaPlayer::CanSeeStartQuest }, - { "CanTakeQuest", &LuaPlayer::CanTakeQuest }, - { "CanAddQuest", &LuaPlayer::CanAddQuest }, - { "CalculateReputationGain", &LuaPlayer::CalculateReputationGain }, - { "HasTitleByIndex", &LuaPlayer::HasTitleByIndex }, - { "IsAtGroupRewardDistance", &LuaPlayer::IsAtGroupRewardDistance }, - { "IsAtLootRewardDistance", &LuaPlayer::IsAtLootRewardDistance }, - { "CanTeleport", &LuaPlayer::CanTeleport }, - { "IsSpectator", &LuaPlayer::IsSpectator }, - // { "HasSpellMod", &LuaPlayer::HasSpellMod }, - - // Gossip - { "GossipMenuAddItem", &LuaPlayer::GossipMenuAddItem }, - { "GossipSendMenu", &LuaPlayer::GossipSendMenu }, - { "GossipComplete", &LuaPlayer::GossipComplete }, - { "GossipClearMenu", &LuaPlayer::GossipClearMenu }, - - // Other - { "SendBroadcastMessage", &LuaPlayer::SendBroadcastMessage }, - { "SendAreaTriggerMessage", &LuaPlayer::SendAreaTriggerMessage }, - { "SendNotification", &LuaPlayer::SendNotification }, - { "SendPacket", &LuaPlayer::SendPacket }, - { "SendAddonMessage", &LuaPlayer::SendAddonMessage }, - { "ModifyMoney", &LuaPlayer::ModifyMoney }, - { "LearnSpell", &LuaPlayer::LearnSpell }, - { "LearnTalent", &LuaPlayer::LearnTalent }, - - { "RunCommand", &LuaPlayer::RunCommand }, - { "SetGlyph", &LuaPlayer::SetGlyph }, - { "GetGlyph", &LuaPlayer::GetGlyph }, - { "RemoveArenaSpellCooldowns", &LuaPlayer::RemoveArenaSpellCooldowns }, - { "RemoveItem", &LuaPlayer::RemoveItem }, - { "RemoveLifetimeKills", &LuaPlayer::RemoveLifetimeKills }, - { "ResurrectPlayer", &LuaPlayer::ResurrectPlayer }, - { "EquipItem", &LuaPlayer::EquipItem }, - { "ResetSpellCooldown", &LuaPlayer::ResetSpellCooldown }, - { "ResetTypeCooldowns", &LuaPlayer::ResetTypeCooldowns }, - { "ResetAllCooldowns", &LuaPlayer::ResetAllCooldowns }, - { "GiveXP", &LuaPlayer::GiveXP }, // :GiveXP(xp[, victim, pureXP, triggerHook]) - UNDOCUMENTED - Gives XP to the player. If pure is false, bonuses are count in. If triggerHook is false, GiveXp hook is not triggered. - // {"RemovePet", &LuaPlayer::RemovePet}, // :RemovePet([mode, returnreagent]) - UNDOCUMENTED - Removes the player's pet. Mode determines if the pet is saved and how - // {"SummonPet", &LuaPlayer::SummonPet}, // :SummonPet(entry, x, y, z, o, petType, despwtime) - Summons a pet for the player - { "Say", &LuaPlayer::Say }, - { "Yell", &LuaPlayer::Yell }, - { "TextEmote", &LuaPlayer::TextEmote }, - { "Whisper", &LuaPlayer::Whisper }, - { "CompleteQuest", &LuaPlayer::CompleteQuest }, - { "IncompleteQuest", &LuaPlayer::IncompleteQuest }, - { "FailQuest", &LuaPlayer::FailQuest }, - { "AddQuest", &LuaPlayer::AddQuest }, - { "RemoveQuest", &LuaPlayer::RemoveQuest }, - // {"RemoveActiveQuest", &LuaPlayer::RemoveActiveQuest}, // :RemoveActiveQuest(entry) - UNDOCUMENTED - Removes an active quest - // {"RemoveRewardedQuest", &LuaPlayer::RemoveRewardedQuest}, // :RemoveRewardedQuest(entry) - UNDOCUMENTED - Removes a rewarded quest - { "AreaExploredOrEventHappens", &LuaPlayer::AreaExploredOrEventHappens }, - { "GroupEventHappens", &LuaPlayer::GroupEventHappens }, - { "KilledMonsterCredit", &LuaPlayer::KilledMonsterCredit }, - // {"KilledPlayerCredit", &LuaPlayer::KilledPlayerCredit}, // :KilledPlayerCredit() - UNDOCUMENTED - Satisfies a player kill for the player - // {"KillGOCredit", &LuaPlayer::KillGOCredit}, // :KillGOCredit(GOEntry[, GUID]) - UNDOCUMENTED - Credits the player for destroying a GO, guid is optional - { "TalkedToCreature", &LuaPlayer::TalkedToCreature }, - { "ResetPetTalents", &LuaPlayer::ResetPetTalents }, - { "AddComboPoints", &LuaPlayer::AddComboPoints }, - // {"GainSpellComboPoints", &LuaPlayer::GainSpellComboPoints}, // :GainSpellComboPoints(amount) - UNDOCUMENTED - Player gains spell combo points - { "ClearComboPoints", &LuaPlayer::ClearComboPoints }, - { "RemoveSpell", &LuaPlayer::RemoveSpell }, - { "ResetTalents", &LuaPlayer::ResetTalents }, - { "ResetTalentsCost", &LuaPlayer::ResetTalentsCost }, - // {"AddTalent", &LuaPlayer::AddTalent}, // :AddTalent(spellid, spec, learning) - UNDOCUMENTED - Adds a talent spell for the player to given spec - { "RemoveFromGroup", &LuaPlayer::RemoveFromGroup }, - { "KillPlayer", &LuaPlayer::KillPlayer }, - { "DurabilityLossAll", &LuaPlayer::DurabilityLossAll }, - { "DurabilityLoss", &LuaPlayer::DurabilityLoss }, - { "DurabilityPointsLoss", &LuaPlayer::DurabilityPointsLoss }, - { "DurabilityPointsLossAll", &LuaPlayer::DurabilityPointsLossAll }, - { "DurabilityPointLossForEquipSlot", &LuaPlayer::DurabilityPointLossForEquipSlot }, - { "DurabilityRepairAll", &LuaPlayer::DurabilityRepairAll }, - { "DurabilityRepair", &LuaPlayer::DurabilityRepair }, - { "ModifyHonorPoints", &LuaPlayer::ModifyHonorPoints }, - { "ModifyArenaPoints", &LuaPlayer::ModifyArenaPoints }, - { "LeaveBattleground", &LuaPlayer::LeaveBattleground }, - // {"BindToInstance", &LuaPlayer::BindToInstance}, // :BindToInstance() - UNDOCUMENTED - Binds the player to the current instance - { "UnbindInstance", &LuaPlayer::UnbindInstance }, - { "UnbindAllInstances", &LuaPlayer::UnbindAllInstances }, - { "RemoveFromBattlegroundRaid", &LuaPlayer::RemoveFromBattlegroundRaid }, - { "ResetAchievements", &LuaPlayer::ResetAchievements }, - { "KickPlayer", &LuaPlayer::KickPlayer }, - { "LogoutPlayer", &LuaPlayer::LogoutPlayer }, - { "SendTrainerList", &LuaPlayer::SendTrainerList }, - { "SendListInventory", &LuaPlayer::SendListInventory }, - { "SendShowBank", &LuaPlayer::SendShowBank }, - { "SendTabardVendorActivate", &LuaPlayer::SendTabardVendorActivate }, - { "SendSpiritResurrect", &LuaPlayer::SendSpiritResurrect }, - { "SendTaxiMenu", &LuaPlayer::SendTaxiMenu }, - { "SendUpdateWorldState", &LuaPlayer::SendUpdateWorldState }, - { "RewardQuest", &LuaPlayer::RewardQuest }, - { "SendAuctionMenu", &LuaPlayer::SendAuctionMenu }, - { "SendShowMailBox", &LuaPlayer::SendShowMailBox }, - { "StartTaxi", &LuaPlayer::StartTaxi }, - { "GossipSendPOI", &LuaPlayer::GossipSendPOI }, - { "GossipAddQuests", &LuaPlayer::GossipAddQuests }, - { "SendQuestTemplate", &LuaPlayer::SendQuestTemplate }, - { "SpawnBones", &LuaPlayer::SpawnBones }, - { "RemovedInsignia", &LuaPlayer::RemovedInsignia }, - { "SendGuildInvite", &LuaPlayer::SendGuildInvite }, - { "Mute", &LuaPlayer::Mute }, - { "SummonPlayer", &LuaPlayer::SummonPlayer }, - { "SaveToDB", &LuaPlayer::SaveToDB }, - { "GroupInvite", &LuaPlayer::GroupInvite }, - { "GroupCreate", &LuaPlayer::GroupCreate }, - { "SendCinematicStart", &LuaPlayer::SendCinematicStart }, - { "SendMovieStart", &LuaPlayer::SendMovieStart }, - { "UpdatePlayerSetting", &LuaPlayer::UpdatePlayerSetting }, - { "TeleportTo", &LuaPlayer::TeleportTo }, - { "SummonPet", &LuaPlayer::SummonPet }, - { "CreatePet", &LuaPlayer::CreatePet }, - { "UnsummonPetTemporarily", &LuaPlayer::UnsummonPetTemporarily }, - { "RemovePet", &LuaPlayer::RemovePet }, - { "ResetPetTalents", &LuaPlayer::ResetPetTalents }, - { "LearnPetTalent", &LuaPlayer::LearnPetTalent }, - { "ResummonPetTemporaryUnSummonedIfAny", &LuaPlayer::ResummonPetTemporaryUnSummonedIfAny }, - { "SetPlayerFlag", &LuaPlayer::SetPlayerFlag }, - { "RemovePlayerFlag", &LuaPlayer::RemovePlayerFlag }, - { "DoRandomRoll", &LuaPlayer::DoRandomRoll }, - { "EnvironmentalDamage", &LuaPlayer::EnvironmentalDamage }, - { "InitTaxiNodesForLevel", &LuaPlayer::InitTaxiNodesForLevel }, - { "AbandonQuest", &LuaPlayer::AbandonQuest }, - { "AddWeaponProficiency", &LuaPlayer::AddWeaponProficiency }, - { "AddArmorProficiency", &LuaPlayer::AddArmorProficiency }, - { "SetAmmo", &LuaPlayer::SetAmmo }, - { "RemoveAmmo", &LuaPlayer::RemoveAmmo }, - { "SetCanTeleport", &LuaPlayer::SetCanTeleport }, - { "SetIsSpectator", &LuaPlayer::SetIsSpectator }, - { "SetViewpoint", &LuaPlayer::SetViewpoint }, - { "ToggleInstantFlight", &LuaPlayer::ToggleInstantFlight }, - { "SetCreationTime", &LuaPlayer::SetCreationTime }, - { "ApplyRatingMod", &LuaPlayer::ApplyRatingMod }, - - { NULL, NULL } -}; - -ALERegister CreatureMethods[] = -{ - // Getters - { "GetAITarget", &LuaCreature::GetAITarget }, - { "GetAITargets", &LuaCreature::GetAITargets }, - { "GetAITargetsCount", &LuaCreature::GetAITargetsCount }, - { "GetHomePosition", &LuaCreature::GetHomePosition }, - { "GetCorpseDelay", &LuaCreature::GetCorpseDelay }, - { "GetCreatureSpellCooldownDelay", &LuaCreature::GetCreatureSpellCooldownDelay }, - { "GetScriptId", &LuaCreature::GetScriptId }, - { "GetAIName", &LuaCreature::GetAIName }, - { "GetScriptName", &LuaCreature::GetScriptName }, - { "GetAggroRange", &LuaCreature::GetAggroRange }, - { "GetDefaultMovementType", &LuaCreature::GetDefaultMovementType }, - { "GetRespawnDelay", &LuaCreature::GetRespawnDelay }, - { "GetWanderRadius", &LuaCreature::GetWanderRadius }, - { "GetCurrentWaypointId", &LuaCreature::GetCurrentWaypointId }, - { "GetSpawnId", &LuaCreature::GetSpawnId }, - { "GetWaypointPath", &LuaCreature::GetWaypointPath }, - { "GetLootMode", &LuaCreature::GetLootMode }, - { "GetLootRecipient", &LuaCreature::GetLootRecipient }, - { "GetLootRecipientGroup", &LuaCreature::GetLootRecipientGroup }, - { "GetNPCFlags", &LuaCreature::GetNPCFlags }, - { "GetUnitFlags", &LuaCreature::GetUnitFlags }, - { "GetUnitFlagsTwo", &LuaCreature::GetUnitFlagsTwo }, - { "GetExtraFlags", &LuaCreature::GetExtraFlags }, - { "GetRank", &LuaCreature::GetRank }, - { "GetShieldBlockValue", &LuaCreature::GetShieldBlockValue }, - { "GetDBTableGUIDLow", &LuaCreature::GetDBTableGUIDLow }, - { "GetCreatureFamily", &LuaCreature::GetCreatureFamily }, - { "GetReactState", &LuaCreature::GetReactState }, - { "GetLoot", &LuaCreature::GetLoot }, - - // Setters - { "SetRegeneratingHealth", &LuaCreature::SetRegeneratingHealth }, - { "SetHover", &LuaCreature::SetHover }, - { "SetDisableGravity", &LuaCreature::SetDisableGravity }, - { "SetAggroEnabled", &LuaCreature::SetAggroEnabled }, - { "SetCorpseDelay", &LuaCreature::SetCorpseDelay }, - { "SetNoCallAssistance", &LuaCreature::SetNoCallAssistance }, - { "SetNoSearchAssistance", &LuaCreature::SetNoSearchAssistance }, - { "SetDefaultMovementType", &LuaCreature::SetDefaultMovementType }, - { "SetRespawnDelay", &LuaCreature::SetRespawnDelay }, - { "SetWanderRadius", &LuaCreature::SetWanderRadius }, - { "SetInCombatWithZone", &LuaCreature::SetInCombatWithZone }, - { "SetDisableReputationGain", &LuaCreature::SetDisableReputationGain }, - { "SetLootMode", &LuaCreature::SetLootMode }, - { "SetNPCFlags", &LuaCreature::SetNPCFlags }, - { "SetUnitFlags", &LuaCreature::SetUnitFlags }, - { "SetUnitFlagsTwo", &LuaCreature::SetUnitFlagsTwo }, - { "SetReactState", &LuaCreature::SetReactState }, - { "SetDeathState", &LuaCreature::SetDeathState }, - { "SetWalk", &LuaCreature::SetWalk }, - { "SetHomePosition", &LuaCreature::SetHomePosition }, - { "SetEquipmentSlots", &LuaCreature::SetEquipmentSlots }, - - // Boolean - { "IsRegeneratingHealth", &LuaCreature::IsRegeneratingHealth }, - { "IsDungeonBoss", &LuaCreature::IsDungeonBoss }, - { "IsWorldBoss", &LuaCreature::IsWorldBoss }, - { "IsRacialLeader", &LuaCreature::IsRacialLeader }, - { "IsCivilian", &LuaCreature::IsCivilian }, - { "IsTrigger", &LuaCreature::IsTrigger }, - { "IsGuard", &LuaCreature::IsGuard }, - { "IsElite", &LuaCreature::IsElite }, - { "IsInEvadeMode", &LuaCreature::IsInEvadeMode }, - { "HasCategoryCooldown", &LuaCreature::HasCategoryCooldown }, - { "CanWalk", &LuaCreature::CanWalk }, - { "CanSwim", &LuaCreature::CanSwim }, - { "CanAggro", &LuaCreature::CanAggro }, - { "CanStartAttack", &LuaCreature::CanStartAttack }, - { "HasSearchedAssistance", &LuaCreature::HasSearchedAssistance }, - { "IsTappedBy", &LuaCreature::IsTappedBy }, - { "HasLootRecipient", &LuaCreature::HasLootRecipient }, - { "CanAssistTo", &LuaCreature::CanAssistTo }, - { "IsTargetableForAttack", &LuaCreature::IsTargetableForAttack }, - { "CanCompleteQuest", &LuaCreature::CanCompleteQuest }, - { "IsReputationGainDisabled", &LuaCreature::IsReputationGainDisabled }, - { "IsDamageEnoughForLootingAndReward", &LuaCreature::IsDamageEnoughForLootingAndReward }, - { "HasLootMode", &LuaCreature::HasLootMode }, - { "HasSpell", &LuaCreature::HasSpell }, - { "HasQuest", &LuaCreature::HasQuest }, - { "HasSpellCooldown", &LuaCreature::HasSpellCooldown }, - { "CanFly", &LuaCreature::CanFly }, - - // Other - { "FleeToGetAssistance", &LuaCreature::FleeToGetAssistance }, - { "CallForHelp", &LuaCreature::CallForHelp }, - { "CallAssistance", &LuaCreature::CallAssistance }, - { "RemoveCorpse", &LuaCreature::RemoveCorpse }, - { "DespawnOrUnsummon", &LuaCreature::DespawnOrUnsummon }, - { "Respawn", &LuaCreature::Respawn }, - { "AttackStart", &LuaCreature::AttackStart }, - { "AddLootMode", &LuaCreature::AddLootMode }, - { "ResetLootMode", &LuaCreature::ResetLootMode }, - { "RemoveLootMode", &LuaCreature::RemoveLootMode }, - { "SaveToDB", &LuaCreature::SaveToDB }, - { "SelectVictim", &LuaCreature::SelectVictim }, - { "MoveWaypoint", &LuaCreature::MoveWaypoint }, - { "UpdateEntry", &LuaCreature::UpdateEntry }, - - { NULL, NULL } -}; - -ALERegister GameObjectMethods[] = -{ - // Getters - { "GetDisplayId", &LuaGameObject::GetDisplayId }, - { "GetGoState", &LuaGameObject::GetGoState }, - { "GetLootState", &LuaGameObject::GetLootState }, - { "GetLootRecipient", &LuaGameObject::GetLootRecipient }, - { "GetLootRecipientGroup", &LuaGameObject::GetLootRecipientGroup }, - { "GetSpawnId", &LuaGameObject::GetSpawnId }, - - // Setters - { "SetGoState", &LuaGameObject::SetGoState }, - { "SetLootState", &LuaGameObject::SetLootState }, - { "SetRespawnTime", &LuaGameObject::SetRespawnTime }, - { "SetRespawnDelay", &LuaGameObject::SetRespawnDelay }, - - // Boolean - { "IsTransport", &LuaGameObject::IsTransport }, - // {"IsDestructible", &LuaGameObject::IsDestructible}, // :IsDestructible() - UNDOCUMENTED - { "IsActive", &LuaGameObject::IsActive }, - { "HasQuest", &LuaGameObject::HasQuest }, - { "IsSpawned", &LuaGameObject::IsSpawned }, - - // Other - { "RemoveFromWorld", &LuaGameObject::RemoveFromWorld }, - { "UseDoorOrButton", &LuaGameObject::UseDoorOrButton }, - { "Despawn", &LuaGameObject::Despawn }, - { "Respawn", &LuaGameObject::Respawn }, - { "SaveToDB", &LuaGameObject::SaveToDB }, - { "AddLoot", &LuaGameObject::AddLoot }, - - { NULL, NULL } -}; - -ALERegister ItemMethods[] = -{ - // Getters - { "GetOwnerGUID", &LuaItem::GetOwnerGUID }, - { "GetOwner", &LuaItem::GetOwner }, - { "GetCount", &LuaItem::GetCount }, - { "GetMaxStackCount", &LuaItem::GetMaxStackCount }, - { "GetSlot", &LuaItem::GetSlot }, - { "GetBagSlot", &LuaItem::GetBagSlot }, - { "GetEnchantmentId", &LuaItem::GetEnchantmentId }, - { "GetSpellId", &LuaItem::GetSpellId }, - { "GetSpellTrigger", &LuaItem::GetSpellTrigger }, - { "GetItemLink", &LuaItem::GetItemLink }, - { "GetClass", &LuaItem::GetClass }, - { "GetSubClass", &LuaItem::GetSubClass }, - { "GetName", &LuaItem::GetName }, - { "GetDisplayId", &LuaItem::GetDisplayId }, - { "GetQuality", &LuaItem::GetQuality }, - { "GetBuyCount", &LuaItem::GetBuyCount }, - { "GetBuyPrice", &LuaItem::GetBuyPrice }, - { "GetSellPrice", &LuaItem::GetSellPrice }, - { "GetInventoryType", &LuaItem::GetInventoryType }, - { "GetAllowableClass", &LuaItem::GetAllowableClass }, - { "GetAllowableRace", &LuaItem::GetAllowableRace }, - { "GetItemLevel", &LuaItem::GetItemLevel }, - { "GetRequiredLevel", &LuaItem::GetRequiredLevel }, - { "GetStatsCount", &LuaItem::GetStatsCount }, - { "GetRandomProperty", &LuaItem::GetRandomProperty }, - { "GetRandomSuffix", &LuaItem::GetRandomSuffix }, - { "GetItemSet", &LuaItem::GetItemSet }, - { "GetBagSize", &LuaItem::GetBagSize }, - { "GetItemTemplate", &LuaItem::GetItemTemplate }, - - // Setters - { "SetOwner", &LuaItem::SetOwner }, - { "SetBinding", &LuaItem::SetBinding }, - { "SetCount", &LuaItem::SetCount }, - { "SetRandomProperty", &LuaItem::SetRandomProperty }, - { "SetRandomSuffix", &LuaItem::SetRandomSuffix }, - - // Boolean - { "IsSoulBound", &LuaItem::IsSoulBound }, - { "IsBoundAccountWide", &LuaItem::IsBoundAccountWide }, - { "IsBoundByEnchant", &LuaItem::IsBoundByEnchant }, - { "IsNotBoundToPlayer", &LuaItem::IsNotBoundToPlayer }, - { "IsLocked", &LuaItem::IsLocked }, - { "IsBag", &LuaItem::IsBag }, - { "IsCurrencyToken", &LuaItem::IsCurrencyToken }, - { "IsNotEmptyBag", &LuaItem::IsNotEmptyBag }, - { "IsBroken", &LuaItem::IsBroken }, - { "CanBeTraded", &LuaItem::CanBeTraded }, - { "IsInTrade", &LuaItem::IsInTrade }, - { "IsInBag", &LuaItem::IsInBag }, - { "IsEquipped", &LuaItem::IsEquipped }, - { "HasQuest", &LuaItem::HasQuest }, - { "IsPotion", &LuaItem::IsPotion }, - { "IsWeaponVellum", &LuaItem::IsWeaponVellum }, - { "IsArmorVellum", &LuaItem::IsArmorVellum }, - { "IsConjuredConsumable", &LuaItem::IsConjuredConsumable }, - //{"IsRefundExpired", &LuaItem::IsRefundExpired}, // :IsRefundExpired() - UNDOCUMENTED - Returns true if the item's refund time has expired - { "SetEnchantment", &LuaItem::SetEnchantment }, - { "ClearEnchantment", &LuaItem::ClearEnchantment }, - - // Other - { "SaveToDB", &LuaItem::SaveToDB }, - - { NULL, NULL } -}; - -ALERegister ItemTemplateMethods[] = -{ - { "GetItemId", &LuaItemTemplate::GetItemId }, - { "GetClass", &LuaItemTemplate::GetClass }, - { "GetSubClass", &LuaItemTemplate::GetSubClass }, - { "GetName", &LuaItemTemplate::GetName }, - { "GetDisplayId", &LuaItemTemplate::GetDisplayId }, - { "GetQuality", &LuaItemTemplate::GetQuality }, - { "GetFlags", &LuaItemTemplate::GetFlags }, - { "GetExtraFlags", &LuaItemTemplate::GetExtraFlags }, - { "GetBuyCount", &LuaItemTemplate::GetBuyCount }, - { "GetBuyPrice", &LuaItemTemplate::GetBuyPrice }, - { "GetSellPrice", &LuaItemTemplate::GetSellPrice }, - { "GetInventoryType", &LuaItemTemplate::GetInventoryType }, - { "GetAllowableClass", &LuaItemTemplate::GetAllowableClass }, - { "GetAllowableRace", &LuaItemTemplate::GetAllowableRace }, - { "GetItemLevel", &LuaItemTemplate::GetItemLevel }, - { "GetRequiredLevel", &LuaItemTemplate::GetRequiredLevel }, - { "GetIcon", &LuaItemTemplate::GetIcon }, - { NULL, NULL } -}; - -ALERegister AuraMethods[] = -{ - // Getters - { "GetCaster", &LuaAura::GetCaster }, - { "GetCasterGUID", &LuaAura::GetCasterGUID }, - { "GetCasterLevel", &LuaAura::GetCasterLevel }, - { "GetDuration", &LuaAura::GetDuration }, - { "GetMaxDuration", &LuaAura::GetMaxDuration }, - { "GetAuraId", &LuaAura::GetAuraId }, - { "GetStackAmount", &LuaAura::GetStackAmount }, - { "GetOwner", &LuaAura::GetOwner }, - - // Setters - { "SetDuration", &LuaAura::SetDuration }, - { "SetMaxDuration", &LuaAura::SetMaxDuration }, - { "SetStackAmount", &LuaAura::SetStackAmount }, - - // Other - { "Remove", &LuaAura::Remove }, - - { NULL, NULL } -}; - -ALERegister SpellMethods[] = -{ - // Getters - { "GetCaster", &LuaSpell::GetCaster }, - { "GetCastTime", &LuaSpell::GetCastTime }, - { "GetEntry", &LuaSpell::GetEntry }, - { "GetDuration", &LuaSpell::GetDuration }, - { "GetPowerCost", &LuaSpell::GetPowerCost }, - { "GetReagentCost", &LuaSpell::GetReagentCost }, - { "GetTargetDest", &LuaSpell::GetTargetDest }, - { "GetTarget", &LuaSpell::GetTarget }, - - // Setters - { "SetAutoRepeat", &LuaSpell::SetAutoRepeat }, - - // Boolean - { "IsAutoRepeat", &LuaSpell::IsAutoRepeat }, - - // Other - { "Cancel", &LuaSpell::Cancel }, - { "Cast", &LuaSpell::Cast }, - { "Finish", &LuaSpell::Finish }, - - { NULL, NULL } -}; - -ALERegister QuestMethods[] = -{ - // Getters - { "GetId", &LuaQuest::GetId }, - { "GetLevel", &LuaQuest::GetLevel }, - // {"GetMaxLevel", &LuaQuest::GetMaxLevel}, // :GetMaxLevel() - UNDOCUMENTED - Returns the quest's max level - { "GetMinLevel", &LuaQuest::GetMinLevel }, - { "GetNextQuestId", &LuaQuest::GetNextQuestId }, - { "GetPrevQuestId", &LuaQuest::GetPrevQuestId }, - { "GetNextQuestInChain", &LuaQuest::GetNextQuestInChain }, - { "GetFlags", &LuaQuest::GetFlags }, - { "GetType", &LuaQuest::GetType }, - - // Boolean - { "HasFlag", &LuaQuest::HasFlag }, - { "IsDaily", &LuaQuest::IsDaily }, - { "IsRepeatable", &LuaQuest::IsRepeatable }, - - { NULL, NULL } -}; - -ALERegister GroupMethods[] = -{ - // Getters - { "GetMembers", &LuaGroup::GetMembers }, - { "GetLeaderGUID", &LuaGroup::GetLeaderGUID }, - { "GetGUID", &LuaGroup::GetGUID }, - { "GetMemberGroup", &LuaGroup::GetMemberGroup }, - { "GetMemberGUID", &LuaGroup::GetMemberGUID }, - { "GetMembersCount", &LuaGroup::GetMembersCount }, - { "GetGroupType", &LuaGroup::GetGroupType }, - - // Setters - { "SetLeader", &LuaGroup::SetLeader }, - { "SetMembersGroup", &LuaGroup::SetMembersGroup }, - { "SetTargetIcon", &LuaGroup::SetTargetIcon }, - { "SetMemberFlag", &LuaGroup::SetMemberFlag }, - - // Boolean - { "IsLeader", &LuaGroup::IsLeader }, - { "AddMember", &LuaGroup::AddMember }, - { "RemoveMember", &LuaGroup::RemoveMember }, - { "Disband", &LuaGroup::Disband }, - { "IsFull", &LuaGroup::IsFull }, - { "IsLFGGroup", &LuaGroup::IsLFGGroup }, - { "IsRaidGroup", &LuaGroup::IsRaidGroup }, - { "IsBGGroup", &LuaGroup::IsBGGroup }, - // {"IsBFGroup", &LuaGroup::IsBFGroup}, // :IsBFGroup() - UNDOCUMENTED - Returns true if the group is a battlefield group - { "IsMember", &LuaGroup::IsMember }, - { "IsAssistant", &LuaGroup::IsAssistant }, - { "SameSubGroup", &LuaGroup::SameSubGroup }, - { "HasFreeSlotSubGroup", &LuaGroup::HasFreeSlotSubGroup }, - - // Other - { "SendPacket", &LuaGroup::SendPacket }, - // {"ConvertToLFG", &LuaGroup::ConvertToLFG}, // :ConvertToLFG() - UNDOCUMENTED - Converts the group to an LFG group - { "ConvertToRaid", &LuaGroup::ConvertToRaid }, - - { NULL, NULL } -}; - -ALERegister GuildMethods[] = -{ - // Getters - { "GetMembers", &LuaGuild::GetMembers }, - { "GetLeader", &LuaGuild::GetLeader }, - { "GetLeaderGUID", &LuaGuild::GetLeaderGUID }, - { "GetId", &LuaGuild::GetId }, - { "GetName", &LuaGuild::GetName }, - { "GetMOTD", &LuaGuild::GetMOTD }, - { "GetInfo", &LuaGuild::GetInfo }, - { "GetMemberCount", &LuaGuild::GetMemberCount }, - { "GetCreatedDate", &LuaGuild::GetCreatedDate }, - { "GetTotalBankMoney", &LuaGuild::GetTotalBankMoney }, - - // Setters - { "SetBankTabText", &LuaGuild::SetBankTabText }, - { "SetMemberRank", &LuaGuild::SetMemberRank }, - { "SetLeader", &LuaGuild::SetLeader }, - { "SetName", &LuaGuild::SetName }, - - // Other - { "SendPacket", &LuaGuild::SendPacket }, - { "SendPacketToRanked", &LuaGuild::SendPacketToRanked }, - { "Disband", &LuaGuild::Disband }, - { "AddMember", &LuaGuild::AddMember }, - { "DeleteMember", &LuaGuild::DeleteMember }, - { "SendMessage", &LuaGuild::SendMessage }, - { "UpdateMemberData", &LuaGuild::UpdateMemberData }, - { "MassInviteToEvent", &LuaGuild::MassInviteToEvent }, - { "SwapItems", &LuaGuild::SwapItems }, - { "SwapItemsWithInventory", &LuaGuild::SwapItemsWithInventory }, - { "ResetTimes", &LuaGuild::ResetTimes }, - { "ModifyBankMoney", &LuaGuild::ModifyBankMoney }, - - { NULL, NULL } -}; - -ALERegister VehicleMethods[] = -{ - // Getters - { "GetOwner", &LuaVehicle::GetOwner }, - { "GetEntry", &LuaVehicle::GetEntry }, - { "GetPassenger", &LuaVehicle::GetPassenger }, - - // Boolean - { "IsOnBoard", &LuaVehicle::IsOnBoard }, - - // Other - { "AddPassenger", &LuaVehicle::AddPassenger }, - { "RemovePassenger", &LuaVehicle::RemovePassenger }, - - { NULL, NULL } -}; - -ALERegister QueryMethods[] = -{ - // Getters - { "GetColumnCount", &LuaQuery::GetColumnCount }, - { "GetRowCount", &LuaQuery::GetRowCount }, - { "GetRow", &LuaQuery::GetRow }, - { "GetBool", &LuaQuery::GetBool }, - { "GetUInt8", &LuaQuery::GetUInt8 }, - { "GetUInt16", &LuaQuery::GetUInt16 }, - { "GetUInt32", &LuaQuery::GetUInt32 }, - { "GetUInt64", &LuaQuery::GetUInt64 }, - { "GetInt8", &LuaQuery::GetInt8 }, - { "GetInt16", &LuaQuery::GetInt16 }, - { "GetInt32", &LuaQuery::GetInt32 }, - { "GetInt64", &LuaQuery::GetInt64 }, - { "GetFloat", &LuaQuery::GetFloat }, - { "GetDouble", &LuaQuery::GetDouble }, - { "GetString", &LuaQuery::GetString }, - - // Boolean - { "NextRow", &LuaQuery::NextRow }, - { "IsNull", &LuaQuery::IsNull }, - - { NULL, NULL } -}; - -ALERegister PacketMethods[] = -{ - // Getters - { "GetOpcode", &LuaPacket::GetOpcode }, - { "GetSize", &LuaPacket::GetSize }, - - // Setters - { "SetOpcode", &LuaPacket::SetOpcode }, - - // Readers - { "ReadByte", &LuaPacket::ReadByte }, - { "ReadUByte", &LuaPacket::ReadUByte }, - { "ReadShort", &LuaPacket::ReadShort }, - { "ReadUShort", &LuaPacket::ReadUShort }, - { "ReadLong", &LuaPacket::ReadLong }, - { "ReadULong", &LuaPacket::ReadULong }, - { "ReadGUID", &LuaPacket::ReadGUID }, - { "ReadPackedGUID", &LuaPacket::ReadPackedGUID }, - { "ReadString", &LuaPacket::ReadString }, - { "ReadFloat", &LuaPacket::ReadFloat }, - { "ReadDouble", &LuaPacket::ReadDouble }, - - // Writers - { "WriteByte", &LuaPacket::WriteByte }, - { "WriteUByte", &LuaPacket::WriteUByte }, - { "WriteShort", &LuaPacket::WriteShort }, - { "WriteUShort", &LuaPacket::WriteUShort }, - { "WriteLong", &LuaPacket::WriteLong }, - { "WriteULong", &LuaPacket::WriteULong }, - { "WriteGUID", &LuaPacket::WriteGUID }, - { "WritePackedGUID", &LuaPacket::WritePackedGUID }, - { "WriteString", &LuaPacket::WriteString }, - { "WriteFloat", &LuaPacket::WriteFloat }, - { "WriteDouble", &LuaPacket::WriteDouble }, - - { NULL, NULL } -}; - -ALERegister MapMethods[] = -{ - // Getters - { "GetName", &LuaMap::GetName }, - { "GetDifficulty", &LuaMap::GetDifficulty }, - { "GetInstanceId", &LuaMap::GetInstanceId }, - { "GetInstanceData", &LuaMap::GetInstanceData }, - { "GetPlayerCount", &LuaMap::GetPlayerCount }, - { "GetPlayers", &LuaMap::GetPlayers }, - { "GetMapId", &LuaMap::GetMapId }, - { "GetAreaId", &LuaMap::GetAreaId }, - { "GetHeight", &LuaMap::GetHeight }, - { "GetWorldObject", &LuaMap::GetWorldObject }, - { "GetCreatures", &LuaMap::GetCreatures }, - { "GetCreaturesByAreaId", &LuaMap::GetCreaturesByAreaId }, - - - // Setters - { "SetWeather", &LuaMap::SetWeather }, - - // Boolean - { "IsArena", &LuaMap::IsArena }, - { "IsBattleground", &LuaMap::IsBattleground }, - { "IsDungeon", &LuaMap::IsDungeon }, - { "IsEmpty", &LuaMap::IsEmpty }, - { "IsHeroic", &LuaMap::IsHeroic }, - { "IsRaid", &LuaMap::IsRaid }, - - // Other - { "SaveInstanceData", &LuaMap::SaveInstanceData }, - - { NULL, NULL } -}; - -ALERegister CorpseMethods[] = -{ - // Getters - { "GetOwnerGUID", &LuaCorpse::GetOwnerGUID }, - { "GetGhostTime", &LuaCorpse::GetGhostTime }, - { "GetType", &LuaCorpse::GetType }, - - // Other - { "ResetGhostTime", &LuaCorpse::ResetGhostTime }, - { "SaveToDB", &LuaCorpse::SaveToDB }, - - { NULL, NULL } -}; - -ALERegister AuctionMethods[] = -{ - { NULL, NULL } -}; - -ALERegister BattleGroundMethods[] = -{ - // Getters - { "GetName", &LuaBattleGround::GetName }, - { "GetAlivePlayersCountByTeam", &LuaBattleGround::GetAlivePlayersCountByTeam }, - { "GetMap", &LuaBattleGround::GetMap }, - { "GetBonusHonorFromKillCount", &LuaBattleGround::GetBonusHonorFromKillCount }, - { "GetEndTime", &LuaBattleGround::GetEndTime }, - { "GetFreeSlotsForTeam", &LuaBattleGround::GetFreeSlotsForTeam }, - { "GetInstanceId", &LuaBattleGround::GetInstanceId }, - { "GetMapId", &LuaBattleGround::GetMapId }, - { "GetTypeId", &LuaBattleGround::GetTypeId }, - { "GetMaxLevel", &LuaBattleGround::GetMaxLevel }, - { "GetMinLevel", &LuaBattleGround::GetMinLevel }, - { "GetMaxPlayers", &LuaBattleGround::GetMaxPlayers }, - { "GetMinPlayers", &LuaBattleGround::GetMinPlayers }, - { "GetMaxPlayersPerTeam", &LuaBattleGround::GetMaxPlayersPerTeam }, - { "GetMinPlayersPerTeam", &LuaBattleGround::GetMinPlayersPerTeam }, - { "GetWinner", &LuaBattleGround::GetWinner }, - { "GetStatus", &LuaBattleGround::GetStatus }, - - { NULL, NULL } -}; - -ALERegister ChatHandlerMethods[] = -{ - { "SendSysMessage", &LuaChatHandler::SendSysMessage }, - { "IsConsole", &LuaChatHandler::IsConsole }, - { "GetPlayer", &LuaChatHandler::GetPlayer }, - { "SendGlobalSysMessage", &LuaChatHandler::SendGlobalSysMessage }, - { "SendGlobalGMSysMessage", &LuaChatHandler::SendGlobalGMSysMessage }, - { "HasLowerSecurity", &LuaChatHandler::HasLowerSecurity }, - { "HasLowerSecurityAccount", &LuaChatHandler::HasLowerSecurityAccount }, - { "GetSelectedPlayer", &LuaChatHandler::GetSelectedPlayer }, - { "GetSelectedCreature", &LuaChatHandler::GetSelectedCreature }, - { "GetSelectedUnit", &LuaChatHandler::GetSelectedUnit }, - { "GetSelectedObject", &LuaChatHandler::GetSelectedObject }, - { "GetSelectedPlayerOrSelf", &LuaChatHandler::GetSelectedPlayerOrSelf }, - { "IsAvailable", &LuaChatHandler::IsAvailable }, - { "HasSentErrorMessage", &LuaChatHandler::HasSentErrorMessage }, - - { NULL, NULL } -}; - -ALERegister AchievementMethods[] = -{ - { "GetId", &LuaAchievement::GetId }, - { "GetName", &LuaAchievement::GetName }, - - { NULL, NULL } -}; - -ALERegister RollMethods[] = -{ - { "GetItemGUID", &LuaRoll::GetItemGUID }, - { "GetItemId", &LuaRoll::GetItemId }, - { "GetItemRandomPropId", &LuaRoll::GetItemRandomPropId }, - { "GetItemRandomSuffix", &LuaRoll::GetItemRandomSuffix }, - { "GetItemCount", &LuaRoll::GetItemCount }, - { "GetPlayerVote", &LuaRoll::GetPlayerVote }, - { "GetPlayerVoteGUIDs", &LuaRoll::GetPlayerVoteGUIDs }, - { "GetTotalPlayersRolling", &LuaRoll::GetTotalPlayersRolling }, - { "GetTotalNeed", &LuaRoll::GetTotalNeed }, - { "GetTotalGreed", &LuaRoll::GetTotalGreed }, - { "GetTotalPass", &LuaRoll::GetTotalPass }, - { "GetItemSlot", &LuaRoll::GetItemSlot }, - { "GetRollVoteMask", &LuaRoll::GetRollVoteMask }, - - { NULL, NULL } -}; - -ALERegister TicketMethods[] = -{ - { "IsClosed", &LuaTicket::IsClosed }, - { "IsCompleted", &LuaTicket::IsCompleted }, - { "IsFromPlayer", &LuaTicket::IsFromPlayer }, - { "IsAssigned", &LuaTicket::IsAssigned }, - { "IsAssignedTo", &LuaTicket::IsAssignedTo }, - { "IsAssignedNotTo", &LuaTicket::IsAssignedNotTo }, - - { "GetId", &LuaTicket::GetId }, - { "GetPlayer", &LuaTicket::GetPlayer }, - { "GetPlayerName", &LuaTicket::GetPlayerName }, - { "GetMessage", &LuaTicket::GetMessage }, - { "GetAssignedPlayer", &LuaTicket::GetAssignedPlayer }, - { "GetAssignedToGUID", &LuaTicket::GetAssignedToGUID }, - { "GetLastModifiedTime", &LuaTicket::GetLastModifiedTime }, - { "GetResponse", &LuaTicket::GetResponse }, - { "GetChatLog", &LuaTicket::GetChatLog }, - - { "SetAssignedTo", &LuaTicket::SetAssignedTo }, - { "SetResolvedBy", &LuaTicket::SetResolvedBy }, - { "SetCompleted", &LuaTicket::SetCompleted }, - { "SetMessage", &LuaTicket::SetMessage }, - { "SetComment", &LuaTicket::SetComment }, - { "SetViewed", &LuaTicket::SetViewed }, - { "SetUnassigned", &LuaTicket::SetUnassigned }, - { "SetPosition", &LuaTicket::SetPosition }, - { "AppendResponse", &LuaTicket::AppendResponse }, - { "DeleteResponse", &LuaTicket::DeleteResponse }, - - { NULL, NULL } -}; - -ALERegister SpellInfoMethods[] = -{ - // Getters - { "GetAttributes", &LuaSpellInfo::GetAttributes }, - { "GetCategory", &LuaSpellInfo::GetCategory }, - { "GetName", &LuaSpellInfo::GetName }, - { "CheckShapeshift", &LuaSpellInfo::CheckShapeshift }, - { "CheckLocation", &LuaSpellInfo::CheckLocation }, - { "CheckTarget", &LuaSpellInfo::CheckTarget }, - { "CheckExplicitTarget", &LuaSpellInfo::CheckExplicitTarget }, - { "CheckTargetCreatureType", &LuaSpellInfo::CheckTargetCreatureType }, - { "CheckTargetCreatureType", &LuaSpellInfo::CheckTargetCreatureType }, - { "GetSchoolMask", &LuaSpellInfo::GetSchoolMask }, - { "GetAllEffectsMechanicMask", &LuaSpellInfo::GetAllEffectsMechanicMask }, - { "GetEffectMechanicMask", &LuaSpellInfo::GetEffectMechanicMask }, - { "GetSpellMechanicMaskByEffectMask", &LuaSpellInfo::GetSpellMechanicMaskByEffectMask }, - { "GetEffectMechanic", &LuaSpellInfo::GetEffectMechanic }, - { "GetDispelMask", &LuaSpellInfo::GetDispelMask }, - { "GetExplicitTargetMask", &LuaSpellInfo::GetExplicitTargetMask }, - { "GetAuraState", &LuaSpellInfo::GetAuraState }, - { "GetSpellSpecific", &LuaSpellInfo::GetSpellSpecific }, - { "GetEffectMiscValueA", &LuaSpellInfo::GetEffectMiscValueA }, - { "GetEffectMiscValueB", &LuaSpellInfo::GetEffectMiscValueB }, - - // Setters - - // Boolean - { "HasAreaAuraEffect", &LuaSpellInfo::HasAreaAuraEffect }, - { "HasAttribute", &LuaSpellInfo::HasAttribute }, - { "HasAura", &LuaSpellInfo::HasAura }, - { "HasEffect", &LuaSpellInfo::HasEffect }, - - { "IsAbilityLearnedWithProfession", &LuaSpellInfo::IsAbilityLearnedWithProfession }, - { "IsAbilityOfSkillType", &LuaSpellInfo::IsAbilityOfSkillType }, - { "IsAffectingArea", &LuaSpellInfo::IsAffectingArea }, - { "IsAllowingDeadTarget", &LuaSpellInfo::IsAllowingDeadTarget }, - { "IsAutocastable", &LuaSpellInfo::IsAutocastable }, - { "IsAutoRepeatRangedSpell", &LuaSpellInfo::IsAutoRepeatRangedSpell }, - { "IsBreakingStealth", &LuaSpellInfo::IsBreakingStealth }, - { "IsChanneled", &LuaSpellInfo::IsChanneled }, - { "IsCooldownStartedOnEvent", &LuaSpellInfo::IsCooldownStartedOnEvent }, - { "IsDeathPersistent", &LuaSpellInfo::IsDeathPersistent }, - { "IsExplicitDiscovery", &LuaSpellInfo::IsExplicitDiscovery }, - { "IsLootCrafting", &LuaSpellInfo::IsLootCrafting }, - { "IsMultiSlotAura", &LuaSpellInfo::IsMultiSlotAura }, - { "IsPassive", &LuaSpellInfo::IsPassive }, - { "IsPassiveStackableWithRanks", &LuaSpellInfo::IsPassiveStackableWithRanks }, - { "IsPositive", &LuaSpellInfo::IsPositive }, - { "IsPositiveEffect", &LuaSpellInfo::IsPositiveEffect }, - { "IsPrimaryProfession", &LuaSpellInfo::IsPrimaryProfession }, - { "IsPrimaryProfessionFirstRank", &LuaSpellInfo::IsPrimaryProfessionFirstRank }, - { "IsProfession", &LuaSpellInfo::IsProfession }, - { "IsProfessionOrRiding", &LuaSpellInfo::IsProfessionOrRiding }, - { "IsRangedWeaponSpell", &LuaSpellInfo::IsRangedWeaponSpell }, - { "IsRequiringDeadTarget", &LuaSpellInfo::IsRequiringDeadTarget }, - { "IsStackableWithRanks", &LuaSpellInfo::IsStackableWithRanks }, - { "IsTargetingArea", &LuaSpellInfo::IsTargetingArea }, - { "IsAffectedBySpellMods", &LuaSpellInfo::IsAffectedBySpellMods }, - /* { "IsAffectedBySpellMod", &LuaSpellInfo::IsAffectedBySpellMod }, */ - { "CanPierceImmuneAura", &LuaSpellInfo::CanPierceImmuneAura }, - { "CanDispelAura", &LuaSpellInfo::CanDispelAura }, - { "IsSingleTarget", &LuaSpellInfo::IsSingleTarget }, - { "IsAuraExclusiveBySpecificWith", &LuaSpellInfo::IsAuraExclusiveBySpecificWith }, - { "IsAuraExclusiveBySpecificPerCasterWith", &LuaSpellInfo::IsAuraExclusiveBySpecificPerCasterWith }, - { "CanBeUsedInCombat", &LuaSpellInfo::CanBeUsedInCombat }, - - { "NeedsComboPoints", &LuaSpellInfo::NeedsComboPoints }, - { "NeedsExplicitUnitTarget", &LuaSpellInfo::NeedsExplicitUnitTarget }, - { "NeedsToBeTriggeredByCaster", &LuaSpellInfo::NeedsToBeTriggeredByCaster }, - - { NULL, NULL } -}; - -ALERegister GemPropertiesEntryMethods[] = -{ - // Getters - { "GetId", &LuaGemPropertiesEntry::GetId }, - { "GetSpellItemEnchantement", &LuaGemPropertiesEntry::GetSpellItemEnchantement }, - - { NULL, NULL } -}; - -ALERegister SpellEntryMethods[] = -{ - // Getters - { "GetId", &LuaSpellEntry::GetId }, - { "GetCategory", &LuaSpellEntry::GetCategory }, - { "GetDispel", &LuaSpellEntry::GetDispel }, - { "GetMechanic", &LuaSpellEntry::GetMechanic }, - { "GetAttributes", &LuaSpellEntry::GetAttributes }, - { "GetAttributesEx", &LuaSpellEntry::GetAttributesEx }, - { "GetAttributesEx2", &LuaSpellEntry::GetAttributesEx2 }, - { "GetAttributesEx3", &LuaSpellEntry::GetAttributesEx3 }, - { "GetAttributesEx4", &LuaSpellEntry::GetAttributesEx4 }, - { "GetAttributesEx5", &LuaSpellEntry::GetAttributesEx5 }, - { "GetAttributesEx6", &LuaSpellEntry::GetAttributesEx6 }, - { "GetAttributesEx7", &LuaSpellEntry::GetAttributesEx7 }, - { "GetStances", &LuaSpellEntry::GetStances }, - { "GetStancesNot", &LuaSpellEntry::GetStancesNot }, - { "GetTargets", &LuaSpellEntry::GetTargets }, - { "GetTargetCreatureType", &LuaSpellEntry::GetTargetCreatureType }, - { "GetRequiresSpellFocus", &LuaSpellEntry::GetRequiresSpellFocus }, - { "GetFacingCasterFlags", &LuaSpellEntry::GetFacingCasterFlags }, - { "GetCasterAuraState", &LuaSpellEntry::GetCasterAuraState }, - { "GetTargetAuraState", &LuaSpellEntry::GetTargetAuraState }, - { "GetCasterAuraStateNot", &LuaSpellEntry::GetCasterAuraStateNot }, - { "GetTargetAuraStateNot", &LuaSpellEntry::GetTargetAuraStateNot }, - { "GetCasterAuraSpell", &LuaSpellEntry::GetCasterAuraSpell }, - { "GetTargetAuraSpell", &LuaSpellEntry::GetTargetAuraSpell }, - { "GetExcludeCasterAuraSpell", &LuaSpellEntry::GetExcludeCasterAuraSpell }, - { "GetExcludeTargetAuraSpell", &LuaSpellEntry::GetExcludeTargetAuraSpell }, - { "GetCastingTimeIndex", &LuaSpellEntry::GetCastingTimeIndex }, - { "GetRecoveryTime", &LuaSpellEntry::GetRecoveryTime }, - { "GetCategoryRecoveryTime", &LuaSpellEntry::GetCategoryRecoveryTime }, - { "GetInterruptFlags", &LuaSpellEntry::GetInterruptFlags }, - { "GetAuraInterruptFlags", &LuaSpellEntry::GetAuraInterruptFlags }, - { "GetChannelInterruptFlags", &LuaSpellEntry::GetChannelInterruptFlags }, - { "GetProcFlags", &LuaSpellEntry::GetProcFlags }, - { "GetProcChance", &LuaSpellEntry::GetProcChance }, - { "GetProcCharges", &LuaSpellEntry::GetProcCharges }, - { "GetMaxLevel", &LuaSpellEntry::GetMaxLevel }, - { "GetBaseLevel", &LuaSpellEntry::GetBaseLevel }, - { "GetSpellLevel", &LuaSpellEntry::GetSpellLevel }, - { "GetDurationIndex", &LuaSpellEntry::GetDurationIndex }, - { "GetPowerType", &LuaSpellEntry::GetPowerType }, - { "GetManaCost", &LuaSpellEntry::GetManaCost }, - { "GetManaCostPerlevel", &LuaSpellEntry::GetManaCostPerlevel }, - { "GetManaPerSecond", &LuaSpellEntry::GetManaPerSecond }, - { "GetManaPerSecondPerLevel", &LuaSpellEntry::GetManaPerSecondPerLevel }, - { "GetRangeIndex", &LuaSpellEntry::GetRangeIndex }, - { "GetSpeed", &LuaSpellEntry::GetSpeed }, - { "GetStackAmount", &LuaSpellEntry::GetStackAmount }, - { "GetTotem", &LuaSpellEntry::GetTotem }, - { "GetReagent", &LuaSpellEntry::GetReagent }, - { "GetReagentCount", &LuaSpellEntry::GetReagentCount }, - { "GetEquippedItemClass", &LuaSpellEntry::GetEquippedItemClass }, - { "GetEquippedItemSubClassMask", &LuaSpellEntry::GetEquippedItemSubClassMask }, - { "GetEquippedItemInventoryTypeMask", &LuaSpellEntry::GetEquippedItemInventoryTypeMask }, - { "GetEffect", &LuaSpellEntry::GetEffect }, - { "GetEffectDieSides", &LuaSpellEntry::GetEffectDieSides }, - { "GetEffectRealPointsPerLevel", &LuaSpellEntry::GetEffectRealPointsPerLevel }, - { "GetEffectBasePoints", &LuaSpellEntry::GetEffectBasePoints }, - { "GetEffectMechanic", &LuaSpellEntry::GetEffectMechanic }, - { "GetEffectImplicitTargetA", &LuaSpellEntry::GetEffectImplicitTargetA }, - { "GetEffectImplicitTargetB", &LuaSpellEntry::GetEffectImplicitTargetB }, - { "GetEffectRadiusIndex", &LuaSpellEntry::GetEffectRadiusIndex }, - { "GetEffectApplyAuraName", &LuaSpellEntry::GetEffectApplyAuraName }, - { "GetEffectAmplitude", &LuaSpellEntry::GetEffectAmplitude }, - { "GetEffectValueMultiplier", &LuaSpellEntry::GetEffectValueMultiplier }, - { "GetEffectChainTarget", &LuaSpellEntry::GetEffectChainTarget }, - { "GetEffectItemType", &LuaSpellEntry::GetEffectItemType }, - { "GetEffectMiscValue", &LuaSpellEntry::GetEffectMiscValue }, - { "GetEffectMiscValueB", &LuaSpellEntry::GetEffectMiscValueB }, - { "GetEffectTriggerSpell", &LuaSpellEntry::GetEffectTriggerSpell }, - { "GetEffectPointsPerComboPoint", &LuaSpellEntry::GetEffectPointsPerComboPoint }, - { "GetEffectSpellClassMask", &LuaSpellEntry::GetEffectSpellClassMask }, - { "GetSpellVisual", &LuaSpellEntry::GetSpellVisual }, - { "GetSpellIconID", &LuaSpellEntry::GetSpellIconID }, - { "GetActiveIconID", &LuaSpellEntry::GetActiveIconID }, - { "GetSpellPriority", &LuaSpellEntry::GetSpellPriority }, - { "GetSpellName", &LuaSpellEntry::GetSpellName }, - { "GetRank", &LuaSpellEntry::GetRank }, - { "GetManaCostPercentage", &LuaSpellEntry::GetManaCostPercentage }, - { "GetStartRecoveryCategory", &LuaSpellEntry::GetStartRecoveryCategory }, - { "GetStartRecoveryTime", &LuaSpellEntry::GetStartRecoveryTime }, - { "GetMaxTargetLevel", &LuaSpellEntry::GetMaxTargetLevel }, - { "GetSpellFamilyName", &LuaSpellEntry::GetSpellFamilyName }, - { "GetSpellFamilyFlags", &LuaSpellEntry::GetSpellFamilyFlags }, - { "GetMaxAffectedTargets", &LuaSpellEntry::GetMaxAffectedTargets }, - { "GetDmgClass", &LuaSpellEntry::GetDmgClass }, - { "GetPreventionType", &LuaSpellEntry::GetPreventionType }, - { "GetEffectDamageMultiplier", &LuaSpellEntry::GetEffectDamageMultiplier }, - { "GetTotemCategory", &LuaSpellEntry::GetTotemCategory }, - { "GetAreaGroupId", &LuaSpellEntry::GetAreaGroupId }, - { "GetSchoolMask", &LuaSpellEntry::GetSchoolMask }, - { "GetRuneCostID", &LuaSpellEntry::GetRuneCostID }, - { "GetEffectBonusMultiplier", &LuaSpellEntry::GetEffectBonusMultiplier }, - - // Setters - { "SetCategory", &LuaSpellEntry::SetCategory }, - { "SetDispel", &LuaSpellEntry::SetDispel }, - { "SetMechanic", &LuaSpellEntry::SetMechanic }, - { "SetAttributes", &LuaSpellEntry::SetAttributes }, - { "SetAttributesEx", &LuaSpellEntry::SetAttributesEx }, - { "SetAttributesEx2", &LuaSpellEntry::SetAttributesEx2 }, - { "SetAttributesEx3", &LuaSpellEntry::SetAttributesEx3 }, - { "SetAttributesEx4", &LuaSpellEntry::SetAttributesEx4 }, - { "SetAttributesEx5", &LuaSpellEntry::SetAttributesEx5 }, - { "SetAttributesEx6", &LuaSpellEntry::SetAttributesEx6 }, - { "SetAttributesEx7", &LuaSpellEntry::SetAttributesEx7 }, - { "SetStances", &LuaSpellEntry::SetStances }, - { "SetStancesNot", &LuaSpellEntry::SetStancesNot }, - { "SetTargets", &LuaSpellEntry::SetTargets }, - { "SetTargetCreatureType", &LuaSpellEntry::SetTargetCreatureType }, - { "SetRequiresSpellFocus", &LuaSpellEntry::SetRequiresSpellFocus }, - { "SetFacingCasterFlags", &LuaSpellEntry::SetFacingCasterFlags }, - { "SetCasterAuraState", &LuaSpellEntry::SetCasterAuraState }, - { "SetTargetAuraState", &LuaSpellEntry::SetTargetAuraState }, - { "SetCasterAuraStateNot", &LuaSpellEntry::SetCasterAuraStateNot }, - { "SetTargetAuraStateNot", &LuaSpellEntry::SetTargetAuraStateNot }, - { "SetCasterAuraSpell", &LuaSpellEntry::SetCasterAuraSpell }, - { "SetTargetAuraSpell", &LuaSpellEntry::SetTargetAuraSpell }, - { "SetExcludeCasterAuraSpell", &LuaSpellEntry::SetExcludeCasterAuraSpell }, - { "SetExcludeTargetAuraSpell", &LuaSpellEntry::SetExcludeTargetAuraSpell }, - { "SetRecoveryTime", &LuaSpellEntry::SetRecoveryTime }, - { "SetCategoryRecoveryTime", &LuaSpellEntry::SetCategoryRecoveryTime }, - { "SetInterruptFlags", &LuaSpellEntry::SetInterruptFlags }, - { "SetAuraInterruptFlags", &LuaSpellEntry::SetAuraInterruptFlags }, - { "SetChannelInterruptFlags", &LuaSpellEntry::SetChannelInterruptFlags }, - { "SetProcFlags", &LuaSpellEntry::SetProcFlags }, - { "SetProcChance", &LuaSpellEntry::SetProcChance }, - { "SetProcCharges", &LuaSpellEntry::SetProcCharges }, - { "SetMaxLevel", &LuaSpellEntry::SetMaxLevel }, - { "SetBaseLevel", &LuaSpellEntry::SetBaseLevel }, - { "SetSpellLevel", &LuaSpellEntry::SetSpellLevel }, - { "SetPowerType", &LuaSpellEntry::SetPowerType }, - { "SetManaCost", &LuaSpellEntry::SetManaCost }, - { "SetManaCostPerlevel", &LuaSpellEntry::SetManaCostPerlevel }, - { "SetManaPerSecond", &LuaSpellEntry::SetManaPerSecond }, - { "SetManaPerSecondPerLevel", &LuaSpellEntry::SetManaPerSecondPerLevel }, - { "SetSpeed", &LuaSpellEntry::SetSpeed }, - { "SetStackAmount", &LuaSpellEntry::SetStackAmount }, - { "SetEquippedItemClass", &LuaSpellEntry::SetEquippedItemClass }, - { "SetEquippedItemSubClassMask", &LuaSpellEntry::SetEquippedItemSubClassMask }, - { "SetEquippedItemInventoryTypeMask", &LuaSpellEntry::SetEquippedItemInventoryTypeMask }, - { "SetSpellIconID", &LuaSpellEntry::SetSpellIconID }, - { "SetActiveIconID", &LuaSpellEntry::SetActiveIconID }, - { "SetSpellPriority", &LuaSpellEntry::SetSpellPriority }, - { "SetManaCostPercentage", &LuaSpellEntry::SetManaCostPercentage }, - { "SetStartRecoveryCategory", &LuaSpellEntry::SetStartRecoveryCategory }, - { "SetStartRecoveryTime", &LuaSpellEntry::SetStartRecoveryTime }, - { "SetMaxTargetLevel", &LuaSpellEntry::SetMaxTargetLevel }, - { "SetSpellFamilyName", &LuaSpellEntry::SetSpellFamilyName }, - { "SetMaxAffectedTargets", &LuaSpellEntry::SetMaxAffectedTargets }, - { "SetDmgClass", &LuaSpellEntry::SetDmgClass }, - { "SetPreventionType", &LuaSpellEntry::SetPreventionType }, - { "SetSchoolMask", &LuaSpellEntry::SetSchoolMask }, - { "SetRuneCostID", &LuaSpellEntry::SetRuneCostID }, - - { NULL, NULL } -}; - -ALERegister PetMethods[] = -{ - // Getters - { "GetPetType", &LuaPet::GetPetType }, - { "GetDuration", &LuaPet::GetDuration }, - { "GetHappinessState", &LuaPet::GetHappinessState }, - { "GetCurrentFoodBenefitLevel", &LuaPet::GetCurrentFoodBenefitLevel }, - { "GetMaxTalentPointsForLevel", &LuaPet::GetMaxTalentPointsForLevel }, - { "GetFreeTalentPoints", &LuaPet::GetFreeTalentPoints }, - { "GetUsedTalentCount", &LuaPet::GetUsedTalentCount }, - { "GetAuraUpdateMaskForRaid", &LuaPet::GetAuraUpdateMaskForRaid }, - { "GetOwner", &LuaPet::GetOwner }, - { "GetPetAutoSpellSize", &LuaPet::GetPetAutoSpellSize }, - { "GetPetAutoSpellOnPos", &LuaPet::GetPetAutoSpellOnPos }, - - // Setters - { "SetPetType", &LuaPet::SetPetType }, - { "SetDuration", &LuaPet::SetDuration }, - { "SetFreeTalentPoints", &LuaPet::SetFreeTalentPoints }, - { "SetUsedTalentCount", &LuaPet::SetUsedTalentCount }, - { "SetAuraUpdateMaskForRaid", &LuaPet::SetAuraUpdateMaskForRaid }, - { "SetRemoved", &LuaPet::SetRemoved }, - - // Boolean - { "IsControlled", &LuaPet::IsControlled }, - { "IsTemporarySummoned", &LuaPet::IsTemporarySummoned }, - { "IsPermanentPetFor", &LuaPet::IsPermanentPetFor }, - { "HaveInDiet", &LuaPet::HaveInDiet }, - { "HasTempSpell", &LuaPet::HasTempSpell }, - { "IsRemoved", &LuaPet::IsRemoved }, - { "IsBeingLoaded", &LuaPet::IsBeingLoaded }, - - // Other - { "CreateBaseAtCreature", &LuaPet::CreateBaseAtCreature }, - { "GivePetXP", &LuaPet::GivePetXP }, - { "GivePetLevel", &LuaPet::GivePetLevel }, - { "SynchronizeLevelWithOwner", &LuaPet::SynchronizeLevelWithOwner }, - { "ToggleAutocast", &LuaPet::ToggleAutocast }, - { "LearnPetPassives", &LuaPet::LearnPetPassives }, - { "CastWhenWillAvailable", &LuaPet::CastWhenWillAvailable }, - { "ClearCastWhenWillAvailable", &LuaPet::ClearCastWhenWillAvailable }, - { "AddSpell", &LuaPet::AddSpell }, - { "LearnSpell", &LuaPet::LearnSpell }, - { "LearnSpellHighRank", &LuaPet::LearnSpellHighRank }, - { "InitLevelupSpellsForLevel", &LuaPet::InitLevelupSpellsForLevel }, - { "UnlearnSpell", &LuaPet::UnlearnSpell }, - { "RemoveSpell", &LuaPet::RemoveSpell }, - { "CleanupActionBar", &LuaPet::CleanupActionBar }, - { "GenerateActionBarData", &LuaPet::GenerateActionBarData }, - { "InitPetCreateSpells", &LuaPet::InitPetCreateSpells }, - { "ResetTalents", &LuaPet::ResetTalents }, - { "InitTalentForLevel", &LuaPet::InitTalentForLevel }, - { "ResetAuraUpdateMaskForRaid", &LuaPet::ResetAuraUpdateMaskForRaid }, - { "SavePetToDB", &LuaPet::SavePetToDB }, - { "Remove", &LuaPet::Remove }, - - { NULL, NULL } -}; - -ALERegister LootMethods[] = -{ - // Get - { "GetMoney", &LuaLoot::GetMoney }, - { "GetItems", &LuaLoot::GetItems }, - { "GetQuestItems", &LuaLoot::GetQuestItems }, - { "GetUnlootedCount", &LuaLoot::GetUnlootedCount }, - { "GetLootType", &LuaLoot::GetLootType }, - { "GetRoundRobinPlayer", &LuaLoot::GetRoundRobinPlayer }, - { "GetLootOwner", &LuaLoot::GetLootOwner }, - { "GetContainer", &LuaLoot::GetContainer }, - { "GetSourceWorldObject", &LuaLoot::GetSourceWorldObject }, - { "GetItemCount", &LuaLoot::GetItemCount }, - { "GetMaxSlotForPlayer", &LuaLoot::GetMaxSlotForPlayer }, - - // Set - { "AddItem", &LuaLoot::AddItem }, - { "RemoveItem", &LuaLoot::RemoveItem }, - { "SetMoney", &LuaLoot::SetMoney }, - { "SetUnlootedCount", &LuaLoot::SetUnlootedCount }, - { "UpdateItemIndex", &LuaLoot::UpdateItemIndex }, - { "SetItemLooted", &LuaLoot::SetItemLooted }, - { "SetLootType", &LuaLoot::SetLootType }, - { "SetRoundRobinPlayer", &LuaLoot::SetRoundRobinPlayer }, - { "SetLootOwner", &LuaLoot::SetLootOwner }, - { "SetContainer", &LuaLoot::SetContainer }, - { "SetSourceWorldObject", &LuaLoot::SetSourceWorldObject }, - { "Clear", &LuaLoot::Clear }, - { "AddLooter", &LuaLoot::AddLooter }, - { "RemoveLooter", &LuaLoot::RemoveLooter }, - - // Boolean - { "HasItem", &LuaLoot::HasItem }, - { "HasQuestItems", &LuaLoot::HasQuestItems }, - { "HasItemForAll", &LuaLoot::HasItemForAll }, - { "HasOverThresholdItem", &LuaLoot::HasOverThresholdItem }, - { "IsLooted", &LuaLoot::IsLooted }, - { "IsEmpty", &LuaLoot::IsEmpty }, - - { NULL, NULL } -}; - -// fix compile error about accessing vehicle destructor -template<> int ALETemplate::CollectGarbage(lua_State* L) -{ - ASSERT(!manageMemory); - - // Get object pointer (and check type, no error) - ALEObject* obj = ALE::CHECKOBJ(L, 1, false); - delete obj; - return 0; -} - -// Template by Mud from http://stackoverflow.com/questions/4484437/lua-integer-type/4485511#4485511 -template<> int ALETemplate::Add(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) + ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::Substract(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) - ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::Multiply(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) * ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::Divide(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) / ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::Mod(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) % ALE::CHECKVAL(L, 2)); return 1; } -// template<> int ALETemplate::UnaryMinus(lua_State* L) { ALE::Push(L, -ALE::CHECKVAL(L, 1)); return 1; } -template<> int ALETemplate::Equal(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) == ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::Less(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) < ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::LessOrEqual(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) <= ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::Pow(lua_State* L) -{ - ALE::Push(L, static_cast(powl(static_cast(ALE::CHECKVAL(L, 1)), static_cast(ALE::CHECKVAL(L, 2))))); - return 1; -} -template<> int ALETemplate::ToString(lua_State* L) -{ - unsigned long long l = ALE::CHECKVAL(L, 1); - std::ostringstream ss; - ss << l; - ALE::Push(L, ss.str()); - return 1; -} - -template<> int ALETemplate::Add(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) + ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::Substract(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) - ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::Multiply(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) * ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::Divide(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) / ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::Mod(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) % ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::UnaryMinus(lua_State* L) { ALE::Push(L, -ALE::CHECKVAL(L, 1)); return 1; } -template<> int ALETemplate::Equal(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) == ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::Less(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) < ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::LessOrEqual(lua_State* L) { ALE::Push(L, ALE::CHECKVAL(L, 1) <= ALE::CHECKVAL(L, 2)); return 1; } -template<> int ALETemplate::Pow(lua_State* L) -{ - ALE::Push(L, static_cast(powl(static_cast(ALE::CHECKVAL(L, 1)), static_cast(ALE::CHECKVAL(L, 2))))); - return 1; -} -template<> int ALETemplate::ToString(lua_State* L) -{ - long long l = ALE::CHECKVAL(L, 1); - std::ostringstream ss; - ss << l; - ALE::Push(L, ss.str()); - return 1; -} - -void RegisterFunctions(ALE* E) -{ - ALEGlobal::SetMethods(E, GlobalMethods); - - ALETemplate::Register(E, "Object"); - ALETemplate::SetMethods(E, ObjectMethods); - - ALETemplate::Register(E, "WorldObject"); - ALETemplate::SetMethods(E, ObjectMethods); - ALETemplate::SetMethods(E, WorldObjectMethods); - - ALETemplate::Register(E, "Unit"); - ALETemplate::SetMethods(E, ObjectMethods); - ALETemplate::SetMethods(E, WorldObjectMethods); - ALETemplate::SetMethods(E, UnitMethods); - - ALETemplate::Register(E, "Player"); - ALETemplate::SetMethods(E, ObjectMethods); - ALETemplate::SetMethods(E, WorldObjectMethods); - ALETemplate::SetMethods(E, UnitMethods); - ALETemplate::SetMethods(E, PlayerMethods); - - ALETemplate::Register(E, "Creature"); - ALETemplate::SetMethods(E, ObjectMethods); - ALETemplate::SetMethods(E, WorldObjectMethods); - ALETemplate::SetMethods(E, UnitMethods); - ALETemplate::SetMethods(E, CreatureMethods); - - ALETemplate::Register(E, "GameObject"); - ALETemplate::SetMethods(E, ObjectMethods); - ALETemplate::SetMethods(E, WorldObjectMethods); - ALETemplate::SetMethods(E, GameObjectMethods); - - ALETemplate::Register(E, "Corpse"); - ALETemplate::SetMethods(E, ObjectMethods); - ALETemplate::SetMethods(E, WorldObjectMethods); - ALETemplate::SetMethods(E, CorpseMethods); - - ALETemplate::Register(E, "Item"); - ALETemplate::SetMethods(E, ObjectMethods); - ALETemplate::SetMethods(E, ItemMethods); - - ALETemplate::Register(E, "ItemTemplate"); - ALETemplate::SetMethods(E, ItemTemplateMethods); - - ALETemplate::Register(E, "Vehicle"); - ALETemplate::SetMethods(E, VehicleMethods); - - ALETemplate::Register(E, "Group"); - ALETemplate::SetMethods(E, GroupMethods); - - ALETemplate::Register(E, "Guild"); - ALETemplate::SetMethods(E, GuildMethods); - - ALETemplate::Register(E, "Aura"); - ALETemplate::SetMethods(E, AuraMethods); - - ALETemplate::Register(E, "Spell"); - ALETemplate::SetMethods(E, SpellMethods); - - ALETemplate::Register(E, "Quest"); - ALETemplate::SetMethods(E, QuestMethods); - - ALETemplate::Register(E, "Map"); - ALETemplate::SetMethods(E, MapMethods); - - ALETemplate::Register(E, "AuctionHouseEntry"); - ALETemplate::SetMethods(E, AuctionMethods); - - ALETemplate::Register(E, "BattleGround"); - ALETemplate::SetMethods(E, BattleGroundMethods); - - ALETemplate::Register(E, "ChatHandler"); - ALETemplate::SetMethods(E, ChatHandlerMethods); - - ALETemplate::Register(E, "WorldPacket", true); - ALETemplate::SetMethods(E, PacketMethods); - - ALETemplate::Register(E, "ALEQuery", true); - ALETemplate::SetMethods(E, QueryMethods); - - ALETemplate::Register(E, "AchievementEntry"); - ALETemplate::SetMethods(E, AchievementMethods); - - ALETemplate::Register(E, "Roll"); - ALETemplate::SetMethods(E, RollMethods); - - ALETemplate::Register(E, "Ticket"); - ALETemplate::SetMethods(E, TicketMethods); - - ALETemplate::Register(E, "SpellInfo"); - ALETemplate::SetMethods(E, SpellInfoMethods); - - ALETemplate::Register(E, "GemPropertiesEntry"); - ALETemplate::SetMethods(E, GemPropertiesEntryMethods); - - ALETemplate::Register(E, "SpellEntry"); - ALETemplate::SetMethods(E, SpellEntryMethods); - - ALETemplate::Register(E, "CreatureTemplate"); - - ALETemplate::Register(E, "long long", true); - - ALETemplate::Register(E, "unsigned long long", true); -} diff --git a/src/LuaEngine/Methods/GlobalMethods.cpp b/src/LuaEngine/Methods/GlobalMethods.cpp new file mode 100644 index 0000000000..04d6b9f7f4 --- /dev/null +++ b/src/LuaEngine/Methods/GlobalMethods.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#include "GlobalMethods.h" +#include "StateManager.h" +#include "TimedEventManager.h" +#include "Log.h" + +namespace Eclipse::Methods::GlobalMethods +{ + /** + * @brief Convert uint32 event ID to WorldEvent enum + * + * Server events use range 1-50 in EventManager. + * Direct cast from uint32 to enum for type safety. + */ + Core::WorldEvent ServerEventToType(uint32 event) + { + return static_cast(event); + } + + /** + * @brief Convert uint32 event ID to PlayerEvent enum + * + * Player events start at 100 in EventManager. + * Direct cast from uint32 to enum for type safety. + */ + Core::PlayerEvent PlayerEventToType(uint32 event) + { + return static_cast(event); + } + + // ======================================================================== + // GLOBAL EVENT FUNCTION REGISTRATION + // ======================================================================== + + /** + * @brief Register all global event functions to Lua state + * + * Centralizes all state.set_function calls for event-related global functions. + * Keeps EventAPI.cpp clean by moving binding logic here. + */ + void RegisterGlobalEventFunctions(sol::state& state) + { + state.set_function("RegisterServerEvent", &RegisterServerEvent); + state.set_function("RegisterPlayerEvent", &RegisterPlayerEvent); + + state.set_function("CancelEvent", &CancelEvent); + state.set_function("CancelServerEvent", &CancelServerEvent); + state.set_function("CancelPlayerEvent", &CancelPlayerEvent); + + LOG_DEBUG("eclipse.methods", "[Eclipse] GlobalMethods - Registered global event functions"); + } + + // ======================================================================== + // EVENT REGISTRATION IMPLEMENTATIONS + // ======================================================================== + + /** + * @brief Register a server/world event handler + * + * Workflow: + * 1. Convert event ID to typed enum (ServerEventToType) + * 2. Move callback to EventManager (zero-copy) + * 3. Store in lock-free event handler vector + * 4. Return unique handler ID for cancellation + * + */ + uint64 RegisterServerEvent(uint32 event, sol::protected_function handler, sol::optional shots) + { + auto eventType = ServerEventToType(event); + return Core::EventManager::GetInstance().RegisterGlobalEvent( + eventType, + std::move(handler), + shots.value_or(0) // Default: infinite shots + ); + } + + /** + * @brief Register a player event handler + * + * Workflow: + * 1. Convert event ID to typed enum (PlayerEventToType) + * 2. Move callback to EventManager (zero-copy) + * 3. Store in lock-free event handler vector + * 4. Return unique handler ID for cancellation + */ + uint64 RegisterPlayerEvent(uint32 event, sol::protected_function handler, sol::optional shots) + { + auto eventType = PlayerEventToType(event); + return Core::EventManager::GetInstance().RegisterGlobalEvent( + eventType, + std::move(handler), + shots.value_or(0) // Default: infinite shots + ); + } + + // ======================================================================== + // EVENT CANCELLATION FUNCTIONS + // ======================================================================== + + /** + * @brief Cancel a specific event handler by ID + * + * Searches all event vectors for matching handler ID. + * Removes first match found (handler IDs are globally unique). + */ + bool CancelEvent(uint64 handlerId) + { + return Core::EventManager::GetInstance().CancelEvent(handlerId); + } + + /** + * @brief Cancel all handlers for a server event + * + * Clears the entire handler vector for this event type. + */ + void CancelServerEvent(uint32 event) + { + auto eventType = ServerEventToType(event); + Core::EventManager::GetInstance().CancelGlobalEvent(eventType); + } + + /** + * @brief Cancel all handlers for a player event + * + * Clears the entire handler vector for this event type. + */ + void CancelPlayerEvent(uint32 event) + { + auto eventType = PlayerEventToType(event); + Core::EventManager::GetInstance().CancelGlobalEvent(eventType); + } + + /** + * @brief Register CreateLuaEvent global function + * + * Lambda captures TimedEventManager pointer for per-state isolation. + */ + void RegisterCreateLuaEvent(sol::state& state, Core::TimedEventManager* mgr) + { + state["CreateLuaEvent"] = [mgr](sol::function callback, uint32 delay, sol::optional repeats) -> uint64 { + uint32 repeatCount = repeats.value_or(1); + sol::protected_function pf(callback); + return mgr->RegisterGlobalEvent(std::move(pf), delay, repeatCount); + }; + } + + /** + * @brief Register RemoveTimedEvent global function + */ + void RegisterRemoveTimedEvent(sol::state& state, Core::TimedEventManager* mgr) + { + state["RemoveTimedEvent"] = [mgr](uint64 eventId) -> bool { + return mgr->RemoveEvent(eventId); + }; + } + + /** + * @brief Register RemoveAllTimedEvents global function + */ + void RegisterRemoveAllTimedEvents(sol::state& state, Core::TimedEventManager* mgr) + { + state["RemoveAllTimedEvents"] = [mgr]() { + mgr->RemoveAllGlobalEvents(); + }; + } + + /** + * @brief Register GetTimedEventCount global function + */ + void RegisterGetTimedEventCount(sol::state& state, Core::TimedEventManager* mgr) + { + state["GetTimedEventCount"] = [mgr]() -> uint32 { + return mgr->GetGlobalEventCount(); + }; + } + +} // namespace Eclipse::Methods::GlobalMethods diff --git a/src/LuaEngine/Methods/Methods.hpp b/src/LuaEngine/Methods/Methods.hpp new file mode 100644 index 0000000000..7706ca068e --- /dev/null +++ b/src/LuaEngine/Methods/Methods.hpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _ECLIPSE_METHODS_HPP +#define _ECLIPSE_METHODS_HPP + +#include +#include "GlobalMethods.h" +#include "UnitMethods.hpp" +#include "PlayerMethods.hpp" +#include "TimedEventMethods.h" +#include "TimedEventManager.h" +#include "Log.h" + +namespace Eclipse::Methods +{ + /** + * @brief Register ALL Lua methods and functions to a state + * + * @param state Lua state to bind all functions to + * @param mapId Map ID for this state (-1 = master, 0+ = specific map) + * @param timedEventMgr TimedEventManager for this state (per-map isolation) + * + * @note CRITICAL ORDER: Base classes MUST be registered BEFORE derived classes! + * 1. Unit (base class) + * 2. Player (inherits Unit via sol::bases()) + * 3. Creature (future - will also inherit Unit) + * 4. Global functions & timed events + * + * @note This is the ONLY place where Lua bindings should be registered. + * Adding a new global function? Add it to GlobalMethods. + * Adding a new Unit method? Add it to UnitMethods. + * Adding a new Player method? Add it to PlayerMethods. + */ + inline void RegisterAllMethods(sol::state& state, int32 mapId, Core::TimedEventManager* timedEventMgr) + { + // Unit MUST be registered BEFORE Player! + // Player uses sol::bases() which requires Unit to be registered first + RegisterUnitMethods(state); + + // Player inherits all Unit methods automatically + RegisterPlayerMethods(state); + + // Global functions (_G namespace) + GlobalMethods::RegisterGlobalEventFunctions(state); + + if (timedEventMgr) + { + GlobalMethods::RegisterCreateLuaEvent(state, timedEventMgr); + GlobalMethods::RegisterRemoveTimedEvent(state, timedEventMgr); + GlobalMethods::RegisterRemoveAllTimedEvents(state, timedEventMgr); + GlobalMethods::RegisterGetTimedEventCount(state, timedEventMgr); + + TimedEventMethods::RegisterTimedEventMethods(state, timedEventMgr); + } + + + LOG_INFO("eclipse.methods", "[Eclipse] RegisterAllMethods - All methods registered for map {}", mapId); + } + +} // namespace Eclipse::Methods + +#endif // _ECLIPSE_METHODS_HPP diff --git a/src/LuaEngine/Methods/PlayerMethods.hpp b/src/LuaEngine/Methods/PlayerMethods.hpp new file mode 100644 index 0000000000..a71859061d --- /dev/null +++ b/src/LuaEngine/Methods/PlayerMethods.hpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _ECLIPSE_PLAYER_METHODS_H +#define _ECLIPSE_PLAYER_METHODS_H + +#include +#include "Player.h" +#include "Unit.h" +#include "Chat.h" +#include "Group.h" +#include "Log.h" + +namespace Eclipse::Methods +{ + namespace PlayerMethods + { + std::string GetName(Player* player) + { + return player->GetName(); + } + + uint64 GetGUID(Player* player) + { + return player->GetGUID().GetRawValue(); + } + + uint8 GetRace(Player* player) + { + return player->getRace(); + } + } // namespace PlayerMethods + + /** + * @brief Register Player methods to Lua state + * + * IMPORTANT: Player inherits from Unit via sol::bases() + * This means ALL Unit methods are automatically available on Player objects! + * + * MUST be called AFTER RegisterUnitMethods()! + * + * @param state Lua state to register Player type to + */ + inline void RegisterPlayerMethods(sol::state& state) + { + auto playerType = state.new_usertype("Player", + sol::no_constructor, + sol::base_classes, + sol::bases() + ); + + // Getters + playerType["GetName"] = &PlayerMethods::GetName; + playerType["GetGUID"] = &PlayerMethods::GetGUID; + playerType["GetRace"] = &PlayerMethods::GetRace; + + // Boolean + // playerType["HasItem"] = &PlayerMethods::HasItem; + // playerType["HasQuest"] = &PlayerMethods::HasQuest; + // playerType["HasQuestCompleted"] = &PlayerMethods::HasQuestCompleted; + // playerType["HasAchieved"] = &PlayerMethods::HasAchieved; + // playerType["HasSpell"] = &PlayerMethods::HasSpell; + // playerType["HasTalent"] = &PlayerMethods::HasTalent; + + // playerType["IsGM"] = &PlayerMethods::IsGM; + // playerType["IsInGroup"] = &PlayerMethods::IsInGroup; + // playerType["IsInRaid"] = &PlayerMethods::IsInRaid; + + // Setters + // playerType["SetMoney"] = &PlayerMethods::SetMoney; + + // Actions + // playerType["ModifyMoney"] = &PlayerMethods::ModifyMoney; + // playerType["SendBroadcastMessage"] = &PlayerMethods::SendBroadcastMessage; + // playerType["SendNotification"] = &PlayerMethods::SendNotification; + // playerType["SendAreaTriggerMessage"] = &PlayerMethods::SendAreaTriggerMessage; + // playerType["Teleport"] = &PlayerMethods::Teleport; + // playerType["ResurrectPlayer"] = &PlayerMethods::ResurrectPlayer; + // playerType["Kill"] = &PlayerMethods::Kill; + // playerType["SaveToDB"] = &PlayerMethods::SaveToDB; + } + +} // namespace Eclipse::Methods + +#endif // _ECLIPSE_PLAYER_METHODS_H diff --git a/src/LuaEngine/Methods/TimedEventMethods.cpp b/src/LuaEngine/Methods/TimedEventMethods.cpp new file mode 100644 index 0000000000..3b9ca3d036 --- /dev/null +++ b/src/LuaEngine/Methods/TimedEventMethods.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#include "TimedEventMethods.h" +#include "TimedEventManager.h" +#include "Log.h" + +namespace Eclipse::Methods::TimedEventMethods { + + // NOTE: All implementations use lambda closures to capture the per-state TimedEventManager* + // This is set up in RegisterTimedEventMethods() + + void RegisterTimedEventMethods(sol::state& state, Core::TimedEventManager* mgr) { + // Capture the manager pointer in lambdas so each state has its own manager + + // NOTE: Global timed event functions (CreateLuaEvent, RemoveTimedEvent, etc.) + // are now registered in GlobalMethods to keep all global functions centralized. + // This file only handles Player/Creature/GameObject method bindings. + + // ======================================================================= + // PLAYER TIMED EVENTS + // ======================================================================= + + state["Player"]["RegisterEvent"] = [mgr](Player* player, sol::function callback, uint32 delay, sol::optional repeats) -> uint64 { + if (!player) { + LOG_ERROR("scripts.eclipse", "Player_RegisterEvent: Player is null"); + return 0; + } + uint32 repeatCount = repeats.value_or(1); + LOG_INFO("scripts.eclipse", "Player:RegisterEvent called for player {}: delay={}ms, repeats={}", + player->GetName(), delay, repeatCount); + + sol::protected_function pf(callback); + return mgr->RegisterObjectEvent(player->GetGUID(), std::move(pf), delay, repeatCount, Core::TimedEventObjectType::PLAYER); + }; + + state["Player"]["RemoveEvent"] = [mgr](Player* player, uint64 eventId) -> bool { + if (!player) return false; + return mgr->RemoveEvent(eventId); + }; + + state["Player"]["RemoveEvents"] = [mgr](Player* player) { + if (!player) return; + mgr->RemoveObjectEvents(player->GetGUID()); + }; + + state["Player"]["GetEventCount"] = [mgr](Player* player) -> uint32 { + if (!player) return 0; + return mgr->GetObjectEventCount(player->GetGUID()); + }; + + // ======================================================================= + // CREATURE TIMED EVENTS + // ======================================================================= + + auto creatureType = state["Creature"].get_or_create(); + + creatureType["RegisterEvent"] = [mgr](Creature* creature, sol::function callback, uint32 delay, sol::optional repeats) -> uint64 { + if (!creature) { + LOG_ERROR("scripts.eclipse", "Creature_RegisterEvent: Creature is null"); + return 0; + } + uint32 repeatCount = repeats.value_or(1); + + sol::protected_function pf(callback); + return mgr->RegisterObjectEvent(creature->GetGUID(), std::move(pf), delay, repeatCount, Core::TimedEventObjectType::CREATURE); + }; + + creatureType["RemoveEvent"] = [mgr](Creature* creature, uint64 eventId) -> bool { + if (!creature) return false; + return mgr->RemoveEvent(eventId); + }; + + creatureType["RemoveEvents"] = [mgr](Creature* creature) { + if (!creature) return; + mgr->RemoveObjectEvents(creature->GetGUID()); + }; + + creatureType["GetEventCount"] = [mgr](Creature* creature) -> uint32 { + if (!creature) return 0; + return mgr->GetObjectEventCount(creature->GetGUID()); + }; + + // ======================================================================= + // GAMEOBJECT TIMED EVENTS + // ======================================================================= + + auto gameobjectType = state["GameObject"].get_or_create(); + + gameobjectType["RegisterEvent"] = [mgr](GameObject* gameobject, sol::function callback, uint32 delay, sol::optional repeats) -> uint64 { + if (!gameobject) { + LOG_ERROR("scripts.eclipse", "GameObject_RegisterEvent: GameObject is null"); + return 0; + } + uint32 repeatCount = repeats.value_or(1); + + sol::protected_function pf(callback); + return mgr->RegisterObjectEvent(gameobject->GetGUID(), std::move(pf), delay, repeatCount, Core::TimedEventObjectType::GAMEOBJECT); + }; + + gameobjectType["RemoveEvent"] = [mgr](GameObject* gameobject, uint64 eventId) -> bool { + if (!gameobject) return false; + return mgr->RemoveEvent(eventId); + }; + + gameobjectType["RemoveEvents"] = [mgr](GameObject* gameobject) { + if (!gameobject) return; + mgr->RemoveObjectEvents(gameobject->GetGUID()); + }; + + gameobjectType["GetEventCount"] = [mgr](GameObject* gameobject) -> uint32 { + if (!gameobject) return 0; + return mgr->GetObjectEventCount(gameobject->GetGUID()); + }; + + LOG_DEBUG("scripts.eclipse", "Registered Player/Creature/GameObject timed event methods"); + } + +} // namespace Eclipse::Methods::TimedEventMethods diff --git a/src/LuaEngine/Methods/TimedEventMethods.h b/src/LuaEngine/Methods/TimedEventMethods.h new file mode 100644 index 0000000000..4f89d890ed --- /dev/null +++ b/src/LuaEngine/Methods/TimedEventMethods.h @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _ECLIPSE_TIMED_EVENT_METHODS_H +#define _ECLIPSE_TIMED_EVENT_METHODS_H + +#include +#include "Player.h" +#include "Creature.h" +#include "GameObject.h" + +namespace Eclipse::Core { + class TimedEventManager; +} + +namespace Eclipse::Methods { + + /** + * @brief Global timed event methods exposed to Lua + */ + namespace TimedEventMethods { + + // ======================================================================= + // GLOBAL TIMED EVENTS + // ======================================================================= + + /** + * @brief Create a global timed event + * @param callback Lua function to execute + * @param delay Delay in milliseconds + * @param repeats Number of times to repeat (0 = infinite) + * @return Event ID + * + * Example: + * local eventId = CreateLuaEvent(function(eventId, delay, repeats) + * print("Event executed!") + * end, 5000, 1) -- Execute once after 5 seconds + */ + uint64 CreateLuaEvent(sol::protected_function callback, uint32 delay, sol::optional repeats); + + /** + * @brief Remove a global timed event + * @param eventId Event ID returned by CreateLuaEvent + * @return true if event was removed + */ + bool RemoveTimedEvent(uint64 eventId); + + /** + * @brief Remove all global timed events + */ + void RemoveAllTimedEvents(); + + /** + * @brief Get the number of active global timed events + */ + uint32 GetTimedEventCount(); + + // ======================================================================= + // PLAYER TIMED EVENTS + // ======================================================================= + + /** + * @brief Register a timed event for a player + * @param player Player object + * @param callback Lua function to execute + * @param delay Delay in milliseconds + * @param repeats Number of times to repeat (0 = infinite) + * @return Event ID + * + * Example: + * player:RegisterEvent(function(eventId, delay, repeats, player) + * player:SendBroadcastMessage("Buff reminder!") + * end, 60000, 0) -- Every minute indefinitely + */ + uint64 Player_RegisterEvent(Player* player, sol::protected_function callback, uint32 delay, sol::optional repeats); + + /** + * @brief Remove a specific event from a player + * @param player Player object + * @param eventId Event ID + * @return true if event was removed + */ + bool Player_RemoveEvent(Player* player, uint64 eventId); + + /** + * @brief Remove all events from a player + * @param player Player object + */ + void Player_RemoveEvents(Player* player); + + /** + * @brief Get the number of active events for a player + * @param player Player object + */ + uint32 Player_GetEventCount(Player* player); + + // ======================================================================= + // CREATURE TIMED EVENTS + // ======================================================================= + + /** + * @brief Register a timed event for a creature + * @param creature Creature object + * @param callback Lua function to execute + * @param delay Delay in milliseconds + * @param repeats Number of times to repeat (0 = infinite) + * @return Event ID + * + * Example: + * creature:RegisterEvent(function(eventId, delay, repeats, creature) + * creature:SendChatMessage("Patrol message") + * end, 30000, 0) -- Every 30 seconds + */ + uint64 Creature_RegisterEvent(Creature* creature, sol::protected_function callback, uint32 delay, sol::optional repeats); + + /** + * @brief Remove a specific event from a creature + * @param creature Creature object + * @param eventId Event ID + * @return true if event was removed + */ + bool Creature_RemoveEvent(Creature* creature, uint64 eventId); + + /** + * @brief Remove all events from a creature + * @param creature Creature object + */ + void Creature_RemoveEvents(Creature* creature); + + /** + * @brief Get the number of active events for a creature + * @param creature Creature object + */ + uint32 Creature_GetEventCount(Creature* creature); + + // ======================================================================= + // GAMEOBJECT TIMED EVENTS + // ======================================================================= + + /** + * @brief Register a timed event for a GameObject + * @param gameobject GameObject object + * @param callback Lua function to execute + * @param delay Delay in milliseconds + * @param repeats Number of times to repeat (0 = infinite) + * @return Event ID + * + * Example: + * gameobject:RegisterEvent(function(eventId, delay, repeats, gameobject) + * gameobject:SetGoState(1) + * end, 10000, 1) -- Open door after 10 seconds + */ + uint64 GameObject_RegisterEvent(GameObject* gameobject, sol::protected_function callback, uint32 delay, sol::optional repeats); + + /** + * @brief Remove a specific event from a GameObject + * @param gameobject GameObject object + * @param eventId Event ID + * @return true if event was removed + */ + bool GameObject_RemoveEvent(GameObject* gameobject, uint64 eventId); + + /** + * @brief Remove all events from a GameObject + * @param gameobject GameObject object + */ + void GameObject_RemoveEvents(GameObject* gameobject); + + /** + * @brief Get the number of active events for a GameObject + * @param gameobject GameObject object + */ + uint32 GameObject_GetEventCount(GameObject* gameobject); + + // ======================================================================= + // REGISTRATION + // ======================================================================= + + /** + * @brief Register all timed event methods with Lua state + * @param state The Lua state to register methods with + * @param timedEventManager The TimedEventManager instance for this state (per-state, not global) + */ + void RegisterTimedEventMethods(sol::state& state, Core::TimedEventManager* timedEventManager); + + } // namespace TimedEventMethods + +} // namespace Eclipse::Methods + +#endif // _ECLIPSE_TIMED_EVENT_METHODS_H diff --git a/src/LuaEngine/Methods/UnitMethods.hpp b/src/LuaEngine/Methods/UnitMethods.hpp new file mode 100644 index 0000000000..72f2cfd0cb --- /dev/null +++ b/src/LuaEngine/Methods/UnitMethods.hpp @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _ECLIPSE_UNIT_METHODS_HPP +#define _ECLIPSE_UNIT_METHODS_HPP + +#include +#include "Unit.h" +#include "Player.h" +#include "Creature.h" +#include "Log.h" +#include "SpellMgr.h" + +namespace Eclipse::Methods +{ + namespace UnitMethods + { + // =========================== + // Health & Power + // =========================== + + uint32 GetHealth(Unit* unit) + { + return unit->GetHealth(); + } + + uint32 GetMaxHealth(Unit* unit) + { + return unit->GetMaxHealth(); + } + + void SetHealth(Unit* unit, uint32 health) + { + unit->SetHealth(health); + } + + uint32 GetPower(Unit* unit, uint8 powerType) + { + return unit->GetPower(static_cast(powerType)); + } + + uint32 GetMaxPower(Unit* unit, uint8 powerType) + { + return unit->GetMaxPower(static_cast(powerType)); + } + + void SetPower(Unit* unit, uint8 powerType, uint32 power) + { + unit->SetPower(static_cast(powerType), power); + } + + // =========================== + // Position & Location + // =========================== + + float GetX(Unit* unit) + { + return unit->GetPositionX(); + } + + float GetY(Unit* unit) + { + return unit->GetPositionY(); + } + + float GetZ(Unit* unit) + { + return unit->GetPositionZ(); + } + + float GetO(Unit* unit) + { + return unit->GetOrientation(); + } + + uint32 GetMapId(Unit* unit) + { + return unit->GetMapId(); + } + + uint32 GetZoneId(Unit* unit) + { + return unit->GetZoneId(); + } + + uint32 GetAreaId(Unit* unit) + { + return unit->GetAreaId(); + } + + // =========================== + // Combat & State + // =========================== + + bool IsInCombat(Unit* unit) + { + return unit->IsInCombat(); + } + + bool IsAlive(Unit* unit) + { + return unit->IsAlive(); + } + + bool IsDead(Unit* unit) + { + return !unit->IsAlive(); + } + + bool IsStandState(Unit* unit) + { + return unit->IsStandState(); + } + + bool IsMounted(Unit* unit) + { + return unit->IsMounted(); + } + + bool IsRooted(Unit* unit) + { + return unit->HasUnitState(UNIT_STATE_ROOT); + } + + bool IsStunned(Unit* unit) + { + return unit->HasUnitState(UNIT_STATE_STUNNED); + } + + // =========================== + // Movement & Speed + // =========================== + + float GetSpeed(Unit* unit, uint8 moveType) + { + return unit->GetSpeed(static_cast(moveType)); + } + + void SetSpeed(Unit* unit, uint8 moveType, float speed, bool forced) + { + unit->SetSpeed(static_cast(moveType), speed, forced); + } + + // =========================== + // Stats & Attributes + // =========================== + + uint8 GetLevel(Unit* unit) + { + return unit->GetLevel(); + } + + void SetLevel(Unit* unit, uint8 level) + { + unit->SetLevel(level); + } + + uint32 GetDisplayId(Unit* unit) + { + return unit->GetDisplayId(); + } + + void SetDisplayId(Unit* unit, uint32 displayId) + { + unit->SetDisplayId(displayId); + } + + uint32 GetNativeDisplayId(Unit* unit) + { + return unit->GetNativeDisplayId(); + } + + // =========================== + // Auras & Spells + // =========================== + + bool HasAura(Unit* unit, uint32 spellId) + { + return unit->HasAura(spellId); + } + + void AddAura(Unit* unit, uint32 spellId, uint32 duration) + { + unit->AddAura(spellId, unit); + } + + void RemoveAura(Unit* unit, uint32 spellId) + { + unit->RemoveAura(spellId); + } + + void RemoveAllAuras(Unit* unit) + { + unit->RemoveAllAuras(); + } + + // =========================== + // Combat Actions + // =========================== + + void CastSpell(Unit* unit, Unit* target, uint32 spellId, bool triggered) + { + unit->CastSpell(target, spellId, triggered); + } + + void Kill(Unit* unit, Unit* victim, sol::optional durabilityLoss, sol::optional attackType, sol::optional spellId) + { + SpellInfo const* spellInfo = nullptr; + if (spellId.has_value()) + { + spellInfo = sSpellMgr->GetSpellInfo(spellId.value()); + } + + Unit::Kill(unit, victim, durabilityLoss.value_or(true), static_cast(attackType.value_or(BASE_ATTACK)), spellInfo, nullptr); + } + + void DealDamage(Unit* unit, Unit* victim, uint32 damage, sol::optional damageType, sol::optional schoolMask, sol::optional spellId, sol::optional durabilityLoss) + { + SpellInfo const* spellInfo = nullptr; + if (spellId.has_value()) + spellInfo = sSpellMgr->GetSpellInfo(spellId.value()); + + unit->DealDamage(unit, victim, damage, nullptr, static_cast(damageType.value_or(DIRECT_DAMAGE)), static_cast(schoolMask.value_or(SPELL_SCHOOL_MASK_NORMAL)), spellInfo, durabilityLoss.value_or(true), false, nullptr); + } + + // =========================== + // Target & Selection + // =========================== + + Unit* GetVictim(Unit* unit) + { + return unit->GetVictim(); + } + + void SetVictim(Unit* unit, Unit* victim) + { + unit->SetInCombatWith(victim); + } + + void ClearVictim(Unit* unit) + { + unit->ClearInCombat(); + } + + } // namespace UnitMethods + + /** + * @brief Register Unit methods to Lua state + * + * Creates the Unit usertype with all common methods. + * Player and Creature will inherit from this via sol::bases(). + * + * MUST be called BEFORE RegisterPlayerMethods and RegisterCreatureMethods! + * + * @param state Lua state to register Unit type to + */ + inline void RegisterUnitMethods(sol::state& state) + { + auto unitType = state.new_usertype("Unit", + sol::no_constructor + ); + + // Health & Power + unitType["GetHealth"] = &UnitMethods::GetHealth; + unitType["GetMaxHealth"] = &UnitMethods::GetMaxHealth; + unitType["SetHealth"] = &UnitMethods::SetHealth; + unitType["GetPower"] = &UnitMethods::GetPower; + unitType["GetMaxPower"] = &UnitMethods::GetMaxPower; + unitType["SetPower"] = &UnitMethods::SetPower; + + // Position & Location + unitType["GetX"] = &UnitMethods::GetX; + unitType["GetY"] = &UnitMethods::GetY; + unitType["GetZ"] = &UnitMethods::GetZ; + unitType["GetO"] = &UnitMethods::GetO; + unitType["GetMapId"] = &UnitMethods::GetMapId; + unitType["GetZoneId"] = &UnitMethods::GetZoneId; + unitType["GetAreaId"] = &UnitMethods::GetAreaId; + + // Combat & State + unitType["IsInCombat"] = &UnitMethods::IsInCombat; + unitType["IsAlive"] = &UnitMethods::IsAlive; + unitType["IsDead"] = &UnitMethods::IsDead; + unitType["IsStandState"] = &UnitMethods::IsStandState; + unitType["IsMounted"] = &UnitMethods::IsMounted; + unitType["IsRooted"] = &UnitMethods::IsRooted; + unitType["IsStunned"] = &UnitMethods::IsStunned; + + // Movement & Speed + unitType["GetSpeed"] = &UnitMethods::GetSpeed; + unitType["SetSpeed"] = &UnitMethods::SetSpeed; + + // Stats & Attributes + unitType["GetLevel"] = &UnitMethods::GetLevel; + unitType["SetLevel"] = &UnitMethods::SetLevel; + unitType["GetDisplayId"] = &UnitMethods::GetDisplayId; + unitType["SetDisplayId"] = &UnitMethods::SetDisplayId; + unitType["GetNativeDisplayId"] = &UnitMethods::GetNativeDisplayId; + + // Auras & Spells + unitType["HasAura"] = &UnitMethods::HasAura; + unitType["AddAura"] = &UnitMethods::AddAura; + unitType["RemoveAura"] = &UnitMethods::RemoveAura; + unitType["RemoveAllAuras"] = &UnitMethods::RemoveAllAuras; + + // Combat Actions + unitType["CastSpell"] = &UnitMethods::CastSpell; + unitType["Kill"] = &UnitMethods::Kill; + unitType["DealDamage"] = &UnitMethods::DealDamage; + + // Target & Selection + unitType["GetVictim"] = &UnitMethods::GetVictim; + unitType["SetVictim"] = &UnitMethods::SetVictim; + unitType["ClearVictim"] = &UnitMethods::ClearVictim; + } + +} // namespace Eclipse::Methods + +#endif // _ECLIPSE_UNIT_METHODS_HPP diff --git a/src/LuaEngine/State/StateManager.cpp b/src/LuaEngine/State/StateManager.cpp new file mode 100644 index 0000000000..f9ec9575a2 --- /dev/null +++ b/src/LuaEngine/State/StateManager.cpp @@ -0,0 +1,394 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#include "StateManager.h" +#include "BytecodeCache.h" +#include "TimedEventManager.h" +#include "Log.h" +#include + +namespace Eclipse::Core +{ + /** + * @brief Singleton getter for StateManager + * + * Thread-safe initialization (C++11 magic statics). + * + * @return Reference to the global StateManager + */ + StateManager& StateManager::GetInstance() + { + static StateManager instance; + return instance; + } + + /** + * @brief Constructor - initializes manager + */ + StateManager::StateManager() + { + LOG_INFO("server.loading", "[Eclipse] StateManager - Creating state manager"); + } + + /** + * @brief Destructor - cleanup all states + */ + StateManager::~StateManager() + { + Shutdown(); + } + + /** + * @brief Initialize state manager and create master state + * + * Creates master state (-1) with its TimedEventManager. + * Called from EclipseScriptLoader during server startup. + * + * @return true on success + */ + bool StateManager::Initialize() + { + // NO LOCK: State -1 is single-threaded + + if (m_initialized) + { + LOG_WARN("server.loading", "[Eclipse] StateManager - Already initialized"); + return true; + } + + LOG_INFO("server.loading", "[Eclipse] StateManager - Initializing state manager"); + + try + { + // Create the master state first + sol::state* masterState = GetOrCreateState(MASTER_STATE_ID); + if (!masterState) + { + LOG_ERROR("server.loading", "[Eclipse] StateManager - Failed to create master state"); + return false; + } + + m_initialized = true; + LOG_INFO("server.loading", "[Eclipse] StateManager - Initialization complete"); + return true; + } + catch (const std::exception& e) + { + LOG_ERROR("server.loading", "[Eclipse] StateManager - Initialization failed: {}", e.what()); + return false; + } + } + + /** + * @brief Shutdown all states + * + * Destroys all Lua VMs and their TimedEventManagers. + * Automatic cleanup via unique_ptr. + */ + void StateManager::Shutdown() + { + // NO LOCK: State -1 is single-threaded + + if (!m_initialized) + return; + + LOG_INFO("server.loading", "[Eclipse] StateManager - Shutting down {} states", m_states.size()); + + // Clear all states (unique_ptr auto-destruction) + m_states.clear(); + m_initialized = false; + + LOG_INFO("server.loading", "[Eclipse] StateManager - Shutdown complete"); + } + + /** + * @brief Get or create state for a map + * + * Current: Always returns master state (-1), ignores mapId. + * Future: Creates per-map states on demand. + * + * @param mapId Map ID (-1 = master, >=0 = per-map) + * @return Pointer to sol::state, never nullptr + */ + sol::state* StateManager::GetOrCreateState(StateId mapId) + { + // NO LOCK: State -1 is single-threaded + + // Check if state already exists + auto it = m_states.find(mapId); + if (it != m_states.end()) + { + return it->second.state.get(); + } + + // Create new state + return CreateNewState(mapId); + } + + /** + * @brief Get existing state (no creation) + * + * @param mapId State ID to retrieve + * @return Pointer to sol::state, nullptr if not found + */ + sol::state* StateManager::GetState(StateId mapId) const + { + // NO LOCK: State -1 is single-threaded + + auto it = m_states.find(mapId); + if (it != m_states.end()) + { + return it->second.state.get(); + } + + return nullptr; + } + + /** + * @brief Remove a state (map unload cleanup) + * + * Current: Only master state (-1) exists, protected from removal. + * Future: Called from Map::Destroy() to cleanup per-map states. + * + * @param mapId Map ID to remove + */ + void StateManager::RemoveState(StateId mapId) + { + // NO LOCK: State -1 is single-threaded + + // Don't allow removing the master state + if (mapId == MASTER_STATE_ID) + { + LOG_WARN("server.loading", "[Eclipse] StateManager - Cannot remove master state"); + return; + } + + auto it = m_states.find(mapId); + if (it != m_states.end()) + { + LOG_DEBUG("server.loading", "[Eclipse] StateManager - Removing state for map {}", mapId); + m_states.erase(it); // Unique_ptr auto-destructs state + managers + } + } + + /** + * @brief Get master state (-1) + * + * Convenience method for accessing the master compilation state. + * + * @return Pointer to master sol::state, never nullptr after Initialize() + */ + sol::state* StateManager::GetMasterState() const + { + return GetState(MASTER_STATE_ID); + } + + /** + * @brief Get number of active states + * + * Current: Always 1 (master state only). + * Future: 1 + number of active maps. + * + * @return State count + */ + size_t StateManager::GetStateCount() const + { + // NO LOCK: State -1 is single-threaded + return m_states.size(); + } + + /** + * @brief Get all active state IDs + * + * Current: Returns {-1}. + * Future: Returns {-1, mapId1, mapId2, ...}. + * + * @return Vector of state IDs + */ + std::vector StateManager::GetAllStateIds() const + { + // NO LOCK: State -1 is single-threaded + + std::vector ids; + ids.reserve(m_states.size()); + + for (const auto& [id, _] : m_states) + { + ids.push_back(id); + } + + return ids; + } + + /** + * @brief Execute function on all states + * + * Iteration helper for bulk operations. + * Future: Used for script reload, metrics collection, etc. + * + * @param func Callback(stateId, sol::state&) + */ + void StateManager::ForEachState(std::function func) + { + // NO LOCK: State -1 is single-threaded + + for (auto& [id, entry] : m_states) + { + if (entry.state) + { + func(id, *entry.state); + } + } + } + + /** + * @brief Get TimedEventManager for a state + * + * Each state owns its TimedEventManager for timed Lua callbacks. + * + * @param mapId State ID + * @return Pointer to TimedEventManager, nullptr if state not found + */ + TimedEventManager* StateManager::GetTimedEventManager(StateId mapId) const + { + // NO LOCK: State -1 is single-threaded + + auto it = m_states.find(mapId); + if (it != m_states.end()) + { + return it->second.timedEventManager.get(); + } + + return nullptr; + } + + /** + * @brief Create new state with default configuration + * + * Initializes: + * - Lua VM (sol::state) + * - Standard libraries (base, string, table, math, etc.) + * - TimedEventManager for this state + * - Global Lua functions (RegisterPlayerEvent, etc.) + * + * Performance: ~10ms for VM init + library loading. + * + * @param mapId State ID for this state + * @return Pointer to created sol::state + */ + sol::state* StateManager::CreateNewState(StateId mapId) + { + try + { + bool isMasterState = (mapId == MASTER_STATE_ID); + + LOG_DEBUG("server.loading", "[Eclipse] StateManager - Creating {} state for map {}", + isMasterState ? "master" : "map", mapId); + + // Create new state entry + StateEntry entry; + entry.state = std::make_unique(); + entry.timedEventManager = std::make_unique(mapId); // Per-state event manager + entry.created = std::chrono::steady_clock::now(); + entry.executionCount = 0; + + // Setup standard Lua libraries + SetupStateLibraries(*entry.state, isMasterState); + + // Register global functions (Eclipse API) + RegisterGlobalFunctions(*entry.state); + + // Store the state and return pointer + sol::state* statePtr = entry.state.get(); + m_states[mapId] = std::move(entry); + + LOG_DEBUG("server.loading", "[Eclipse] StateManager - State {} created successfully with dedicated TimedEventManager", mapId); + + return statePtr; + } + catch (const std::exception& e) + { + LOG_ERROR("server.loading", "[Eclipse] StateManager - Failed to create state for map {}: {}", + mapId, e.what()); + return nullptr; + } + } + + /** + * @brief Setup standard Lua libraries for a state + * + * Loads: + * - base: print, assert, pcall, etc. + * - package: require, module system + * - coroutine: coroutine support + * - string: string manipulation + * - table: table operations + * - math: math functions + * - bit32: bitwise operations + * - io: file I/O (restricted in future) + * - os: OS functions (restricted in future) + * - debug: debug library (master state only in future) + * + * @param state Lua state to configure + * @param isMasterState Whether this is the master state + */ + void StateManager::SetupStateLibraries(sol::state& state, bool isMasterState) + { + // Open standard Lua libraries + state.open_libraries( + sol::lib::base, + sol::lib::package, + sol::lib::coroutine, + sol::lib::string, + sol::lib::table, + sol::lib::math, + sol::lib::bit32, + sol::lib::io, // Future: Restrict for per-map states + sol::lib::os, // Future: Restrict for per-map states + sol::lib::debug // Future: Master state only + ); + + // Set up package paths (configured in ScriptLoader) + // state["package"]["path"] = "./lua/?.lua;./lua/?/init.lua"; + // state["package"]["cpath"] = "./lua/?.dll;./lua/?/init.dll"; + + LOG_DEBUG("server.loading", "[Eclipse] StateManager - Libraries setup complete for {} state", + isMasterState ? "master" : "map"); + } + + /** + * @brief Register global functions exposed to Lua + * + * Registers Eclipse API functions: + * - RegisterPlayerEvent(eventId, callback) + * - RegisterCreatureGossipEvent(entry, eventId, callback) + * - RegisterTimedEvent(delay, callback, repeats) + * - CancelTimedEvent(eventId) + * - print(...) - custom Lua print logging + * + * Additional APIs registered by EclipseScriptLoader after state creation. + * + * @param state Lua state to register functions in + */ + void StateManager::RegisterGlobalFunctions(sol::state& state) + { + // Custom global functions registered here + // Example: + // state.set_function("PrintInfo", [](const std::string& msg) { + // LOG_INFO("eclipse.lua", "{}", msg); + // }); + + // Core Eclipse API registered by EclipseScriptLoader: + // - Player usertype + // - Creature usertype + // - GameObject usertype + // - Event registration functions + // - Timed event functions + + // Additional registration happens in RegisterLuaFunctions() + } + +} // namespace Eclipse::Core diff --git a/src/LuaEngine/State/StateManager.h b/src/LuaEngine/State/StateManager.h new file mode 100644 index 0000000000..ee3c51e71f --- /dev/null +++ b/src/LuaEngine/State/StateManager.h @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ + +#ifndef _SOL_STATE_MANAGER_H +#define _SOL_STATE_MANAGER_H + +#include +#include +#include +#include +#include +#include +#include +#include "Common.h" + +namespace Eclipse::Core +{ + class ScriptCompiler; + class BytecodeCache; + class TimedEventManager; + + /** + * @class StateManager + * @brief Manages Lua states and their lifecycle + * + * @note Currently operates ONLY on master state (-1) + */ + class StateManager + { + public: + using StateId = int32; + + /** + * @brief Master state ID constant (-1) + */ + static constexpr StateId MASTER_STATE_ID = -1; + + /** + * @brief Default constructor + */ + StateManager(); + + /** + * @brief Destructor - cleans up all states + */ + ~StateManager(); + + StateManager(const StateManager&) = delete; + StateManager& operator=(const StateManager&) = delete; + StateManager(StateManager&&) = delete; + StateManager& operator=(StateManager&&) = delete; + + /** + * @brief Get singleton instance + * @return Reference to the global StateManager + */ + static StateManager& GetInstance(); + + /** + * @brief Initialize state manager and create master state + * + * @return true on success + */ + bool Initialize(); + + /** + * @brief Shutdown all states and cleanup + * + * Destroys all states and their associated managers. + * Called during server shutdown. + */ + void Shutdown(); + + /** + * @brief Get or create a state for a specific map + * + * @param mapId Map ID (-1 = master, >=0 = per-map) + * @return Pointer to sol::state, never nullptr (creates if missing) + */ + sol::state* GetOrCreateState(StateId mapId); + + /** + * @brief Get existing state (no creation) + * + * @param mapId Map ID to retrieve + * @return Pointer to sol::state, nullptr if not found + */ + sol::state* GetState(StateId mapId) const; + + /** + * @brief Remove a state (map unload cleanup) + * + * @param mapId Map ID to remove (>=0 only) + */ + void RemoveState(StateId mapId); + + /** + * @brief Get master state (-1) + * + * @return Pointer to master sol::state, never nullptr after Initialize() + */ + sol::state* GetMasterState() const; + + /** + * @brief Check initialization status + * + * @return true if Initialize() succeeded + */ + bool IsInitialized() const { return m_initialized; } + + /** + * @brief Get number of active states + * + * @return State count + */ + size_t GetStateCount() const; + + /** + * @brief Get all active state IDs + * + * @return Vector of state IDs + */ + std::vector GetAllStateIds() const; + + /** + * @brief Execute function on all states + * + * Iteration helper for operations affecting multiple states. + * + * @param func Callback(stateId, sol::state&) + */ + void ForEachState(std::function func); + + /** + * @brief Get TimedEventManager for a state + * + * Each state owns its TimedEventManager for timed Lua callbacks. + * + * @param mapId State ID + * @return Pointer to TimedEventManager, nullptr if state not found + */ + TimedEventManager* GetTimedEventManager(StateId mapId) const; + + private: + /** + * @struct StateEntry + * @brief Storage for state and its associated managers + */ + struct StateEntry + { + std::unique_ptr state; ///< Lua VM instance + std::unique_ptr timedEventManager; ///< Timed event scheduler + std::chrono::steady_clock::time_point created; ///< Creation timestamp + size_t executionCount = 0; ///< Script execution counter + }; + + std::unordered_map m_states; ///< Map of state ID -> StateEntry + bool m_initialized = false; ///< Initialization flag + + /** + * @brief Create new state with default configuration + * + * Initializes Lua VM, loads libraries, creates TimedEventManager. + * + * @param mapId State ID for this state + * @return Pointer to created sol::state + */ + sol::state* CreateNewState(StateId mapId); + + /** + * @brief Setup standard Lua libraries + * + * Loads: base, coroutine, string, table, math, os (restricted), io (restricted) + * + * @param state Lua state to configure + * @param isMasterState Whether this is master state (affects library restrictions) + */ + void SetupStateLibraries(sol::state& state, bool isMasterState); + + /** + * @brief Register global functions exposed to Lua + * + * Registers: print, RegisterPlayerEvent, RegisterTimedEvent, etc. + * + * @param state Lua state to register functions in + */ + void RegisterGlobalFunctions(sol::state& state); + }; + +} // namespace Eclipse::Core + +#endif // _SOL_STATE_MANAGER_H diff --git a/src/LuaEngine/docs/ALEDoc/templates/index.html b/src/LuaEngine/docs/ALEDoc/templates/index.html index f363428a8e..5830f8603e 100644 --- a/src/LuaEngine/docs/ALEDoc/templates/index.html +++ b/src/LuaEngine/docs/ALEDoc/templates/index.html @@ -31,10 +31,7 @@

If you come from the TypeScript / JavaScript world, or would prefer to use a typed language instead of Lua, check out ale-ts!

- You can get support in the #ale-ac channel of AzerothCore's Discord server. -

-

- You can also join the official ALE Discord server, where you'll be able to find resources, releases and support provided by the ALE community. + You can get support in the #ale-ac channel of AzerothCore's Discord server.

diff --git a/src/LuaEngine/docs/DOC_GEN.md b/src/LuaEngine/docs/DOC_GEN.md index 6acac22bbf..aa2e540cfc 100644 --- a/src/LuaEngine/docs/DOC_GEN.md +++ b/src/LuaEngine/docs/DOC_GEN.md @@ -1,5 +1,5 @@ # Documentation generation -Eluna uses a custom made documentation generator to create it's [web documentation](http://elunaluaengine.github.io/). +Eluna uses a custom made documentation generator to create it's [web documentation](http://elunaluaengine.github.io/). The generator is written in python by Patman. It works by parsing Eluna's source files for comments and then generates the HTML and javascript for the documentation based on them. This page guides you through generating the web documentation locally and explains the standards of the documentation comments for you to help us improve our documentation. To contribute with your documentation changes, create a [pull request](https://help.github.com/articles/using-pull-requests/) @@ -14,7 +14,7 @@ This page guides you through generating the web documentation locally and explai - [Jinja2](https://pypi.python.org/pypi/Jinja2) - [typedecorator](https://pypi.python.org/pypi/typedecorator) - [markdown](https://pypi.python.org/pypi/Markdown) -- Run in cmd `python -m ElunaDoc` when at `\LuaEngine\docs\` +- Run in cmd `python -m ALEDoc` when at `\LuaEngine\docs\` # Documenting You can document functions in the Eluna source code. To find examples simply open a method header file like `PlayerMethods.h` and see the comments. diff --git a/src/LuaEngine/hooks/AllCreatureHooks.cpp b/src/LuaEngine/hooks/AllCreatureHooks.cpp deleted file mode 100644 index f32fe110e1..0000000000 --- a/src/LuaEngine/hooks/AllCreatureHooks.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALEIncludes.h" -#include "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK(EVENT) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EventKey(EVENT);\ - if (!AllCreatureEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -#define START_HOOK_WITH_RETVAL(EVENT, RETVAL) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return RETVAL;\ - auto key = EventKey(EVENT);\ - if (!AllCreatureEventBindings->HasBindingsFor(key))\ - return RETVAL;\ - LOCK_ALE - -void ALE::OnAllCreatureAddToWorld(Creature* creature) -{ - START_HOOK(ALL_CREATURE_EVENT_ON_ADD); - Push(creature); - CallAllFunctions(AllCreatureEventBindings, key); -} - -void ALE::OnAllCreatureRemoveFromWorld(Creature* creature) -{ - START_HOOK(ALL_CREATURE_EVENT_ON_REMOVE); - Push(creature); - CallAllFunctions(AllCreatureEventBindings, key); -} - -void ALE::OnAllCreatureSelectLevel(const CreatureTemplate* cinfo, Creature* creature) -{ - START_HOOK(ALL_CREATURE_EVENT_ON_SELECT_LEVEL); - Push(cinfo); - Push(creature); - CallAllFunctions(AllCreatureEventBindings, key); -} - -void ALE::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(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(level, levelIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(3); -} - -void ALE::OnAllCreatureAuraApply(Creature* me, Aura* aura) -{ - START_HOOK(ALL_CREATURE_EVENT_ON_AURA_APPLY); - Push(me); - Push(aura); - CallAllFunctions(AllCreatureEventBindings, key); -} - -void ALE::OnAllCreatureAuraRemove(Creature* me, Aura* aura, AuraRemoveMode mode) -{ - START_HOOK(ALL_CREATURE_EVENT_ON_AURA_REMOVE); - Push(me); - Push(aura); - Push(mode); - CallAllFunctions(AllCreatureEventBindings, key); -} - -void ALE::OnAllCreatureHeal(Creature* me, Unit* target, uint32& gain) -{ - START_HOOK(ALL_CREATURE_EVENT_ON_HEAL); - Push(me); - Push(target); - Push(gain); - - int gainIndex = lua_gettop(L); - int n = SetupStack(AllCreatureEventBindings, key, 3); - while (n > 0) - { - int r = CallOneFunction(n--, 3, 1); - if (lua_isnumber(L, r)) - { - gain = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(gain, gainIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(3); -} - -void ALE::OnAllCreatureDamage(Creature* me, Unit* target, uint32& damage) -{ - START_HOOK(ALL_CREATURE_EVENT_ON_DAMAGE); - Push(me); - Push(target); - Push(damage); - - int damageIndex = lua_gettop(L); - int n = SetupStack(AllCreatureEventBindings, key, 3); - while (n > 0) - { - int r = CallOneFunction(n--, 3, 1); - if (lua_isnumber(L, r)) - { - damage = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(damage, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(3); -} - -void ALE::OnAllCreatureModifyPeriodicDamageAurasTick(Creature* me, Unit* target, uint32& damage, SpellInfo const* spellInfo) -{ - START_HOOK(ALL_CREATURE_EVENT_ON_MODIFY_PERIODIC_DAMAGE_AURAS_TICK); - Push(me); - Push(target); - Push(damage); - Push(spellInfo); - - int damageIndex = lua_gettop(L) - 1; - int n = SetupStack(AllCreatureEventBindings, key, 4); - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - if (lua_isnumber(L, r)) - { - damage = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(damage, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); -} - -void ALE::OnAllCreatureModifyMeleeDamage(Creature* me, Unit* target, uint32& damage) -{ - START_HOOK(ALL_CREATURE_EVENT_ON_MODIFY_MELEE_DAMAGE); - Push(me); - Push(target); - Push(damage); - - int damageIndex = lua_gettop(L); - int n = SetupStack(AllCreatureEventBindings, key, 3); - while (n > 0) - { - int r = CallOneFunction(n--, 3, 1); - if (lua_isnumber(L, r)) - { - damage = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(damage, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(3); -} - -void ALE::OnAllCreatureModifySpellDamageTaken(Creature* me, Unit* target, int32& damage, SpellInfo const* spellInfo) -{ - START_HOOK(ALL_CREATURE_EVENT_ON_MODIFY_SPELL_DAMAGE_TAKEN); - Push(me); - Push(target); - Push(damage); - Push(spellInfo); - - int damageIndex = lua_gettop(L) - 1; - int n = SetupStack(AllCreatureEventBindings, key, 4); - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - if (lua_isnumber(L, r)) - { - damage = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(damage, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); -} - -void ALE::OnAllCreatureModifyHealReceived(Creature* me, Unit* target, uint32& heal, SpellInfo const* spellInfo) -{ - START_HOOK(ALL_CREATURE_EVENT_ON_MODIFY_HEAL_RECEIVED); - Push(me); - Push(target); - Push(heal); - Push(spellInfo); - - int healIndex = lua_gettop(L) - 1; - int n = SetupStack(AllCreatureEventBindings, key, 4); - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - if (lua_isnumber(L, r)) - { - heal = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(heal, healIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); -} - -uint32 ALE::OnAllCreatureDealDamage(Creature* me, Unit* target, uint32 damage, DamageEffectType damagetype) -{ - START_HOOK_WITH_RETVAL(ALL_CREATURE_EVENT_ON_DEAL_DAMAGE, damage); - uint32 result = damage; - Push(me); - Push(target); - Push(damage); - Push(damagetype); - int damageIndex = lua_gettop(L) - 1; - int n = SetupStack(AllCreatureEventBindings, key, 4); - - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - - if (lua_isnumber(L, r)) - { - result = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(result, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); - return result; -} diff --git a/src/LuaEngine/hooks/BattleGroundHooks.cpp b/src/LuaEngine/hooks/BattleGroundHooks.cpp deleted file mode 100644 index ec70cf5a15..0000000000 --- a/src/LuaEngine/hooks/BattleGroundHooks.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK(EVENT) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EventKey(EVENT);\ - if (!BGEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -void ALE::OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) -{ - START_HOOK(BG_EVENT_ON_START); - Push(bg); - Push(bgId); - Push(instanceId); - CallAllFunctions(BGEventBindings, key); -} - -void ALE::OnBGEnd(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId, TeamId winner) -{ - START_HOOK(BG_EVENT_ON_END); - Push(bg); - Push(bgId); - Push(instanceId); - Push(winner); - CallAllFunctions(BGEventBindings, key); -} - -void ALE::OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) -{ - START_HOOK(BG_EVENT_ON_CREATE); - Push(bg); - Push(bgId); - Push(instanceId); - CallAllFunctions(BGEventBindings, key); -} - -void ALE::OnBGDestroy(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) -{ - START_HOOK(BG_EVENT_ON_PRE_DESTROY); - Push(bg); - Push(bgId); - Push(instanceId); - CallAllFunctions(BGEventBindings, key); -} diff --git a/src/LuaEngine/hooks/CreatureHooks.cpp b/src/LuaEngine/hooks/CreatureHooks.cpp deleted file mode 100644 index 9fca834e48..0000000000 --- a/src/LuaEngine/hooks/CreatureHooks.cpp +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALEIncludes.h" -#include "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK(EVENT, CREATURE) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto entry_key = EntryKey(EVENT, CREATURE->GetEntry());\ - auto unique_key = UniqueObjectKey(EVENT, CREATURE->GET_GUID(), CREATURE->GetInstanceId());\ - if (!CreatureEventBindings->HasBindingsFor(entry_key))\ - if (!CreatureUniqueBindings->HasBindingsFor(unique_key))\ - return;\ - LOCK_ALE - -#define START_HOOK_WITH_RETVAL(EVENT, CREATURE, RETVAL) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return RETVAL;\ - auto entry_key = EntryKey(EVENT, CREATURE->GetEntry());\ - auto unique_key = UniqueObjectKey(EVENT, CREATURE->GET_GUID(), CREATURE->GetInstanceId());\ - if (!CreatureEventBindings->HasBindingsFor(entry_key))\ - if (!CreatureUniqueBindings->HasBindingsFor(unique_key))\ - return RETVAL;\ - LOCK_ALE - -void ALE::OnDummyEffect(WorldObject* pCaster, uint32 spellId, SpellEffIndex effIndex, Creature* pTarget) -{ - START_HOOK(CREATURE_EVENT_ON_DUMMY_EFFECT, pTarget); - Push(pCaster); - Push(spellId); - Push(effIndex); - Push(pTarget); - CallAllFunctions(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -bool ALE::OnQuestAccept(Player* pPlayer, Creature* pCreature, Quest const* pQuest) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_QUEST_ACCEPT, pCreature, false); - Push(pPlayer); - Push(pCreature); - Push(pQuest); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -bool ALE::OnQuestReward(Player* pPlayer, Creature* pCreature, Quest const* pQuest, uint32 opt) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_QUEST_REWARD, pCreature, false); - Push(pPlayer); - Push(pCreature); - Push(pQuest); - Push(opt); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -void ALE::GetDialogStatus(const Player* pPlayer, const Creature* pCreature) -{ - START_HOOK(CREATURE_EVENT_ON_DIALOG_STATUS, pCreature); - Push(pPlayer); - Push(pCreature); - CallAllFunctions(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -void ALE::OnAddToWorld(Creature* pCreature) -{ - START_HOOK(CREATURE_EVENT_ON_ADD, pCreature); - Push(pCreature); - CallAllFunctions(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -void ALE::OnRemoveFromWorld(Creature* pCreature) -{ - START_HOOK(CREATURE_EVENT_ON_REMOVE, pCreature); - Push(pCreature); - CallAllFunctions(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -bool ALE::OnSummoned(Creature* pCreature, Unit* pSummoner) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_SUMMONED, pCreature, false); - Push(pCreature); - Push(pSummoner); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -bool ALE::UpdateAI(Creature* me, const uint32 diff) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_AIUPDATE, me, false); - Push(me); - Push(diff); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -//Called for reaction at enter to combat if not in combat yet (enemy can be NULL) -//Called at creature aggro either by MoveInLOS or Attack Start -bool ALE::EnterCombat(Creature* me, Unit* target) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_ENTER_COMBAT, me, false); - Push(me); - Push(target); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// Called at any Damage from any attacker (before damage apply) -bool ALE::DamageTaken(Creature* me, Unit* attacker, uint32& damage) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_DAMAGE_TAKEN, me, false); - bool result = false; - Push(me); - Push(attacker); - Push(damage); - int damageIndex = lua_gettop(L); - int n = SetupStack(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key, 3); - - while (n > 0) - { - int r = CallOneFunction(n--, 3, 2); - - if (lua_isboolean(L, r + 0) && lua_toboolean(L, r + 0)) - result = true; - - if (lua_isnumber(L, r + 1)) - { - damage = ALE::CHECKVAL(L, r + 1); - // Update the stack for subsequent calls. - ReplaceArgument(damage, damageIndex); - } - - lua_pop(L, 2); - } - - CleanUpStack(3); - return result; -} - -//Called at creature death -bool ALE::JustDied(Creature* me, Unit* killer) -{ - On_Reset(me); - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_DIED, me, false); - Push(me); - Push(killer); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -//Called at creature killing another unit -bool ALE::KilledUnit(Creature* me, Unit* victim) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_TARGET_DIED, me, false); - Push(me); - Push(victim); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// Called when the creature summon successfully other creature -bool ALE::JustSummoned(Creature* me, Creature* summon) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE, me, false); - Push(me); - Push(summon); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// Called when a summoned creature is despawned -bool ALE::SummonedCreatureDespawn(Creature* me, Creature* summon) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN, me, false); - Push(me); - Push(summon); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -//Called at waypoint reached or PointMovement end -bool ALE::MovementInform(Creature* me, uint32 type, uint32 id) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_REACH_WP, me, false); - Push(me); - Push(type); - Push(id); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// Called before EnterCombat even before the creature is in combat. -bool ALE::AttackStart(Creature* me, Unit* target) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_PRE_COMBAT, me, false); - Push(me); - Push(target); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// Called for reaction at stopping attack at no attackers or targets -bool ALE::EnterEvadeMode(Creature* me) -{ - On_Reset(me); - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_LEAVE_COMBAT, me, false); - Push(me); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// Called when creature is spawned or respawned (for reseting variables) -bool ALE::JustRespawned(Creature* me) -{ - On_Reset(me); - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_SPAWN, me, false); - Push(me); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// Called at reaching home after evade -bool ALE::JustReachedHome(Creature* me) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_REACH_HOME, me, false); - Push(me); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// Called at text emote receive from player -bool ALE::ReceiveEmote(Creature* me, Player* player, uint32 emoteId) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_RECEIVE_EMOTE, me, false); - Push(me); - Push(player); - Push(emoteId); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// called when the corpse of this creature gets removed -bool ALE::CorpseRemoved(Creature* me, uint32& respawnDelay) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_CORPSE_REMOVED, me, false); - bool result = false; - Push(me); - Push(respawnDelay); - int respawnDelayIndex = lua_gettop(L); - int n = SetupStack(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key, 2); - - while (n > 0) - { - int r = CallOneFunction(n--, 2, 2); - - if (lua_isboolean(L, r + 0) && lua_toboolean(L, r + 0)) - result = true; - - if (lua_isnumber(L, r + 1)) - { - respawnDelay = ALE::CHECKVAL(L, r + 1); - // Update the stack for subsequent calls. - ReplaceArgument(respawnDelay, respawnDelayIndex); - } - - lua_pop(L, 2); - } - - CleanUpStack(2); - return result; -} - -bool ALE::MoveInLineOfSight(Creature* me, Unit* who) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_MOVE_IN_LOS, me, false); - Push(me); - Push(who); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// Called on creature initial spawn, respawn, death, evade (leave combat) -void ALE::On_Reset(Creature* me) // Not an override, custom -{ - START_HOOK(CREATURE_EVENT_ON_RESET, me); - Push(me); - CallAllFunctions(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// Called when hit by a spell -bool ALE::SpellHit(Creature* me, WorldObject* caster, SpellInfo const* spell) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_HIT_BY_SPELL, me, false); - Push(me); - Push(caster); - Push(spell->Id); // Pass spell object? - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// Called when spell hits a target -bool ALE::SpellHitTarget(Creature* me, WorldObject* target, SpellInfo const* spell) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_SPELL_HIT_TARGET, me, false); - Push(me); - Push(target); - Push(spell->Id); // Pass spell object? - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -bool ALE::SummonedCreatureDies(Creature* me, Creature* summon, Unit* killer) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED, me, false); - Push(me); - Push(summon); - Push(killer); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// Called when owner takes damage -bool ALE::OwnerAttackedBy(Creature* me, Unit* attacker) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_OWNER_ATTACKED_AT, me, false); - Push(me); - Push(attacker); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -// Called when owner attacks something -bool ALE::OwnerAttacked(Creature* me, Unit* target) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_OWNER_ATTACKED, me, false); - Push(me); - Push(target); - return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -void ALE::OnCreatureAuraApply(Creature* me, Aura* aura) -{ - START_HOOK(CREATURE_EVENT_ON_AURA_APPLY, me); - Push(me); - Push(aura); - CallAllFunctions(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -void ALE::OnCreatureAuraRemove(Creature* me, Aura* aura, AuraRemoveMode mode) -{ - START_HOOK(CREATURE_EVENT_ON_AURA_REMOVE, me); - Push(me); - Push(aura); - Push(mode); - CallAllFunctions(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); -} - -void ALE::OnCreatureHeal(Creature* me, Unit* target, uint32& gain) -{ - START_HOOK(CREATURE_EVENT_ON_HEAL, me); - Push(me); - Push(target); - Push(gain); - - int gainIndex = lua_gettop(L); - int n = SetupStack(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key, 3); - while (n > 0) - { - int r = CallOneFunction(n--, 3, 1); - if (lua_isnumber(L, r)) - { - gain = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(gain, gainIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(3); -} - -void ALE::OnCreatureDamage(Creature* me, Unit* target, uint32& damage) -{ - START_HOOK(CREATURE_EVENT_ON_DAMAGE, me); - Push(me); - Push(target); - Push(damage); - - int damageIndex = lua_gettop(L); - int n = SetupStack(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key, 3); - while (n > 0) - { - int r = CallOneFunction(n--, 3, 1); - if (lua_isnumber(L, r)) - { - damage = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(damage, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(3); -} - -void ALE::OnCreatureModifyPeriodicDamageAurasTick(Creature* me, Unit* target, uint32& damage, SpellInfo const* spellInfo) -{ - START_HOOK(CREATURE_EVENT_ON_MODIFY_PERIODIC_DAMAGE_AURAS_TICK, me); - Push(me); - Push(target); - Push(damage); - Push(spellInfo); - - int damageIndex = lua_gettop(L) - 1; - int n = SetupStack(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key, 4); - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - if (lua_isnumber(L, r)) - { - damage = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(damage, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); -} - -void ALE::OnCreatureModifyMeleeDamage(Creature* me, Unit* target, uint32& damage) -{ - START_HOOK(CREATURE_EVENT_ON_MODIFY_MELEE_DAMAGE, me); - Push(me); - Push(target); - Push(damage); - - int damageIndex = lua_gettop(L); - int n = SetupStack(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key, 3); - while (n > 0) - { - int r = CallOneFunction(n--, 3, 1); - if (lua_isnumber(L, r)) - { - damage = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(damage, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(3); -} - -void ALE::OnCreatureModifySpellDamageTaken(Creature* me, Unit* target, int32& damage, SpellInfo const* spellInfo) -{ - START_HOOK(CREATURE_EVENT_ON_MODIFY_SPELL_DAMAGE_TAKEN, me); - Push(me); - Push(target); - Push(damage); - Push(spellInfo); - - int damageIndex = lua_gettop(L) - 1; - int n = SetupStack(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key, 4); - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - if (lua_isnumber(L, r)) - { - damage = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(damage, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); -} - -void ALE::OnCreatureModifyHealReceived(Creature* me, Unit* target, uint32& heal, SpellInfo const* spellInfo) -{ - START_HOOK(CREATURE_EVENT_ON_MODIFY_HEAL_RECEIVED, me); - Push(me); - Push(target); - Push(heal); - Push(spellInfo); - - int healIndex = lua_gettop(L) - 1; - int n = SetupStack(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key, 4); - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - if (lua_isnumber(L, r)) - { - heal = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(heal, healIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); -} - -uint32 ALE::OnCreatureDealDamage(Creature* me, Unit* target, uint32 damage, DamageEffectType damagetype) -{ - START_HOOK_WITH_RETVAL(CREATURE_EVENT_ON_DEAL_DAMAGE, me, damage); - uint32 result = damage; - Push(me); - Push(target); - Push(damage); - Push(damagetype); - int damageIndex = lua_gettop(L) - 1; - int n = SetupStack(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key, 4); - - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - - if (lua_isnumber(L, r)) - { - result = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(result, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); - return result; -} diff --git a/src/LuaEngine/hooks/GameObjectHooks.cpp b/src/LuaEngine/hooks/GameObjectHooks.cpp deleted file mode 100644 index 7dd8508f4f..0000000000 --- a/src/LuaEngine/hooks/GameObjectHooks.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALEIncludes.h" -#include "ALEEventMgr.h" -#include "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK(EVENT, ENTRY) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EntryKey(EVENT, ENTRY);\ - if (!GameObjectEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -#define START_HOOK_WITH_RETVAL(EVENT, ENTRY, RETVAL) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return RETVAL;\ - auto key = EntryKey(EVENT, ENTRY);\ - if (!GameObjectEventBindings->HasBindingsFor(key))\ - return RETVAL;\ - LOCK_ALE - -void ALE::OnDummyEffect(WorldObject* pCaster, uint32 spellId, SpellEffIndex effIndex, GameObject* pTarget) -{ - START_HOOK(GAMEOBJECT_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry()); - Push(pCaster); - Push(spellId); - Push(effIndex); - Push(pTarget); - CallAllFunctions(GameObjectEventBindings, key); -} - -void ALE::UpdateAI(GameObject* pGameObject, uint32 diff) -{ - pGameObject->ALEEvents->Update(diff); - START_HOOK(GAMEOBJECT_EVENT_ON_AIUPDATE, pGameObject->GetEntry()); - Push(pGameObject); - Push(diff); - CallAllFunctions(GameObjectEventBindings, key); -} - -bool ALE::OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest) -{ - START_HOOK_WITH_RETVAL(GAMEOBJECT_EVENT_ON_QUEST_ACCEPT, pGameObject->GetEntry(), false); - Push(pPlayer); - Push(pGameObject); - Push(pQuest); - return CallAllFunctionsBool(GameObjectEventBindings, key); -} - -bool ALE::OnQuestReward(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest, uint32 opt) -{ - START_HOOK_WITH_RETVAL(GAMEOBJECT_EVENT_ON_QUEST_REWARD, pGameObject->GetEntry(), false); - Push(pPlayer); - Push(pGameObject); - Push(pQuest); - Push(opt); - return CallAllFunctionsBool(GameObjectEventBindings, key); -} - -void ALE::GetDialogStatus(const Player* pPlayer, const GameObject* pGameObject) -{ - START_HOOK(GAMEOBJECT_EVENT_ON_DIALOG_STATUS, pGameObject->GetEntry()); - Push(pPlayer); - Push(pGameObject); - CallAllFunctions(GameObjectEventBindings, key); -} - -void ALE::OnDestroyed(GameObject* pGameObject, WorldObject* attacker) -{ - START_HOOK(GAMEOBJECT_EVENT_ON_DESTROYED, pGameObject->GetEntry()); - Push(pGameObject); - Push(attacker); - CallAllFunctions(GameObjectEventBindings, key); -} - -void ALE::OnDamaged(GameObject* pGameObject, WorldObject* attacker) -{ - START_HOOK(GAMEOBJECT_EVENT_ON_DAMAGED, pGameObject->GetEntry()); - Push(pGameObject); - Push(attacker); - CallAllFunctions(GameObjectEventBindings, key); -} - -void ALE::OnLootStateChanged(GameObject* pGameObject, uint32 state) -{ - START_HOOK(GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE, pGameObject->GetEntry()); - Push(pGameObject); - Push(state); - CallAllFunctions(GameObjectEventBindings, key); -} - -void ALE::OnGameObjectStateChanged(GameObject* pGameObject, uint32 state) -{ - START_HOOK(GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED, pGameObject->GetEntry()); - Push(pGameObject); - Push(state); - CallAllFunctions(GameObjectEventBindings, key); -} - -void ALE::OnSpawn(GameObject* pGameObject) -{ - START_HOOK(GAMEOBJECT_EVENT_ON_SPAWN, pGameObject->GetEntry()); - Push(pGameObject); - CallAllFunctions(GameObjectEventBindings, key); -} - -void ALE::OnAddToWorld(GameObject* pGameObject) -{ - START_HOOK(GAMEOBJECT_EVENT_ON_ADD, pGameObject->GetEntry()); - Push(pGameObject); - CallAllFunctions(GameObjectEventBindings, key); -} - -void ALE::OnRemoveFromWorld(GameObject* pGameObject) -{ - START_HOOK(GAMEOBJECT_EVENT_ON_REMOVE, pGameObject->GetEntry()); - Push(pGameObject); - CallAllFunctions(GameObjectEventBindings, key); -} - -bool ALE::OnGameObjectUse(Player* pPlayer, GameObject* pGameObject) -{ - START_HOOK_WITH_RETVAL(GAMEOBJECT_EVENT_ON_USE, pGameObject->GetEntry(), false); - Push(pGameObject); - Push(pPlayer); - return CallAllFunctionsBool(GameObjectEventBindings, key); -} diff --git a/src/LuaEngine/hooks/GossipHooks.cpp b/src/LuaEngine/hooks/GossipHooks.cpp deleted file mode 100644 index 5fa324516f..0000000000 --- a/src/LuaEngine/hooks/GossipHooks.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* 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 "ALEIncludes.h" -#include "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK(BINDINGS, EVENT, ENTRY) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EntryKey(EVENT, ENTRY);\ - if (!BINDINGS->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -#define START_HOOK_WITH_RETVAL(BINDINGS, EVENT, ENTRY, RETVAL) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return RETVAL;\ - auto key = EntryKey(EVENT, ENTRY);\ - if (!BINDINGS->HasBindingsFor(key))\ - return RETVAL;\ - LOCK_ALE - -bool ALE::OnGossipHello(Player* pPlayer, GameObject* pGameObject) -{ - START_HOOK_WITH_RETVAL(GameObjectGossipBindings, GOSSIP_EVENT_ON_HELLO, pGameObject->GetEntry(), false); - pPlayer->PlayerTalkClass->ClearMenus(); - Push(pPlayer); - Push(pGameObject); - return CallAllFunctionsBool(GameObjectGossipBindings, key, true); -} - -bool ALE::OnGossipSelect(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action) -{ - START_HOOK_WITH_RETVAL(GameObjectGossipBindings, GOSSIP_EVENT_ON_SELECT, pGameObject->GetEntry(), false); - pPlayer->PlayerTalkClass->ClearMenus(); - Push(pPlayer); - Push(pGameObject); - Push(sender); - Push(action); - return CallAllFunctionsBool(GameObjectGossipBindings, key, true); -} - -bool ALE::OnGossipSelectCode(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action, const char* code) -{ - START_HOOK_WITH_RETVAL(GameObjectGossipBindings, GOSSIP_EVENT_ON_SELECT, pGameObject->GetEntry(), false); - pPlayer->PlayerTalkClass->ClearMenus(); - Push(pPlayer); - Push(pGameObject); - Push(sender); - Push(action); - Push(code); - return CallAllFunctionsBool(GameObjectGossipBindings, key, true); -} - -void ALE::HandleGossipSelectOption(Player* pPlayer, uint32 menuId, uint32 sender, uint32 action, const std::string& code) -{ - START_HOOK(PlayerGossipBindings, GOSSIP_EVENT_ON_SELECT, menuId); - pPlayer->PlayerTalkClass->ClearMenus(); - - Push(pPlayer); // receiver - Push(pPlayer); // sender, just not to mess up the amount of args. - Push(sender); - Push(action); - if (code.empty()) - Push(); - else - Push(code); - - CallAllFunctions(PlayerGossipBindings, key); -} - -bool ALE::OnItemGossip(Player* pPlayer, Item* pItem, SpellCastTargets const& /*targets*/) -{ - START_HOOK_WITH_RETVAL(ItemGossipBindings, GOSSIP_EVENT_ON_HELLO, pItem->GetEntry(), true); - pPlayer->PlayerTalkClass->ClearMenus(); - Push(pPlayer); - Push(pItem); - return CallAllFunctionsBool(ItemGossipBindings, key, true); -} - -void ALE::HandleGossipSelectOption(Player* pPlayer, Item* pItem, uint32 sender, uint32 action, const std::string& code) -{ - START_HOOK(ItemGossipBindings, GOSSIP_EVENT_ON_SELECT, pItem->GetEntry()); - pPlayer->PlayerTalkClass->ClearMenus(); - - Push(pPlayer); - Push(pItem); - Push(sender); - Push(action); - if (code.empty()) - Push(); - else - Push(code); - - CallAllFunctions(ItemGossipBindings, key); -} - -bool ALE::OnGossipHello(Player* pPlayer, Creature* pCreature) -{ - START_HOOK_WITH_RETVAL(CreatureGossipBindings, GOSSIP_EVENT_ON_HELLO, pCreature->GetEntry(), false); - pPlayer->PlayerTalkClass->ClearMenus(); - Push(pPlayer); - Push(pCreature); - return CallAllFunctionsBool(CreatureGossipBindings, key, true); -} - -bool ALE::OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action) -{ - START_HOOK_WITH_RETVAL(CreatureGossipBindings, GOSSIP_EVENT_ON_SELECT, pCreature->GetEntry(), false); - auto originalMenu = *pPlayer->PlayerTalkClass; - pPlayer->PlayerTalkClass->ClearMenus(); - Push(pPlayer); - Push(pCreature); - Push(sender); - Push(action); - auto preventDefault = CallAllFunctionsBool(CreatureGossipBindings, key, true); - if (!preventDefault) { - *pPlayer->PlayerTalkClass = originalMenu; - } - return preventDefault; -} - -bool ALE::OnGossipSelectCode(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action, const char* code) -{ - START_HOOK_WITH_RETVAL(CreatureGossipBindings, GOSSIP_EVENT_ON_SELECT, pCreature->GetEntry(), false); - auto originalMenu = *pPlayer->PlayerTalkClass; - pPlayer->PlayerTalkClass->ClearMenus(); - Push(pPlayer); - Push(pCreature); - Push(sender); - Push(action); - Push(code); - auto preventDefault = CallAllFunctionsBool(CreatureGossipBindings, key, true); - if (!preventDefault) { - *pPlayer->PlayerTalkClass = originalMenu; - } - return preventDefault; -} diff --git a/src/LuaEngine/hooks/GroupHooks.cpp b/src/LuaEngine/hooks/GroupHooks.cpp deleted file mode 100644 index aac809d4aa..0000000000 --- a/src/LuaEngine/hooks/GroupHooks.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK(EVENT) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EventKey(EVENT);\ - if (!GroupEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -void ALE::OnAddMember(Group* group, ObjectGuid guid) -{ - START_HOOK(GROUP_EVENT_ON_MEMBER_ADD); - Push(group); - Push(guid); - CallAllFunctions(GroupEventBindings, key); -} - -void ALE::OnInviteMember(Group* group, ObjectGuid guid) -{ - START_HOOK(GROUP_EVENT_ON_MEMBER_INVITE); - Push(group); - Push(guid); - CallAllFunctions(GroupEventBindings, key); -} - -void ALE::OnRemoveMember(Group* group, ObjectGuid guid, uint8 method) -{ - START_HOOK(GROUP_EVENT_ON_MEMBER_REMOVE); - Push(group); - Push(guid); - Push(method); - CallAllFunctions(GroupEventBindings, key); -} - -void ALE::OnChangeLeader(Group* group, ObjectGuid newLeaderGuid, ObjectGuid oldLeaderGuid) -{ - START_HOOK(GROUP_EVENT_ON_LEADER_CHANGE); - Push(group); - Push(newLeaderGuid); - Push(oldLeaderGuid); - CallAllFunctions(GroupEventBindings, key); -} - -void ALE::OnDisband(Group* group) -{ - START_HOOK(GROUP_EVENT_ON_DISBAND); - Push(group); - CallAllFunctions(GroupEventBindings, key); -} - -void ALE::OnCreate(Group* group, ObjectGuid leaderGuid, GroupType groupType) -{ - START_HOOK(GROUP_EVENT_ON_CREATE); - Push(group); - Push(leaderGuid); - Push(groupType); - CallAllFunctions(GroupEventBindings, key); -} diff --git a/src/LuaEngine/hooks/GuildHooks.cpp b/src/LuaEngine/hooks/GuildHooks.cpp deleted file mode 100644 index 8b3adf9a69..0000000000 --- a/src/LuaEngine/hooks/GuildHooks.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK(EVENT) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EventKey(EVENT);\ - if (!GuildEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -void ALE::OnAddMember(Guild* guild, Player* player, uint32 plRank) -{ - START_HOOK(GUILD_EVENT_ON_ADD_MEMBER); - Push(guild); - Push(player); - Push(plRank); - CallAllFunctions(GuildEventBindings, key); -} - -void ALE::OnRemoveMember(Guild* guild, Player* player, bool isDisbanding) -{ - START_HOOK(GUILD_EVENT_ON_REMOVE_MEMBER); - Push(guild); - Push(player); - Push(isDisbanding); - CallAllFunctions(GuildEventBindings, key); -} - -void ALE::OnMOTDChanged(Guild* guild, const std::string& newMotd) -{ - START_HOOK(GUILD_EVENT_ON_MOTD_CHANGE); - Push(guild); - Push(newMotd); - CallAllFunctions(GuildEventBindings, key); -} - -void ALE::OnInfoChanged(Guild* guild, const std::string& newInfo) -{ - START_HOOK(GUILD_EVENT_ON_INFO_CHANGE); - Push(guild); - Push(newInfo); - CallAllFunctions(GuildEventBindings, key); -} - -void ALE::OnCreate(Guild* guild, Player* leader, const std::string& name) -{ - START_HOOK(GUILD_EVENT_ON_CREATE); - Push(guild); - Push(leader); - Push(name); - CallAllFunctions(GuildEventBindings, key); -} - -void ALE::OnDisband(Guild* guild) -{ - START_HOOK(GUILD_EVENT_ON_DISBAND); - Push(guild); - CallAllFunctions(GuildEventBindings, key); -} - -void ALE::OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, bool isRepair) -{ - START_HOOK(GUILD_EVENT_ON_MONEY_WITHDRAW); - Push(guild); - Push(player); - Push(amount); - Push(isRepair); // isRepair not a part of Mangos, implement? - int amountIndex = lua_gettop(L) - 1; - int n = SetupStack(GuildEventBindings, key, 4); - - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - - if (lua_isnumber(L, r)) - { - amount = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(amount, amountIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); -} - -void ALE::OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount) -{ - START_HOOK(GUILD_EVENT_ON_MONEY_DEPOSIT); - Push(guild); - Push(player); - Push(amount); - int amountIndex = lua_gettop(L); - int n = SetupStack(GuildEventBindings, key, 3); - - while (n > 0) - { - int r = CallOneFunction(n--, 3, 1); - - if (lua_isnumber(L, r)) - { - amount = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(amount, amountIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(3); -} - -void ALE::OnItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId, - bool isDestBank, uint8 destContainer, uint8 destSlotId) -{ - START_HOOK(GUILD_EVENT_ON_ITEM_MOVE); - Push(guild); - Push(player); - Push(pItem); - Push(isSrcBank); - Push(srcContainer); - Push(srcSlotId); - Push(isDestBank); - Push(destContainer); - Push(destSlotId); - CallAllFunctions(GuildEventBindings, key); -} - -void ALE::OnEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank) -{ - START_HOOK(GUILD_EVENT_ON_EVENT); - Push(guild); - Push(eventType); - Push(playerGuid1); - Push(playerGuid2); - Push(newRank); - CallAllFunctions(GuildEventBindings, key); -} - -void ALE::OnBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) -{ - START_HOOK(GUILD_EVENT_ON_BANK_EVENT); - Push(guild); - Push(eventType); - Push(tabId); - Push(playerGuid); - Push(itemOrMoney); - Push(itemStackCount); - Push(destTabId); - CallAllFunctions(GuildEventBindings, key); -} diff --git a/src/LuaEngine/hooks/InstanceHooks.cpp b/src/LuaEngine/hooks/InstanceHooks.cpp deleted file mode 100644 index 113ca2b348..0000000000 --- a/src/LuaEngine/hooks/InstanceHooks.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALEIncludes.h" -#include "ALETemplate.h" -#include "ALEInstanceAI.h" - -using namespace Hooks; - -#define START_HOOK(EVENT, AI) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto mapKey = EntryKey(EVENT, AI->instance->GetId());\ - auto instanceKey = EntryKey(EVENT, AI->instance->GetInstanceId());\ - if (!MapEventBindings->HasBindingsFor(mapKey) && !InstanceEventBindings->HasBindingsFor(instanceKey))\ - return;\ - LOCK_ALE;\ - PushInstanceData(L, AI);\ - Push(AI->instance) - -#define START_HOOK_WITH_RETVAL(EVENT, AI, RETVAL) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return RETVAL;\ - auto mapKey = EntryKey(EVENT, AI->instance->GetId());\ - auto instanceKey = EntryKey(EVENT, AI->instance->GetInstanceId());\ - if (!MapEventBindings->HasBindingsFor(mapKey) && !InstanceEventBindings->HasBindingsFor(instanceKey))\ - return RETVAL;\ - LOCK_ALE;\ - PushInstanceData(L, AI);\ - Push(AI->instance) - -void ALE::OnInitialize(ALEInstanceAI* ai) -{ - START_HOOK(INSTANCE_EVENT_ON_INITIALIZE, ai); - CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); -} - -void ALE::OnLoad(ALEInstanceAI* ai) -{ - START_HOOK(INSTANCE_EVENT_ON_LOAD, ai); - CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); -} - -void ALE::OnUpdateInstance(ALEInstanceAI* ai, uint32 diff) -{ - START_HOOK(INSTANCE_EVENT_ON_UPDATE, ai); - Push(diff); - CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); -} - -void ALE::OnPlayerEnterInstance(ALEInstanceAI* ai, Player* player) -{ - START_HOOK(INSTANCE_EVENT_ON_PLAYER_ENTER, ai); - Push(player); - CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); -} - -void ALE::OnCreatureCreate(ALEInstanceAI* ai, Creature* creature) -{ - START_HOOK(INSTANCE_EVENT_ON_CREATURE_CREATE, ai); - Push(creature); - CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); -} - -void ALE::OnGameObjectCreate(ALEInstanceAI* ai, GameObject* gameobject) -{ - START_HOOK(INSTANCE_EVENT_ON_GAMEOBJECT_CREATE, ai); - Push(gameobject); - CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); -} - -bool ALE::OnCheckEncounterInProgress(ALEInstanceAI* ai) -{ - START_HOOK_WITH_RETVAL(INSTANCE_EVENT_ON_CHECK_ENCOUNTER_IN_PROGRESS, ai, false); - return CallAllFunctionsBool(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); -} diff --git a/src/LuaEngine/hooks/ItemHooks.cpp b/src/LuaEngine/hooks/ItemHooks.cpp deleted file mode 100644 index 9bc347480c..0000000000 --- a/src/LuaEngine/hooks/ItemHooks.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALEIncludes.h" -#include "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK(EVENT, ENTRY) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EntryKey(EVENT, ENTRY);\ - if (!ItemEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -#define START_HOOK_WITH_RETVAL(EVENT, ENTRY, RETVAL) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return RETVAL;\ - auto key = EntryKey(EVENT, ENTRY);\ - if (!ItemEventBindings->HasBindingsFor(key))\ - return RETVAL;\ - LOCK_ALE - -void ALE::OnDummyEffect(WorldObject* pCaster, uint32 spellId, SpellEffIndex effIndex, Item* pTarget) -{ - START_HOOK(ITEM_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry()); - Push(pCaster); - Push(spellId); - Push(effIndex); - Push(pTarget); - CallAllFunctions(ItemEventBindings, key); -} - -bool ALE::OnQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest) -{ - START_HOOK_WITH_RETVAL(ITEM_EVENT_ON_QUEST_ACCEPT, pItem->GetEntry(), false); - Push(pPlayer); - Push(pItem); - Push(pQuest); - return CallAllFunctionsBool(ItemEventBindings, key); -} - -bool ALE::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) -{ - ObjectGuid guid = pItem->GET_GUID(); - bool castSpell = true; - - if (!OnItemUse(pPlayer, pItem, targets)) - castSpell = false; - - pItem = pPlayer->GetItemByGuid(guid); - if (pItem) - { - if (!OnItemGossip(pPlayer, pItem, targets)) - castSpell = false; - pItem = pPlayer->GetItemByGuid(guid); - } - - if (pItem && castSpell) - return true; - - // Send equip error that shows no message - // This is a hack fix to stop spell casting visual bug when a spell is not cast on use - WorldPacket data(SMSG_INVENTORY_CHANGE_FAILURE, 18); - data << uint8(59); // EQUIP_ERR_NONE / EQUIP_ERR_CANT_BE_DISENCHANTED - data << guid; - data << ObjectGuid(uint64(0)); - data << uint8(0); - pPlayer->GetSession()->SendPacket(&data); - return false; -} - -bool ALE::OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) -{ - START_HOOK_WITH_RETVAL(ITEM_EVENT_ON_USE, pItem->GetEntry(), true); - Push(pPlayer); - Push(pItem); - - if (GameObject* target = targets.GetGOTarget()) - Push(target); - else if (Item* target = targets.GetItemTarget()) - Push(target); - else if (Corpse* target = targets.GetCorpseTarget()) - Push(target); - else if (Unit* target = targets.GetUnitTarget()) - Push(target); - else if (WorldObject* target = targets.GetObjectTarget()) - Push(target); - else - Push(); - - return CallAllFunctionsBool(ItemEventBindings, key, true); -} - -bool ALE::OnExpire(Player* pPlayer, ItemTemplate const* pProto) -{ - START_HOOK_WITH_RETVAL(ITEM_EVENT_ON_EXPIRE, pProto->ItemId, false); - Push(pPlayer); - Push(pProto->ItemId); - return CallAllFunctionsBool(ItemEventBindings, key); -} - -bool ALE::OnRemove(Player* pPlayer, Item* pItem) -{ - START_HOOK_WITH_RETVAL(ITEM_EVENT_ON_REMOVE, pItem->GetEntry(), false); - Push(pPlayer); - Push(pItem); - return CallAllFunctionsBool(ItemEventBindings, key); -} diff --git a/src/LuaEngine/hooks/PacketHooks.cpp b/src/LuaEngine/hooks/PacketHooks.cpp deleted file mode 100644 index db9ca3474e..0000000000 --- a/src/LuaEngine/hooks/PacketHooks.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALEIncludes.h" -#include "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK_SERVER(EVENT) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EventKey(EVENT);\ - if (!ServerEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -#define START_HOOK_PACKET(EVENT, OPCODE) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EntryKey(EVENT, OPCODE);\ - if (!PacketEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -bool ALE::OnPacketSend(WorldSession* session, const WorldPacket& packet) -{ - bool result = true; - Player* player = NULL; - if (session) - player = session->GetPlayer(); - OnPacketSendAny(player, packet, result); - OnPacketSendOne(player, packet, result); - return result; -} -void ALE::OnPacketSendAny(Player* player, const WorldPacket& packet, bool& result) -{ - START_HOOK_SERVER(SERVER_EVENT_ON_PACKET_SEND); - Push(new WorldPacket(packet)); - Push(player); - int n = SetupStack(ServerEventBindings, key, 2); - - while (n > 0) - { - int r = CallOneFunction(n--, 2, 1); - - if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) - result = false; - - lua_pop(L, 1); - } - - CleanUpStack(2); -} - -void ALE::OnPacketSendOne(Player* player, const WorldPacket& packet, bool& result) -{ - START_HOOK_PACKET(PACKET_EVENT_ON_PACKET_SEND, packet.GetOpcode()); - Push(new WorldPacket(packet)); - Push(player); - int n = SetupStack(PacketEventBindings, key, 2); - - while (n > 0) - { - int r = CallOneFunction(n--, 2, 1); - - if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) - result = false; - - lua_pop(L, 1); - } - - CleanUpStack(2); -} - -bool ALE::OnPacketReceive(WorldSession* session, WorldPacket& packet) -{ - bool result = true; - Player* player = NULL; - if (session) - player = session->GetPlayer(); - OnPacketReceiveAny(player, packet, result); - OnPacketReceiveOne(player, packet, result); - return result; -} - -void ALE::OnPacketReceiveAny(Player* player, WorldPacket& packet, bool& result) -{ - START_HOOK_SERVER(SERVER_EVENT_ON_PACKET_RECEIVE); - Push(new WorldPacket(packet)); - Push(player); - int n = SetupStack(ServerEventBindings, key, 2); - - while (n > 0) - { - int r = CallOneFunction(n--, 2, 2); - - if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) - result = false; - - if (lua_isuserdata(L, r + 1)) - if (WorldPacket* data = CHECKOBJ(L, r + 1, false)) - packet = *data; - - lua_pop(L, 2); - } - - CleanUpStack(2); -} - -void ALE::OnPacketReceiveOne(Player* player, WorldPacket& packet, bool& result) -{ - START_HOOK_PACKET(PACKET_EVENT_ON_PACKET_RECEIVE, packet.GetOpcode()); - Push(new WorldPacket(packet)); - Push(player); - int n = SetupStack(PacketEventBindings, key, 2); - - while (n > 0) - { - int r = CallOneFunction(n--, 2, 2); - - if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) - result = false; - - if (lua_isuserdata(L, r + 1)) - if (WorldPacket* data = CHECKOBJ(L, r + 1, false)) - packet = *data; - - lua_pop(L, 2); - } - - CleanUpStack(2); -} diff --git a/src/LuaEngine/hooks/PlayerHooks.cpp b/src/LuaEngine/hooks/PlayerHooks.cpp deleted file mode 100644 index 5ad27f8b32..0000000000 --- a/src/LuaEngine/hooks/PlayerHooks.cpp +++ /dev/null @@ -1,969 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALEIncludes.h" -#include "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK(EVENT) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EventKey(EVENT);\ - if (!PlayerEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -#define START_HOOK_WITH_RETVAL(EVENT, RETVAL) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return RETVAL;\ - auto key = EventKey(EVENT);\ - if (!PlayerEventBindings->HasBindingsFor(key))\ - return RETVAL;\ - LOCK_ALE - -void ALE::OnLearnTalents(Player* pPlayer, uint32 talentId, uint32 talentRank, uint32 spellid) -{ - START_HOOK(PLAYER_EVENT_ON_LEARN_TALENTS); - Push(pPlayer); - Push(talentId); - Push(talentRank); - Push(spellid); - CallAllFunctions(PlayerEventBindings, key); -} - -bool ALE::OnCommand(ChatHandler& handler, const char* text) -{ - Player* player = handler.IsConsole() ? nullptr : handler.GetSession()->GetPlayer(); - // If from console, player is NULL - if (!player || player->GetSession()->GetSecurity() >= SEC_ADMINISTRATOR) - { - std::string reload = text; - std::transform(reload.begin(), reload.end(), reload.begin(), ::tolower); - if (reload.find("reload ale") == 0) - { - ReloadALE(); - return false; - } - } - - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_COMMAND, true); - Push(player); - Push(text); - Push(&handler); - return CallAllFunctionsBool(PlayerEventBindings, key, true); -} - -void ALE::OnLootItem(Player* pPlayer, Item* pItem, uint32 count, ObjectGuid guid) -{ - START_HOOK(PLAYER_EVENT_ON_LOOT_ITEM); - Push(pPlayer); - Push(pItem); - Push(count); - Push(guid); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnLootMoney(Player* pPlayer, uint32 amount) -{ - START_HOOK(PLAYER_EVENT_ON_LOOT_MONEY); - Push(pPlayer); - Push(amount); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnFirstLogin(Player* pPlayer) -{ - START_HOOK(PLAYER_EVENT_ON_FIRST_LOGIN); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnRepop(Player* pPlayer) -{ - START_HOOK(PLAYER_EVENT_ON_REPOP); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnResurrect(Player* pPlayer) -{ - START_HOOK(PLAYER_EVENT_ON_RESURRECT); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnQuestAbandon(Player* pPlayer, uint32 questId) -{ - START_HOOK(PLAYER_EVENT_ON_QUEST_ABANDON); - Push(pPlayer); - Push(questId); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnEquip(Player* pPlayer, Item* pItem, uint8 bag, uint8 slot) -{ - START_HOOK(PLAYER_EVENT_ON_EQUIP); - Push(pPlayer); - Push(pItem); - Push(bag); - Push(slot); - CallAllFunctions(PlayerEventBindings, key); -} - -InventoryResult ALE::OnCanUseItem(const Player* pPlayer, uint32 itemEntry) -{ - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CAN_USE_ITEM, EQUIP_ERR_OK); - InventoryResult result = EQUIP_ERR_OK; - Push(pPlayer); - Push(itemEntry); - int n = SetupStack(PlayerEventBindings, key, 2); - - while (n > 0) - { - int r = CallOneFunction(n--, 2, 1); - - if (lua_isnumber(L, r)) - result = (InventoryResult)CHECKVAL(L, r); - - lua_pop(L, 1); - } - - CleanUpStack(2); - return result; -} -void ALE::OnPlayerEnterCombat(Player* pPlayer, Unit* pEnemy) -{ - START_HOOK(PLAYER_EVENT_ON_ENTER_COMBAT); - Push(pPlayer); - Push(pEnemy); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnPlayerLeaveCombat(Player* pPlayer) -{ - START_HOOK(PLAYER_EVENT_ON_LEAVE_COMBAT); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnPVPKill(Player* pKiller, Player* pKilled) -{ - START_HOOK(PLAYER_EVENT_ON_KILL_PLAYER); - Push(pKiller); - Push(pKilled); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnCreatureKill(Player* pKiller, Creature* pKilled) -{ - START_HOOK(PLAYER_EVENT_ON_KILL_CREATURE); - Push(pKiller); - Push(pKilled); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnPlayerKilledByCreature(Creature* pKiller, Player* pKilled) -{ - START_HOOK(PLAYER_EVENT_ON_KILLED_BY_CREATURE); - Push(pKiller); - Push(pKilled); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnLevelChanged(Player* pPlayer, uint8 oldLevel) -{ - START_HOOK(PLAYER_EVENT_ON_LEVEL_CHANGE); - Push(pPlayer); - Push(oldLevel); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnFreeTalentPointsChanged(Player* pPlayer, uint32 newPoints) -{ - START_HOOK(PLAYER_EVENT_ON_TALENTS_CHANGE); - Push(pPlayer); - Push(newPoints); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnTalentsReset(Player* pPlayer, bool noCost) -{ - START_HOOK(PLAYER_EVENT_ON_TALENTS_RESET); - Push(pPlayer); - Push(noCost); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnMoneyChanged(Player* pPlayer, int32& amount) -{ - START_HOOK(PLAYER_EVENT_ON_MONEY_CHANGE); - Push(pPlayer); - Push(amount); - int amountIndex = lua_gettop(L); - int n = SetupStack(PlayerEventBindings, key, 2); - - while (n > 0) - { - int r = CallOneFunction(n--, 2, 1); - - if (lua_isnumber(L, r)) - { - amount = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(amount, amountIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(2); -} - -void ALE::OnGiveXP(Player* pPlayer, uint32& amount, Unit* pVictim, uint8 xpSource) -{ - START_HOOK(PLAYER_EVENT_ON_GIVE_XP); - Push(pPlayer); - Push(amount); - Push(pVictim); - Push(xpSource); - int amountIndex = lua_gettop(L) - 1; - int n = SetupStack(PlayerEventBindings, key, 4); - - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - - if (lua_isnumber(L, r)) - { - amount = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(amount, amountIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); -} - -bool ALE::OnReputationChange(Player* pPlayer, uint32 factionID, int32& standing, bool incremental) -{ - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_REPUTATION_CHANGE, true); - bool result = true; - Push(pPlayer); - Push(factionID); - Push(standing); - Push(incremental); - int standingIndex = lua_gettop(L) - 1; - int n = SetupStack(PlayerEventBindings, key, 4); - - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - - if (lua_isnumber(L, r)) - { - standing = CHECKVAL(L, r); - if (standing == -1) - result = false; - // Update the stack for subsequent calls. - ReplaceArgument(standing, standingIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); - return result; -} - -void ALE::OnDuelRequest(Player* pTarget, Player* pChallenger) -{ - START_HOOK(PLAYER_EVENT_ON_DUEL_REQUEST); - Push(pTarget); - Push(pChallenger); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnDuelStart(Player* pStarter, Player* pChallenger) -{ - START_HOOK(PLAYER_EVENT_ON_DUEL_START); - Push(pStarter); - Push(pChallenger); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnDuelEnd(Player* pWinner, Player* pLoser, DuelCompleteType type) -{ - START_HOOK(PLAYER_EVENT_ON_DUEL_END); - Push(pWinner); - Push(pLoser); - Push(type); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnEmote(Player* pPlayer, uint32 emote) -{ - START_HOOK(PLAYER_EVENT_ON_EMOTE); - Push(pPlayer); - Push(emote); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnTextEmote(Player* pPlayer, uint32 textEmote, uint32 emoteNum, ObjectGuid guid) -{ - START_HOOK(PLAYER_EVENT_ON_TEXT_EMOTE); - Push(pPlayer); - Push(textEmote); - Push(emoteNum); - Push(guid); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnPlayerSpellCast(Player* pPlayer, Spell* pSpell, bool skipCheck) -{ - START_HOOK(PLAYER_EVENT_ON_SPELL_CAST); - Push(pPlayer); - Push(pSpell); - Push(skipCheck); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnLogin(Player* pPlayer) -{ - START_HOOK(PLAYER_EVENT_ON_LOGIN); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnLogout(Player* pPlayer) -{ - START_HOOK(PLAYER_EVENT_ON_LOGOUT); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnCreate(Player* pPlayer) -{ - START_HOOK(PLAYER_EVENT_ON_CHARACTER_CREATE); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnDelete(uint32 guidlow) -{ - START_HOOK(PLAYER_EVENT_ON_CHARACTER_DELETE); - Push(guidlow); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnSave(Player* pPlayer) -{ - START_HOOK(PLAYER_EVENT_ON_SAVE); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnBindToInstance(Player* pPlayer, Difficulty difficulty, uint32 mapid, bool permanent) -{ - START_HOOK(PLAYER_EVENT_ON_BIND_TO_INSTANCE); - Push(pPlayer); - Push(difficulty); - Push(mapid); - Push(permanent); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnUpdateArea(Player* pPlayer, uint32 oldArea, uint32 newArea) -{ - START_HOOK(PLAYER_EVENT_ON_UPDATE_AREA); - Push(pPlayer); - Push(oldArea); - Push(newArea); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnUpdateZone(Player* pPlayer, uint32 newZone, uint32 newArea) -{ - START_HOOK(PLAYER_EVENT_ON_UPDATE_ZONE); - Push(pPlayer); - Push(newZone); - Push(newArea); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnMapChanged(Player* player) -{ - START_HOOK(PLAYER_EVENT_ON_MAP_CHANGE); - Push(player); - CallAllFunctions(PlayerEventBindings, key); -} - -bool ALE::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg) -{ - if (lang == LANG_ADDON) - return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, NULL); - - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CHAT, true); - bool result = true; - Push(pPlayer); - Push(msg); - Push(type); - Push(lang); - int n = SetupStack(PlayerEventBindings, key, 4); - - while (n > 0) - { - int r = CallOneFunction(n--, 4, 2); - - if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) - result = false; - - if (lua_isstring(L, r + 1)) - msg = std::string(lua_tostring(L, r + 1)); - - lua_pop(L, 2); - } - - CleanUpStack(4); - return result; -} - -bool ALE::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Group* pGroup) -{ - if (lang == LANG_ADDON) - return OnAddonMessage(pPlayer, type, msg, NULL, NULL, pGroup, NULL); - - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_GROUP_CHAT, true); - bool result = true; - Push(pPlayer); - Push(msg); - Push(type); - Push(lang); - Push(pGroup); - int n = SetupStack(PlayerEventBindings, key, 5); - - while (n > 0) - { - int r = CallOneFunction(n--, 5, 2); - - if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) - result = false; - - if (lua_isstring(L, r + 1)) - msg = std::string(lua_tostring(L, r + 1)); - - lua_pop(L, 2); - } - - CleanUpStack(5); - return result; -} - -bool ALE::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Guild* pGuild) -{ - if (lang == LANG_ADDON) - return OnAddonMessage(pPlayer, type, msg, NULL, pGuild, NULL, NULL); - - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_GUILD_CHAT, true); - bool result = true; - Push(pPlayer); - Push(msg); - Push(type); - Push(lang); - Push(pGuild); - int n = SetupStack(PlayerEventBindings, key, 5); - - while (n > 0) - { - int r = CallOneFunction(n--, 5, 2); - - if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) - result = false; - - if (lua_isstring(L, r + 1)) - msg = std::string(lua_tostring(L, r + 1)); - - lua_pop(L, 2); - } - - CleanUpStack(5); - return result; -} - -bool ALE::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Channel* pChannel) -{ - if (lang == LANG_ADDON) - return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, pChannel); - - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CHANNEL_CHAT, true); - bool result = true; - Push(pPlayer); - Push(msg); - Push(type); - Push(lang); - Push(pChannel->IsConstant() ? static_cast(pChannel->GetChannelId()) : -static_cast(pChannel->GetChannelDBId())); - int n = SetupStack(PlayerEventBindings, key, 5); - - while (n > 0) - { - int r = CallOneFunction(n--, 5, 2); - - if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) - result = false; - - if (lua_isstring(L, r + 1)) - msg = std::string(lua_tostring(L, r + 1)); - - lua_pop(L, 2); - } - - CleanUpStack(5); - return result; -} - -bool ALE::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Player* pReceiver) -{ - if (lang == LANG_ADDON) - return OnAddonMessage(pPlayer, type, msg, pReceiver, NULL, NULL, NULL); - - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_WHISPER, true); - bool result = true; - Push(pPlayer); - Push(msg); - Push(type); - Push(lang); - Push(pReceiver); - int n = SetupStack(PlayerEventBindings, key, 5); - - while (n > 0) - { - int r = CallOneFunction(n--, 5, 2); - - if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) - result = false; - - if (lua_isstring(L, r + 1)) - msg = std::string(lua_tostring(L, r + 1)); - - lua_pop(L, 2); - } - - CleanUpStack(5); - return result; -} - -void ALE::OnPetAddedToWorld(Player* player, Creature* pet) -{ - START_HOOK(PLAYER_EVENT_ON_PET_ADDED_TO_WORLD); - Push(player); - Push(pet); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnLearnSpell(Player* player, uint32 spellId) -{ - START_HOOK(PLAYER_EVENT_ON_LEARN_SPELL); - Push(player); - Push(spellId); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnAchiComplete(Player* player, AchievementEntry const* achievement) -{ - START_HOOK(PLAYER_EVENT_ON_ACHIEVEMENT_COMPLETE); - Push(player); - Push(achievement); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnFfaPvpStateUpdate(Player* player, bool hasFfaPvp) -{ - START_HOOK(PLAYER_EVENT_ON_FFAPVP_CHANGE); - Push(player); - Push(hasFfaPvp); - CallAllFunctions(PlayerEventBindings, key); -} - -bool ALE::OnCanInitTrade(Player* player, Player* target) -{ - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CAN_INIT_TRADE, true); - Push(player); - Push(target); - return CallAllFunctionsBool(PlayerEventBindings, key); -} - -bool ALE::OnCanSendMail(Player* player, ObjectGuid receiverGuid, ObjectGuid mailbox, std::string& subject, std::string& body, uint32 money, uint32 cod, Item* item) -{ - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CAN_SEND_MAIL, true); - Push(player); - Push(receiverGuid); - Push(mailbox); - Push(subject); - Push(body); - Push(money); - Push(cod); - Push(item); - return CallAllFunctionsBool(PlayerEventBindings, key); -} - -bool ALE::OnCanJoinLfg(Player* player, uint8 roles, lfg::LfgDungeonSet& dungeons, const std::string& comment) -{ - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CAN_JOIN_LFG, true); - Push(player); - Push(roles); - - lua_newtable(L); - int table = lua_gettop(L); - uint32 counter = 1; - for (uint32 dungeon : dungeons) - { - ALE::Push(L, dungeon); - lua_rawseti(L, table, counter); - ++counter; - } - lua_settop(L, table); - ++push_counter; - - Push(comment); - return CallAllFunctionsBool(PlayerEventBindings, key); -} - -void ALE::OnQuestRewardItem(Player* player, Item* item, uint32 count) -{ - START_HOOK(PLAYER_EVENT_ON_QUEST_REWARD_ITEM); - Push(player); - Push(item); - Push(count); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnCreateItem(Player* player, Item* item, uint32 count) -{ - START_HOOK(PLAYER_EVENT_ON_CREATE_ITEM); - Push(player); - Push(item); - Push(count); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnStoreNewItem(Player* player, Item* item, uint32 count) -{ - START_HOOK(PLAYER_EVENT_ON_STORE_NEW_ITEM); - Push(player); - Push(item); - Push(count); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnPlayerCompleteQuest(Player* player, Quest const* quest) -{ - START_HOOK(PLAYER_EVENT_ON_COMPLETE_QUEST); - Push(player); - Push(quest); - CallAllFunctions(PlayerEventBindings, key); -} - -bool ALE::OnCanGroupInvite(Player* player, std::string& memberName) -{ - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CAN_GROUP_INVITE, true); - Push(player); - Push(memberName); - return CallAllFunctionsBool(PlayerEventBindings, key); -} - -void ALE::OnGroupRollRewardItem(Player* player, Item* item, uint32 count, RollVote voteType, Roll* roll) -{ - START_HOOK(PLAYER_EVENT_ON_GROUP_ROLL_REWARD_ITEM); - Push(player); - Push(item); - Push(count); - Push(voteType); - Push(roll); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnBattlegroundDesertion(Player* player, const BattlegroundDesertionType type) -{ - START_HOOK(PLAYER_EVENT_ON_BG_DESERTION); - Push(player); - Push(type); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnCreatureKilledByPet(Player* player, Creature* killed) -{ - START_HOOK(PLAYER_EVENT_ON_PET_KILL); - Push(player); - Push(killed); - CallAllFunctions(PlayerEventBindings, key); -} - -bool ALE::OnPlayerCanUpdateSkill(Player* player, uint32 skill_id) -{ - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CAN_UPDATE_SKILL, true); - Push(player); - Push(skill_id); - return CallAllFunctionsBool(PlayerEventBindings, key); -} - -void ALE::OnPlayerBeforeUpdateSkill(Player* player, uint32 skill_id, uint32& value, uint32 max, uint32 step) -{ - START_HOOK(PLAYER_EVENT_ON_BEFORE_UPDATE_SKILL); - Push(player); - Push(skill_id); - Push(value); - Push(max); - Push(step); - - int valueIndex = lua_gettop(L) -2; - int n = SetupStack(PlayerEventBindings, key, 5); - while (n > 0) - { - int r = CallOneFunction(n--, 5, 1); - if (lua_isnumber(L, r)) - { - value = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(value, valueIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(5); -} - -void ALE::OnPlayerUpdateSkill(Player* player, uint32 skill_id, uint32 value, uint32 max, uint32 step, uint32 new_value) -{ - START_HOOK(PLAYER_EVENT_ON_UPDATE_SKILL); - Push(player); - Push(skill_id); - Push(value); - Push(max); - Push(step); - Push(new_value); - CallAllFunctions(PlayerEventBindings, key); -} - -bool ALE::CanPlayerResurrect(Player* player) -{ - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CAN_RESURRECT, true); - Push(player); - return CallAllFunctionsBool(PlayerEventBindings, key); -} - -void ALE::OnPlayerQuestAccept(Player* player, Quest const* quest) -{ - START_HOOK(PLAYER_EVENT_ON_QUEST_ACCEPT); - Push(player); - Push(quest); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnPlayerAuraApply(Player* player, Aura* aura) -{ - START_HOOK(PLAYER_EVENT_ON_AURA_APPLY); - Push(player); - Push(aura); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnPlayerHeal(Player* player, Unit* target, uint32& gain) -{ - START_HOOK(PLAYER_EVENT_ON_HEAL); - Push(player); - Push(target); - Push(gain); - - int gainIndex = lua_gettop(L); - int n = SetupStack(PlayerEventBindings, key, 3); - while (n > 0) - { - int r = CallOneFunction(n--, 3, 1); - if (lua_isnumber(L, r)) - { - gain = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(gain, gainIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(3); -} - -void ALE::OnPlayerDamage(Player* player, Unit* target, uint32& damage) -{ - START_HOOK(PLAYER_EVENT_ON_DAMAGE); - Push(player); - Push(target); - Push(damage); - - int damageIndex = lua_gettop(L); - int n = SetupStack(PlayerEventBindings, key, 3); - while (n > 0) - { - int r = CallOneFunction(n--, 3, 1); - if (lua_isnumber(L, r)) - { - damage = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(damage, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(3); -} - -void ALE::OnPlayerAuraRemove(Player* player, Aura* aura, AuraRemoveMode mode) -{ - START_HOOK(PLAYER_EVENT_ON_AURA_REMOVE); - Push(player); - Push(aura); - Push(mode); - CallAllFunctions(PlayerEventBindings, key); -} - -void ALE::OnPlayerModifyPeriodicDamageAurasTick(Player* player, Unit* target, uint32& damage, SpellInfo const* spellInfo) -{ - START_HOOK(PLAYER_EVENT_ON_MODIFY_PERIODIC_DAMAGE_AURAS_TICK); - Push(player); - Push(target); - Push(damage); - Push(spellInfo); - - int damageIndex = lua_gettop(L) - 1; - int n = SetupStack(PlayerEventBindings, key, 4); - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - if (lua_isnumber(L, r)) - { - damage = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(damage, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); -} - -void ALE::OnPlayerModifyMeleeDamage(Player* player, Unit* target, uint32& damage) -{ - START_HOOK(PLAYER_EVENT_ON_MODIFY_MELEE_DAMAGE); - Push(player); - Push(target); - Push(damage); - - int damageIndex = lua_gettop(L); - int n = SetupStack(PlayerEventBindings, key, 3); - while (n > 0) - { - int r = CallOneFunction(n--, 3, 1); - if (lua_isnumber(L, r)) - { - damage = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(damage, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(3); -} - -void ALE::OnPlayerModifySpellDamageTaken(Player* player, Unit* target, int32& damage, SpellInfo const* spellInfo) -{ - START_HOOK(PLAYER_EVENT_ON_MODIFY_SPELL_DAMAGE_TAKEN); - Push(player); - Push(target); - Push(damage); - Push(spellInfo); - - int damageIndex = lua_gettop(L) - 1; - int n = SetupStack(PlayerEventBindings, key, 4); - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - if (lua_isnumber(L, r)) - { - damage = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(damage, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); -} - -void ALE::OnPlayerModifyHealReceived(Player* player, Unit* target, uint32& heal, SpellInfo const* spellInfo) -{ - START_HOOK(PLAYER_EVENT_ON_MODIFY_HEAL_RECEIVED); - Push(player); - Push(target); - Push(heal); - Push(spellInfo); - - int healIndex = lua_gettop(L) - 1; - int n = SetupStack(PlayerEventBindings, key, 4); - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - if (lua_isnumber(L, r)) - { - heal = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(heal, healIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); -} - -uint32 ALE::OnPlayerDealDamage(Player* player, Unit* target, uint32 damage, DamageEffectType damagetype) -{ - START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_DEAL_DAMAGE, damage); - Push(player); - Push(target); - Push(damage); - Push(damagetype); - int damageIndex = lua_gettop(L) - 1; - int n = SetupStack(PlayerEventBindings, key, 4); - - uint32 result = damage; - while (n > 0) - { - int r = CallOneFunction(n--, 4, 1); - - if (lua_isnumber(L, r)) - { - result = CHECKVAL(L, r); - // Update the stack for subsequent calls. - ReplaceArgument(result, damageIndex); - } - - lua_pop(L, 1); - } - - CleanUpStack(4); - return result; -} diff --git a/src/LuaEngine/hooks/ServerHooks.cpp b/src/LuaEngine/hooks/ServerHooks.cpp deleted file mode 100644 index f305c97b7e..0000000000 --- a/src/LuaEngine/hooks/ServerHooks.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALEEventMgr.h" -#include "ALEIncludes.h" -#include "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK(EVENT) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EventKey(EVENT);\ - if (!ServerEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -#define START_HOOK_WITH_RETVAL(EVENT, RETVAL) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return RETVAL;\ - auto key = EventKey(EVENT);\ - if (!ServerEventBindings->HasBindingsFor(key))\ - return RETVAL;\ - LOCK_ALE - -bool ALE::OnAddonMessage(Player* sender, uint32 type, std::string& msg, Player* receiver, Guild* guild, Group* group, Channel* channel) -{ - START_HOOK_WITH_RETVAL(ADDON_EVENT_ON_MESSAGE, true); - Push(sender); - Push(type); - - auto delimeter_position = msg.find('\t'); - if (delimeter_position == std::string::npos) - { - Push(msg); // prefix - Push(); // msg - } - else - { - std::string prefix = msg.substr(0, delimeter_position); - std::string content = msg.substr(delimeter_position + 1, std::string::npos); - Push(prefix); - Push(content); - } - - if (receiver) - Push(receiver); - else if (guild) - Push(guild); - else if (group) - Push(group); - else if (channel) - Push(channel->GetChannelId()); - else - Push(); - - return CallAllFunctionsBool(ServerEventBindings, key, true); -} - -void ALE::OnTimedEvent(int funcRef, uint32 delay, uint32 calls, WorldObject* obj) -{ - LOCK_ALE; - ASSERT(!event_level); - - // Get function - lua_rawgeti(L, LUA_REGISTRYINDEX, funcRef); - - // Push parameters - Push(L, funcRef); - Push(L, delay); - Push(L, calls); - Push(L, obj); - - // Call function - ExecuteCall(4, 0); - - ASSERT(!event_level); - InvalidateObjects(); -} - -void ALE::OnGameEventStart(uint32 eventid) -{ - START_HOOK(GAME_EVENT_START); - Push(eventid); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnGameEventStop(uint32 eventid) -{ - START_HOOK(GAME_EVENT_STOP); - Push(eventid); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnLuaStateClose() -{ - START_HOOK(ALE_EVENT_ON_LUA_STATE_CLOSE); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnLuaStateOpen() -{ - START_HOOK(ALE_EVENT_ON_LUA_STATE_OPEN); - CallAllFunctions(ServerEventBindings, key); -} - -// AreaTrigger -bool ALE::OnAreaTrigger(Player* pPlayer, AreaTriggerEntry const* pTrigger) -{ - START_HOOK_WITH_RETVAL(TRIGGER_EVENT_ON_TRIGGER, false); - Push(pPlayer); - Push(pTrigger->entry); - - return CallAllFunctionsBool(ServerEventBindings, key); -} - -// Weather -void ALE::OnChange(Weather* /*weather*/, uint32 zone, WeatherState state, float grade) -{ - START_HOOK(WEATHER_EVENT_ON_CHANGE); - Push(zone); - Push(state); - Push(grade); - CallAllFunctions(ServerEventBindings, key); -} - -// Auction House -void ALE::OnAdd(AuctionHouseObject* /*ah*/, AuctionEntry* entry) -{ - Player* owner = eObjectAccessor()FindPlayer(entry->owner); - - Item* item = eAuctionMgr->GetAItem(entry->item_guid); - uint32 expiretime = entry->expire_time; - - if (!owner || !item) - return; - - START_HOOK(AUCTION_EVENT_ON_ADD); - Push(entry->Id); - Push(owner); - Push(item); - Push(expiretime); - Push(entry->buyout); - Push(entry->startbid); - Push(entry->bid); - Push(entry->bidder); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnRemove(AuctionHouseObject* /*ah*/, AuctionEntry* entry) -{ - Player* owner = eObjectAccessor()FindPlayer(entry->owner); - - Item* item = eAuctionMgr->GetAItem(entry->item_guid); - uint32 expiretime = entry->expire_time; - - if (!owner || !item) - return; - - START_HOOK(AUCTION_EVENT_ON_REMOVE); - Push(entry->Id); - Push(owner); - Push(item); - Push(expiretime); - Push(entry->buyout); - Push(entry->startbid); - Push(entry->bid); - Push(entry->bidder); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnSuccessful(AuctionHouseObject* /*ah*/, AuctionEntry* entry) -{ - Player* owner = eObjectAccessor()FindPlayer(entry->owner); - - Item* item = eAuctionMgr->GetAItem(entry->item_guid); - uint32 expiretime = entry->expire_time; - - if (!owner || !item) - return; - - START_HOOK(AUCTION_EVENT_ON_SUCCESSFUL); - Push(entry->Id); - Push(owner); - Push(item); - Push(expiretime); - Push(entry->buyout); - Push(entry->startbid); - Push(entry->bid); - Push(entry->bidder); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnExpire(AuctionHouseObject* /*ah*/, AuctionEntry* entry) -{ - Player* owner = eObjectAccessor()FindPlayer(entry->owner); - - Item* item = eAuctionMgr->GetAItem(entry->item_guid); - uint32 expiretime = entry->expire_time; - - if (!owner || !item) - return; - - START_HOOK(AUCTION_EVENT_ON_EXPIRE); - Push(entry->Id); - Push(owner); - Push(item); - Push(expiretime); - Push(entry->buyout); - Push(entry->startbid); - Push(entry->bid); - Push(entry->bidder); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnOpenStateChange(bool open) -{ - START_HOOK(WORLD_EVENT_ON_OPEN_STATE_CHANGE); - Push(open); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnConfigLoad(bool reload, bool isBefore) -{ - START_HOOK(WORLD_EVENT_ON_CONFIG_LOAD); - Push(reload); - Push(isBefore); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask) -{ - START_HOOK(WORLD_EVENT_ON_SHUTDOWN_INIT); - Push(code); - Push(mask); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnShutdownCancel() -{ - START_HOOK(WORLD_EVENT_ON_SHUTDOWN_CANCEL); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnWorldUpdate(uint32 diff) -{ - { - LOCK_ALE; - if (ShouldReload()) - _ReloadALE(); - } - - eventMgr->globalProcessor->Update(diff); - httpManager.HandleHttpResponses(); - queryProcessor.ProcessReadyCallbacks(); - - START_HOOK(WORLD_EVENT_ON_UPDATE); - Push(diff); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnStartup() -{ - START_HOOK(WORLD_EVENT_ON_STARTUP); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnShutdown() -{ - START_HOOK(WORLD_EVENT_ON_SHUTDOWN); - CallAllFunctions(ServerEventBindings, key); -} - -/* Map */ -void ALE::OnCreate(Map* map) -{ - START_HOOK(MAP_EVENT_ON_CREATE); - Push(map); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnDestroy(Map* map) -{ - START_HOOK(MAP_EVENT_ON_DESTROY); - Push(map); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnPlayerEnter(Map* map, Player* player) -{ - START_HOOK(MAP_EVENT_ON_PLAYER_ENTER); - Push(map); - Push(player); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnPlayerLeave(Map* map, Player* player) -{ - START_HOOK(MAP_EVENT_ON_PLAYER_LEAVE); - Push(map); - Push(player); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnUpdate(Map* map, uint32 diff) -{ - START_HOOK(MAP_EVENT_ON_UPDATE); - // enable this for multithread - // eventMgr->globalProcessor->Update(diff); - Push(map); - Push(diff); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnRemove(GameObject* gameobject) -{ - START_HOOK(WORLD_EVENT_ON_DELETE_GAMEOBJECT); - Push(gameobject); - CallAllFunctions(ServerEventBindings, key); -} - -void ALE::OnRemove(Creature* creature) -{ - START_HOOK(WORLD_EVENT_ON_DELETE_CREATURE); - Push(creature); - CallAllFunctions(ServerEventBindings, key); -} diff --git a/src/LuaEngine/hooks/SpellHooks.cpp b/src/LuaEngine/hooks/SpellHooks.cpp deleted file mode 100644 index 8c0801893e..0000000000 --- a/src/LuaEngine/hooks/SpellHooks.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALEIncludes.h" -#include "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK(EVENT, ENTRY) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EntryKey(EVENT, ENTRY);\ - if (!SpellEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -#define START_HOOK_WITH_RETVAL(EVENT, ENTRY, RETVAL) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return RETVAL;\ - auto key = EntryKey(EVENT, ENTRY);\ - if (!SpellEventBindings->HasBindingsFor(key))\ - return RETVAL;\ - LOCK_ALE - -void ALE::OnSpellCastCancel(Unit* caster, Spell* spell, SpellInfo const* spellInfo, bool bySelf) -{ - START_HOOK(SPELL_EVENT_ON_CAST_CANCEL, spellInfo->Id); - Push(caster); - Push(spell); - Push(bySelf); - - CallAllFunctions(SpellEventBindings, key); -} - -void ALE::OnSpellCast(Unit* caster, Spell* spell, SpellInfo const* spellInfo, bool skipCheck) -{ - START_HOOK(SPELL_EVENT_ON_CAST, spellInfo->Id); - Push(caster); - Push(spell); - Push(skipCheck); - - CallAllFunctions(SpellEventBindings, key); -} - -void ALE::OnSpellPrepare(Unit* caster, Spell* spell, SpellInfo const* spellInfo) -{ - START_HOOK(SPELL_EVENT_ON_PREPARE, spellInfo->Id); - Push(caster); - Push(spell); - - CallAllFunctions(SpellEventBindings, key); -} - diff --git a/src/LuaEngine/hooks/TicketHooks.cpp b/src/LuaEngine/hooks/TicketHooks.cpp deleted file mode 100644 index 594d7e4fb4..0000000000 --- a/src/LuaEngine/hooks/TicketHooks.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALEIncludes.h" -#include "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK(EVENT) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EventKey(EVENT);\ - if (!TicketEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -#define START_HOOK(EVENT) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EventKey(EVENT);\ - if (!TicketEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -void ALE::OnTicketCreate(GmTicket* ticket) -{ - START_HOOK(TICKET_EVENT_ON_CREATE); - Push(ticket); - CallAllFunctions(TicketEventBindings, key); -} - -void ALE::OnTicketUpdateLastChange(GmTicket* ticket) -{ - START_HOOK(TICKET_EVENT_UPDATE_LAST_CHANGE); - Push(ticket); - CallAllFunctions(TicketEventBindings, key); -} - -void ALE::OnTicketClose(GmTicket* ticket) -{ - START_HOOK(TICKET_EVENT_ON_CLOSE); - Push(ticket); - CallAllFunctions(TicketEventBindings, key); -} - -void ALE::OnTicketResolve(GmTicket* ticket) -{ - START_HOOK(TICKET_EVENT_ON_RESOLVE); - Push(ticket); - CallAllFunctions(TicketEventBindings, key); -} - diff --git a/src/LuaEngine/hooks/VehicleHooks.cpp b/src/LuaEngine/hooks/VehicleHooks.cpp deleted file mode 100644 index f03a9657f9..0000000000 --- a/src/LuaEngine/hooks/VehicleHooks.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2010 - 2025 Eluna Lua Engine - * 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 "ALETemplate.h" - -using namespace Hooks; - -#define START_HOOK(EVENT) \ - if (!ALEConfig::GetInstance().IsALEEnabled())\ - return;\ - auto key = EventKey(EVENT);\ - if (!VehicleEventBindings->HasBindingsFor(key))\ - return;\ - LOCK_ALE - -void ALE::OnInstall(Vehicle* vehicle) -{ - START_HOOK(VEHICLE_EVENT_ON_INSTALL); - Push(vehicle); - CallAllFunctions(VehicleEventBindings, key); -} - -void ALE::OnUninstall(Vehicle* vehicle) -{ - START_HOOK(VEHICLE_EVENT_ON_UNINSTALL); - Push(vehicle); - CallAllFunctions(VehicleEventBindings, key); -} - -void ALE::OnInstallAccessory(Vehicle* vehicle, Creature* accessory) -{ - START_HOOK(VEHICLE_EVENT_ON_INSTALL_ACCESSORY); - Push(vehicle); - Push(accessory); - CallAllFunctions(VehicleEventBindings, key); -} - -void ALE::OnAddPassenger(Vehicle* vehicle, Unit* passenger, int8 seatId) -{ - START_HOOK(VEHICLE_EVENT_ON_ADD_PASSENGER); - Push(vehicle); - Push(passenger); - Push(seatId); - CallAllFunctions(VehicleEventBindings, key); -} - -void ALE::OnRemovePassenger(Vehicle* vehicle, Unit* passenger) -{ - START_HOOK(VEHICLE_EVENT_ON_REMOVE_PASSENGER); - Push(vehicle); - Push(passenger); - CallAllFunctions(VehicleEventBindings, key); -} diff --git a/src/LuaEngine/lmarshal.cpp b/src/LuaEngine/lmarshal.cpp deleted file mode 100644 index 936d677766..0000000000 --- a/src/LuaEngine/lmarshal.cpp +++ /dev/null @@ -1,580 +0,0 @@ -/* - * lmarshal.c - * A Lua library for serializing and deserializing Lua values - * Richard Hundt , Eluna Lua Engine - * - * License: MIT - * - * Copyright (c) 2010 Richard Hundt - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include "ALECompat.h" - -#if LUA_VERSION_NUM == 501 && !defined(luaL_setfuncs) - #define luaL_setfuncs(L, l, n) luaL_register(L, NULL, l) -#endif - -#define MAR_TREF 1 -#define MAR_TVAL 2 -#define MAR_TUSR 3 - -#define MAR_CHR 1 -#define MAR_I32 4 -#define MAR_I64 8 - -#define MAR_MAGIC 0x8f -#define SEEN_IDX 3 - -#define MAR_ENV_IDX_KEY "E" -#define MAR_NUPS_IDX_KEY "n" - -typedef struct mar_Buffer { - size_t size; - size_t seek; - size_t head; - char* data; -} mar_Buffer; - -static int mar_encode_table(lua_State *L, mar_Buffer *buf, size_t *idx); -static int mar_decode_table(lua_State *L, const char* buf, size_t len, size_t *idx); - -static void buf_init(lua_State *L, mar_Buffer *buf) -{ - buf->size = 128; - buf->seek = 0; - buf->head = 0; - if (!(buf->data = (char*)malloc(buf->size))) luaL_error(L, "Out of memory!"); -} - -static void buf_done(lua_State* /*L*/, mar_Buffer *buf) -{ - free(buf->data); -} - -static int buf_write(lua_State* L, const char* str, size_t len, mar_Buffer *buf) -{ - if (len > UINT32_MAX) luaL_error(L, "buffer too long"); - if (buf->size - buf->head < len) { - size_t new_size = buf->size << 1; - size_t cur_head = buf->head; - while (new_size - cur_head <= len) { - new_size = new_size << 1; - } - char* data = (char*)realloc(buf->data, new_size); - if (!data) { - return luaL_error(L, "Out of memory!"); - } - buf->data = data; - buf->size = new_size; - } - memcpy(&buf->data[buf->head], str, len); - buf->head += len; - return 0; -} - -static const char* buf_read(lua_State* /*L*/, mar_Buffer *buf, size_t *len) -{ - if (buf->seek < buf->head) { - buf->seek = buf->head; - *len = buf->seek; - return buf->data; - } - *len = 0; - return NULL; -} - -static void mar_encode_value(lua_State *L, mar_Buffer *buf, int val, size_t *idx) -{ - size_t l; - int val_type = lua_type(L, val); - lua_pushvalue(L, val); - - buf_write(L, (const char*)&val_type, MAR_CHR, buf); - switch (val_type) { - case LUA_TBOOLEAN: { - int int_val = lua_toboolean(L, -1); - buf_write(L, (const char*)&int_val, MAR_CHR, buf); - break; - } - case LUA_TSTRING: { - const char *str_val = lua_tolstring(L, -1, &l); - buf_write(L, (const char*)&l, MAR_I32, buf); - buf_write(L, str_val, l, buf); - break; - } - case LUA_TNUMBER: { - lua_Number num_val = lua_tonumber(L, -1); - buf_write(L, (const char*)&num_val, MAR_I64, buf); - break; - } - case LUA_TTABLE: { - int tag, ref; - lua_pushvalue(L, -1); - lua_rawget(L, SEEN_IDX); - if (!lua_isnil(L, -1)) { - ref = lua_tointeger(L, -1); - tag = MAR_TREF; - buf_write(L, (const char*)&tag, MAR_CHR, buf); - buf_write(L, (const char*)&ref, MAR_I32, buf); - lua_pop(L, 1); - } - else { - mar_Buffer rec_buf; - lua_pop(L, 1); /* pop nil */ - if (luaL_getmetafield(L, -1, "__persist")) { - tag = MAR_TUSR; - - lua_pushvalue(L, -2); /* self */ - lua_call(L, 1, 1); - if (!lua_isfunction(L, -1)) { - luaL_error(L, "__persist must return a function"); - } - - lua_remove(L, -2); /* __persist */ - - lua_newtable(L); - lua_pushvalue(L, -2); /* callback */ - lua_rawseti(L, -2, 1); - - buf_init(L, &rec_buf); - mar_encode_table(L, &rec_buf, idx); - - buf_write(L, (const char*)&tag, MAR_CHR, buf); - buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf); - buf_write(L, rec_buf.data, rec_buf.head, buf); - buf_done(L, &rec_buf); - lua_pop(L, 1); - } - else { - tag = MAR_TVAL; - - lua_pushvalue(L, -1); - lua_pushinteger(L, (*idx)++); - lua_rawset(L, SEEN_IDX); - - lua_pushvalue(L, -1); - buf_init(L, &rec_buf); - mar_encode_table(L, &rec_buf, idx); - lua_pop(L, 1); - - buf_write(L, (const char*)&tag, MAR_CHR, buf); - buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf); - buf_write(L, rec_buf.data,rec_buf.head, buf); - buf_done(L, &rec_buf); - } - } - break; - } - case LUA_TFUNCTION: { - int tag, ref; - lua_pushvalue(L, -1); - lua_rawget(L, SEEN_IDX); - if (!lua_isnil(L, -1)) { - ref = lua_tointeger(L, -1); - tag = MAR_TREF; - buf_write(L, (const char*)&tag, MAR_CHR, buf); - buf_write(L, (const char*)&ref, MAR_I32, buf); - lua_pop(L, 1); - } - else { - mar_Buffer rec_buf; - unsigned char i; - lua_Debug ar; - lua_pop(L, 1); /* pop nil */ - - lua_pushvalue(L, -1); - lua_getinfo(L, ">nuS", &ar); - if (ar.what[0] != 'L') { - luaL_error(L, "attempt to persist a C function '%s'", ar.name); - } - tag = MAR_TVAL; - lua_pushvalue(L, -1); - lua_pushinteger(L, (*idx)++); - lua_rawset(L, SEEN_IDX); - - lua_pushvalue(L, -1); - buf_init(L, &rec_buf); - lua_dump(L, (lua_Writer)buf_write, &rec_buf); - - buf_write(L, (const char*)&tag, MAR_CHR, buf); - buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf); - buf_write(L, rec_buf.data, rec_buf.head, buf); - buf_done(L, &rec_buf); - lua_pop(L, 1); - - lua_createtable(L, ar.nups, 0); - for (i = 1; i <= ar.nups; i++) { - const char* upvalue_name = lua_getupvalue(L, -2, i); - if (strcmp("_ENV", upvalue_name) == 0) { - lua_pop(L, 1); - // Mark where _ENV is expected. - lua_pushstring(L, MAR_ENV_IDX_KEY); - lua_pushinteger(L, i); - lua_rawset(L, -3); - } - else { - lua_rawseti(L, -2, i); - } - } - lua_pushstring(L, MAR_NUPS_IDX_KEY); - lua_pushnumber(L, ar.nups); - lua_rawset(L, -3); - - buf_init(L, &rec_buf); - mar_encode_table(L, &rec_buf, idx); - - buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf); - buf_write(L, rec_buf.data, rec_buf.head, buf); - buf_done(L, &rec_buf); - lua_pop(L, 1); - } - - break; - } - case LUA_TUSERDATA: { - int tag, ref; - lua_pushvalue(L, -1); - lua_rawget(L, SEEN_IDX); - if (!lua_isnil(L, -1)) { - ref = lua_tointeger(L, -1); - tag = MAR_TREF; - buf_write(L, (const char*)&tag, MAR_CHR, buf); - buf_write(L, (const char*)&ref, MAR_I32, buf); - lua_pop(L, 1); - } - else { - mar_Buffer rec_buf; - lua_pop(L, 1); /* pop nil */ - if (luaL_getmetafield(L, -1, "__persist")) { - tag = MAR_TUSR; - - lua_pushvalue(L, -2); - lua_pushinteger(L, (*idx)++); - lua_rawset(L, SEEN_IDX); - - lua_pushvalue(L, -2); - lua_call(L, 1, 1); - if (!lua_isfunction(L, -1)) { - luaL_error(L, "__persist must return a function"); - } - lua_newtable(L); - lua_pushvalue(L, -2); - lua_rawseti(L, -2, 1); - lua_remove(L, -2); - - buf_init(L, &rec_buf); - mar_encode_table(L, &rec_buf, idx); - - buf_write(L, (const char*)&tag, MAR_CHR, buf); - buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf); - buf_write(L, rec_buf.data, rec_buf.head, buf); - buf_done(L, &rec_buf); - } - else { - luaL_error(L, "attempt to encode userdata (no __persist hook)"); - } - lua_pop(L, 1); - } - break; - } - case LUA_TNIL: break; - default: - luaL_error(L, "invalid value type (%s)", lua_typename(L, val_type)); - } - lua_pop(L, 1); -} - -static int mar_encode_table(lua_State *L, mar_Buffer *buf, size_t *idx) -{ - lua_pushnil(L); - while (lua_next(L, -2) != 0) { - mar_encode_value(L, buf, -2, idx); - mar_encode_value(L, buf, -1, idx); - lua_pop(L, 1); - } - return 1; -} - -#define mar_incr_ptr(l) \ - if (((*p)-buf)+(ptrdiff_t)(l) > (ptrdiff_t)len) luaL_error(L, "bad code"); (*p) += (l); - -#define mar_next_len(l,T) \ - if (((*p)-buf)+(ptrdiff_t)sizeof(T) > (ptrdiff_t)len) luaL_error(L, "bad code"); \ - l = *(T*)*p; (*p) += sizeof(T); - -static void mar_decode_value - (lua_State *L, const char *buf, size_t len, const char **p, size_t *idx) -{ - size_t l; - char val_type = **p; - mar_incr_ptr(MAR_CHR); - switch (val_type) { - case LUA_TBOOLEAN: - lua_pushboolean(L, *(char*)*p); - mar_incr_ptr(MAR_CHR); - break; - case LUA_TNUMBER: - lua_pushnumber(L, *(lua_Number*)*p); - mar_incr_ptr(MAR_I64); - break; - case LUA_TSTRING: - mar_next_len(l, uint32_t); - lua_pushlstring(L, *p, l); - mar_incr_ptr(l); - break; - case LUA_TTABLE: { - char tag = *(char*)*p; - mar_incr_ptr(MAR_CHR); - if (tag == MAR_TREF) { - int ref; - mar_next_len(ref, int); - lua_rawgeti(L, SEEN_IDX, ref); - } - else if (tag == MAR_TVAL) { - mar_next_len(l, uint32_t); - lua_newtable(L); - lua_pushvalue(L, -1); - lua_rawseti(L, SEEN_IDX, (*idx)++); - mar_decode_table(L, *p, l, idx); - mar_incr_ptr(l); - } - else if (tag == MAR_TUSR) { - mar_next_len(l, uint32_t); - lua_newtable(L); - mar_decode_table(L, *p, l, idx); - lua_rawgeti(L, -1, 1); - lua_call(L, 0, 1); - lua_remove(L, -2); - lua_pushvalue(L, -1); - lua_rawseti(L, SEEN_IDX, (*idx)++); - mar_incr_ptr(l); - } - else { - luaL_error(L, "bad encoded data"); - } - break; - } - case LUA_TFUNCTION: { - unsigned int nups; - unsigned int i; - mar_Buffer dec_buf; - char tag = *(char*)*p; - mar_incr_ptr(1); - if (tag == MAR_TREF) { - int ref; - mar_next_len(ref, int); - lua_rawgeti(L, SEEN_IDX, ref); - } - else { - mar_next_len(l, uint32_t); - dec_buf.data = (char*)*p; - dec_buf.size = l; - dec_buf.head = l; - dec_buf.seek = 0; - lua_load(L, (lua_Reader)buf_read, &dec_buf, "=marshal", NULL); - mar_incr_ptr(l); - - lua_pushvalue(L, -1); - lua_rawseti(L, SEEN_IDX, (*idx)++); - - mar_next_len(l, uint32_t); - lua_newtable(L); - mar_decode_table(L, *p, l, idx); - - lua_pushstring(L, MAR_ENV_IDX_KEY); - lua_rawget(L, -2); - if (lua_isnumber(L, -1)) { - lua_pushglobaltable(L); - lua_rawset(L, -3); - } - else { - lua_pop(L, 1); - } - - lua_pushstring(L, MAR_NUPS_IDX_KEY); - lua_rawget(L, -2); - nups = luaL_checknumber(L, -1); - lua_pop(L, 1); - - for (i = 1; i <= nups; i++) { - lua_rawgeti(L, -1, i); - lua_setupvalue(L, -3, i); - } - - lua_pop(L, 1); - mar_incr_ptr(l); - } - break; - } - case LUA_TUSERDATA: { - char tag = *(char*)*p; - mar_incr_ptr(MAR_CHR); - if (tag == MAR_TREF) { - int ref; - mar_next_len(ref, int); - lua_rawgeti(L, SEEN_IDX, ref); - } - else if (tag == MAR_TUSR) { - mar_next_len(l, uint32_t); - lua_newtable(L); - mar_decode_table(L, *p, l, idx); - lua_rawgeti(L, -1, 1); - lua_call(L, 0, 1); - lua_remove(L, -2); - lua_pushvalue(L, -1); - lua_rawseti(L, SEEN_IDX, (*idx)++); - mar_incr_ptr(l); - } - else { /* tag == MAR_TVAL */ - lua_pushnil(L); - } - break; - } - case LUA_TNIL: - case LUA_TTHREAD: - lua_pushnil(L); - break; - default: - luaL_error(L, "bad code"); - } -} - -static int mar_decode_table(lua_State *L, const char* buf, size_t len, size_t *idx) -{ - const char* p; - p = buf; - while (p - buf < (ptrdiff_t)len) { - mar_decode_value(L, buf, len, &p, idx); - mar_decode_value(L, buf, len, &p, idx); - lua_rawset(L, -3); - } - return 1; -} - -int mar_encode(lua_State* L) -{ - const unsigned char m = MAR_MAGIC; - size_t idx, len; - mar_Buffer buf; - - if (lua_isnone(L, 1)) { - lua_pushnil(L); - } - if (lua_isnoneornil(L, 2)) { - lua_newtable(L); - } - else if (!lua_istable(L, 2)) { - luaL_error(L, "bad argument #2 to encode (expected table)"); - } - lua_settop(L, 2); - - len = lua_rawlen(L, 2); - lua_newtable(L); - for (idx = 1; idx <= len; idx++) { - lua_rawgeti(L, 2, idx); - if (lua_isnil(L, -1)) { - lua_pop(L, 1); - continue; - } - lua_pushinteger(L, idx); - lua_rawset(L, SEEN_IDX); - } - lua_pushvalue(L, 1); - - buf_init(L, &buf); - buf_write(L, (const char*)&m, 1, &buf); - - mar_encode_value(L, &buf, -1, &idx); - - lua_pop(L, 1); - - lua_pushlstring(L, buf.data, buf.head); - - buf_done(L, &buf); - - lua_remove(L, SEEN_IDX); - - return 1; -} - -int mar_decode(lua_State* L) -{ - size_t l, idx, len; - const char *p; - const char *s = luaL_checklstring(L, 1, &l); - - if (l < 1) luaL_error(L, "bad header"); - if (*(unsigned char *)s++ != MAR_MAGIC) luaL_error(L, "bad magic"); - l -= 1; - - if (lua_isnoneornil(L, 2)) { - lua_newtable(L); - } - else if (!lua_istable(L, 2)) { - luaL_error(L, "bad argument #2 to decode (expected table)"); - } - lua_settop(L, 2); - - len = lua_rawlen(L, 2); - lua_newtable(L); - for (idx = 1; idx <= len; idx++) { - lua_rawgeti(L, 2, idx); - lua_rawseti(L, SEEN_IDX, idx); - } - - p = s; - mar_decode_value(L, s, l, &p, &idx); - - lua_remove(L, SEEN_IDX); - lua_remove(L, 2); - - return 1; -} - -int mar_clone(lua_State* L) -{ - mar_encode(L); - lua_replace(L, 1); - mar_decode(L); - return 1; -} - -static const luaL_Reg R[] = -{ - {"encode", mar_encode}, - {"decode", mar_decode}, - {"clone", mar_clone}, - {NULL, NULL} -}; - -int luaopen_marshal(lua_State *L) -{ - lua_newtable(L); - luaL_setfuncs(L, R, 0); - return 1; -} - diff --git a/src/LuaEngine/lmarshal.h b/src/LuaEngine/lmarshal.h deleted file mode 100644 index fed50b9a79..0000000000 --- a/src/LuaEngine/lmarshal.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) 2025 Eluna Lua Engine - * This program is free software licensed under GPL version 3 - * Please see the included DOCS/LICENSE.md for more information - */ - -extern "C" { -#include "lua.h" -} - -int mar_encode(lua_State* L); -int mar_decode(lua_State* L); diff --git a/src/LuaEngine/methods/ALEQueryMethods.h b/src/LuaEngine/methods/ALEQueryMethods.h deleted file mode 100644 index 474c4ecddc..0000000000 --- a/src/LuaEngine/methods/ALEQueryMethods.h +++ /dev/null @@ -1,316 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef QUERYMETHODS_H -#define QUERYMETHODS_H - -#define RESULT (*result) - -/*** - * The result of a database query. - * - * E.g. the return value of [Global:WorldDBQuery]. - * - * Inherits all methods from: none - */ -namespace LuaQuery -{ - static void CheckFields(lua_State* L, ALEQuery* result) - { - uint32 field = ALE::CHECKVAL(L, 2); - uint32 count = RESULT->GetFieldCount(); - if (field >= count) - { - char arr[256]; - snprintf(arr, sizeof(arr), "trying to access invalid field index %u. There are %u fields available and the indexes start from 0", field, count); - luaL_argerror(L, 2, arr); - } - } - - /** - * Returns `true` if the specified column of the current row is `NULL`, otherwise `false`. - * - * @param uint32 column - * @return bool isNull - */ - int IsNull(lua_State* L, ALEQuery* result) - { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - - ALE::Push(L, RESULT->Fetch()[col].IsNull()); - return 1; - } - - /** - * Returns the number of columns in the result set. - * - * @return uint32 columnCount - */ - int GetColumnCount(lua_State* L, ALEQuery* result) - { - ALE::Push(L, RESULT->GetFieldCount()); - return 1; - } - - /** - * Returns the number of rows in the result set. - * - * @return uint32 rowCount - */ - int GetRowCount(lua_State* L, ALEQuery* result) - { - if (RESULT->GetRowCount() > (uint32)-1) - ALE::Push(L, (uint32)-1); - else - ALE::Push(L, (uint32)(RESULT->GetRowCount())); - return 1; - } - - /** - * Returns the data in the specified column of the current row, casted to a boolean. - * - * @param uint32 column - * @return bool data - */ - int GetBool(lua_State* L, ALEQuery* result) - { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; - } - - /** - * Returns the data in the specified column of the current row, casted to an unsigned 8-bit integer. - * - * @param uint32 column - * @return uint8 data - */ - int GetUInt8(lua_State* L, ALEQuery* result) - { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; - } - - /** - * Returns the data in the specified column of the current row, casted to an unsigned 16-bit integer. - * - * @param uint32 column - * @return uint16 data - */ - int GetUInt16(lua_State* L, ALEQuery* result) - { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; - } - - /** - * Returns the data in the specified column of the current row, casted to an unsigned 32-bit integer. - * - * @param uint32 column - * @return uint32 data - */ - int GetUInt32(lua_State* L, ALEQuery* result) - { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; - } - - /** - * Returns the data in the specified column of the current row, casted to an unsigned 64-bit integer. - * - * @param uint32 column - * @return uint64 data - */ - int GetUInt64(lua_State* L, ALEQuery* result) - { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; - } - - /** - * Returns the data in the specified column of the current row, casted to a signed 8-bit integer. - * - * @param uint32 column - * @return int8 data - */ - int GetInt8(lua_State* L, ALEQuery* result) - { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; - } - - /** - * Returns the data in the specified column of the current row, casted to a signed 16-bit integer. - * - * @param uint32 column - * @return int16 data - */ - int GetInt16(lua_State* L, ALEQuery* result) - { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; - } - - /** - * Returns the data in the specified column of the current row, casted to a signed 32-bit integer. - * - * @param uint32 column - * @return int32 data - */ - int GetInt32(lua_State* L, ALEQuery* result) - { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; - } - - /** - * Returns the data in the specified column of the current row, casted to a signed 64-bit integer. - * - * @param uint32 column - * @return int64 data - */ - int GetInt64(lua_State* L, ALEQuery* result) - { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; - } - - /** - * Returns the data in the specified column of the current row, casted to a 32-bit floating point value. - * - * @param uint32 column - * @return float data - */ - int GetFloat(lua_State* L, ALEQuery* result) - { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; - } - - /** - * Returns the data in the specified column of the current row, casted to a 64-bit floating point value. - * - * @param uint32 column - * @return double data - */ - int GetDouble(lua_State* L, ALEQuery* result) - { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; - } - - /** - * Returns the data in the specified column of the current row, casted to a string. - * - * @param uint32 column - * @return string data - */ - int GetString(lua_State* L, ALEQuery* result) - { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; - } - - /** - * Advances the [ALEQuery] to the next row in the result set. - * - * *Do not* call this immediately after a query, or you'll skip the first row. - * - * Returns `false` if there was no new row, otherwise `true`. - * - * @return bool hadNextRow - */ - int NextRow(lua_State* L, ALEQuery* result) - { - ALE::Push(L, RESULT->NextRow()); - return 1; - } - - /** - * Returns a table from the current row where keys are field names and values are the row's values. - * - * All numerical values will be numbers and everything else is returned as a string. - * - * **For example,** the query: - * - * SELECT entry, name FROM creature_template - * - * would result in a table like: - * - * { entry = 123, name = "some creature name" } - * - * To move to next row use [ALEQuery:NextRow]. - * - * @return table rowData : table filled with row columns and data where `T[column] = data` - */ - int GetRow(lua_State* L, ALEQuery* result) - { - uint32 col = RESULT->GetFieldCount(); - Field* row = RESULT->Fetch(); - - lua_createtable(L, 0, col); - int tbl = lua_gettop(L); - - for (uint32 i = 0; i < col; ++i) - { - ALE::Push(L, RESULT->GetFieldName(i)); - - std::string _str = row[i].Get(); - const char* str = _str.c_str(); - if (row[i].IsNull() || !str) - ALE::Push(L); - else - { - // MYSQL_TYPE_LONGLONG Interpreted as string for lua - switch (row[i].GetType()) - { - case DatabaseFieldTypes::Int8: - case DatabaseFieldTypes::Int16: - case DatabaseFieldTypes::Int32: - case DatabaseFieldTypes::Int64: - case DatabaseFieldTypes::Float: - case DatabaseFieldTypes::Double: - ALE::Push(L, strtod(str, NULL)); - break; - default: - ALE::Push(L, str); - break; - } - } - lua_rawset(L, tbl); - } - - lua_settop(L, tbl); - return 1; - } -}; -#undef RESULT - -#endif diff --git a/src/LuaEngine/methods/AchievementMethods.h b/src/LuaEngine/methods/AchievementMethods.h deleted file mode 100644 index e5d34e61fa..0000000000 --- a/src/LuaEngine/methods/AchievementMethods.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef ACHIEVEMENTMETHODS_H -#define ACHIEVEMENTMETHODS_H - -/*** - * Represents an entry from the game's achievement database (e.g., achievement earned for completing certain tasks). - * - * Inherits all methods from: none - */ -namespace LuaAchievement -{ - /** - * Returns the [Achievement]'s ID. - * - * @return uint32 id - */ - int GetId(lua_State* L, AchievementEntry* const achievement) - { - ALE::Push(L, achievement->ID); - return 1; - } - - /** - * Returns the [Achievement]'s name. - * - * enum LocaleConstant - * { - * LOCALE_enUS = 0, - * LOCALE_koKR = 1, - * LOCALE_frFR = 2, - * LOCALE_deDE = 3, - * LOCALE_zhCN = 4, - * LOCALE_zhTW = 5, - * LOCALE_esES = 6, - * LOCALE_esMX = 7, - * LOCALE_ruRU = 8 - * }; - * - * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the [Achievement] name in - * @return string name - */ - int GetName(lua_State* L, AchievementEntry* const achievement) - { - uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE); - if (locale >= TOTAL_LOCALES) - { - return luaL_argerror(L, 2, "valid LocaleConstant expected"); - } - - ALE::Push(L, achievement->name[locale]); - return 1; - } -}; -#endif diff --git a/src/LuaEngine/methods/AuraMethods.h b/src/LuaEngine/methods/AuraMethods.h deleted file mode 100644 index 3f63743d25..0000000000 --- a/src/LuaEngine/methods/AuraMethods.h +++ /dev/null @@ -1,169 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef AURAMETHODS_H -#define AURAMETHODS_H - -/*** - * The persistent effect of a [Spell] that remains on a [Unit] after the [Spell] - * has been cast. - * - * As an example, if you cast a damage-over-time spell on a target, an [Aura] is - * put on the target that deals damage continuously. - * - * [Aura]s on your player are displayed in-game as a series of icons to the left - * of the mini-map. - * - * Inherits all methods from: none - */ -namespace LuaAura -{ - /** - * Returns the [Unit] that casted the [Spell] that caused this [Aura] to be applied. - * - * @return [Unit] caster - */ - int GetCaster(lua_State* L, Aura* aura) - { - ALE::Push(L, aura->GetCaster()); - return 1; - } - - /** - * Returns the GUID of the [Unit] that casted the [Spell] that caused this [Aura] to be applied. - * - * @return string caster_guid : the GUID of the Unit as a decimal string - */ - int GetCasterGUID(lua_State* L, Aura* aura) - { - ALE::Push(L, aura->GetCasterGUID()); - return 1; - } - - /** - * Returns the level of the [Unit] that casted the [Spell] that caused this [Aura] to be applied. - * - * @return uint32 caster_level - */ - int GetCasterLevel(lua_State* L, Aura* aura) - { - ALE::Push(L, aura->GetCaster()->GetLevel()); - return 1; - } - - /** - * Returns the amount of time left until the [Aura] expires. - * - * @return int32 duration : amount of time left in milliseconds - */ - int GetDuration(lua_State* L, Aura* aura) - { - ALE::Push(L, aura->GetDuration()); - return 1; - } - - /** - * Returns the ID of the [Spell] that caused this [Aura] to be applied. - * - * @return uint32 aura_id - */ - int GetAuraId(lua_State* L, Aura* aura) - { - ALE::Push(L, aura->GetId()); - return 1; - } - - /** - * Returns the amount of time this [Aura] lasts when applied. - * - * To determine how much time has passed since this Aura was applied, - * subtract the result of [Aura]:GetDuration from the result of this method. - * - * @return int32 max_duration : the maximum duration of the Aura, in milliseconds - */ - int GetMaxDuration(lua_State* L, Aura* aura) - { - ALE::Push(L, aura->GetMaxDuration()); - return 1; - } - - /** - * Returns the number of times the [Aura] has "stacked". - * - * This is the same as the number displayed on the [Aura]'s icon in-game. - * - * @return uint32 stack_amount - */ - int GetStackAmount(lua_State* L, Aura* aura) - { - ALE::Push(L, aura->GetStackAmount()); - return 1; - } - - /** - * Returns the [Unit] that the [Aura] has been applied to. - * - * @return [Unit] owner - */ - int GetOwner(lua_State* L, Aura* aura) - { - ALE::Push(L, aura->GetOwner()); - return 1; - } - - /** - * Change the amount of time before the [Aura] expires. - * - * @param int32 duration : the new duration of the Aura, in milliseconds - */ - int SetDuration(lua_State* L, Aura* aura) - { - int32 duration = ALE::CHECKVAL(L, 2); - aura->SetDuration(duration); - return 0; - } - - /** - * Change the maximum amount of time before the [Aura] expires. - * - * This does not affect the current duration of the [Aura], but if the [Aura] - * is reset to the maximum duration, it will instead change to `duration`. - * - * @param int32 duration : the new maximum duration of the Aura, in milliseconds - */ - int SetMaxDuration(lua_State* L, Aura* aura) - { - int32 duration = ALE::CHECKVAL(L, 2); - aura->SetMaxDuration(duration); - return 0; - } - - /** - * Change the amount of times the [Aura] has "stacked" on the [Unit]. - * - * If `amount` is greater than or equal to the current number of stacks, - * then the [Aura] has its duration reset to the maximum duration. - * - * @param uint32 amount - */ - int SetStackAmount(lua_State* L, Aura* aura) - { - uint8 amount = ALE::CHECKVAL(L, 2); - aura->SetStackAmount(amount); - return 0; - } - - /** - * Remove this [Aura] from the [Unit] it is applied to. - */ - int Remove(lua_State* L, Aura* aura) - { - aura->Remove(); - ALE::CHECKOBJ(L, 1)->Invalidate(); - return 0; - } -}; -#endif diff --git a/src/LuaEngine/methods/BattleGroundMethods.h b/src/LuaEngine/methods/BattleGroundMethods.h deleted file mode 100644 index 70e97bbf2d..0000000000 --- a/src/LuaEngine/methods/BattleGroundMethods.h +++ /dev/null @@ -1,213 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef BATTLEGROUNDMETHODS_H -#define BATTLEGROUNDMETHODS_H - -/*** - * Contains the state of a battleground, e.g. Warsong Gulch, Arathi Basin, etc. - * - * Inherits all methods from: none - */ -namespace LuaBattleGround -{ - /** - * Returns the name of the [BattleGround]. - * - * @return string name - */ - int GetName(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetName()); - return 1; - } - - /** - * Returns the amount of alive players in the [BattleGround] by the team ID. - * - * @param [Team] team : team ID - * @return uint32 count - */ - int GetAlivePlayersCountByTeam(lua_State* L, BattleGround* bg) - { - uint32 team = ALE::CHECKVAL(L, 2); - - ALE::Push(L, bg->GetAlivePlayersCountByTeam((TeamId)team)); - return 1; - } - - /** - * Returns the [Map] of the [BattleGround]. - * - * @return [Map] map - */ - int GetMap(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetBgMap()); - return 1; - } - - /** - * Returns the bonus honor given by amount of kills in the specific [BattleGround]. - * - * @param uint32 kills : amount of kills - * @return uint32 bonusHonor - */ - int GetBonusHonorFromKillCount(lua_State* L, BattleGround* bg) - { - uint32 kills = ALE::CHECKVAL(L, 2); - - ALE::Push(L, bg->GetBonusHonorFromKill(kills)); - return 1; - } - - /** - * Returns the end time of the [BattleGround]. - * - * @return uint32 endTime - */ - int GetEndTime(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetEndTime()); - return 1; - } - - /** - * Returns the amount of free slots for the selected team in the specific [BattleGround]. - * - * @param [Team] team : team ID - * @return uint32 freeSlots - */ - int GetFreeSlotsForTeam(lua_State* L, BattleGround* bg) - { - uint32 team = ALE::CHECKVAL(L, 2); - - ALE::Push(L, bg->GetFreeSlotsForTeam((TeamId)team)); - return 1; - } - - /** - * Returns the instance ID of the [BattleGround]. - * - * @return uint32 instanceId - */ - int GetInstanceId(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetInstanceID()); - return 1; - } - - /** - * Returns the map ID of the [BattleGround]. - * - * @return uint32 mapId - */ - int GetMapId(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetMapId()); - return 1; - } - - /** - * Returns the type ID of the [BattleGround]. - * - * @return [BattleGroundTypeId] typeId - */ - int GetTypeId(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetBgTypeID()); - return 1; - } - - /** - * Returns the max allowed [Player] level of the specific [BattleGround]. - * - * @return uint32 maxLevel - */ - int GetMaxLevel(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetMaxLevel()); - return 1; - } - - /** - * Returns the minimum allowed [Player] level of the specific [BattleGround]. - * - * @return uint32 minLevel - */ - int GetMinLevel(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetMinLevel()); - return 1; - } - - /** - * Returns the maximum allowed [Player] count of the specific [BattleGround]. - * - * @return uint32 maxPlayerCount - */ - int GetMaxPlayers(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetMaxPlayersPerTeam() * 2); - return 1; - } - - /** - * Returns the minimum allowed [Player] count of the specific [BattleGround]. - * - * @return uint32 minPlayerCount - */ - int GetMinPlayers(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetMaxPlayersPerTeam() * 2); - return 1; - } - - /** - * Returns the maximum allowed [Player] count per team of the specific [BattleGround]. - * - * @return uint32 maxTeamPlayerCount - */ - int GetMaxPlayersPerTeam(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetMaxPlayersPerTeam()); - return 1; - } - - /** - * Returns the minimum allowed [Player] count per team of the specific [BattleGround]. - * - * @return uint32 minTeamPlayerCount - */ - int GetMinPlayersPerTeam(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetMinPlayersPerTeam()); - return 1; - } - - /** - * Returns the winning team of the specific [BattleGround]. - * - * @return [Team] team - */ - int GetWinner(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetWinner()); - return 1; - } - - /** - * Returns the status of the specific [BattleGround]. - * - * @return [BattleGroundStatus] status - */ - int GetStatus(lua_State* L, BattleGround* bg) - { - ALE::Push(L, bg->GetStatus()); - return 1; - } -}; -#endif diff --git a/src/LuaEngine/methods/ChatHandlerMethods.h b/src/LuaEngine/methods/ChatHandlerMethods.h deleted file mode 100644 index ac6f9a2900..0000000000 --- a/src/LuaEngine/methods/ChatHandlerMethods.h +++ /dev/null @@ -1,199 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef CHATHANDLERMETHODS_H -#define CHATHANDLERMETHODS_H - -#include "Chat.h" - -/*** - * Provides access to in-game and console chat commands, messages, and selection context for command execution. - * - * Used primarily in GM scripts or command handlers to send messages, check permissions, and access selected targets. - * - * Inherits all methods from: none - */ -namespace LuaChatHandler -{ - /** - * Sends text to the chat handler - * - * @proto (text) - * @proto (entry) - * @param string text : text to display in chat or console - * @param uint32 entry : id of the string to display - */ - int SendSysMessage(lua_State* L, ChatHandler* handler) - { - if (lua_isnumber(L, 2)) - { - uint32 entry = ALE::CHECKVAL(L, 2); - handler->SendSysMessage(entry); - } - else - { - std::string text = ALE::CHECKVAL(L, 2); - handler->SendSysMessage(text); - } - return 0; - } - - /** - * Returns `true` if the [ChatHandler] comes from the console, `false` if it comes from a player - * - * @return bool isConsole - */ - int IsConsole(lua_State* L, ChatHandler* handler) - { - ALE::Push(L, handler->IsConsole()); - return 1; - } - - /** - * Returns the [Player] associated with the handler. Returns `nil` in the case of a console handler - * - * @return [Player] player - */ - int GetPlayer(lua_State* L, ChatHandler* handler) - { - ALE::Push(L, handler->GetPlayer()); - return 1; - } - - /** - * Sends a message to all connected players - * - * @param string text : text to send - */ - int SendGlobalSysMessage(lua_State* L, ChatHandler* handler) - { - std::string text = ALE::CHECKVAL(L, 2); - handler->SendGlobalSysMessage(text.c_str()); - return 0; - } - - /** - * Sends a message to all connected Game Masters - * - * @param string text : text to send - */ - int SendGlobalGMSysMessage(lua_State* L, ChatHandler* handler) - { - std::string text = ALE::CHECKVAL(L, 2); - handler->SendGlobalGMSysMessage(text.c_str()); - return 0; - } - - /** - * Checks if the current security level is lower than the specified [Player]'s account - * - * @param [Player] player - * @param [bool] strong = false : Forces non-player accounts (security level greater than `0`) to go through the regular check if set to `true`.
Also, if set to `true`, the current security level will be considered as lower than the [Player]'s security level if the two levels are equal - * @return [bool] lower - */ - int HasLowerSecurity(lua_State* L, ChatHandler* handler) - { - Player* player = ALE::CHECKOBJ(L, 2); - bool strong = ALE::CHECKVAL(L, 3); - ALE::Push(L, handler->HasLowerSecurity(player, ObjectGuid::Empty, strong)); - return 1; - } - - /** - * Checks if the current security level is lower than the specified `account`'s level - * - * @param [uint32] account : the target account ID to compare security levels with - * @param [bool] strong = false : Forces non-player accounts (security level greater than `0`) to go through the regular check if set to `true`.
Also, if set to `true`, the current security level will be considered as lower than the `account`'s security level if the two levels are equal - * @return [bool] lower - */ - int HasLowerSecurityAccount(lua_State* L, ChatHandler* handler) - { - uint32 account = ALE::CHECKVAL(L, 2); - bool strong = ALE::CHECKVAL(L, 3); - ALE::Push(L, handler->HasLowerSecurityAccount(nullptr, account, strong)); - return 1; - } - - /** - * Returns the selected [Player] - * - * @return [Player] player - */ - int GetSelectedPlayer(lua_State* L, ChatHandler* handler) - { - ALE::Push(L, handler->getSelectedPlayer()); - return 1; - } - - /** - * Returns the selected [Creature] - * - * @return [Creature] creature - */ - int GetSelectedCreature(lua_State* L, ChatHandler* handler) - { - ALE::Push(L, handler->getSelectedCreature()); - return 1; - } - - /** - * Returns the selected [Unit] - * - * @return [Unit] unit - */ - int GetSelectedUnit(lua_State* L, ChatHandler* handler) - { - ALE::Push(L, handler->getSelectedUnit()); - return 1; - } - - /** - * Returns the selected [WorldObject] - * - * @return [WorldObject] object - */ - int GetSelectedObject(lua_State* L, ChatHandler* handler) - { - ALE::Push(L, handler->getSelectedObject()); - return 1; - } - - /** - * Returns the selected [Player] or the current [Player] if nothing is targeted or the target is not a player - * - * @return [Player] player - */ - int GetSelectedPlayerOrSelf(lua_State* L, ChatHandler* handler) - { - ALE::Push(L, handler->getSelectedPlayerOrSelf()); - return 1; - } - - /** - * Checks if the `securityLevel` is available - * - * @param [uint32] securityLevel - * @return [bool] isAvailable - */ - int IsAvailable(lua_State* L, ChatHandler* handler) - { - uint32 securityLevel = ALE::CHECKVAL(L, 2); - ALE::Push(L, handler->IsAvailable(securityLevel)); - return 1; - } - - /** - * Returns `true` if other previously called [ChatHandler] methods sent an error - * - * @return [bool] sentErrorMessage - */ - int HasSentErrorMessage(lua_State* L, ChatHandler* handler) - { - ALE::Push(L, handler->HasSentErrorMessage()); - return 1; - } -} -#endif diff --git a/src/LuaEngine/methods/CorpseMethods.h b/src/LuaEngine/methods/CorpseMethods.h deleted file mode 100644 index cf8f6f71ed..0000000000 --- a/src/LuaEngine/methods/CorpseMethods.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef CORPSEMETHODS_H -#define CORPSEMETHODS_H - -/*** - * The remains of a [Player] that has died. - * - * Inherits all methods from: [Object], [WorldObject] - */ -namespace LuaCorpse -{ - /** - * Returns the GUID of the [Player] that left the [Corpse] behind. - * - * @return ObjectGuid ownerGUID - */ - int GetOwnerGUID(lua_State* L, Corpse* corpse) - { - ALE::Push(L, corpse->GetOwnerGUID()); - return 1; - } - - /** - * Returns the time when the [Player] became a ghost and spawned this [Corpse]. - * - * @return uint32 ghostTime - */ - int GetGhostTime(lua_State* L, Corpse* corpse) - { - ALE::Push(L, corpse->GetGhostTime()); - return 1; - } - - /** - * Returns the [CorpseType] of a [Corpse]. - * - * enum CorpseType - * { - * CORPSE_BONES = 0, - * CORPSE_RESURRECTABLE_PVE = 1, - * CORPSE_RESURRECTABLE_PVP = 2 - * }; - * - * @return [CorpseType] corpseType - */ - int GetType(lua_State* L, Corpse* corpse) - { - ALE::Push(L, corpse->GetType()); - return 1; - } - - /** - * Sets the "ghost time" to the current time. - * - * See [Corpse:GetGhostTime]. - */ - int ResetGhostTime(lua_State* /*L*/, Corpse* corpse) - { - corpse->ResetGhostTime(); - return 0; - } - - /** - * Saves the [Corpse] to the database. - */ - int SaveToDB(lua_State* /*L*/, Corpse* corpse) - { - corpse->SaveToDB(); - return 0; - } -}; -#endif diff --git a/src/LuaEngine/methods/CreatureMethods.h b/src/LuaEngine/methods/CreatureMethods.h deleted file mode 100644 index f96ad37681..0000000000 --- a/src/LuaEngine/methods/CreatureMethods.h +++ /dev/null @@ -1,1372 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef CREATUREMETHODS_H -#define CREATUREMETHODS_H - -/*** - * Non-[Player] controlled [Unit]s (i.e. NPCs). - * - * Inherits all methods from: [Object], [WorldObject], [Unit] - */ -namespace LuaCreature -{ - /** - * Returns `true` if the [Creature] can regenerate health, - * and returns `false` otherwise. - * - * @return bool isRegenerating - */ - int IsRegeneratingHealth(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->isRegeneratingHealth()); - return 1; - } - - /** - * Sets whether the [Creature] can regenerate health or not. - * - * @param bool enable = true : `true` to enable health regeneration, `false` to disable it - */ - int SetRegeneratingHealth(lua_State* L, Creature* creature) - { - bool enable = ALE::CHECKVAL(L, 2, true); - - creature->SetRegeneratingHealth(enable); - return 0; - } - - /** - * Returns `true` if the [Creature] is set to not give reputation when killed, - * and returns `false` otherwise. - * - * @return bool reputationDisabled - */ - int IsReputationGainDisabled(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->IsReputationRewardDisabled()); - return 1; - } - - /** - * Returns `true` if the [Creature] completes the [Quest] with the ID `questID`, - * and returns `false` otherwise. - * - * @param uint32 questID : the ID of a [Quest] - * @return bool completesQuest - */ - int CanCompleteQuest(lua_State* L, Creature* creature) - { - uint32 quest_id = ALE::CHECKVAL(L, 2); - - ALE::Push(L, creature->hasInvolvedQuest(quest_id)); - return 1; - } - - /** - * Returns `true` if the [Creature] can be targeted for attack, - * and returns `false` otherwise. - * - * @param bool mustBeDead = false : if `true`, only returns `true` if the [Creature] is also dead. Otherwise, it must be alive. - * @return bool targetable - */ - int IsTargetableForAttack(lua_State* L, Creature* creature) - { - bool mustBeDead = ALE::CHECKVAL(L, 2, false); - - ALE::Push(L, creature->isTargetableForAttack(mustBeDead)); - return 1; - } - - /** - * Returns `true` if the [Creature] can assist `friend` in combat against `enemy`, - * and returns `false` otherwise. - * - * @param [Unit] friend : the Unit we will be assisting - * @param [Unit] enemy : the Unit that we would attack if we assist `friend` - * @param bool checkFaction = true : if `true`, the [Creature] must be the same faction as `friend` to assist - * @return bool canAssist - */ - int CanAssistTo(lua_State* L, Creature* creature) - { - Unit* u = ALE::CHECKOBJ(L, 2); - Unit* enemy = ALE::CHECKOBJ(L, 3); - bool checkfaction = ALE::CHECKVAL(L, 4, true); - - ALE::Push(L, creature->CanAssistTo(u, enemy, checkfaction)); - return 1; - } - - /** - * Returns `true` if the [Creature] has searched for combat assistance already, - * and returns `false` otherwise. - * - * @return bool searchedForAssistance - */ - int HasSearchedAssistance(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->HasSearchedAssistance()); - return 1; - } - - /** - * Returns `true` if the [Creature] will give its loot to `player`, - * and returns `false` otherwise. - * - * @return bool tapped - */ - int IsTappedBy(lua_State* L, Creature* creature) - { - Player* player = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, creature->isTappedBy(player)); - return 1; - } - - /** - * Returns `true` if the [Creature] will give its loot to a [Player] or [Group], - * and returns `false` otherwise. - * - * @return bool hasLootRecipient - */ - int HasLootRecipient(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->hasLootRecipient()); - return 1; - } - - /** - * Returns `true` if the [Creature] can start attacking nearby hostile [Unit]s, - * and returns `false` otherwise. - * - * @return bool canAggro - */ - int CanAggro(lua_State* L, Creature* creature) - { - ALE::Push(L, !creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC)); - return 1; - } - - /** - * Returns `true` if the [Creature] can move through deep water, - * and returns `false` otherwise. - * - * @return bool canSwim - */ - int CanSwim(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->CanSwim()); - return 1; - } - - /** - * Returns `true` if the [Creature] can move on land, - * and returns `false` otherwise. - * - * @return bool canWalk - */ - int CanWalk(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->CanWalk()); - return 1; - } - - /** - * Returns `true` if the [Creature] is returning to its spawn position from combat, - * and returns `false` otherwise. - * - * @return bool inEvadeMode - */ - int IsInEvadeMode(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->IsInEvadeMode()); - return 1; - } - - /** - * Returns `true` if the [Creature]'s rank is Elite or Rare Elite, - * and returns `false` otherwise. - * - * @return bool isElite - */ - int IsElite(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->isElite()); - return 1; - } - - /** - * Returns `true` if the [Creature] is a city guard, - * and returns `false` otherwise. - * - * @return bool isGuard - */ - int IsGuard(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->IsGuard()); - return 1; - } - - /** - * Returns `true` if the [Creature] is a civilian, - * and returns `false` otherwise. - * - * @return bool isCivilian - */ - int IsCivilian(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->IsCivilian()); - return 1; - } - - /** - * Returns `true` if the [Creature] is the leader of a player faction, - * and returns `false` otherwise. - * - * @return bool isLeader - */ - int IsRacialLeader(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->IsRacialLeader()); - return 1; - } - - /** - * Returns `true` if the [Creature]'s flags_extra includes Dungeon Boss (0x1000000), - * and returns `false` otherwise. - * - * @return bool isDungeonBoss - */ - int IsDungeonBoss(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->IsDungeonBoss()); - return 1; - } - - /** - * Returns `true` if the [Creature]'s rank is Boss, - * and returns `false` otherwise. - * - * @return bool isWorldBoss - */ - int IsWorldBoss(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->isWorldBoss()); - return 1; - } - - /** - * Returns `true` if the [Creature] cannot cast `spellId` due to a category cooldown, - * and returns `false` otherwise. - * - * @param uint32 spellId : the ID of a [Spell] - * @return bool hasCooldown - */ - int HasCategoryCooldown(lua_State* L, Creature* creature) - { - uint32 spell = ALE::CHECKVAL(L, 2); - - if (const SpellInfo* info = sSpellMgr->GetSpellInfo(spell)) - ALE::Push(L, info->GetCategory() && creature->HasSpellCooldown(spell)); - else - ALE::Push(L, false); - return 1; - } - - /** - * Returns `true` if the [Creature] can cast `spellId` when mind-controlled, - * and returns `false` otherwise. - * - * @param uint32 spellId : the ID of a [Spell] - * @return bool hasSpell - */ - int HasSpell(lua_State* L, Creature* creature) - { - uint32 id = ALE::CHECKVAL(L, 2); - - ALE::Push(L, creature->HasSpell(id)); - return 1; - } - - /** - * Returns `true` if the [Creature] starts the [Quest] `questId`, - * and returns `false` otherwise. - * - * @param uint32 questId : the ID of a [Quest] - * @return bool hasQuest - */ - int HasQuest(lua_State* L, Creature* creature) - { - uint32 questId = ALE::CHECKVAL(L, 2); - - ALE::Push(L, creature->hasQuest(questId)); - return 1; - } - - /** - * Returns `true` if the [Creature] has `spellId` on cooldown, - * and returns `false` otherwise. - * - * @param uint32 spellId : the ID of a [Spell] - * @return bool hasCooldown - */ - int HasSpellCooldown(lua_State* L, Creature* creature) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - - ALE::Push(L, creature->HasSpellCooldown(spellId)); - return 1; - } - - /** - * Returns `true` if the [Creature] can fly, - * and returns `false` otherwise. - * - * @return bool canFly - */ - int CanFly(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->CanFly()); - return 1; - } - - /** - * Returns `true` if the [Creature] is an invisible trigger, - * and returns `false` otherwise. - * - * @return bool canFly - */ - int IsTrigger(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->IsTrigger()); - return 1; - } - - /** - * Returns true if the [Creature] is damaged enough for looting - * - * @return bool isDamagedEnough - */ - int IsDamageEnoughForLootingAndReward(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->IsDamageEnoughForLootingAndReward()); - return 1; - } - - /** - * Returns true if the [Creature] can start attacking specified target - * - * Does not work on most targets - * - * @param [Unit] target - * @param bool force = true : force [Creature] to attack - */ - int CanStartAttack(lua_State* L, Creature* creature) // TODO: Implement core side - { - Unit* target = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, creature->CanStartAttack(target)); - return 1; - } - - /** - * Returns true if [Creature] has the specified loot mode - * - * @param uint16 lootMode - * @return bool hasLootMode - */ - int HasLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features - { - uint16 lootMode = ALE::CHECKVAL(L, 2); - - ALE::Push(L, creature->HasLootMode(lootMode)); - return 1; - } - - /** - * Returns the time it takes for this [Creature] to respawn once killed. - * - * This value does not usually change over a [Creature]'s lifespan, - * but can be modified by [Creature:SetRespawnDelay]. - * - * @return uint32 respawnDelay : the respawn delay, in seconds - */ - int GetRespawnDelay(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetRespawnDelay()); - return 1; - } - - /** - * Returns the radius the [Creature] is permitted to wander from its - * respawn point. - * - * @return float wanderRadius - */ - int GetWanderRadius(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetWanderDistance()); - return 1; - } - - /** - * Returns the current waypoint path ID of the [Creature]. - * - * @return uint32 pathId - */ - int GetWaypointPath(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetWaypointPath()); - return 1; - } - - /** - * Returns the current waypoint ID of the [Creature]. - * - * @return uint32 wpId - */ - int GetCurrentWaypointId(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetCurrentWaypointID()); - return 1; - } - - /** - * Returns the spawn ID for this [Creature]. - * - * @return uint32 spawnId - */ - int GetSpawnId(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetSpawnId()); - return 1; - } - - /** - * Returns the default movement type for this [Creature]. - * - * @return [MovementGeneratorType] defaultMovementType - */ - int GetDefaultMovementType(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetDefaultMovementType()); - return 1; - } - - /** - * Returns the aggro range of the [Creature] for `target`. - * - * @param [Unit] target - * @return float aggroRange - */ - int GetAggroRange(lua_State* L, Creature* creature) - { - Unit* target = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, creature->GetAggroRange(target)); - return 1; - } - - /** - * Returns the [Group] that can loot this [Creature]. - * - * @return [Group] lootRecipientGroup : the group or `nil` - */ - int GetLootRecipientGroup(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetLootRecipientGroup()); - return 1; - } - - /** - * Returns the [Player] that can loot this [Creature]. - * - * @return [Player] lootRecipient : the player or `nil` - */ - int GetLootRecipient(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetLootRecipient()); - return 1; - } - - /** - * Returns the [Creature]'s script name. - * - * This is used by the core to apply C++ scripts to the Creature. - * - * It is not used by ALE. ALE will override AI scripts. - * - * @return string scriptName - */ - int GetScriptName(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetScriptName()); - return 1; - } - - /** - * Returns the [Creature]'s AI name. - * - * This is used by the core to assign the Creature's default AI. - * - * If the Creature is scripted by ALE, the AI is overriden. - * - * @return string AIName - */ - int GetAIName(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetAIName()); - return 1; - } - - /** - * Returns the [Creature]'s script ID. - * - * Every C++ script name is assigned a unique ID by the core. - * This returns the ID for this [Creature]'s script name. - * - * @return uint32 scriptID - */ - int GetScriptId(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetScriptId()); - return 1; - } - - /** - * Returns the [Creature]'s cooldown for `spellID`. - * - * @param uint32 spellID - * @return uint32 cooldown : the cooldown, in milliseconds - */ - int GetCreatureSpellCooldownDelay(lua_State* L, Creature* creature) - { - uint32 spell = ALE::CHECKVAL(L, 2); - - if (sSpellMgr->GetSpellInfo(spell)) - ALE::Push(L, creature->GetSpellCooldown(spell)); - else - ALE::Push(L, 0); - - return 1; - } - - /** - * Returns the delay between when the [Creature] dies and when its body despawns. - * - * @return uint32 corpseDelay : the delay, in seconds - */ - int GetCorpseDelay(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetCorpseDelay()); - return 1; - } - - /** - * Returns position the [Creature] returns to when evading from combat - * or respawning. - * - * @return float x - * @return float y - * @return float z - * @return float o - */ - int GetHomePosition(lua_State* L, Creature* creature) - { - float x, y, z, o; - creature->GetHomePosition(x, y, z, o); - - ALE::Push(L, x); - ALE::Push(L, y); - ALE::Push(L, z); - ALE::Push(L, o); - return 4; - } - - /** - * Sets the position the [Creature] returns to when evading from combat - * or respawning. - * - * @param float x - * @param float y - * @param float z - * @param float o - */ - int SetHomePosition(lua_State* L, Creature* creature) - { - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 3); - float z = ALE::CHECKVAL(L, 4); - float o = ALE::CHECKVAL(L, 5); - - creature->SetHomePosition(x, y, z, o); - return 0; - } - - enum SelectAggroTarget - { - SELECT_TARGET_RANDOM = 0, // Just selects a random target - SELECT_TARGET_TOPAGGRO, // Selects targes from top aggro to bottom - SELECT_TARGET_BOTTOMAGGRO, // Selects targets from bottom aggro to top - SELECT_TARGET_NEAREST, - SELECT_TARGET_FARTHEST - }; - - /** - * Returns a target from the [Creature]'s threat list based on the - * supplied arguments. - * - * enum SelectAggroTarget - * { - * SELECT_TARGET_RANDOM = 0, //Just selects a random target - * SELECT_TARGET_TOPAGGRO, //Selects targets from top aggro to bottom - * SELECT_TARGET_BOTTOMAGGRO, //Selects targets from bottom aggro to top - * SELECT_TARGET_NEAREST, - * SELECT_TARGET_FARTHEST - * }; - * - * For example, if you wanted to select the third-farthest [Player] - * within 50 yards that has the [Aura] "Corrupted Blood" (ID 24328), - * you could use this function like so: - * - * target = creature:GetAITarget(4, true, 3, 50, 24328) - * - * @param [SelectAggroTarget] targetType : how the threat list should be sorted - * @param bool playerOnly = false : if `true`, skips targets that aren't [Player]s - * @param uint32 position = 0 : used as an offset into the threat list. If `targetType` is random, used as the number of players from top of aggro to choose from - * @param float distance = 0.0 : if positive, the maximum distance for the target. If negative, the minimum distance - * @param int32 aura = 0 : if positive, the target must have this [Aura]. If negative, the the target must not have this Aura - * @return [Unit] target : the target, or `nil` - */ - int GetAITarget(lua_State* L, Creature* creature) - { - uint32 targetType = ALE::CHECKVAL(L, 2); - bool playerOnly = ALE::CHECKVAL(L, 3, false); - uint32 position = ALE::CHECKVAL(L, 4, 0); - float dist = ALE::CHECKVAL(L, 5, 0.0f); - int32 aura = ALE::CHECKVAL(L, 6, 0); - - auto const& threatlist = creature->GetThreatMgr().GetThreatList(); - - if (threatlist.empty()) - return 1; - if (position >= threatlist.size()) - return 1; - - std::list targetList; - - for (auto itr = threatlist.begin(); itr != threatlist.end(); ++itr) - { - Unit* target = (*itr)->getTarget(); - - if (!target) - continue; - if (playerOnly && target->GetTypeId() != TYPEID_PLAYER) - continue; - if (aura > 0 && !target->HasAura(aura)) - continue; - else if (aura < 0 && target->HasAura(-aura)) - continue; - if (dist > 0.0f && !creature->IsWithinDist(target, dist)) - continue; - else if (dist < 0.0f && creature->IsWithinDist(target, -dist)) - continue; - targetList.push_back(target); - } - - if (targetList.empty()) - return 1; - if (position >= targetList.size()) - return 1; - - if (targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) - targetList.sort(ALEUtil::ObjectDistanceOrderPred(creature)); - - switch (targetType) - { - case SELECT_TARGET_NEAREST: - case SELECT_TARGET_TOPAGGRO: - { - std::list::const_iterator itr = targetList.begin(); - if (position) - std::advance(itr, position); - ALE::Push(L, *itr); - } - break; - case SELECT_TARGET_FARTHEST: - case SELECT_TARGET_BOTTOMAGGRO: - { - std::list::reverse_iterator ritr = targetList.rbegin(); - if (position) - std::advance(ritr, position); - ALE::Push(L, *ritr); - } - break; - case SELECT_TARGET_RANDOM: - { - std::list::const_iterator itr = targetList.begin(); - if (position) - std::advance(itr, urand(0, position)); - else - std::advance(itr, urand(0, targetList.size() - 1)); - ALE::Push(L, *itr); - } - break; - default: - luaL_argerror(L, 2, "SelectAggroTarget expected"); - break; - } - - return 1; - } - - /** - * Returns all [Unit]s in the [Creature]'s threat list. - * - * @return table targets - */ - int GetAITargets(lua_State* L, Creature* creature) - { - auto const& threatlist = creature->GetThreatMgr().GetThreatList(); - - lua_createtable(L, threatlist.size(), 0); - int tbl = lua_gettop(L); - uint32 i = 0; - for (auto itr = threatlist.begin(); itr != threatlist.end(); ++itr) - { - Unit* target = (*itr)->getTarget(); - - if (!target) - continue; - - ALE::Push(L, target); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); - return 1; - } - - /** - * Returns the number of [Unit]s in this [Creature]'s threat list. - * - * @return int targetsCount - */ - int GetAITargetsCount(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetThreatMgr().GetThreatListSize()); - return 1; - } - - /** - * Returns the [Creature]'s NPC flags. - * - * These are used to control whether the NPC is a vendor, can repair items, - * can give quests, etc. - * - * @return [NPCFlags] npcFlags - */ - int GetNPCFlags(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetUInt32Value(UNIT_NPC_FLAGS)); - return 1; - } - - /** - * Returns the [Creature]'s Unit flags. - * - * These are used to control whether the NPC is attackable or not, among other things. - * - * @return [UnitFlags] unitFlags - */ - int GetUnitFlags(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetUInt32Value(UNIT_FIELD_FLAGS)); - return 1; - } - - /** - * Returns the [Creature]'s Unit flags 2. - * - * @return [UnitFlags2] unitFlags2 - */ - int GetUnitFlagsTwo(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetUInt32Value(UNIT_FIELD_FLAGS_2)); - return 1; - } - - /** - * Returns the [Creature]'s Extra flags. - * - * These are used to control whether the NPC is a civilian, uses pathfinding, - * if it's a guard, etc. - * - * @return [ExtraFlags] extraFlags - */ - int GetExtraFlags(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetCreatureTemplate()->flags_extra); - return 1; - } - - /** - * Returns the [Creature]'s rank. - * - * @return [Rank] rank - */ - int GetRank(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetCreatureTemplate()->rank); - return 1; - } - - /** - * Returns the [Creature]'s shield block value. - * - * @return uint32 shieldBlockValue - */ - int GetShieldBlockValue(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetShieldBlockValue()); - return 1; - } - - /** - * Returns the loot mode flags for the specified [Creature]. - * - * @param [Creature] creature : the creature whose loot mode to get - * @return uint16 lootMode : the loot mode bitmask of the creature - */ - int GetLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features - { - ALE::Push(L, creature->GetLootMode()); - return 1; - } - - /** - * Returns the guid of the [Creature] that is used as the ID in the database - * - * @return uint32 dbguid - */ - int GetDBTableGUIDLow(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->GetSpawnId()); - return 1; - } - - /** - * Returns the [Creature]'s current ReactState. - * - *
-     * enum ReactState
-     * {
-     *     REACT_PASSIVE       = 0,
-     *     REACT_DEFENSIVE     = 1,
-     *     REACT_AGGRESSIVE    = 2
-     * };
-     * 
- * - * @return [ReactState] state - */ - int GetReactState(lua_State* L, Creature* creature) - { - ReactStates state = creature->GetReactState(); - lua_pushinteger(L, (int)state); - return 1; - } - - /** - * Sets the [Creature]'s NPC flags to `flags`. - * - * @param [NPCFlags] flags - */ - int SetNPCFlags(lua_State* L, Creature* creature) - { - uint32 flags = ALE::CHECKVAL(L, 2); - - creature->SetUInt32Value(UNIT_NPC_FLAGS, flags); - return 0; - } - - /** - * Sets the [Creature]'s Unit flags to `flags`. - * - * @param [UnitFlags] flags - */ - int SetUnitFlags(lua_State* L, Creature* creature) - { - uint32 flags = ALE::CHECKVAL(L, 2); - creature->SetUInt32Value(UNIT_FIELD_FLAGS, flags); - return 0; - } - - /** - * Sets the [Creature]'s Unit flags2 to `flags`. - * - * @param [UnitFlags2] flags - */ - int SetUnitFlagsTwo(lua_State* L, Creature* creature) - { - uint32 flags = ALE::CHECKVAL(L, 2); - creature->SetUInt32Value(UNIT_FIELD_FLAGS_2, flags); - return 0; - } - - /** - * Sets the [Creature]'s ReactState to `state`. - * - * @param [ReactState] state - */ - int SetReactState(lua_State* L, Creature* creature) - { - uint32 state = ALE::CHECKVAL(L, 2); - - creature->SetReactState((ReactStates)state); - return 0; - } - - /** - * Makes the [Creature] able to fly if enabled. - * - * @param bool disable - */ - int SetDisableGravity(lua_State* L, Creature* creature) - { - bool disable = ALE::CHECKVAL(L, 2); - - creature->SetDisableGravity(disable); - return 0; - } - - /** - * Sets the loot mode flags for the specified [Creature]. - * - * @param [Creature] creature : the creature whose loot mode to set - * @param uint16 lootMode : the loot mode bitmask to apply - */ - int SetLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features - { - uint16 lootMode = ALE::CHECKVAL(L, 2); - - creature->SetLootMode(lootMode); - return 0; - } - - /** - * Sets the [Creature]'s death state to `deathState`. - * - * @param [DeathState] deathState - */ - int SetDeathState(lua_State* L, Creature* creature) - { - int32 state = ALE::CHECKVAL(L, 2); - - creature->setDeathState((DeathState)state); - return 0; - } - - /** - * Sets whether the [Creature] is currently walking or running. - * - * @param bool enable = true : `true` to enable walking, `false` for running - */ - int SetWalk(lua_State* L, Creature* creature) // TODO: Move same to Player ? - { - bool enable = ALE::CHECKVAL(L, 2, true); - - creature->SetWalk(enable); - return 0; - } - - /** - * Equips given [Item]s to the [Unit]. Using 0 removes the equipped [Item] - * - * @param uint32 main_hand : main hand [Item]'s entry - * @param uint32 off_hand : off hand [Item]'s entry - * @param uint32 ranged : ranged [Item]'s entry - */ - int SetEquipmentSlots(lua_State* L, Creature* creature) - { - uint32 main_hand = ALE::CHECKVAL(L, 2); - uint32 off_hand = ALE::CHECKVAL(L, 3); - uint32 ranged = ALE::CHECKVAL(L, 4); - - creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, main_hand); - creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, off_hand); - creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, ranged); - - return 0; - } - - /** - * Sets whether the [Creature] can be aggroed. - * - * @param bool allow = true : `true` to allow aggro, `false` to disable aggro - */ - int SetAggroEnabled(lua_State* L, Creature* creature) - { - bool allow = ALE::CHECKVAL(L, 2, true); - - if (allow) - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); - else - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); - - return 0; - } - - /** - * Sets whether the [Creature] gives reputation or not. - * - * @param bool disable = true : `true` to disable reputation, `false` to enable - */ - int SetDisableReputationGain(lua_State* L, Creature* creature) - { - bool disable = ALE::CHECKVAL(L, 2, true); - - creature->SetReputationRewardDisabled(disable); - return 0; - } - - /** - * Sets the [Creature] as in combat with all [Player]s in the dungeon instance. - * - * This is used by raid bosses to prevent Players from using out-of-combat - * actions once the encounter has begun. - */ - int SetInCombatWithZone(lua_State* /*L*/, Creature* creature) - { - if (creature->IsAIEnabled) - creature->AI()->DoZoneInCombat(); - - return 0; - } - - /** - * Sets the distance the [Creature] can wander from it's spawn point. - * - * @param float distance - */ - int SetWanderRadius(lua_State* L, Creature* creature) - { - float dist = ALE::CHECKVAL(L, 2); - - creature->SetWanderDistance(dist); - - return 0; - } - - /** - * Sets the time it takes for the [Creature] to respawn when killed. - * - * @param uint32 delay : the delay, in seconds - */ - int SetRespawnDelay(lua_State* L, Creature* creature) - { - uint32 delay = ALE::CHECKVAL(L, 2); - - creature->SetRespawnDelay(delay); - return 0; - } - - /** - * Sets the default movement type of the [Creature]. - * - * @param [MovementGeneratorType] type - */ - int SetDefaultMovementType(lua_State* L, Creature* creature) - { - int32 type = ALE::CHECKVAL(L, 2); - - creature->SetDefaultMovementType((MovementGeneratorType)type); - return 0; - } - - /** - * Sets whether the [Creature] can search for assistance at low health or not. - * - * @param bool enable = true : `true` to disable searching, `false` to allow - */ - int SetNoSearchAssistance(lua_State* L, Creature* creature) - { - bool val = ALE::CHECKVAL(L, 2, true); - - creature->SetNoSearchAssistance(val); - return 0; - } - - /** - * Sets whether the [Creature] can call nearby enemies for help in combat or not. - * - * @param bool enable = true : `true` to disable calling for help, `false` to enable - */ - int SetNoCallAssistance(lua_State* L, Creature* creature) - { - bool val = ALE::CHECKVAL(L, 2, true); - - creature->SetNoCallAssistance(val); - return 0; - } - - /** - * Sets whether the creature is hovering / levitating or not. - * - * @param bool enable = true : `true` to enable hovering, `false` to disable - */ - int SetHover(lua_State* L, Creature* creature) - { - bool enable = ALE::CHECKVAL(L, 2, true); - - creature->SetHover(enable); - - return 0; - } - - /** - * Despawn this [Creature]. - * - * @param uint32 delay = 0 : dely to despawn in milliseconds - */ - int DespawnOrUnsummon(lua_State* L, Creature* creature) - { - uint32 msTimeToDespawn = ALE::CHECKVAL(L, 2, 0); - creature->DespawnOrUnsummon(Milliseconds(msTimeToDespawn)); - - return 0; - } - - /** - * Respawn this [Creature]. - */ - int Respawn(lua_State* /*L*/, Creature* creature) - { - creature->Respawn(); - return 0; - } - - /** - * Remove this [Creature]'s corpse. - */ - int RemoveCorpse(lua_State* /*L*/, Creature* creature) - { - creature->RemoveCorpse(); - return 0; - } - - /** - * Sets the time it takes for the [Creature]'s corpse to despawn when killed. - * - * @param uint32 delay : the delay, in seconds - */ - int SetCorpseDelay(lua_State* L, Creature* creature) - { - uint32 delay = ALE::CHECKVAL(L, 2); - creature->SetCorpseDelay(delay); - return 0; - } - - /** - * Make the [Creature] start following its waypoint path. - */ - int MoveWaypoint(lua_State* /*L*/, Creature* creature) - { - creature->GetMotionMaster()->MoveWaypoint(creature->GetWaypointPath(), true); - - return 0; - } - - /** - * Make the [Creature] call for assistance in combat from other nearby [Creature]s. - */ - int CallAssistance(lua_State* /*L*/, Creature* creature) - { - creature->CallAssistance(); - return 0; - } - - /** - * Make the [Creature] call for help in combat from friendly [Creature]s within `radius`. - * - * @param float radius - */ - int CallForHelp(lua_State* L, Creature* creature) - { - float radius = ALE::CHECKVAL(L, 2); - - creature->CallForHelp(radius); - return 0; - } - - /** - * Make the [Creature] flee combat to get assistance from a nearby friendly [Creature]. - */ - int FleeToGetAssistance(lua_State* /*L*/, Creature* creature) - { - creature->DoFleeToGetAssistance(); - return 0; - } - - /** - * Make the [Creature] attack `target`. - * - * @param [Unit] target - */ - int AttackStart(lua_State* L, Creature* creature) - { - Unit* target = ALE::CHECKOBJ(L, 2); - - creature->AI()->AttackStart(target); - return 0; - } - - /** - * Save the [Creature] in the database. - */ - int SaveToDB(lua_State* /*L*/, Creature* creature) - { - creature->SaveToDB(); - return 0; - } - - /** - * Make the [Creature] try to find a new target. - * - * This should be called every update cycle for the Creature's AI. - */ - int SelectVictim(lua_State* L, Creature* creature) - { - ALE::Push(L, creature->SelectVictim()); - return 1; - } - - /** - * Transform the [Creature] into another Creature. - * - * @param uint32 entry : the Creature ID to transform into - * @param uint32 dataGUIDLow = 0 : use this Creature's model and equipment instead of the defaults - */ - int UpdateEntry(lua_State* L, Creature* creature) - { - uint32 entry = ALE::CHECKVAL(L, 2); - uint32 dataGuidLow = ALE::CHECKVAL(L, 3, 0); - - creature->UpdateEntry(entry, dataGuidLow ? eObjectMgr->GetCreatureData(dataGuidLow) : NULL); - return 0; - } - - /** - * Resets [Creature]'s loot mode to default - */ - int ResetLootMode(lua_State* /*L*/, Creature* creature) // TODO: Implement LootMode features - { - creature->ResetLootMode(); - return 0; - } - - /** - * Removes specified loot mode from [Creature] - * - * @param uint16 lootMode - */ - int RemoveLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features - { - uint16 lootMode = ALE::CHECKVAL(L, 2); - - creature->RemoveLootMode(lootMode); - return 0; - } - - /** - * Adds a loot mode to the [Creature] - * - * @param uint16 lootMode - */ - int AddLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features - { - uint16 lootMode = ALE::CHECKVAL(L, 2); - - creature->AddLootMode(lootMode); - return 0; - } - - /** - * Returns the [Creature]'s creature family ID (enumerated in CreatureFamily.dbc). - * - *
-     * enum CreatureFamily
-     * {
-     *     CREATURE_FAMILY_NONE                = 0,    // TrinityCore only
-     *     CREATURE_FAMILY_WOLF                = 1,
-     *     CREATURE_FAMILY_CAT                 = 2,
-     *     CREATURE_FAMILY_SPIDER              = 3,
-     *     CREATURE_FAMILY_BEAR                = 4,
-     *     CREATURE_FAMILY_BOAR                = 5,
-     *     CREATURE_FAMILY_CROCOLISK           = 6,
-     *     CREATURE_FAMILY_CARRION_BIRD        = 7,
-     *     CREATURE_FAMILY_CRAB                = 8,
-     *     CREATURE_FAMILY_GORILLA             = 9,
-     *     CREATURE_FAMILY_HORSE_CUSTOM        = 10,   // Does not exist in DBC but used for horse like beasts in DB
-     *     CREATURE_FAMILY_RAPTOR              = 11,
-     *     CREATURE_FAMILY_TALLSTRIDER         = 12,
-     *     CREATURE_FAMILY_FELHUNTER           = 15,
-     *     CREATURE_FAMILY_VOIDWALKER          = 16,
-     *     CREATURE_FAMILY_SUCCUBUS            = 17,
-     *     CREATURE_FAMILY_DOOMGUARD           = 19,
-     *     CREATURE_FAMILY_SCORPID             = 20,
-     *     CREATURE_FAMILY_TURTLE              = 21,
-     *     CREATURE_FAMILY_IMP                 = 23,
-     *     CREATURE_FAMILY_BAT                 = 24,
-     *     CREATURE_FAMILY_HYENA               = 25,
-     *     CREATURE_FAMILY_BIRD_OF_PREY        = 26,   // Named CREATURE_FAMILY_OWL in Mangos
-     *     CREATURE_FAMILY_WIND_SERPENT        = 27,
-     *     CREATURE_FAMILY_REMOTE_CONTROL      = 28,
-     *     CREATURE_FAMILY_FELGUARD            = 29,   // This and below is TBC+
-     *     CREATURE_FAMILY_DRAGONHAWK          = 30,
-     *     CREATURE_FAMILY_RAVAGER             = 31,
-     *     CREATURE_FAMILY_WARP_STALKER        = 32,
-     *     CREATURE_FAMILY_SPOREBAT            = 33,
-     *     CREATURE_FAMILY_NETHER_RAY          = 34,
-     *     CREATURE_FAMILY_SERPENT             = 35,
-     *     CREATURE_FAMILY_SEA_LION            = 36,   // TBC only
-     *     CREATURE_FAMILY_MOTH                = 37,   // This and below is WotLK+
-     *     CREATURE_FAMILY_CHIMAERA            = 38,
-     *     CREATURE_FAMILY_DEVILSAUR           = 39,
-     *     CREATURE_FAMILY_GHOUL               = 40,
-     *     CREATURE_FAMILY_SILITHID            = 41,
-     *     CREATURE_FAMILY_WORM                = 42,
-     *     CREATURE_FAMILY_RHINO               = 43,
-     *     CREATURE_FAMILY_WASP                = 44,
-     *     CREATURE_FAMILY_CORE_HOUND          = 45,
-     *     CREATURE_FAMILY_SPIRIT_BEAST        = 46
-     * };
-     * 
- * - * @return [CreatureFamily] creatureFamily - */ - int GetCreatureFamily(lua_State* L, Creature* creature) - { - uint32 entry = creature->GetEntry(); - - CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(entry); - if (cInfo) - ALE::Push(L, cInfo->family); - - return 1; - } - - /** - * Returns the [Creature]'s loot. - * - * @return [Loot] loot : the loot object - */ - int GetLoot(lua_State* L, Creature* creature) - { - ALE::Push(L, &creature->loot); - return 1; - } -}; -#endif diff --git a/src/LuaEngine/methods/GameObjectMethods.h b/src/LuaEngine/methods/GameObjectMethods.h deleted file mode 100644 index 43e8ffd33d..0000000000 --- a/src/LuaEngine/methods/GameObjectMethods.h +++ /dev/null @@ -1,373 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef GAMEOBJECTMETHODS_H -#define GAMEOBJECTMETHODS_H - -/*** - * Represents a game object in the world, such as doors, chests, and other interactive objects. - * - * Inherits all methods from: [Object], [WorldObject] - */ -namespace LuaGameObject -{ - /** - * Returns 'true' if the [GameObject] can give the specified [Quest] - * - * @param uint32 questId : quest entry Id to check - * @return bool hasQuest - */ - int HasQuest(lua_State* L, GameObject* go) - { - uint32 questId = ALE::CHECKVAL(L, 2); - - ALE::Push(L, go->hasQuest(questId)); - return 1; - } - - /** - * Returns 'true' if the [GameObject] is spawned - * - * @return bool isSpawned - */ - int IsSpawned(lua_State* L, GameObject* go) - { - ALE::Push(L, go->isSpawned()); - return 1; - } - - /** - * Returns 'true' if the [GameObject] is a transport - * - * @return bool isTransport - */ - int IsTransport(lua_State* L, GameObject* go) - { - ALE::Push(L, go->IsTransport()); - return 1; - } - - /** - * Returns 'true' if the [GameObject] is active - * - * @return bool isActive - */ - int IsActive(lua_State* L, GameObject* go) - { - ALE::Push(L, go->isActiveObject()); - return 1; - } - - /*int IsDestructible(lua_State* L, GameObject* go) // TODO: Implementation core side - { - ALE::Push(L, go->IsDestructibleBuilding()); - return 1; - }*/ - - /** - * Returns display ID of the [GameObject] - * - * @return uint32 displayId - */ - int GetDisplayId(lua_State* L, GameObject* go) - { - ALE::Push(L, go->GetDisplayId()); - return 1; - } - - /** - * Returns the state of a [GameObject] - * Below are client side [GOState]s off of 3.3.5a - * - *
-     * enum GOState
-     * {
-     *     GO_STATE_ACTIVE             = 0,                        // show in world as used and not reset (closed door open)
-     *     GO_STATE_READY              = 1,                        // show in world as ready (closed door close)
-     *     GO_STATE_ACTIVE_ALTERNATIVE = 2                         // show in world as used in alt way and not reset (closed door open by cannon fire)
-     * };
-     * 
- * - * @return [GOState] goState - */ - int GetGoState(lua_State* L, GameObject* go) - { - ALE::Push(L, go->GetGoState()); - return 1; - } - - /** - * Returns the [LootState] of a [GameObject] - * Below are [LootState]s off of 3.3.5a - * - *
-     * enum LootState
-     * {
-     *     GO_NOT_READY = 0,
-     *     GO_READY,                                               // can be ready but despawned, and then not possible activate until spawn
-     *     GO_ACTIVATED,
-     *     GO_JUST_DEACTIVATED
-     * };
-     * 
- * - * @return [LootState] lootState - */ - int GetLootState(lua_State* L, GameObject* go) - { - ALE::Push(L, go->getLootState()); - return 1; - } - - /** - * Returns the [Player] that can loot the [GameObject] - * - * Not the original looter and may be nil. - * - * @return [Player] player - */ - int GetLootRecipient(lua_State* L, GameObject* go) - { - ALE::Push(L, go->GetLootRecipient()); - return 1; - } - - /** - * Returns the [Group] that can loot the [GameObject] - * - * Not the original looter and may be nil. - * - * @return [Group] group - */ - int GetLootRecipientGroup(lua_State* L, GameObject* go) - { - ALE::Push(L, go->GetLootRecipientGroup()); - return 1; - } - - /** - * Returns the spawn ID for this [GameObject]. - * - * @return uint32 spawnId - */ - int GetSpawnId(lua_State* L, GameObject* go) - { - ALE::Push(L, go->GetSpawnId()); - return 1; - } - - /** - * Sets the state of a [GameObject] - * - *
-     * enum GOState
-     * {
-     *     GO_STATE_ACTIVE             = 0,                        // show in world as used and not reset (closed door open)
-     *     GO_STATE_READY              = 1,                        // show in world as ready (closed door close)
-     *     GO_STATE_ACTIVE_ALTERNATIVE = 2                         // show in world as used in alt way and not reset (closed door open by cannon fire)
-     * };
-     * 
- * - * @param [GOState] state : all available go states can be seen above - */ - int SetGoState(lua_State* L, GameObject* go) - { - uint32 state = ALE::CHECKVAL(L, 2, 0); - - if (state == 0) - go->SetGoState(GO_STATE_ACTIVE); - else if (state == 1) - go->SetGoState(GO_STATE_READY); - else if (state == 2) - go->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - - return 0; - } - - /** - * Sets the [LootState] of a [GameObject] - * Below are [LootState]s off of 3.3.5a - * - *
-     * enum LootState
-     * {
-     *     GO_NOT_READY = 0,
-     *     GO_READY,                                               // can be ready but despawned, and then not possible activate until spawn
-     *     GO_ACTIVATED,
-     *     GO_JUST_DEACTIVATED
-     * };
-     * 
- * - * @param [LootState] state : all available loot states can be seen above - */ - int SetLootState(lua_State* L, GameObject* go) - { - uint32 state = ALE::CHECKVAL(L, 2, 0); - - if (state == 0) - go->SetLootState(GO_NOT_READY); - else if (state == 1) - go->SetLootState(GO_READY); - else if (state == 2) - go->SetLootState(GO_ACTIVATED); - else if (state == 3) - go->SetLootState(GO_JUST_DEACTIVATED); - - return 0; - } - - /** - * Adds an [Item] to the loot of a [GameObject] - * Requires an gameobject with loot_template set to 0. - * - * @param uint32 entry : The entry of the [Item] - * @param uint32 amount = 1 : amount of the [Item] to add to the loot - * @return uint32 itemGUIDlow : low GUID of the [Item] - */ - int AddLoot(lua_State* L, GameObject* go) - { - int i = 1; - int argAmount = lua_gettop(L); - - CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); - - uint8 addedItems = 0; - while (i + 2 <= argAmount) - { - uint32 entry = ALE::CHECKVAL(L, ++i); - uint32 amount = ALE::CHECKVAL(L, ++i); - - ItemTemplate const* item_proto = eObjectMgr->GetItemTemplate(entry); - if (!item_proto) - { - luaL_error(L, "Item entry %d does not exist", entry); - continue; - } - if (amount < 1 || (item_proto->MaxCount > 0 && amount > uint32(item_proto->MaxCount))) - { - luaL_error(L, "Item entry %d has invalid amount %d", entry, amount); - continue; - } - if (Item* item = Item::CreateItem(entry, amount)) - { - item->SaveToDB(trans); - LootStoreItem storeItem(item->GetEntry(), 0, 100, 0, LOOT_MODE_DEFAULT, 0, item->GetCount(), item->GetCount()); - go->loot.AddItem(storeItem); - ALE::Push(L, item->GetGUID().GetCounter()); - ++addedItems; - } - } - - CharacterDatabase.CommitTransaction(trans); - - return addedItems; - } - - /** - * Saves [GameObject] to the database - * - */ - int SaveToDB(lua_State* /*L*/, GameObject* go) - { - go->SaveToDB(); - return 0; - } - - /** - * Removes [GameObject] from the world - * - * The object is no longer reachable after this and it is not respawned. - * - * @param bool deleteFromDB : if true, it will delete the [GameObject] from the database - */ - int RemoveFromWorld(lua_State* L, GameObject* go) - { - bool deldb = ALE::CHECKVAL(L, 2, false); - - // cs_gobject.cpp copy paste - ObjectGuid ownerGuid = go->GetOwnerGUID(); - if (ownerGuid) - { - Unit* owner = eObjectAccessor()GetUnit(*go, ownerGuid); - if (!owner || !ownerGuid.IsPlayer()) - return 0; - - owner->RemoveGameObject(go, false); - } - - if (deldb) - go->DeleteFromDB(); - - go->SetRespawnTime(0); - go->Delete(); - - ALE::CHECKOBJ(L, 1)->Invalidate(); - return 0; - } - - /** - * Activates a door or a button/lever - * - * @param uint32 delay = 0 : cooldown time in seconds to restore the [GameObject] back to normal. 0 for infinite duration - */ - int UseDoorOrButton(lua_State* L, GameObject* go) - { - uint32 delay = ALE::CHECKVAL(L, 2, 0); - - go->UseDoorOrButton(delay); - return 0; - } - - /** - * Despawns a [GameObject] - * - * The gameobject may be automatically respawned by the core - */ - int Despawn(lua_State* /*L*/, GameObject* go) - { - go->SetLootState(GO_JUST_DEACTIVATED); - return 0; - } - - /** - * Respawns a [GameObject] - */ - int Respawn(lua_State* /*L*/, GameObject* go) - { - go->Respawn(); - return 0; - } - - /** - * Sets the respawn or despawn time for the gameobject. - * - * Respawn time is also used as despawn time depending on gameobject settings - * - * @param int32 delay = 0 : cooldown time in seconds to respawn or despawn the object. 0 means never - */ - int SetRespawnTime(lua_State* L, GameObject* go) - { - int32 respawn = ALE::CHECKVAL(L, 2); - - go->SetRespawnTime(respawn); - return 0; - } - - /** - * Sets the respawn or despawn time for the gameobject. - * - * Respawn time is also used as despawn time depending on gameobject settings - * - * @param int32 delay = 0 : cooldown time in seconds to respawn or despawn the object. 0 means never - */ - int SetRespawnDelay(lua_State* L, GameObject* go) - { - int32 respawn = ALE::CHECKVAL(L, 2); - - go->SetRespawnDelay(respawn); - return 0; - } -}; -#endif diff --git a/src/LuaEngine/methods/GemPropertiesEntryMethods.h b/src/LuaEngine/methods/GemPropertiesEntryMethods.h deleted file mode 100644 index b76edae2b9..0000000000 --- a/src/LuaEngine/methods/GemPropertiesEntryMethods.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef GEMPROPERTIESENTRYMETHODS_H -#define GEMPROPERTIESENTRYMETHODS_H - -/*** - * Represents static gem data used in item enhancement, including spell enchantments triggered by socketed gems. - * - * Provides access to gem-related properties from the DBC table `GemProperties.dbc`. - * - * Inherits all methods from: none - */ -namespace LuaGemPropertiesEntry -{ - - /** - * Returns the ID of a [GemPropertiesEntry]. - * - * This method retrieves the ID from a given GemPropertiesEntry instance - * and pushes it onto the Lua stack. - * - * @return uint32 id : The ID of the specified GemPropertiesEntry. - */ - int GetId(lua_State* L, GemPropertiesEntry* gemProperties) - { - ALE::Push(L, gemProperties->ID); - return 1; - } - - /** - * Returns the spell item enchantment of a [GemPropertiesEntry]. - * - * This function retrieves the `spellitemenchantement` attribute from the provided `GemPropertiesEntry`. - * - * @return uint32 spellitemenchantement : The spell item enchantment ID. - */ - int GetSpellItemEnchantement(lua_State* L, GemPropertiesEntry* entry) - { - ALE::Push(L, entry->spellitemenchantement); - return 1; - } -} -#endif - diff --git a/src/LuaEngine/methods/GlobalMethods.h b/src/LuaEngine/methods/GlobalMethods.h index 367f6b34d1..2a9e115aa2 100644 --- a/src/LuaEngine/methods/GlobalMethods.h +++ b/src/LuaEngine/methods/GlobalMethods.h @@ -1,3561 +1,261 @@ /* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef GLOBALMETHODS_H -#define GLOBALMETHODS_H + * Copyright (C) 2010 - 2026 ALE - AzerothCore Lua Engine + * This program is free software licensed under GPL version 3 + * Please see the included DOCS/LICENSE.md for more information + */ -#include "BindingMap.h" -#include "ALEDBCRegistry.h" +#ifndef _ECLIPSE_GLOBAL_METHODS_H +#define _ECLIPSE_GLOBAL_METHODS_H -#include "BanMgr.h" -#include "GameTime.h" -#include "SharedDefines.h" -#include "OutdoorPvPMgr.h" -#include "../../../../src/server/scripts/OutdoorPvP/OutdoorPvPNA.h" +#include +#include "EventManager.h" +#include "Common.h" +// Forward declarations +class Player; +class Creature; +class GameObject; -enum BanMode +namespace Eclipse::Core { - BAN_ACCOUNT = 1, - BAN_CHARACTER = 2, - BAN_IP = 3 -}; + class TimedEventManager; +} -/*** - * These functions can be used anywhere at any time, including at start-up. - */ -namespace LuaGlobalFunctions +namespace Eclipse::Methods { /** - * Returns Lua engine's name. - * - * Always returns "ALEEngine" on ALE. - * - * @return string engineName - */ - int GetLuaEngine(lua_State* L) - { - ALE::Push(L, "ALEEngine"); - return 1; - } - - /** - * Returns emulator's name. - * - * The result will be either `MaNGOS`, `cMaNGOS`, or `TrinityCore`. - * - * @return string coreName - */ - int GetCoreName(lua_State* L) - { - ALE::Push(L, CORE_NAME); - return 1; - } - - /** - * Returns config value as a string. - * - * @param string name : name of the value - * @return string value - */ - int GetConfigValue(lua_State* L) - { - const char* key = ALE::CHECKVAL(L, 1); - if (!key) return 0; - - std::string val = sConfigMgr->GetOption(key, "", false); - - if (val.empty()) - { - ALE::Push(L, val); - return 1; - } - - std::string lower = val; - std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); - - if (lower == "true") - { - ALE::Push(L, true); - return 1; - } - else if (lower == "false") - { - ALE::Push(L, false); - return 1; - } - - auto intVal = Acore::StringTo(val); - if (intVal) { - ALE::Push(L, *intVal); - return 1; - } - - ALE::Push(L, val); - return 1; - } - - /** - * Returns emulator .conf RealmID - * - * - for MaNGOS returns the realmID as it is stored in the core. - * - for TrinityCore returns the realmID as it is in the conf file. - * @return uint32 realm ID - */ - int GetRealmID(lua_State* L) - { - ALE::Push(L, sConfigMgr->GetOption("RealmID", 1)); - return 1; - } - - /** - * Returns emulator version - * - * - For TrinityCore returns the date of the last revision, e.g. `2015-08-26 22:53:12 +0300` - * - For cMaNGOS returns the date and time of the last revision, e.g. `2015-09-06 13:18:50` - * - for MaNGOS returns the version number as string, e.g. `21000` - * - * @return string version - */ - int GetCoreVersion(lua_State* L) - { - ALE::Push(L, CORE_VERSION); - return 1; - } - - /** - * Returns emulator's supported expansion. - * - * Expansion is 0 for pre-TBC, 1 for TBC, 2 for WotLK, and 3 for Cataclysm. - * - * @return int32 expansion - */ - int GetCoreExpansion(lua_State* L) - { - ALE::Push(L, 2); - return 1; - } - - /** - * Returns the [Map] pointer of the Lua state. Returns null for the "World" state. - * - * @return [Map] map - */ - int GetStateMap(lua_State* L) - { - // Until AC supports multistate, this will always return nil - ALE::Push(L); - return 1; - } - - /** - * Returns the map ID of the Lua state. Returns -1 for the "World" state. - * - * @return int32 mapId - */ - int GetStateMapId(lua_State* L) - { - // Until AC supports multistate, this will always return -1 - ALE::Push(L, -1); - return 1; - } - - /** - * Returns the instance ID of the Lua state. Returns 0 for continent maps and the world state. - * - * @return uint32 instanceId - */ - int GetStateInstanceId(lua_State* L) - { - // Until AC supports multistate, this will always return 0 - ALE::Push(L, 0); - return 1; - } - - /** - * Returns [Quest] template - * - * @param uint32 questId : [Quest] entry ID - * @return [Quest] quest - */ - int GetQuest(lua_State* L) - { - uint32 questId = ALE::CHECKVAL(L, 1); - - ALE::Push(L, eObjectMgr->GetQuestTemplate(questId)); - return 1; - } - - /** - * Finds and Returns [Player] by guid if found - * - * @param ObjectGuid guid : guid of the [Player], you can get it with [Object:GetGUID] - * @return [Player] player - */ - int GetPlayerByGUID(lua_State* L) - { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - ALE::Push(L, eObjectAccessor()FindPlayer(guid)); - return 1; - } - - /** - * Finds and Returns [Player] by name if found - * - * @param string name : name of the [Player] - * @return [Player] player - */ - int GetPlayerByName(lua_State* L) - { - const char* name = ALE::CHECKVAL(L, 1); - ALE::Push(L, eObjectAccessor()FindPlayerByName(name)); - return 1; - } - - /** - * Returns game time in seconds - * - * @return uint32 time - */ - int GetGameTime(lua_State* L) - { - ALE::Push(L, GameTime::GetGameTime().count()); - return 1; - } - - /** - * Returns a table with all the current [Player]s in the world - * - * Does not return players that may be teleporting or otherwise not on any map. - * - * enum TeamId - * { - * TEAM_ALLIANCE = 0, - * TEAM_HORDE = 1, - * TEAM_NEUTRAL = 2 - * }; - * - * @param [TeamId] team = TEAM_NEUTRAL : optional check team of the [Player], Alliance, Horde or Neutral (All) - * @param bool onlyGM = false : optional check if GM only - * @return table worldPlayers - */ - int GetPlayersInWorld(lua_State* L) - { - uint32 team = ALE::CHECKVAL(L, 1, TEAM_NEUTRAL); - bool onlyGM = ALE::CHECKVAL(L, 2, false); - - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - { - std::shared_lock lock(*HashMapHolder::GetLock()); - const HashMapHolder::MapType& m = eObjectAccessor()GetPlayers(); - for (HashMapHolder::MapType::const_iterator it = m.begin(); it != m.end(); ++it) - { - if (Player* player = it->second) - { - if (!player->IsInWorld()) - continue; - - if ((team == TEAM_NEUTRAL || player->GetTeamId() == team) && (!onlyGM || player->IsGameMaster())) - { - ALE::Push(L, player); - lua_rawseti(L, tbl, ++i); - } - } - } - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a [Guild] by name. - * - * @param string name - * @return [Guild] guild : the Guild, or `nil` if it doesn't exist - */ - int GetGuildByName(lua_State* L) - { - const char* name = ALE::CHECKVAL(L, 1); - ALE::Push(L, eGuildMgr->GetGuildByName(name)); - return 1; - } - - /** - * Returns a [Map] by ID. - * - * @param uint32 mapId : see [Map.dbc](https://github.com/cmangos/issues/wiki/Map.dbc) - * @param uint32 instanceId = 0 : required if the map is an instance, otherwise don't pass anything - * @return [Map] map : the Map, or `nil` if it doesn't exist - */ - int GetMapById(lua_State* L) - { - uint32 mapid = ALE::CHECKVAL(L, 1); - uint32 instance = ALE::CHECKVAL(L, 2, 0); - - ALE::Push(L, eMapMgr->FindMap(mapid, instance)); - return 1; - } - - /** - * Returns [Guild] by the leader's GUID - * - * @param ObjectGuid guid : the guid of a [Guild] leader - * @return [Guild] guild, or `nil` if it doesn't exist - */ - int GetGuildByLeaderGUID(lua_State* L) - { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - - ALE::Push(L, eGuildMgr->GetGuildByLeader(guid)); - return 1; - } - - /** - * Returns the amount of [Player]s in the world. - * - * @return uint32 count - */ - int GetPlayerCount(lua_State* L) - { - ALE::Push(L, eWorldSessionMgr->GetActiveSessionCount()); - return 1; - } - - /** - * Builds a [Player]'s GUID - * - * [Player] GUID consist of low GUID and type ID - * - * [Player] and [Creature] for example can have the same low GUID but not GUID. - * - * @param uint32 lowguid : low GUID of the [Player] - * @return ObjectGuid guid - */ - int GetPlayerGUID(lua_State* L) - { - uint32 lowguid = ALE::CHECKVAL(L, 1); - ALE::Push(L, MAKE_NEW_GUID(lowguid, 0, HIGHGUID_PLAYER)); - return 1; - } - - /** - * Builds an [Item]'s GUID. - * - * [Item] GUID consist of low GUID and type ID - * [Player] and [Item] for example can have the same low GUID but not GUID. - * - * @param uint32 lowguid : low GUID of the [Item] - * @return ObjectGuid guid - */ - int GetItemGUID(lua_State* L) - { - uint32 lowguid = ALE::CHECKVAL(L, 1); - ALE::Push(L, MAKE_NEW_GUID(lowguid, 0, HIGHGUID_ITEM)); - return 1; - } - - /** - * Returns the [ItemTemplate] for the specified item ID. The ItemTemplate contains all static data about an item, such as name, quality, stats, required level, and more. - * - * @param uint32 itemID : the item entry ID from `item_template` to look up - * @return [ItemTemplate] itemTemplate - */ - int GetItemTemplate(lua_State* L) - { - uint32 entry = ALE::CHECKVAL(L, 1); - ALE::Push(L, eObjectMgr->GetItemTemplate(entry)); - return 1; - } - - /** - * Builds a [GameObject]'s GUID. - * - * A GameObject's GUID consist of entry ID, low GUID and type ID - * - * A [Player] and GameObject for example can have the same low GUID but not GUID. - * - * @param uint32 lowguid : low GUID of the [GameObject] - * @param uint32 entry : entry ID of the [GameObject] - * @return ObjectGuid guid - */ - int GetObjectGUID(lua_State* L) - { - uint32 lowguid = ALE::CHECKVAL(L, 1); - uint32 entry = ALE::CHECKVAL(L, 2); - ALE::Push(L, MAKE_NEW_GUID(lowguid, entry, HIGHGUID_GAMEOBJECT)); - return 1; - } - - /** - * Builds a [Creature]'s GUID. - * - * [Creature] GUID consist of entry ID, low GUID and type ID - * - * [Player] and [Creature] for example can have the same low GUID but not GUID. - * - * @param uint32 lowguid : low GUID of the [Creature] - * @param uint32 entry : entry ID of the [Creature] - * @return ObjectGuid guid - */ - int GetUnitGUID(lua_State* L) - { - uint32 lowguid = ALE::CHECKVAL(L, 1); - uint32 entry = ALE::CHECKVAL(L, 2); - ALE::Push(L, MAKE_NEW_GUID(lowguid, entry, HIGHGUID_UNIT)); - return 1; - } - - /** - * Returns the low GUID from a GUID. - * - * A GUID consists of a low GUID, type ID, and possibly an entry ID depending on the type ID. - * - * Low GUID is an ID to distinct the objects of the same type. - * - * [Player] and [Creature] for example can have the same low GUID but not GUID. - * - * On TrinityCore all low GUIDs are different for all objects of the same type. - * For example creatures in instances are assigned new GUIDs when the Map is created. - * - * On MaNGOS and cMaNGOS low GUIDs are unique only on the same map. - * For example creatures in instances use the same low GUID assigned for that spawn in the database. - * This is why to identify a creature you have to know the instanceId and low GUID. See [Map:GetIntstanceId] - * - * @param ObjectGuid guid : GUID of an [Object] - * @return uint32 lowguid : low GUID of the [Object] - */ - int GetGUIDLow(lua_State* L) - { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - - ALE::Push(L, guid.GetCounter()); - return 1; - } - - /** - * Returns an chat link for an [Item]. - * - * enum LocaleConstant - * { - * LOCALE_enUS = 0, - * LOCALE_koKR = 1, - * LOCALE_frFR = 2, - * LOCALE_deDE = 3, - * LOCALE_zhCN = 4, - * LOCALE_zhTW = 5, - * LOCALE_esES = 6, - * LOCALE_esMX = 7, - * LOCALE_ruRU = 8 - * }; - * - * @param uint32 entry : entry ID of an [Item] - * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the [Item] name in - * @return string itemLink - */ - int GetItemLink(lua_State* L) - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE); - if (locale >= TOTAL_LOCALES) - return luaL_argerror(L, 2, "valid LocaleConstant expected"); - - const ItemTemplate* temp = eObjectMgr->GetItemTemplate(entry); - if (!temp) - return luaL_argerror(L, 1, "valid ItemEntry expected"); - - std::string name = temp->Name1; - if (ItemLocale const* il = eObjectMgr->GetItemLocale(entry)) - ObjectMgr::GetLocaleString(il->Name, static_cast(locale), name); - - std::ostringstream oss; - oss << "|c" << std::hex << ItemQualityColors[temp->Quality] << std::dec << - "|Hitem:" << entry << ":0:" << - "0:0:0:0:" << - "0:0:0:0|h[" << name << "]|h|r"; - - ALE::Push(L, oss.str()); - return 1; - } - - /** - * Returns the type ID from a GUID. - * - * Type ID is different for each type ([Player], [Creature], [GameObject], etc.). - * - * GUID consist of entry ID, low GUID, and type ID. - * - * @param ObjectGuid guid : GUID of an [Object] - * @return int32 typeId : type ID of the [Object] - */ - int GetGUIDType(lua_State* L) - { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - ALE::Push(L, static_cast(guid.GetHigh())); - return 1; - } - - /** - * Returns the entry ID from a GUID. - * - * GUID consist of entry ID, low GUID, and type ID. - * - * @param ObjectGuid guid : GUID of an [Creature] or [GameObject] - * @return uint32 entry : entry ID, or `0` if `guid` is not a [Creature] or [GameObject] - */ - int GetGUIDEntry(lua_State* L) - { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - ALE::Push(L, guid.GetEntry()); - return 1; - } - - /** - * Returns the byte size in bytes (2-9) of the ObjectGuid when packed. - * - * @param ObjectGuid guid : the ObjectGuid to get packed size for - * @return number size - */ - int GetPackedGUIDSize(lua_State* L) - { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - PackedGuid packedGuid(guid); - ALE::Push(L, static_cast(packedGuid.size())); - return 1; - } - - /** - * Returns the area or zone's name. - * - * enum LocaleConstant - * { - * LOCALE_enUS = 0, - * LOCALE_koKR = 1, - * LOCALE_frFR = 2, - * LOCALE_deDE = 3, - * LOCALE_zhCN = 4, - * LOCALE_zhTW = 5, - * LOCALE_esES = 6, - * LOCALE_esMX = 7, - * LOCALE_ruRU = 8 - * }; - * - * @param uint32 areaOrZoneId : area ID or zone ID - * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the name in - * @return string areaOrZoneName - */ - int GetAreaName(lua_State* L) - { - uint32 areaOrZoneId = ALE::CHECKVAL(L, 1); - uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE); - if (locale >= TOTAL_LOCALES) - return luaL_argerror(L, 2, "valid LocaleConstant expected"); - - AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaOrZoneId); - - if (!areaEntry) - return luaL_argerror(L, 1, "valid Area or Zone ID expected"); - - ALE::Push(L, areaEntry->area_name[locale]); - return 1; - } - - /** - * Returns the currently active game events. - * - * @return table activeEvents - */ - int GetActiveGameEvents(lua_State* L) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 counter = 1; - GameEventMgr::ActiveEvents const& activeEvents = eGameEventMgr->GetActiveEventList(); - - for (GameEventMgr::ActiveEvents::const_iterator i = activeEvents.begin(); i != activeEvents.end(); ++i) - { - ALE::Push(L, *i); - lua_rawseti(L, tbl, counter); - - counter++; - } - - lua_settop(L, tbl); - return 1; - } - - static int RegisterEntryHelper(lua_State* L, int regtype) - { - uint32 id = ALE::CHECKVAL(L, 1); - uint32 ev = ALE::CHECKVAL(L, 2); - luaL_checktype(L, 3, LUA_TFUNCTION); - uint32 shots = ALE::CHECKVAL(L, 4, 0); - - lua_pushvalue(L, 3); - int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); - if (functionRef >= 0) - return ALE::GetALE(L)->Register(L, regtype, id, ObjectGuid(), 0, ev, functionRef, shots); - else - luaL_argerror(L, 3, "unable to make a ref to function"); - return 0; - } - - static int RegisterEventHelper(lua_State* L, int regtype) - { - uint32 ev = ALE::CHECKVAL(L, 1); - luaL_checktype(L, 2, LUA_TFUNCTION); - uint32 shots = ALE::CHECKVAL(L, 3, 0); - - lua_pushvalue(L, 2); - int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); - if (functionRef >= 0) - return ALE::GetALE(L)->Register(L, regtype, 0, ObjectGuid(), 0, ev, functionRef, shots); - else - luaL_argerror(L, 2, "unable to make a ref to function"); - return 0; - } - - static int RegisterUniqueHelper(lua_State* L, int regtype) - { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - uint32 instanceId = ALE::CHECKVAL(L, 2); - uint32 ev = ALE::CHECKVAL(L, 3); - luaL_checktype(L, 4, LUA_TFUNCTION); - uint32 shots = ALE::CHECKVAL(L, 5, 0); - - lua_pushvalue(L, 4); - int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); - if (functionRef >= 0) - return ALE::GetALE(L)->Register(L, regtype, 0, guid, instanceId, ev, functionRef, shots); - else - luaL_argerror(L, 4, "unable to make a ref to function"); - return 0; - } - - /** - * Registers a server event handler. - * - * 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, newPacket - * 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, newPacket - * - * // World - * WORLD_EVENT_ON_OPEN_STATE_CHANGE = 8, // (event, open) - Needs core support on Mangos - * WORLD_EVENT_ON_CONFIG_LOAD = 9, // (event, reload) - * // UNUSED = 10, - * 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) - * - * // ALE - * ALE_EVENT_ON_LUA_STATE_CLOSE = 16, // (event) - triggers just before shutting down ALE (on shutdown and restart) - * - * // 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) - * - * // Area trigger - * TRIGGER_EVENT_ON_TRIGGER = 24, // (event, player, triggerId) - Can return true - * - * // Weather - * WEATHER_EVENT_ON_CHANGE = 25, // (event, zoneId, state, grade) - * - * // Auction house - * AUCTION_EVENT_ON_ADD = 26, // (event, auctionId, owner, item, expireTime, buyout, startBid, currentBid, bidderGUIDLow) - * AUCTION_EVENT_ON_REMOVE = 27, // (event, auctionId, owner, item, expireTime, buyout, startBid, currentBid, bidderGUIDLow) - * AUCTION_EVENT_ON_SUCCESSFUL = 28, // (event, auctionId, owner, item, expireTime, buyout, startBid, currentBid, bidderGUIDLow) - * AUCTION_EVENT_ON_EXPIRE = 29, // (event, auctionId, owner, item, expireTime, buyout, startBid, currentBid, bidderGUIDLow) - * - * // AddOns - * ADDON_EVENT_ON_MESSAGE = 30, // (event, sender, type, prefix, msg, target) - target can be nil/whisper_target/guild/group/channel. Can return false - * - * WORLD_EVENT_ON_DELETE_CREATURE = 31, // (event, creature) - * WORLD_EVENT_ON_DELETE_GAMEOBJECT = 32, // (event, gameobject) - * - * // ALE - * ALE_EVENT_ON_LUA_STATE_OPEN = 33, // (event) - triggers after all scripts are loaded - * - * GAME_EVENT_START = 34, // (event, gameeventid) - * GAME_EVENT_STOP = 35, // (event, gameeventid) - * }; - * - * @proto cancel = (event, function) - * @proto cancel = (event, function, shots) - * - * @param uint32 event : server event ID, refer to ServerEvents above - * @param function function : function that will be called when the event occurs - * @param uint32 shots = 0 : the number of times the function will be called, 0 means "always call this function" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterServerEvent(lua_State* L) - { - return RegisterEventHelper(L, Hooks::REGTYPE_SERVER); - } - - /** - * Registers a [Player] event handler. - * - *
-     * 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, source) - Can return new XP amount
-     *     PLAYER_EVENT_ON_LEVEL_CHANGE                         =     13,       // (event, player, oldLevel)
-     *     PLAYER_EVENT_ON_MONEY_CHANGE                         =     14,       // (event, player, amount) - Can return new money amount
-     *     PLAYER_EVENT_ON_REPUTATION_CHANGE                    =     15,       // (event, player, factionId, standing, incremental) - Can return new standing -> if standing == -1, it will prevent default action (rep gain)
-     *     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, newMessage
-     *     PLAYER_EVENT_ON_WHISPER                              =     19,       // (event, player, msg, Type, lang, receiver) - Can return false, newMessage
-     *     PLAYER_EVENT_ON_GROUP_CHAT                           =     20,       // (event, player, msg, Type, lang, group) - Can return false, newMessage
-     *     PLAYER_EVENT_ON_GUILD_CHAT                           =     21,       // (event, player, msg, Type, lang, guild) - Can return false, newMessage
-     *     PLAYER_EVENT_ON_CHANNEL_CHAT                         =     22,       // (event, player, msg, Type, lang, channel) - channel is negative for custom channels. Can return false, newMessage
-     *     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)
-     *
-     *     // 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) - Can return InventoryResult enum value
-     *     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)
-     *     PLAYER_EVENT_ON_LEARN_TALENTS                        =     39,       // (event, player, talentId, talentRank, spellid)
-     *     // UNUSED                                            =     40,       // (event, player)
-     *     // UNUSED                                            =     41,       // (event, player)
-     *     PLAYER_EVENT_ON_COMMAND                              =     42,       // (event, player, command, chatHandler) - player is nil if command used from console. Can return false
-     *     PLAYER_EVENT_ON_PET_ADDED_TO_WORLD                   =     43,       // (event, player, pet)
-     *     PLAYER_EVENT_ON_LEARN_SPELL                          =     44,       // (event, player, spellId)
-     *     PLAYER_EVENT_ON_ACHIEVEMENT_COMPLETE                 =     45,       // (event, player, achievement)
-     *     PLAYER_EVENT_ON_FFAPVP_CHANGE                        =     46,       // (event, player, hasFfaPvp)
-     *     PLAYER_EVENT_ON_UPDATE_AREA                          =     47,       // (event, player, oldArea, newArea)
-     *     PLAYER_EVENT_ON_CAN_INIT_TRADE                       =     48,       // (event, player, target) - Can return false to prevent the trade
-     *     PLAYER_EVENT_ON_CAN_SEND_MAIL                        =     49,       // (event, player, receiverGuid, mailbox, subject, body, money, cod, item) - Can return false to prevent sending the mail
-     *     PLAYER_EVENT_ON_CAN_JOIN_LFG                         =     50,       // (event, player, roles, dungeons, comment) - Can return false to prevent queueing
-     *     PLAYER_EVENT_ON_QUEST_REWARD_ITEM                    =     51,       //  (event, player, item, count)
-     *     PLAYER_EVENT_ON_CREATE_ITEM                          =     52,       //  (event, player, item, count)
-     *     PLAYER_EVENT_ON_STORE_NEW_ITEM                       =     53,       //  (event, player, item, count)
-     *     PLAYER_EVENT_ON_COMPLETE_QUEST                       =     54,       // (event, player, quest)
-     *     PLAYER_EVENT_ON_CAN_GROUP_INVITE                     =     55,       // (event, player, memberName) - Can return false to prevent inviting
-     *     PLAYER_EVENT_ON_GROUP_ROLL_REWARD_ITEM               =     56,       // (event, player, item, count, voteType, roll)
-     *     PLAYER_EVENT_ON_BG_DESERTION                         =     57,       // (event, player, type)
-     *     PLAYER_EVENT_ON_PET_KILL                             =     58,       // (event, player, killer)
-     *     PLAYER_EVENT_ON_CAN_RESURRECT                        =     59,       // (event, player)
-     *     PLAYER_EVENT_ON_CAN_UPDATE_SKILL                     =     60,       // (event, player, skill_id) -- Can return true or false
-     *     PLAYER_EVENT_ON_BEFORE_UPDATE_SKILL                  =     61,       // (event, player, skill_id, value, max, step) -- Can return new amount
-     *     PLAYER_EVENT_ON_UPDATE_SKILL                         =     62,       // (event, player, skill_id, value, max, step, new_value)
-     *     PLAYER_EVENT_ON_QUEST_ACCEPT                         =     63,       // (event, player, quest)
-     *     PLAYER_EVENT_ON_AURA_APPLY                           =     64,       // (event, player, aura)
-     *     PLAYER_EVENT_ON_HEAL                                 =     65,       // (event, player, target, heal) - Can return new heal amount
-     *     PLAYER_EVENT_ON_DAMAGE                               =     66,       // (event, player, target, damage) - Can return new damage amount
-     *     PLAYER_EVENT_ON_AURA_REMOVE                          =     67,       // (event, player, aura, remove_mode)
-     *     PLAYER_EVENT_ON_MODIFY_PERIODIC_DAMAGE_AURAS_TICK    =     68,    // (event, player, target, damage, spellInfo) - Can return new damage amount
-     *     PLAYER_EVENT_ON_MODIFY_MELEE_DAMAGE                  =     69,       // (event, player, target, damage) - Can return new damage amount
-     *     PLAYER_EVENT_ON_MODIFY_SPELL_DAMAGE_TAKEN            =     70,       // (event, player, target, damage, spellInfo) - Can return new damage amount
-     *     PLAYER_EVENT_ON_MODIFY_HEAL_RECEIVED                 =     71,       // (event, player, target, heal, spellInfo) - Can return new heal amount
-     *     PLAYER_EVENT_ON_DEAL_DAMAGE                          =     72,       // (event, player, target, damage, damagetype) - Can return new damage amount
-     * };
-     * 
- * - * @proto cancel = (event, function) - * @proto cancel = (event, function, shots) - * - * @param uint32 event : [Player] event Id, refer to PlayerEvents 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" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterPlayerEvent(lua_State* L) - { - return RegisterEventHelper(L, Hooks::REGTYPE_PLAYER); - } - - /** - * Registers a [Guild] event handler. - * - *
-     * enum GuildEvents
-     * {
-     *     // Guild
-     *     GUILD_EVENT_ON_ADD_MEMBER               =     1,       // (event, guild, player, rank)
-     *     GUILD_EVENT_ON_REMOVE_MEMBER            =     2,       // (event, guild, player, 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) - Can return new money amount
-     *     GUILD_EVENT_ON_MONEY_DEPOSIT            =     8,       // (event, guild, player, amount) - Can return new money 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)
-     *
-     *     GUILD_EVENT_COUNT
-     * };
-     * 
- * - * @proto cancel = (event, function) - * @proto cancel = (event, function, shots) - * - * @param uint32 event : [Guild] event Id, refer to GuildEvents 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" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterGuildEvent(lua_State* L) - { - return RegisterEventHelper(L, Hooks::REGTYPE_GUILD); - } - - /** - * Registers a [Group] event handler. - * - *
-     * 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)
-     *
-     *     GROUP_EVENT_COUNT
-     * };
-     * 
- * - * @proto cancel = (event, function) - * @proto cancel = (event, function, shots) - * - * @param uint32 event : [Group] event Id, refer to GroupEvents 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" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterGroupEvent(lua_State* L) - { - return RegisterEventHelper(L, Hooks::REGTYPE_GROUP); - } - - /** - * Registers a [BattleGround] event handler. - * - *
-     * enum BGEvents
-     * {
-     *     BG_EVENT_ON_START                               = 1,    // (event, bg, bgId, instanceId) - Needs to be added to TC
-     *     BG_EVENT_ON_END                                 = 2,    // (event, bg, bgId, instanceId, winner) - Needs to be added to TC
-     *     BG_EVENT_ON_CREATE                              = 3,    // (event, bg, bgId, instanceId) - Needs to be added to TC
-     *     BG_EVENT_ON_PRE_DESTROY                         = 4,    // (event, bg, bgId, instanceId) - Needs to be added to TC
-     *     BG_EVENT_COUNT
-     * };
-     * 
- * - * @proto cancel = (event, function) - * @proto cancel = (event, function, shots) - * - * @param uint32 event : [BattleGround] event Id, refer to BGEvents 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" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterBGEvent(lua_State* L) - { - return RegisterEventHelper(L, Hooks::REGTYPE_BG); - } - - /** - * Registers a [WorldPacket] event handler. - * - *
-     * enum PacketEvents
-     * {
-     *     PACKET_EVENT_ON_PACKET_RECEIVE          =     5,       // (event, packet, player) - Player only if accessible. Can return false, newPacket
-     *     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, newPacket
-     *
-     *     PACKET_EVENT_COUNT
-     * };
-     * 
- * - * @proto cancel = (entry, event, function) - * @proto cancel = (entry, event, function, shots) - * - * @param uint32 entry : opcode - * @param uint32 event : packet event Id, refer to PacketEvents 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" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterPacketEvent(lua_State* L) - { - return RegisterEntryHelper(L, Hooks::REGTYPE_PACKET); - } - - /** - * Registers a [Creature] gossip event handler. - * - *
-     * enum GossipEvents
-     * {
-     *     GOSSIP_EVENT_ON_HELLO                           = 1,    // (event, player, object) - Object is the Creature/GameObject/Item. Can return false to do default action. For item gossip can return false to stop spell casting.
-     *     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. Can return false to do default action.
-     *     GOSSIP_EVENT_COUNT
-     * };
-     * 
- * - * @proto cancel = (entry, event, function) - * @proto cancel = (entry, event, function, shots) - * - * @param uint32 entry : [Creature] entry Id - * @param uint32 event : [Creature] gossip event Id, refer to GossipEvents 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" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterCreatureGossipEvent(lua_State* L) - { - return RegisterEntryHelper(L, Hooks::REGTYPE_CREATURE_GOSSIP); - } - - /** - * Registers a [GameObject] gossip event handler. - * - *
-     * enum GossipEvents
-     * {
-     *     GOSSIP_EVENT_ON_HELLO                           = 1,    // (event, player, object) - Object is the Creature/GameObject/Item. Can return false to do default action. For item gossip can return false to stop spell casting.
-     *     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. Can return false to do default action.
-     *     GOSSIP_EVENT_COUNT
-     * };
-     * 
- * - * @proto cancel = (entry, event, function) - * @proto cancel = (entry, event, function, shots) - * - * @param uint32 entry : [GameObject] entry Id - * @param uint32 event : [GameObject] gossip event Id, refer to GossipEvents 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" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterGameObjectGossipEvent(lua_State* L) - { - return RegisterEntryHelper(L, Hooks::REGTYPE_GAMEOBJECT_GOSSIP); - } - - /** - * Registers an [Item] event handler. - * - *
-     * enum ItemEvents
-     * {
-     *     ITEM_EVENT_ON_DUMMY_EFFECT                      = 1,    // (event, caster, spellid, effindex, item)
-     *     ITEM_EVENT_ON_USE                               = 2,    // (event, player, item, target) - Can return false to stop the spell casting
-     *     ITEM_EVENT_ON_QUEST_ACCEPT                      = 3,    // (event, player, item, quest) - Can return true
-     *     ITEM_EVENT_ON_EXPIRE                            = 4,    // (event, player, itemid) - Can return true
-     *     ITEM_EVENT_ON_REMOVE                            = 5,    // (event, player, item) - Can return true
-     *     ITEM_EVENT_COUNT
-     * };
-     * 
- * - * @proto cancel = (entry, event, function) - * @proto cancel = (entry, event, function, shots) - * - * @param uint32 entry : [Item] entry Id - * @param uint32 event : [Item] event Id, refer to ItemEvents 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" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterItemEvent(lua_State* L) - { - return RegisterEntryHelper(L, Hooks::REGTYPE_ITEM); - } - - /** - * Registers an [Item] gossip event handler. - * - *
-     * enum GossipEvents
-     * {
-     *     GOSSIP_EVENT_ON_HELLO                           = 1,    // (event, player, object) - Object is the Creature/GameObject/Item. Can return false to do default action. For item gossip can return false to stop spell casting.
-     *     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. Can return false to do default action.
-     *     GOSSIP_EVENT_COUNT
-     * };
-     * 
- * - * @proto cancel = (entry, event, function) - * @proto cancel = (entry, event, function, shots) - * - * @param uint32 entry : [Item] entry Id - * @param uint32 event : [Item] gossip event Id, refer to GossipEvents 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" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterItemGossipEvent(lua_State* L) - { - return RegisterEntryHelper(L, Hooks::REGTYPE_ITEM_GOSSIP); - } - - /** - * Registers a [Map] event handler for all instance of a [Map]. - * - *
-     * enum InstanceEvents
-     * {
-     *     INSTANCE_EVENT_ON_INITIALIZE                    = 1,    // (event, instance_data, map)
-     *     INSTANCE_EVENT_ON_LOAD                          = 2,    // (event, instance_data, map)
-     *     INSTANCE_EVENT_ON_UPDATE                        = 3,    // (event, instance_data, map, diff)
-     *     INSTANCE_EVENT_ON_PLAYER_ENTER                  = 4,    // (event, instance_data, map, player)
-     *     INSTANCE_EVENT_ON_CREATURE_CREATE               = 5,    // (event, instance_data, map, creature)
-     *     INSTANCE_EVENT_ON_GAMEOBJECT_CREATE             = 6,    // (event, instance_data, map, go)
-     *     INSTANCE_EVENT_ON_CHECK_ENCOUNTER_IN_PROGRESS   = 7,    // (event, instance_data, map)
-     *     INSTANCE_EVENT_COUNT
-     * };
-     * 
- * - * @param uint32 map_id : ID of a [Map] - * @param uint32 event : [Map] event ID, refer to MapEvents 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 RegisterMapEvent(lua_State* L) - { - return RegisterEntryHelper(L, Hooks::REGTYPE_MAP); - } - - /** - * Registers a [Map] event handler for one instance of a [Map]. - * - *
-     * enum InstanceEvents
-     * {
-     *     INSTANCE_EVENT_ON_INITIALIZE                    = 1,    // (event, instance_data, map)
-     *     INSTANCE_EVENT_ON_LOAD                          = 2,    // (event, instance_data, map)
-     *     INSTANCE_EVENT_ON_UPDATE                        = 3,    // (event, instance_data, map, diff)
-     *     INSTANCE_EVENT_ON_PLAYER_ENTER                  = 4,    // (event, instance_data, map, player)
-     *     INSTANCE_EVENT_ON_CREATURE_CREATE               = 5,    // (event, instance_data, map, creature)
-     *     INSTANCE_EVENT_ON_GAMEOBJECT_CREATE             = 6,    // (event, instance_data, map, go)
-     *     INSTANCE_EVENT_ON_CHECK_ENCOUNTER_IN_PROGRESS   = 7,    // (event, instance_data, map)
-     *     INSTANCE_EVENT_COUNT
-     * };
-     * 
- * - * @param uint32 instance_id : ID of an instance of a [Map] - * @param uint32 event : [Map] event ID, refer to MapEvents 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 RegisterInstanceEvent(lua_State* L) - { - return RegisterEntryHelper(L, Hooks::REGTYPE_INSTANCE); - } - - /** - * Registers a [Player] gossip event handler. - * - * Note that you can not use `GOSSIP_EVENT_ON_HELLO` with this hook. It does nothing since players dont have an "on hello". - * - *
-     * enum GossipEvents
-     * {
-     *     GOSSIP_EVENT_ON_HELLO                           = 1,    // (event, player, object) - Object is the Creature/GameObject/Item. Can return false to do default action. For item gossip can return false to stop spell casting.
-     *     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. Can return false to do default action.
-     *     GOSSIP_EVENT_COUNT
-     * };
-     * 
- * - * @proto cancel = (menu_id, event, function) - * @proto cancel = (menu_id, event, function, shots) - * - * @param uint32 menu_id : [Player] gossip menu Id - * @param uint32 event : [Player] gossip event Id, refer to GossipEvents 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" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterPlayerGossipEvent(lua_State* L) - { - return RegisterEntryHelper(L, Hooks::REGTYPE_PLAYER_GOSSIP); - } - - /** - * Registers a [Creature] event handler. - * - *
-     * enum CreatureEvents
-     * {
-     *     CREATURE_EVENT_ON_ENTER_COMBAT                       = 1,  // (event, creature, target) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_LEAVE_COMBAT                       = 2,  // (event, creature) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_TARGET_DIED                        = 3,  // (event, creature, victim) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_DIED                               = 4,  // (event, creature, killer) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_SPAWN                              = 5,  // (event, creature) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_REACH_WP                           = 6,  // (event, creature, type, id) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_AIUPDATE                           = 7,  // (event, creature, diff) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_RECEIVE_EMOTE                      = 8,  // (event, creature, player, emoteid) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_DAMAGE_TAKEN                       = 9,  // (event, creature, attacker, damage) - Can return true to stop normal action, can return new damage as second return value.
-     *     CREATURE_EVENT_ON_PRE_COMBAT                         = 10, // (event, creature, target) - Can return true to stop normal action
-     *     // UNUSED
-     *     CREATURE_EVENT_ON_OWNER_ATTACKED                     = 12, // (event, creature, target) - Can return true to stop normal action            // Not on mangos
-     *     CREATURE_EVENT_ON_OWNER_ATTACKED_AT                  = 13, // (event, creature, attacker) - Can return true to stop normal action          // Not on mangos
-     *     CREATURE_EVENT_ON_HIT_BY_SPELL                       = 14, // (event, creature, caster, spellid) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_SPELL_HIT_TARGET                   = 15, // (event, creature, target, spellid) - Can return true to stop normal action
-     *     // UNUSED                                            = 16, // (event, creature)
-     *     // UNUSED                                            = 17, // (event, creature)
-     *     // UNUSED                                            = 18, // (event, creature)
-     *     CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE             = 19, // (event, creature, summon) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN          = 20, // (event, creature, summon) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED             = 21, // (event, creature, summon, killer) - Can return true to stop normal action    // Not on mangos
-     *     CREATURE_EVENT_ON_SUMMONED                           = 22, // (event, creature, summoner) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_RESET                              = 23, // (event, creature)
-     *     CREATURE_EVENT_ON_REACH_HOME                         = 24, // (event, creature) - Can return true to stop normal action
-     *     // UNUSED                                            = 25, // (event, creature)
-     *     CREATURE_EVENT_ON_CORPSE_REMOVED                     = 26, // (event, creature, respawndelay) - Can return true to stop normal action, can return new respawndelay as second return value
-     *     CREATURE_EVENT_ON_MOVE_IN_LOS                        = 27, // (event, creature, unit) - Can return true to stop normal action. Does not actually check LOS, just uses the sight range
-     *     // 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) - Can return true
-     *     // UNUSED                                            = 32, // (event, creature)
-     *     // UNUSED                                            = 33, // (event, creature)
-     *     CREATURE_EVENT_ON_QUEST_REWARD                       = 34, // (event, player, creature, quest, opt) - Can return true
-     *     CREATURE_EVENT_ON_DIALOG_STATUS                      = 35, // (event, player, creature)
-     *     CREATURE_EVENT_ON_ADD                                = 36, // (event, creature)
-     *     CREATURE_EVENT_ON_REMOVE                             = 37, // (event, creature)
-     *     CREATURE_EVENT_ON_AURA_APPLY                         = 38, // (event, creature, aura)
-     *     CREATURE_EVENT_ON_HEAL                               = 39, // (event, creature, target, heal) - Can return new heal amount
-     *     CREATURE_EVENT_ON_DAMAGE                             = 40, // (event, creature, target, damage) - Can return new damage amount
-     *     CREATURE_EVENT_ON_AURA_REMOVE                        = 41, // (event, creature, aura, remove_mode)
-     *     CREATURE_EVENT_ON_MODIFY_PERIODIC_DAMAGE_AURAS_TICK  = 42, // (event, creature, target, damage, spellInfo) - Can return new damage amount
-     *     CREATURE_EVENT_ON_MODIFY_MELEE_DAMAGE                = 43, // (event, creature, target, damage) - Can return new damage amount
-     *     CREATURE_EVENT_ON_MODIFY_SPELL_DAMAGE_TAKEN          = 44, // (event, creature, target, damage, spellInfo) - Can return new damage amount
-     *     CREATURE_EVENT_ON_MODIFY_HEAL_RECEIVED               = 45, // (event, creature, target, heal, spellInfo) - Can return new heal amount
-     *     CREATURE_EVENT_ON_DEAL_DAMAGE                        = 46, // (event, creature, target, damage, damagetype) - Can return new damage amount
-     *     CREATURE_EVENT_COUNT
-     * };
-     * 
- * - * @proto cancel = (entry, event, function) - * @proto cancel = (entry, event, function, shots) - * - * @param uint32 entry : the ID of one or more [Creature]s - * @param uint32 event : refer to CreatureEvents above - * @param function function : function that will be called when the event occurs - * @param uint32 shots = 0 : the number of times the function will be called, 0 means "always call this function" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterCreatureEvent(lua_State* L) - { - return RegisterEntryHelper(L, Hooks::REGTYPE_CREATURE); - } - - /** - * Registers a [Creature] event handler for a *single* [Creature]. - * - *
-     * enum CreatureEvents
-     * {
-     *     CREATURE_EVENT_ON_ENTER_COMBAT                    = 1,  // (event, creature, target) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_LEAVE_COMBAT                    = 2,  // (event, creature) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_TARGET_DIED                     = 3,  // (event, creature, victim) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_DIED                            = 4,  // (event, creature, killer) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_SPAWN                           = 5,  // (event, creature) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_REACH_WP                        = 6,  // (event, creature, type, id) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_AIUPDATE                        = 7,  // (event, creature, diff) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_RECEIVE_EMOTE                   = 8,  // (event, creature, player, emoteid) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_DAMAGE_TAKEN                    = 9,  // (event, creature, attacker, damage) - Can return true to stop normal action, can return new damage as second return value.
-     *     CREATURE_EVENT_ON_PRE_COMBAT                      = 10, // (event, creature, target) - Can return true to stop normal action
-     *     // UNUSED
-     *     CREATURE_EVENT_ON_OWNER_ATTACKED                  = 12, // (event, creature, target) - Can return true to stop normal action            // Not on mangos
-     *     CREATURE_EVENT_ON_OWNER_ATTACKED_AT               = 13, // (event, creature, attacker) - Can return true to stop normal action          // Not on mangos
-     *     CREATURE_EVENT_ON_HIT_BY_SPELL                    = 14, // (event, creature, caster, spellid) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_SPELL_HIT_TARGET                = 15, // (event, creature, target, spellid) - Can return true to stop normal action
-     *     // UNUSED                                         = 16, // (event, creature)
-     *     // UNUSED                                         = 17, // (event, creature)
-     *     // UNUSED                                         = 18, // (event, creature)
-     *     CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE          = 19, // (event, creature, summon) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN       = 20, // (event, creature, summon) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED          = 21, // (event, creature, summon, killer) - Can return true to stop normal action    // Not on mangos
-     *     CREATURE_EVENT_ON_SUMMONED                        = 22, // (event, creature, summoner) - Can return true to stop normal action
-     *     CREATURE_EVENT_ON_RESET                           = 23, // (event, creature)
-     *     CREATURE_EVENT_ON_REACH_HOME                      = 24, // (event, creature) - Can return true to stop normal action
-     *     // UNUSED                                         = 25, // (event, creature)
-     *     CREATURE_EVENT_ON_CORPSE_REMOVED                  = 26, // (event, creature, respawndelay) - Can return true to stop normal action, can return new respawndelay as second return value
-     *     CREATURE_EVENT_ON_MOVE_IN_LOS                     = 27, // (event, creature, unit) - Can return true to stop normal action. Does not actually check LOS, just uses the sight range
-     *     // 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) - Can return true
-     *     // UNUSED                                         = 32, // (event, creature)
-     *     // UNUSED                                         = 33, // (event, creature)
-     *     CREATURE_EVENT_ON_QUEST_REWARD                    = 34, // (event, player, creature, quest, opt) - Can return true
-     *     CREATURE_EVENT_ON_DIALOG_STATUS                   = 35, // (event, player, creature)
-     *     CREATURE_EVENT_ON_ADD                             = 36, // (event, creature)
-     *     CREATURE_EVENT_ON_REMOVE                          = 37, // (event, creature)
-     *     CREATURE_EVENT_ON_AURA_APPLY                      = 38, // (event, creature, aura)
-     *     CREATURE_EVENT_ON_HEAL                            = 39, // (event, creature, target, gain) - Can return new heal amount
-     *     CREATURE_EVENT_ON_DAMAGE                          = 40, // (event, creature, target, damage) - Can return new damage amount
-     *     CREATURE_EVENT_ON_AURA_REMOVE                     = 41, // (event, creature, aura, remove_mode)
-     *     CREATURE_EVENT_ON_MODIFY_PERIODIC_DAMAGE_AURAS_TICK = 42, // (event, creature, target, damage, spellInfo) - Can return new damage amount
-     *     CREATURE_EVENT_ON_MODIFY_MELEE_DAMAGE            = 43, // (event, creature, target, damage) - Can return new damage amount
-     *     CREATURE_EVENT_ON_MODIFY_SPELL_DAMAGE_TAKEN      = 44, // (event, creature, target, damage, spellInfo) - Can return new damage amount
-     *     CREATURE_EVENT_ON_MODIFY_HEAL_RECEIVED           = 45, // (event, creature, target, heal, spellInfo) - Can return new heal amount
-     *     CREATURE_EVENT_ON_DEAL_DAMAGE                    = 46, // (event, creature, target, damage, damagetype) - Can return new damage amount
-     *     CREATURE_EVENT_COUNT
-     * };
-     * 
- * - * @proto cancel = (guid, instance_id, event, function) - * @proto cancel = (guid, instance_id, event, function, shots) - * - * @param ObjectGuid guid : the GUID of a single [Creature] - * @param uint32 instance_id : the instance ID of a single [Creature] - * @param uint32 event : refer to CreatureEvents above - * @param function function : function that will be called when the event occurs - * @param uint32 shots = 0 : the number of times the function will be called, 0 means "always call this function" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterUniqueCreatureEvent(lua_State* L) - { - return RegisterUniqueHelper(L, Hooks::REGTYPE_CREATURE); - } - - /** - * Registers a [GameObject] event handler. - * - *
-     * 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) - Can return true to stop normal action
-     *     GAMEOBJECT_EVENT_ON_QUEST_ACCEPT                = 4,    // (event, player, go, quest) - Can return true to stop normal action
-     *     GAMEOBJECT_EVENT_ON_QUEST_REWARD                = 5,    // (event, player, go, quest, opt) - Can return true to stop normal action
-     *     GAMEOBJECT_EVENT_ON_DIALOG_STATUS               = 6,    // (event, player, go)
-     *     GAMEOBJECT_EVENT_ON_DESTROYED                   = 7,    // (event, go, attacker)
-     *     GAMEOBJECT_EVENT_ON_DAMAGED                     = 8,    // (event, go, attacker)
-     *     GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE           = 9,    // (event, go, state)
-     *     GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED            = 10,   // (event, go, state)
-     *     // UNUSED                                       = 11,   // (event, gameobject)
-     *     GAMEOBJECT_EVENT_ON_ADD                         = 12,   // (event, gameobject)
-     *     GAMEOBJECT_EVENT_ON_REMOVE                      = 13,   // (event, gameobject)
-     *     GAMEOBJECT_EVENT_ON_USE                         = 14,   // (event, go, player) - Can return true to stop normal action
-     *     GAMEOBJECT_EVENT_COUNT
-     * };
-     * 
- * - * @proto cancel = (entry, event, function) - * @proto cancel = (entry, event, function, shots) - * - * @param uint32 entry : [GameObject] entry Id - * @param uint32 event : [GameObject] event Id, refer to GameObjectEvents 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" - * - * @return function cancel : a function that cancels the binding when called - */ - int RegisterGameObjectEvent(lua_State* L) - { - return RegisterEntryHelper(L, Hooks::REGTYPE_GAMEOBJECT); - } - - /** - * Registers a [Ticket] event handler. - * - *
-     * enum TicketEvents
-     * {
-     *     TICKET_EVENT_ON_CREATE                          = 1,    // (event, player, ticket)
-     *     TICKET_EVENT_ON_UPDATE                          = 2,    // (event, player, ticket, message)
-     *     TICKET_EVENT_ON_CLOSE                           = 3,    // (event, player, ticket)
-     *     TICKET_EVENT_STATUS_UPDATE                      = 4,    // (event, player, ticket)
-     *     TICKET_EVENT_ON_RESOLVE                         = 5,    // (event, player, ticket)
-     *     TICKET_EVENT_COUNT
-     * };
-     * 
- * - * @param uint32 event : event ID, refer to UnitEvents 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 RegisterTicketEvent(lua_State* L) - { - return RegisterEventHelper(L, Hooks::REGTYPE_TICKET); - } - - /** - * Registers a [Spell] event handler. - * - *
-     * enum SpellEvents
-     * {
-     *     SPELL_EVENT_ON_PREPARE                          = 1, // (event, caster, spell)
-     *     SPELL_EVENT_ON_CAST                             = 2, // (event, caster, spell, skipCheck)
-     *     SPELL_EVENT_ON_CAST_CANCEL                      = 3, // (event, caster, spell, bySelf)
-     *     SPELL_EVENT_COUNT
-     * };
-     * 
- * - * @param uint32 entry : [Spell] entry Id - * @param uint32 event : event ID, refer to SpellEvents 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 RegisterSpellEvent(lua_State* L) - { - return RegisterEntryHelper(L, Hooks::REGTYPE_SPELL); - } - - /** - * Registers a [Creature] event handler. It used AllCreatureScript so this don't need creature entry as a key. - * - *
-     * 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_ON_AURA_APPLY                        = 5, // (event, creature, aura)
-     *     ALL_CREATURE_EVENT_ON_HEAL                              = 6, // (event, creature, target, gain) - Can return new heal amount
-     *     ALL_CREATURE_EVENT_ON_DAMAGE                            = 7, // (event, creature, target, damage) - Can return new damage amount
-     *     ALL_CREATURE_EVENT_ON_AURA_REMOVE                       = 8, // (event, creature, aura, remove_mode)
-     *     ALL_CREATURE_EVENT_ON_MODIFY_PERIODIC_DAMAGE_AURAS_TICK = 9, // (event, creature, target, damage, spellInfo) - Can return new damage amount
-     *     ALL_CREATURE_EVENT_ON_MODIFY_MELEE_DAMAGE               = 10, // (event, creature, target, damage) - Can return new damage amount
-     *     ALL_CREATURE_EVENT_ON_MODIFY_SPELL_DAMAGE_TAKEN         = 11, // (event, creature, target, damage, spellInfo) - Can return new damage amount
-     *     ALL_CREATURE_EVENT_ON_MODIFY_HEAL_RECEIVED              = 12, // (event, creature, target, heal, spellInfo) - Can return new heal amount
-     *     ALL_CREATURE_EVENT_ON_DEAL_DAMAGE                       = 13, // (event, creature, target, damage, damagetype) - Can return new damage amount
-     *     ALL_CREATURE_EVENT_COUNT
-     * };
-     * 
- * - * @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. - */ - int ReloadALE(lua_State* /*L*/) - { - ALE::ReloadALE(); - return 0; - } - - /** - * Runs a command. - * - * @param string command : the command to run - */ - int RunCommand(lua_State* L) - { - const char* command = ALE::CHECKVAL(L, 1); - - eWorld->QueueCliCommand(new CliCommandHolder(nullptr, command, [](void*, std::string_view view) - { - std::string str = { view.begin(), view.end() }; - str.erase(std::find_if(str.rbegin(), str.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(), str.end()); // Remove trailing spaces and line breaks - ALE_LOG_INFO("{}", str); - }, nullptr)); - - return 0; - } - - /** - * Sends a message to all [Player]s online. - * - * @param string message : message to send - */ - int SendWorldMessage(lua_State* L) - { - const char* message = ALE::CHECKVAL(L, 1); - eWorldSessionMgr->SendServerMessage(SERVER_MSG_STRING, message); - return 0; - } - - template - static int DBQueryAsync(lua_State* L, DatabaseWorkerPool& db) - { - const char* query = ALE::CHECKVAL(L, 1); - luaL_checktype(L, 2, LUA_TFUNCTION); - lua_pushvalue(L, 2); - int funcRef = luaL_ref(L, LUA_REGISTRYINDEX); - if (funcRef == LUA_REFNIL || funcRef == LUA_NOREF) - { - luaL_argerror(L, 2, "unable to make a ref to function"); - return 0; - } - - ALE::GALE->queryProcessor.AddCallback(db.AsyncQuery(query).WithCallback([L, funcRef](QueryResult result) - { - ALEQuery* eq = result ? new ALEQuery(result) : nullptr; - - LOCK_ALE; - - // Get function - lua_rawgeti(L, LUA_REGISTRYINDEX, funcRef); - - // Push parameters - ALE::Push(L, eq); - - // Call function - ALE::GALE->ExecuteCall(1, 0); - - luaL_unref(L, LUA_REGISTRYINDEX, funcRef); - })); - - return 0; - } - - /** - * Executes a SQL query on the world database and returns an [ALEQuery]. - * - * The query is always executed synchronously - * (i.e. execution halts until the query has finished and then results are returned). - * If you need to execute the query asynchronously, use [Global:WorldDBQueryAsync] instead. - * - * local Q = WorldDBQuery("SELECT entry, name FROM creature_template LIMIT 10") - * if Q then - * repeat - * local entry, name = Q:GetUInt32(0), Q:GetString(1) - * print(entry, name) - * until not Q:NextRow() - * end - * - * @param string sql : query to execute - * @return [ALEQuery] results or nil if no rows found or nil if no rows found - */ - int WorldDBQuery(lua_State* L) - { - const char* query = ALE::CHECKVAL(L, 1); - - int numArgs = lua_gettop(L); - if (numArgs > 1) - query = ALE::FormatQuery(L, query).c_str(); - - ALEQuery result = WorldDatabase.Query(query); - if (result) - ALE::Push(L, new ALEQuery(result)); - else - ALE::Push(L); - return 1; - } - - /** - * Executes an asynchronous SQL query on the world database and passes an [ALEQuery] to a callback function. - * - * The query is executed asynchronously - * (i.e. the server keeps running while the query is executed in parallel, and results are passed to a callback function). - * If you need to execute the query synchronously, use [Global:WorldDBQuery] instead. - * - * WorldDBQueryAsync("SELECT entry, name FROM creature_template LIMIT 10", function(Q) - * if Q then - * repeat - * local entry, name = Q:GetUInt32(0), Q:GetString(1) - * print(entry, name) - * until not Q:NextRow() - * end - * end) - * - * @param string sql : query to execute - * @param function callback : function that will be called when the results are available - */ - int WorldDBQueryAsync(lua_State* L) - { - return DBQueryAsync(L, WorldDatabase); - } - - /** - * Executes a SQL query on the world database. - * - * The query may be executed *asynchronously* (at a later, unpredictable time). - * If you need to execute the query synchronously, use [Global:WorldDBQuery] instead. - * - * Any results produced are ignored. - * If you need results from the query, use [Global:WorldDBQuery] or [Global:WorldDBQueryAsync] instead. - * - * WorldDBExecute("DELETE FROM my_table") - * - * @param string sql : query to execute - */ - int WorldDBExecute(lua_State* L) - { - const char* query = ALE::CHECKVAL(L, 1); - - int numArgs = lua_gettop(L); - if (numArgs > 1) - query = ALE::FormatQuery(L, query).c_str(); - - WorldDatabase.Execute(query); - return 0; - } - - /** - * Executes a SQL query on the character database and returns an [ALEQuery]. - * - * The query is always executed synchronously - * (i.e. execution halts until the query has finished and then results are returned). - * If you need to execute the query asynchronously, use [Global:CharDBQueryAsync] instead. - * - * For an example see [Global:WorldDBQuery]. - * - * @param string sql : query to execute - * @return [ALEQuery] results or nil if no rows found - */ - int CharDBQuery(lua_State* L) - { - const char* query = ALE::CHECKVAL(L, 1); - - int numArgs = lua_gettop(L); - if (numArgs > 1) - query = ALE::FormatQuery(L, query).c_str(); - - QueryResult result = CharacterDatabase.Query(query); - if (result) - ALE::Push(L, new QueryResult(result)); - else - ALE::Push(L); - return 1; - } - - /** - * Executes an asynchronous SQL query on the character database and passes an [ALEQuery] to a callback function. - * - * The query is executed asynchronously - * (i.e. the server keeps running while the query is executed in parallel, and results are passed to a callback function). - * If you need to execute the query synchronously, use [Global:CharDBQuery] instead. - * - * For an example see [Global:WorldDBQueryAsync]. - * - * @param string sql : query to execute - * @param function callback : function that will be called when the results are available - */ - int CharDBQueryAsync(lua_State* L) - { - return DBQueryAsync(L, CharacterDatabase); - } - - /** - * Executes a SQL query on the character database. - * - * The query may be executed *asynchronously* (at a later, unpredictable time). - * If you need to execute the query synchronously, use [Global:CharDBQuery] instead. - * - * Any results produced are ignored. - * If you need results from the query, use [Global:CharDBQuery] or [Global:CharDBQueryAsync] instead. - * - * CharDBExecute("DELETE FROM my_table") - * - * @param string sql : query to execute - */ - int CharDBExecute(lua_State* L) - { - const char* query = ALE::CHECKVAL(L, 1); - - int numArgs = lua_gettop(L); - if (numArgs > 1) - query = ALE::FormatQuery(L, query).c_str(); - - CharacterDatabase.Execute(query); - return 0; - } - - /** - * Executes a SQL query on the login database and returns an [ALEQuery]. - * - * The query is always executed synchronously - * (i.e. execution halts until the query has finished and then results are returned). - * If you need to execute the query asynchronously, use [Global:AuthDBQueryAsync] instead. - * - * For an example see [Global:WorldDBQuery]. - * - * @param string sql : query to execute - * @return [ALEQuery] results or nil if no rows found - */ - int AuthDBQuery(lua_State* L) - { - const char* query = ALE::CHECKVAL(L, 1); - - int numArgs = lua_gettop(L); - if (numArgs > 1) - query = ALE::FormatQuery(L, query).c_str(); - - QueryResult result = LoginDatabase.Query(query); - if (result) - ALE::Push(L, new QueryResult(result)); - else - ALE::Push(L); - return 1; - } - - /** - * Executes an asynchronous SQL query on the character database and passes an [ALEQuery] to a callback function. - * - * The query is executed asynchronously - * (i.e. the server keeps running while the query is executed in parallel, and results are passed to a callback function). - * If you need to execute the query synchronously, use [Global:AuthDBQuery] instead. - * - * For an example see [Global:WorldDBQueryAsync]. - * - * @param string sql : query to execute - * @param function callback : function that will be called when the results are available - */ - int AuthDBQueryAsync(lua_State* L) - { - return DBQueryAsync(L, LoginDatabase); - } - - /** - * Executes a SQL query on the login database. - * - * The query may be executed *asynchronously* (at a later, unpredictable time). - * If you need to execute the query synchronously, use [Global:AuthDBQuery] instead. - * - * Any results produced are ignored. - * If you need results from the query, use [Global:AuthDBQuery] or [Global:AuthDBQueryAsync] instead. - * - * AuthDBExecute("DELETE FROM my_table") - * - * @param string sql : query to execute - */ - int AuthDBExecute(lua_State* L) - { - const char* query = ALE::CHECKVAL(L, 1); - - int numArgs = lua_gettop(L); - if (numArgs > 1) - query = ALE::FormatQuery(L, query).c_str(); - - LoginDatabase.Execute(query); - return 0; - } - - /** - * Registers a global timed event. - * - * When the passed function is called, the parameters `(eventId, delay, repeats)` are passed to it. - * - * Repeats will decrease on each call if the event does not repeat indefinitely - * - * @proto eventId = (function, delay) - * @proto eventId = (function, delaytable) - * @proto eventId = (function, delay, repeats) - * @proto eventId = (function, delaytable, repeats) - * - * @param function function : function to trigger when the time has passed - * @param uint32 delay : set time in milliseconds for the event to trigger - * @param table delaytable : a table `{min, max}` containing the minimum and maximum delay time - * @param uint32 repeats = 1 : how many times for the event to repeat, 0 is infinite - * @return int eventId : unique ID for the timed event used to cancel it or nil - */ - int CreateLuaEvent(lua_State* L) - { - luaL_checktype(L, 1, LUA_TFUNCTION); - uint32 min, max; - if (lua_istable(L, 2)) - { - ALE::Push(L, 1); - lua_gettable(L, 2); - min = ALE::CHECKVAL(L, -1); - ALE::Push(L, 2); - lua_gettable(L, 2); - max = ALE::CHECKVAL(L, -1); - lua_pop(L, 2); - } - else - min = max = ALE::CHECKVAL(L, 2); - uint32 repeats = ALE::CHECKVAL(L, 3, 1); - - if (min > max) - return luaL_argerror(L, 2, "min is bigger than max delay"); - - lua_pushvalue(L, 1); - int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); - if (functionRef != LUA_REFNIL && functionRef != LUA_NOREF) - { - ALE::GetALE(L)->eventMgr->globalProcessor->AddEvent(functionRef, min, max, repeats); - ALE::Push(L, functionRef); - } - return 1; - } - - /** - * Removes a global timed event specified by ID. - * - * @param int eventId : event Id to remove - * @param bool all_Events = false : remove from all events, not just global - */ - int RemoveEventById(lua_State* L) - { - int eventId = ALE::CHECKVAL(L, 1); - bool all_Events = ALE::CHECKVAL(L, 1, false); - - // not thread safe - if (all_Events) - ALE::GetALE(L)->eventMgr->SetState(eventId, LUAEVENT_STATE_ABORT); - else - ALE::GetALE(L)->eventMgr->globalProcessor->SetState(eventId, LUAEVENT_STATE_ABORT); - return 0; - } - - /** - * Removes all global timed events. - * - * @param bool all_Events = false : remove all events, not just global - */ - int RemoveEvents(lua_State* L) - { - bool all_Events = ALE::CHECKVAL(L, 1, false); - - // not thread safe - if (all_Events) - ALE::GetALE(L)->eventMgr->SetStates(LUAEVENT_STATE_ABORT); - else - ALE::GetALE(L)->eventMgr->globalProcessor->SetStates(LUAEVENT_STATE_ABORT); - return 0; - } - - /** - * Performs an in-game spawn and returns the [Creature] or [GameObject] spawned. - * - * @param int32 spawnType : type of object to spawn, 1 = [Creature], 2 = [GameObject] - * @param uint32 entry : entry ID of the [Creature] or [GameObject] - * @param uint32 mapId : map ID to spawn the [Creature] or [GameObject] in - * @param uint32 instanceId : instance ID to put the [Creature] or [GameObject] in. Non instance is 0 - * @param float x : x coordinate of the [Creature] or [GameObject] - * @param float y : y coordinate of the [Creature] or [GameObject] - * @param float z : z coordinate of the [Creature] or [GameObject] - * @param float o : o facing/orientation of the [Creature] or [GameObject] - * @param bool save = false : optional to save the [Creature] or [GameObject] to the database - * @param uint32 durorresptime = 0 : despawn time of the [Creature] if it's not saved or respawn time of [GameObject] - * @param uint32 phase = 1 : phase to put the [Creature] or [GameObject] in - * @return [WorldObject] worldObject : returns [Creature] or [GameObject] - */ - int PerformIngameSpawn(lua_State* L) - { - int spawntype = ALE::CHECKVAL(L, 1); - uint32 entry = ALE::CHECKVAL(L, 2); - uint32 mapID = ALE::CHECKVAL(L, 3); - uint32 instanceID = ALE::CHECKVAL(L, 4); - - float x = ALE::CHECKVAL(L, 5); - float y = ALE::CHECKVAL(L, 6); - float z = ALE::CHECKVAL(L, 7); - float o = ALE::CHECKVAL(L, 8); - bool save = ALE::CHECKVAL(L, 9, false); - uint32 durorresptime = ALE::CHECKVAL(L, 10, 0); - uint32 phase = ALE::CHECKVAL(L, 11, PHASEMASK_NORMAL); - - if (!phase) - { - ALE::Push(L); - return 1; - } - - Map* map = eMapMgr->FindMap(mapID, instanceID); - if (!map) - { - ALE::Push(L); - return 1; - } - - Position pos = { x, y, z, o }; - - if (spawntype == 1) // spawn creature - { - if (save) - { - Creature* creature = new Creature(); - if (!creature->Create(map->GenerateLowGuid(), map, phase, entry, 0, x, y, z, o)) - { - delete creature; - ALE::Push(L); - return 1; - } - - creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), phase); - - uint32 db_guid = creature->GetSpawnId(); - - // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells() - // current "creature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior - creature->CleanupsBeforeDelete(); - delete creature; - creature = new Creature(); - - if (!creature->LoadCreatureFromDB(db_guid, map, true, true)) - { - delete creature; - ALE::Push(L); - return 1; - } - - eObjectMgr->AddCreatureToGrid(db_guid, eObjectMgr->GetCreatureData(db_guid)); - ALE::Push(L, creature); - } - else - { - TempSummon* creature = map->SummonCreature(entry, pos, NULL, durorresptime); - if (!creature) - { - ALE::Push(L); - return 1; - } - - if (durorresptime) - creature->SetTempSummonType(TEMPSUMMON_TIMED_OR_DEAD_DESPAWN); - else - creature->SetTempSummonType(TEMPSUMMON_MANUAL_DESPAWN); - - ALE::Push(L, creature); - } - - return 1; - } - - if (spawntype == 2) // Spawn object - { - const GameObjectTemplate* objectInfo = eObjectMgr->GetGameObjectTemplate(entry); - if (!objectInfo) - { - ALE::Push(L); - return 1; - } - - if (objectInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(objectInfo->displayId)) - { - ALE::Push(L); - return 1; - } - - GameObject* object = new GameObject; - uint32 guidLow = map->GenerateLowGuid(); - - if (!object->Create(guidLow, entry, map, phase, x, y, z, o, G3D::Quat(0.0f, 0.0f, 0.0f, 0.0f), 100, GO_STATE_READY)) - { - delete object; - ALE::Push(L); - return 1; - } - - if (durorresptime) - object->SetRespawnTime(durorresptime); - - if (save) - { - // fill the gameobject data and save to the db - object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), phase); - guidLow = object->GetSpawnId(); - - // delete the old object and do a clean load from DB with a fresh new GameObject instance. - // this is required to avoid weird behavior and memory leaks - delete object; - - object = new GameObject(); - // this will generate a new lowguid if the object is in an instance - if (!object->LoadGameObjectFromDB(guidLow, map, true)) - { - delete object; - ALE::Push(L); - return 1; - } - - eObjectMgr->AddGameobjectToGrid(guidLow, eObjectMgr->GetGameObjectData(guidLow)); - } - else - map->AddToMap(object); - ALE::Push(L, object); - return 1; - } - ALE::Push(L); - return 1; - } - - /** - * Creates a [WorldPacket]. - * - * @param [Opcodes] opcode : the opcode of the packet - * @param uint32 size : the size of the packet - * @return [WorldPacket] packet - */ - int CreatePacket(lua_State* L) - { - uint32 opcode = ALE::CHECKVAL(L, 1); - size_t size = ALE::CHECKVAL(L, 2); - if (opcode >= NUM_MSG_TYPES) - return luaL_argerror(L, 1, "valid opcode expected"); - - ALE::Push(L, new WorldPacket((OpcodesList)opcode, size)); - return 1; - } - - /** - * Adds an [Item] to a vendor and updates the world database. - * - * @param uint32 entry : [Creature] entry Id - * @param uint32 item : [Item] entry Id - * @param int32 maxcount : max [Item] stack count - * @param uint32 incrtime : combined with maxcount, incrtime tells how often (in seconds) the vendor list is refreshed and the limited [Item] copies are restocked - * @param uint32 extendedcost : unique cost of an [Item], such as conquest points for example - */ - int AddVendorItem(lua_State* L) - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 item = ALE::CHECKVAL(L, 2); - int maxcount = ALE::CHECKVAL(L, 3); - uint32 incrtime = ALE::CHECKVAL(L, 4); - uint32 extendedcost = ALE::CHECKVAL(L, 5); - - if (!eObjectMgr->IsVendorItemValid(entry, item, maxcount, incrtime, extendedcost)) - return 0; - eObjectMgr->AddVendorItem(entry, item, maxcount, incrtime, extendedcost); - - return 0; - } - - /** - * Removes an [Item] from a vendor and updates the database. - * - * @param uint32 entry : [Creature] entry Id - * @param uint32 item : [Item] entry Id - */ - int VendorRemoveItem(lua_State* L) - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 item = ALE::CHECKVAL(L, 2); - if (!eObjectMgr->GetCreatureTemplate(entry)) - return luaL_argerror(L, 1, "valid CreatureEntry expected"); - - eObjectMgr->RemoveVendorItem(entry, item); - return 0; - } - - /** - * Removes all [Item]s from a vendor and updates the database. - * - * @param uint32 entry : [Creature] entry Id - */ - int VendorRemoveAllItems(lua_State* L) - { - uint32 entry = ALE::CHECKVAL(L, 1); - - VendorItemData const* items = eObjectMgr->GetNpcVendorItemList(entry); - if (!items || items->Empty()) - return 0; - - auto const& itemlist = items->m_items; - for (auto itr = itemlist.rbegin(); itr != itemlist.rend(); ++itr) - eObjectMgr->RemoveVendorItem(entry, (*itr)->item); - return 0; - } - - /** - * Kicks a [Player] from the server. - * - * @param [Player] player : [Player] to kick - */ - int Kick(lua_State* L) - { - Player* player = ALE::CHECKOBJ(L, 1); - player->GetSession()->KickPlayer(); - return 0; - } - - /** - * Ban's a [Player]'s account, character or IP - * - * enum BanMode - * { - * BAN_ACCOUNT = 0, - * BAN_CHARACTER = 1, - * BAN_IP = 2 - * }; - * - * @param [BanMode] banMode : method of ban, refer to BanMode above - * @param string nameOrIP : If BanMode is 0 then accountname, if 1 then charactername if 2 then ip - * @param uint32 duration : duration (in seconds) of the ban - * @param string reason = "" : ban reason, this is optional - * @param string whoBanned = "" : the [Player]'s name that banned the account, character or IP, this is optional - * @return int result : status of the ban. 0 if success, 1 if syntax error, 2 if target not found, 3 if a longer ban already exists, nil if unknown result - */ - int Ban(lua_State* L) - { - int banMode = ALE::CHECKVAL(L, 1); - std::string nameOrIP = ALE::CHECKVAL(L, 2); - uint32 duration = ALE::CHECKVAL(L, 3); - const char* reason = ALE::CHECKVAL(L, 4, ""); - const char* whoBanned = ALE::CHECKVAL(L, 5, ""); - - const int BAN_ACCOUNT = 0; - const int BAN_CHARACTER = 1; - const int BAN_IP = 2; - - switch (banMode) - { - case BAN_ACCOUNT: - if (!Utf8ToUpperOnlyLatin(nameOrIP)) - return luaL_argerror(L, 2, "invalid account name"); - break; - case BAN_CHARACTER: - if (!normalizePlayerName(nameOrIP)) - return luaL_argerror(L, 2, "invalid character name"); - break; - case BAN_IP: - if (!IsIPAddress(nameOrIP.c_str())) - return luaL_argerror(L, 2, "invalid ip"); - break; - default: - return luaL_argerror(L, 1, "unknown banmode"); - } - - BanReturn result; - switch (banMode) - { - case BAN_ACCOUNT: - result = sBan->BanAccount(nameOrIP, std::to_string(duration) + "s", reason, whoBanned); - break; - case BAN_CHARACTER: - result = sBan->BanCharacter(nameOrIP, std::to_string(duration) + "s", reason, whoBanned); - break; - case BAN_IP: - result = sBan->BanIP(nameOrIP, std::to_string(duration) + "s", reason, whoBanned); - break; - } - - switch (result) - { - case BanReturn::BAN_SUCCESS: - ALE::Push(L, 0); - break; - case BanReturn::BAN_SYNTAX_ERROR: - ALE::Push(L, 1); - break; - case BanReturn::BAN_NOTFOUND: - ALE::Push(L, 2); - break; - case BanReturn::BAN_LONGER_EXISTS: - ALE::Push(L, 3); - break; - } - return 1; - } - - /** - * Saves all [Player]s. - */ - int SaveAllPlayers(lua_State* /*L*/) - { - eObjectAccessor()SaveAllPlayers(); - return 0; - } - - /** - * Sends mail to a [Player]. - * - * There can be several item entry-amount pairs at the end of the function. - * There can be maximum of 12 different items. - * - * enum MailStationery - * { - * MAIL_STATIONERY_TEST = 1, - * MAIL_STATIONERY_DEFAULT = 41, - * MAIL_STATIONERY_GM = 61, - * MAIL_STATIONERY_AUCTION = 62, - * MAIL_STATIONERY_VAL = 64, // Valentine - * MAIL_STATIONERY_CHR = 65, // Christmas - * MAIL_STATIONERY_ORP = 67 // Orphan - * }; - * - * @param string subject : title (subject) of the mail - * @param string text : contents of the mail - * @param uint32 receiverGUIDLow : low GUID of the receiver - * @param uint32 senderGUIDLow = 0 : low GUID of the sender - * @param [MailStationery] stationary = MAIL_STATIONERY_DEFAULT : type of mail that is being sent as, refer to MailStationery above - * @param uint32 delay = 0 : mail send delay in milliseconds - * @param uint32 money = 0 : money to send - * @param uint32 cod = 0 : cod money amount - * @param uint32 entry = 0 : entry of an [Item] to send with mail - * @param uint32 amount = 0 : amount of the [Item] to send with mail - * @return uint32 itemGUIDlow : low GUID of the item. Up to 12 values returned, returns nil if no further items are sent - */ - int SendMail(lua_State* L) - { - int i = 0; - std::string subject = ALE::CHECKVAL(L, ++i); - std::string text = ALE::CHECKVAL(L, ++i); - uint32 receiverGUIDLow = ALE::CHECKVAL(L, ++i); - uint32 senderGUIDLow = ALE::CHECKVAL(L, ++i, 0); - uint32 stationary = ALE::CHECKVAL(L, ++i, MAIL_STATIONERY_DEFAULT); - uint32 delay = ALE::CHECKVAL(L, ++i, 0); - uint32 money = ALE::CHECKVAL(L, ++i, 0); - uint32 cod = ALE::CHECKVAL(L, ++i, 0); - int argAmount = lua_gettop(L); - - MailSender sender(MAIL_NORMAL, senderGUIDLow, (MailStationery)stationary); - MailDraft draft(subject, text); - - if (cod) - draft.AddCOD(cod); - if (money) - draft.AddMoney(money); - - CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); - uint8 addedItems = 0; - while (addedItems <= MAX_MAIL_ITEMS && i + 2 <= argAmount) - { - uint32 entry = ALE::CHECKVAL(L, ++i); - uint32 amount = ALE::CHECKVAL(L, ++i); - - ItemTemplate const* item_proto = eObjectMgr->GetItemTemplate(entry); - if (!item_proto) - { - luaL_error(L, "Item entry %d does not exist", entry); - continue; - } - if (amount < 1 || (item_proto->MaxCount > 0 && amount > uint32(item_proto->MaxCount))) - { - luaL_error(L, "Item entry %d has invalid amount %d", entry, amount); - continue; - } - if (Item* item = Item::CreateItem(entry, amount)) - { - item->SaveToDB(trans); - draft.AddItem(item); - ALE::Push(L, item->GetGUID().GetCounter()); - ++addedItems; - } - } - - Player* receiverPlayer = eObjectAccessor()FindPlayer(MAKE_NEW_GUID(receiverGUIDLow, 0, HIGHGUID_PLAYER)); - draft.SendMailTo(trans, MailReceiver(receiverPlayer, receiverGUIDLow), sender, MAIL_CHECK_MASK_NONE, delay); - CharacterDatabase.CommitTransaction(trans); - return addedItems; - } - - /** - * Performs a bitwise AND (a & b). - * - * @param uint32 a - * @param uint32 b - * @return uint32 result - */ - int bit_and(lua_State* L) - { - uint32 a = ALE::CHECKVAL(L, 1); - uint32 b = ALE::CHECKVAL(L, 2); - ALE::Push(L, a & b); - return 1; - } - - /** - * Performs a bitwise OR (a | b). - * - * @param uint32 a - * @param uint32 b - * @return uint32 result - */ - int bit_or(lua_State* L) - { - uint32 a = ALE::CHECKVAL(L, 1); - uint32 b = ALE::CHECKVAL(L, 2); - ALE::Push(L, a | b); - return 1; - } - - /** - * Performs a bitwise left-shift (a << b). - * - * @param uint32 a - * @param uint32 b - * @return uint32 result - */ - int bit_lshift(lua_State* L) - { - uint32 a = ALE::CHECKVAL(L, 1); - uint32 b = ALE::CHECKVAL(L, 2); - ALE::Push(L, a << b); - return 1; - } - - /** - * Performs a bitwise right-shift (a >> b). - * - * @param uint32 a - * @param uint32 b - * @return uint32 result - */ - int bit_rshift(lua_State* L) - { - uint32 a = ALE::CHECKVAL(L, 1); - uint32 b = ALE::CHECKVAL(L, 2); - ALE::Push(L, a >> b); - return 1; - } - - /** - * Performs a bitwise XOR (a ^ b). - * - * @param uint32 a - * @param uint32 b - * @return uint32 result - */ - int bit_xor(lua_State* L) - { - uint32 a = ALE::CHECKVAL(L, 1); - uint32 b = ALE::CHECKVAL(L, 2); - ALE::Push(L, a ^ b); - return 1; - } - - /** - * Performs a bitwise NOT (~a). - * - * @param uint32 a - * @return uint32 result - */ - int bit_not(lua_State* L) - { - uint32 a = ALE::CHECKVAL(L, 1); - ALE::Push(L, ~a); - return 1; - } - - /** - * Adds a taxi path to a specified map, returns the used pathId. - * - * Note that the first taxi point needs to be near the player when he starts the taxi path. - * The function should also be used only **once** per path added so use it on server startup for example. - * - * Related function: [Player:StartTaxi] - * - * -- Execute on startup - * local pathTable = {{mapid, x, y, z}, {mapid, x, y, z}} - * local path = AddTaxiPath(pathTable, 28135, 28135) - * - * -- Execute when the player should fly - * player:StartTaxi(path) - * - * @param table waypoints : table containing waypoints: {map, x, y, z[, actionFlag, delay]} - * @param uint32 mountA : alliance [Creature] entry - * @param uint32 mountH : horde [Creature] entry - * @param uint32 price = 0 : price of the taxi path - * @param uint32 pathId = 0 : path Id of the taxi path - * @return uint32 actualPathId - */ - int AddTaxiPath(lua_State* L) - { - luaL_checktype(L, 1, LUA_TTABLE); - uint32 mountA = ALE::CHECKVAL(L, 2); - uint32 mountH = ALE::CHECKVAL(L, 3); - uint32 price = ALE::CHECKVAL(L, 4, 0); - uint32 pathId = ALE::CHECKVAL(L, 5, 0); - lua_pushvalue(L, 1); - // Stack: {nodes}, mountA, mountH, price, pathid, {nodes} - - std::list nodes; - - int start = lua_gettop(L); - int end = start; - - ALE::Push(L); - // Stack: {nodes}, mountA, mountH, price, pathid, {nodes}, nil - while (lua_next(L, -2) != 0) - { - // Stack: {nodes}, mountA, mountH, price, pathid, {nodes}, key, value - luaL_checktype(L, -1, LUA_TTABLE); - ALE::Push(L); - // Stack: {nodes}, mountA, mountH, price, pathid, {nodes}, key, value, nil - while (lua_next(L, -2) != 0) - { - // Stack: {nodes}, mountA, mountH, price, pathid, {nodes}, key, value, key2, value2 - lua_insert(L, end++); - // Stack: {nodes}, mountA, mountH, price, pathid, {nodes}, value2, key, value, key2 - } - // Stack: {nodes}, mountA, mountH, price, pathid, {nodes}, value2, key, value - if (start == end) - continue; - if (end - start < 4) // no mandatory args, dont add - return luaL_argerror(L, 1, "all waypoints do not have mandatory arguments"); - - while (end - start < 8) // fill optional args with 0 - { - ALE::Push(L, 0); - lua_insert(L, end++); - // Stack: {nodes}, mountA, mountH, price, pathid, {nodes}, node, key, value - } - TaxiPathNodeEntry entry; - // mandatory - entry.mapid = ALE::CHECKVAL(L, start); - entry.x = ALE::CHECKVAL(L, start + 1); - entry.y = ALE::CHECKVAL(L, start + 2); - entry.z = ALE::CHECKVAL(L, start + 3); - // optional - entry.actionFlag = ALE::CHECKVAL(L, start + 4, 0); - entry.delay = ALE::CHECKVAL(L, start + 5, 0); - - nodes.push_back(entry); - - while (end != start) // remove args - if (!lua_isnone(L, --end)) - lua_remove(L, end); - // Stack: {nodes}, mountA, mountH, price, pathid, {nodes}, key, value - - lua_pop(L, 1); - // Stack: {nodes}, mountA, mountH, price, pathid, {nodes}, key - } - // Stack: {nodes}, mountA, mountH, price, pathid, {nodes} - lua_pop(L, 1); - // Stack: {nodes}, mountA, mountH, price, pathid - - if (nodes.size() < 2) - return 1; - if (!pathId) - pathId = sTaxiPathNodesByPath.size(); - if (sTaxiPathNodesByPath.size() <= pathId) - sTaxiPathNodesByPath.resize(pathId + 1); - - sTaxiPathNodesByPath[pathId].clear(); - sTaxiPathNodesByPath[pathId].resize(nodes.size()); - static uint32 nodeId = 500; - uint32 startNode = nodeId; - uint32 index = 0; - - for (std::list::iterator it = nodes.begin(); it != nodes.end(); ++it) - { - TaxiPathNodeEntry& entry = *it; - TaxiNodesEntry* nodeEntry = new TaxiNodesEntry(); - entry.path = pathId; - entry.index = nodeId; - nodeEntry->ID = index; - nodeEntry->map_id = entry.mapid; - nodeEntry->x = entry.x; - nodeEntry->y = entry.y; - nodeEntry->z = entry.z; - nodeEntry->MountCreatureID[0] = mountH; - nodeEntry->MountCreatureID[1] = mountA; - sTaxiNodesStore.SetEntry(nodeId++, nodeEntry); - sTaxiPathNodesByPath[pathId][index++] = new TaxiPathNodeEntry(entry); - } - if (startNode >= nodeId) - return 1; - - TaxiPathEntry* pathEntry = new TaxiPathEntry(); - pathEntry->from = startNode; - pathEntry->to = nodeId - 1; - pathEntry->price = price; - pathEntry->ID = pathId; - sTaxiPathStore.SetEntry(pathId, pathEntry); - sTaxiPathSetBySource[startNode][nodeId - 1] = pathEntry; - - ALE::Push(L, pathId); - return 1; - } - - /** - * Returns `true` if ALE is in compatibility mode, `false` if in multistate. - * - * @return bool isCompatibilityMode - */ - int IsCompatibilityMode(lua_State* L) - { - // Until AC supports multistate, this will always return true - ALE::Push(L, true); - return 1; - } - - /** - * Returns `true` if the bag and slot is a valid inventory position, otherwise `false`. - * - * Some commonly used combinations: - * - * *Bag 255 (common character inventory)* - * - * - Slots 0-18: equipment - * - Slots 19-22: bag slots - * - Slots 23-38: backpack - * - Slots 39-66: bank main slots - * - Slots 67-74: bank bag slots - * - Slots 86-117: keyring - * - * *Bags 19-22 (equipped bags)* - * - * - Slots 0-35 - * - * *Bags 67-74 (bank bags)* - * - * - Slots 0-35 - * - * @param uint8 bag : the bag the [Item] is in, you can get this with [Item:GetBagSlot] - * @param uint8 slot : the slot the [Item] is in within the bag, you can get this with [Item:GetSlot] - * @return bool isInventoryPos - */ - int IsInventoryPos(lua_State* L) - { - uint8 bag = ALE::CHECKVAL(L, 1); - uint8 slot = ALE::CHECKVAL(L, 2); - - ALE::Push(L, Player::IsInventoryPos(bag, slot)); - return 1; - } - - /** - * Returns `true` if the bag and slot is a valid equipment position, otherwise `false`. - * - * See [Global:IsInventoryPos] for bag/slot combination examples. - * - * @param uint8 bag : the bag the [Item] is in, you can get this with [Item:GetBagSlot] - * @param uint8 slot : the slot the [Item] is in within the bag, you can get this with [Item:GetSlot] - * @return bool isEquipmentPosition - */ - int IsEquipmentPos(lua_State* L) - { - uint8 bag = ALE::CHECKVAL(L, 1); - uint8 slot = ALE::CHECKVAL(L, 2); - - ALE::Push(L, Player::IsEquipmentPos(bag, slot)); - return 1; - } - - /** - * Returns `true` if the bag and slot is a valid bank position, otherwise `false`. - * - * See [Global:IsInventoryPos] for bag/slot combination examples. - * - * @param uint8 bag : the bag the [Item] is in, you can get this with [Item:GetBagSlot] - * @param uint8 slot : the slot the [Item] is in within the bag, you can get this with [Item:GetSlot] - * @return bool isBankPosition - */ - int IsBankPos(lua_State* L) - { - uint8 bag = ALE::CHECKVAL(L, 1); - uint8 slot = ALE::CHECKVAL(L, 2); - - ALE::Push(L, Player::IsBankPos(bag, slot)); - return 1; - } - - /** - * Returns `true` if the bag and slot is a valid bag position, otherwise `false`. - * - * See [Global:IsInventoryPos] for bag/slot combination examples. - * - * @param uint8 bag : the bag the [Item] is in, you can get this with [Item:GetBagSlot] - * @param uint8 slot : the slot the [Item] is in within the bag, you can get this with [Item:GetSlot] - * @return bool isBagPosition - */ - int IsBagPos(lua_State* L) - { - uint8 bag = ALE::CHECKVAL(L, 1); - uint8 slot = ALE::CHECKVAL(L, 2); - - ALE::Push(L, Player::IsBagPos((bag << 8) + slot)); - return 1; - } - - /** - * Returns `true` if the event is currently active, otherwise `false`. - * - * @param uint16 eventId : the event id to check. - * @return bool isActive - */ - int IsGameEventActive(lua_State* L) - { - uint16 eventId = ALE::CHECKVAL(L, 1); - - ALE::Push(L, eGameEventMgr->IsActiveEvent(eventId)); - return 1; - } - - /** - * Returns the server's current time. - * - * @return uint32 currTime : the current time, in milliseconds - */ - int GetCurrTime(lua_State* L) - { - ALE::Push(L, ALEUtil::GetCurrTime()); - return 1; - } - - /** - * Returns the difference between an old timestamp and the current time. - * - * @param uint32 oldTime : an old timestamp, in milliseconds - * @return uint32 timeDiff : the difference, in milliseconds - */ - int GetTimeDiff(lua_State* L) - { - uint32 oldtimems = ALE::CHECKVAL(L, 1); - - ALE::Push(L, ALEUtil::GetTimeDiff(oldtimems)); - return 1; - } - - static std::string GetStackAsString(lua_State* L) - { - std::ostringstream oss; - int top = lua_gettop(L); - for (int i = 1; i <= top; ++i) - { - oss << luaL_tolstring(L, i, NULL); - lua_pop(L, 1); - } - return oss.str(); - } - - /** - * Prints given parameters to the info log. - * - * @param ... - */ - int PrintInfo(lua_State* L) - { - ALE_LOG_INFO("{}", GetStackAsString(L)); - return 0; - } - - /** - * Prints given parameters to the error log. - * - * @param ... - */ - int PrintError(lua_State* L) - { - ALE_LOG_ERROR("{}", GetStackAsString(L)); - return 0; - } - - /** - * Prints given parameters to the debug log. - * - * @param ... - */ - int PrintDebug(lua_State* L) - { - ALE_LOG_DEBUG("{}", GetStackAsString(L)); - return 0; - } - - /** - * Starts the event by eventId, if force is set, the event will force start regardless of previous event state. - * - * @param uint16 eventId : the event id to start. - * @param bool force = false : set `true` to force start the event. - */ - int StartGameEvent(lua_State* L) - { - uint16 eventId = ALE::CHECKVAL(L, 1); - bool force = ALE::CHECKVAL(L, 2, false); - - eGameEventMgr->StartEvent(eventId, force); - return 0; - } - - /** - * Stops the event by eventId, if force is set, the event will force stop regardless of previous event state. - * - * @param uint16 eventId : the event id to stop. - * @param bool force = false : set `true` to force stop the event. - */ - int StopGameEvent(lua_State* L) - { - uint16 eventId = ALE::CHECKVAL(L, 1); - bool force = ALE::CHECKVAL(L, 2, false); - - eGameEventMgr->StopEvent(eventId, force); - return 0; - } - - /** - * Performs a non-blocking HTTP request. - * - * When the passed callback function is called, the parameters `(status, body, headers)` are passed to it. - * - * -- GET example (prints a random word) - * HttpRequest("GET", "https://random-word-api.herokuapp.com/word", function(status, body, headers) - * print("Random word: " .. string.sub(body, 3, body:len() - 2)) - * end) - * - * -- POST example with JSON request body - * HttpRequest("POST", "https://jsonplaceholder.typicode.com/posts", '{"userId": 1,"title": "Foo","body": "Bar!"}', "application/json", function(status, body, headers) - * print(body) - * end) - * - * -- Example with request headers - * HttpRequest("GET", "https://postman-echo.com/headers", { Accept = "application/json", ["User-Agent"] = "ALE Lua Engine" }, function(status, body, headers) - * print(body) - * end) - * - * @proto (httpMethod, url, function) - * @proto (httpMethod, url, headers, function) - * @proto (httpMethod, url, body, contentType, function) - * @proto (httpMethod, url, body, contentType, headers, function) - * - * @param string httpMethod : the HTTP method to use (possible values are: `"GET"`, `"HEAD"`, `"POST"`, `"PUT"`, `"PATCH"`, `"DELETE"`, `"OPTIONS"`) - * @param string url : the URL to query - * @param table headers : a table with string key-value pairs containing the request headers - * @param string body : the request's body (only used for POST, PUT and PATCH requests) - * @param string contentType : the body's content-type - * @param function function : function that will be called when the request is executed - */ - int HttpRequest(lua_State* L) - { - std::string httpVerb = ALE::CHECKVAL(L, 1); - std::string url = ALE::CHECKVAL(L, 2); - std::string body; - std::string bodyContentType; - httplib::Headers headers; - - int headersIdx = 3; - int callbackIdx = 3; - - if (!lua_istable(L, headersIdx) && lua_isstring(L, headersIdx) && lua_isstring(L, headersIdx + 1)) - { - body = ALE::CHECKVAL(L, 3); - bodyContentType = ALE::CHECKVAL(L, 4); - headersIdx = 5; - callbackIdx = 5; - } - - if (lua_istable(L, headersIdx)) - { - ++callbackIdx; - - lua_pushnil(L); // First key - while (lua_next(L, headersIdx) != 0) - { - // Uses 'key' (at index -2) and 'value' (at index -1) - if (lua_isstring(L, -2)) - { - std::string key(lua_tostring(L, -2)); - std::string value(lua_tostring(L, -1)); - headers.insert(std::pair(key, value)); - } - // Removes 'value'; keeps 'key' for next iteration - lua_pop(L, 1); - } - } - - lua_pushvalue(L, callbackIdx); - int funcRef = luaL_ref(L, LUA_REGISTRYINDEX); - if (funcRef >= 0) - { - ALE::GALE->httpManager.PushRequest(new HttpWorkItem(funcRef, httpVerb, url, body, bodyContentType, headers)); - } - else - { - luaL_argerror(L, callbackIdx, "unable to make a ref to function"); - } - - return 0; - } - - /** - * Returns an object representing a `long long` (64-bit) value. - * - * The value by default is 0, but can be initialized to a value by passing a number or long long as a string. - * - * @proto value = () - * @proto value = (n) - * @proto value = (n_ll) - * @proto value = (n_str) - * @param int32 n - * @param int64 n_ll - * @param string n_str - * @return int64 value - */ - int CreateLongLong(lua_State* L) - { - long long init = 0; - if (lua_isstring(L, 1)) - { - std::string str = ALE::CHECKVAL(L, 1); - std::istringstream iss(str); - iss >> init; - if (iss.bad()) - return luaL_argerror(L, 1, "long long (as string) could not be converted"); - } - else if (!lua_isnoneornil(L, 1)) - init = ALE::CHECKVAL(L, 1); - - ALE::Push(L, init); - return 1; - } - - /** - * Returns an object representing an `unsigned long long` (64-bit) value. - * - * The value by default is 0, but can be initialized to a value by passing a number or unsigned long long as a string. - * - * @proto value = () - * @proto value = (n) - * @proto value = (n_ull) - * @proto value = (n_str) - * @param uint32 n - * @param uint64 n_ull - * @param string n_str - * @return uint64 value - */ - int CreateULongLong(lua_State* L) - { - unsigned long long init = 0; - if (lua_isstring(L, 1)) - { - std::string str = ALE::CHECKVAL(L, 1); - std::istringstream iss(str); - iss >> init; - if (iss.bad()) - return luaL_argerror(L, 1, "unsigned long long (as string) could not be converted"); - } - else if (!lua_isnoneornil(L, 1)) - init = ALE::CHECKVAL(L, 1); - - ALE::Push(L, init); - return 1; - } - - /** - * Unbinds event handlers for either all [BattleGround] events, or one type of event. - * - * If `event_type` is `nil`, all [BattleGround] 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:RegisterBGEvent] - */ - int ClearBattleGroundEvents(lua_State* L) - { - typedef EventKey Key; - - if (lua_isnoneornil(L, 1)) - { - ALE::GetALE(L)->BGEventBindings->Clear(); - } - else - { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->BGEventBindings->Clear(Key((Hooks::BGEvents)event_type)); - } - return 0; - } - - /** - * Unbinds event handlers for either all of a [Creature]'s events, or one type of event. - * - * If `event_type` is `nil`, all the [Creature]'s event handlers are cleared. - * - * Otherwise, only event handlers for `event_type` are cleared. - * - * **NOTE:** this will affect all instances of the [Creature], not just one. - * To bind and unbind events to a single [Creature], see [Global:RegisterUniqueCreatureEvent] and [Global:ClearUniqueCreatureEvents]. - * - * @proto (entry) - * @proto (entry, event_type) - * @param uint32 entry : the ID of one or more [Creature]s whose handlers will be cleared - * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterCreatureEvent] - */ - int ClearCreatureEvents(lua_State* L) - { - typedef EntryKey Key; - - if (lua_isnoneornil(L, 2)) - { - uint32 entry = ALE::CHECKVAL(L, 1); - - ALE* E = ALE::GetALE(L); - for (uint32 i = 1; i < Hooks::CREATURE_EVENT_COUNT; ++i) - E->CreatureEventBindings->Clear(Key((Hooks::CreatureEvents)i, entry)); - } - else - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 event_type = ALE::CHECKVAL(L, 2); - ALE::GetALE(L)->CreatureEventBindings->Clear(Key((Hooks::CreatureEvents)event_type, entry)); - } - return 0; - } - - /** - * Unbinds event handlers for either all of a [Creature]'s events, or one type of event. - * - * If `event_type` is `nil`, all the [Creature]'s event handlers are cleared. - * - * Otherwise, only event handlers for `event_type` are cleared. - * - * **NOTE:** this will affect only a single [Creature]. - * To bind and unbind events to all instances of a [Creature], see [Global:RegisterCreatureEvent] and [Global:ClearCreatureEvent]. - * - * @proto (entry) - * @proto (entry, event_type) - * @param ObjectGuid guid : the GUID of a single [Creature] whose handlers will be cleared - * @param uint32 instance_id : the instance ID of a single [Creature] whose handlers will be cleared - * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterCreatureEvent] - */ - int ClearUniqueCreatureEvents(lua_State* L) - { - typedef UniqueObjectKey Key; - - if (lua_isnoneornil(L, 3)) - { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - uint32 instanceId = ALE::CHECKVAL(L, 2); - - ALE* E = ALE::GetALE(L); - for (uint32 i = 1; i < Hooks::CREATURE_EVENT_COUNT; ++i) - E->CreatureUniqueBindings->Clear(Key((Hooks::CreatureEvents)i, guid, instanceId)); - } - else - { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - uint32 instanceId = ALE::CHECKVAL(L, 2); - uint32 event_type = ALE::CHECKVAL(L, 3); - ALE::GetALE(L)->CreatureUniqueBindings->Clear(Key((Hooks::CreatureEvents)event_type, guid, instanceId)); - } - return 0; - } - - /** - * Unbinds event handlers for either all of a [Creature]'s gossip events, or one type of event. - * - * If `event_type` is `nil`, all the [Creature]'s gossip event handlers are cleared. - * - * Otherwise, only event handlers for `event_type` are cleared. - * - * **NOTE:** this will affect all instances of the [Creature], not just one. - * To bind and unbind gossip events to a single [Creature], tell the ALE developers to implement that. - * - * @proto (entry) - * @proto (entry, event_type) - * @param uint32 entry : the ID of a [Creature] whose handlers will be cleared - * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterCreatureGossipEvent] - */ - int ClearCreatureGossipEvents(lua_State* L) - { - typedef EntryKey Key; - - if (lua_isnoneornil(L, 2)) - { - uint32 entry = ALE::CHECKVAL(L, 1); - - ALE* E = ALE::GetALE(L); - for (uint32 i = 1; i < Hooks::GOSSIP_EVENT_COUNT; ++i) - E->CreatureGossipBindings->Clear(Key((Hooks::GossipEvents)i, entry)); - } - else - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 event_type = ALE::CHECKVAL(L, 2); - ALE::GetALE(L)->CreatureGossipBindings->Clear(Key((Hooks::GossipEvents)event_type, entry)); - } - return 0; - } - - /** - * Unbinds event handlers for either all of a [GameObject]'s events, or one type of event. - * - * If `event_type` is `nil`, all the [GameObject]'s event handlers are cleared. - * - * Otherwise, only event handlers for `event_type` are cleared. - * - * **NOTE:** this will affect all instances of the [GameObject], not just one. - * To bind and unbind events to a single [GameObject], tell the ALE developers to implement that. - * - * @proto (entry) - * @proto (entry, event_type) - * @param uint32 entry : the ID of a [GameObject] whose handlers will be cleared - * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterGameObjectEvent] - */ - int ClearGameObjectEvents(lua_State* L) - { - typedef EntryKey Key; - - if (lua_isnoneornil(L, 2)) - { - uint32 entry = ALE::CHECKVAL(L, 1); - - ALE* E = ALE::GetALE(L); - for (uint32 i = 1; i < Hooks::GAMEOBJECT_EVENT_COUNT; ++i) - E->GameObjectEventBindings->Clear(Key((Hooks::GameObjectEvents)i, entry)); - } - else - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 event_type = ALE::CHECKVAL(L, 2); - ALE::GetALE(L)->GameObjectEventBindings->Clear(Key((Hooks::GameObjectEvents)event_type, entry)); - } - return 0; - } - - /** - * Unbinds event handlers for either all of a [GameObject]'s gossip events, or one type of event. - * - * If `event_type` is `nil`, all the [GameObject]'s gossip event handlers are cleared. - * - * Otherwise, only event handlers for `event_type` are cleared. - * - * **NOTE:** this will affect all instances of the [GameObject], not just one. - * To bind and unbind gossip events to a single [GameObject], tell the ALE developers to implement that. - * - * @proto (entry) - * @proto (entry, event_type) - * @param uint32 entry : the ID of a [GameObject] whose handlers will be cleared - * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterGameObjectGossipEvent] - */ - int ClearGameObjectGossipEvents(lua_State* L) - { - typedef EntryKey Key; - - if (lua_isnoneornil(L, 2)) - { - uint32 entry = ALE::CHECKVAL(L, 1); - - ALE* E = ALE::GetALE(L); - for (uint32 i = 1; i < Hooks::GOSSIP_EVENT_COUNT; ++i) - E->GameObjectGossipBindings->Clear(Key((Hooks::GossipEvents)i, entry)); - } - else - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 event_type = ALE::CHECKVAL(L, 2); - ALE::GetALE(L)->GameObjectGossipBindings->Clear(Key((Hooks::GossipEvents)event_type, entry)); - } - return 0; - } - - /** - * Unbinds event handlers for either all [Group] events, or one type of [Group] event. - * - * If `event_type` is `nil`, all [Group] 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:RegisterGroupEvent] - */ - int ClearGroupEvents(lua_State* L) - { - typedef EventKey Key; - - if (lua_isnoneornil(L, 1)) - { - ALE::GetALE(L)->GroupEventBindings->Clear(); - } - else - { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->GroupEventBindings->Clear(Key((Hooks::GroupEvents)event_type)); - } - return 0; - } - - /** - * Unbinds event handlers for either all [Guild] events, or one type of [Guild] event. - * - * If `event_type` is `nil`, all [Guild] 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:RegisterGuildEvent] - */ - int ClearGuildEvents(lua_State* L) - { - typedef EventKey Key; - - if (lua_isnoneornil(L, 1)) - { - ALE::GetALE(L)->GuildEventBindings->Clear(); - } - else - { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->GuildEventBindings->Clear(Key((Hooks::GuildEvents)event_type)); - } - return 0; - } - - /** - * Unbinds event handlers for either all of an [Item]'s events, or one type of event. - * - * If `event_type` is `nil`, all the [Item]'s event handlers are cleared. - * - * Otherwise, only event handlers for `event_type` are cleared. - * - * **NOTE:** this will affect all instances of the [Item], not just one. - * To bind and unbind events to a single [Item], tell the ALE developers to implement that. - * - * @proto (entry) - * @proto (entry, event_type) - * @param uint32 entry : the ID of an [Item] whose handlers will be cleared - * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterItemEvent] - */ - int ClearItemEvents(lua_State* L) - { - typedef EntryKey Key; - - if (lua_isnoneornil(L, 2)) - { - uint32 entry = ALE::CHECKVAL(L, 1); - - ALE* E = ALE::GetALE(L); - for (uint32 i = 1; i < Hooks::ITEM_EVENT_COUNT; ++i) - E->ItemEventBindings->Clear(Key((Hooks::ItemEvents)i, entry)); - } - else - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 event_type = ALE::CHECKVAL(L, 2); - ALE::GetALE(L)->ItemEventBindings->Clear(Key((Hooks::ItemEvents)event_type, entry)); - } - return 0; - } - - /** - * Unbinds event handlers for either all of an [Item]'s gossip events, or one type of event. - * - * If `event_type` is `nil`, all the [Item]'s gossip event handlers are cleared. - * - * Otherwise, only event handlers for `event_type` are cleared. - * - * **NOTE:** this will affect all instances of the [Item], not just one. - * To bind and unbind gossip events to a single [Item], tell the ALE developers to implement that. - * - * @proto (entry) - * @proto (entry, event_type) - * @param uint32 entry : the ID of an [Item] whose handlers will be cleared - * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterItemGossipEvent] - */ - int ClearItemGossipEvents(lua_State* L) - { - typedef EntryKey Key; - - if (lua_isnoneornil(L, 2)) - { - uint32 entry = ALE::CHECKVAL(L, 1); - - ALE* E = ALE::GetALE(L); - for (uint32 i = 1; i < Hooks::GOSSIP_EVENT_COUNT; ++i) - E->ItemGossipBindings->Clear(Key((Hooks::GossipEvents)i, entry)); - } - else - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 event_type = ALE::CHECKVAL(L, 2); - ALE::GetALE(L)->ItemGossipBindings->Clear(Key((Hooks::GossipEvents)event_type, entry)); - } - return 0; - } - - /** - * Unbinds event handlers for either all of a [WorldPacket] opcode's events, or one type of event. - * - * If `event_type` is `nil`, all the [WorldPacket] opcode's event handlers are cleared. - * - * Otherwise, only event handlers for `event_type` are cleared. - * - * @proto (opcode) - * @proto (opcode, event_type) - * @param uint32 opcode : the type of [WorldPacket] whose handlers will be cleared - * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterPacketEvent] - */ - int ClearPacketEvents(lua_State* L) - { - typedef EntryKey Key; - - if (lua_isnoneornil(L, 2)) - { - uint32 entry = ALE::CHECKVAL(L, 1); - - ALE* E = ALE::GetALE(L); - for (uint32 i = 1; i < Hooks::PACKET_EVENT_COUNT; ++i) - E->PacketEventBindings->Clear(Key((Hooks::PacketEvents)i, entry)); - } - else - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 event_type = ALE::CHECKVAL(L, 2); - ALE::GetALE(L)->PacketEventBindings->Clear(Key((Hooks::PacketEvents)event_type, entry)); - } - return 0; - } - - /** - * Unbinds event handlers for either all [Player] events, or one type of [Player] event. - * - * If `event_type` is `nil`, all [Player] 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:RegisterPlayerEvent] - */ - int ClearPlayerEvents(lua_State* L) - { - typedef EventKey Key; - - if (lua_isnoneornil(L, 1)) - { - ALE::GetALE(L)->PlayerEventBindings->Clear(); - } - else - { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->PlayerEventBindings->Clear(Key((Hooks::PlayerEvents)event_type)); - } - return 0; - } - - /** - * Unbinds event handlers for either all of a [Player]'s gossip events, or one type of event. - * - * If `event_type` is `nil`, all the [Player]'s gossip event handlers are cleared. - * - * Otherwise, only event handlers for `event_type` are cleared. - * - * @proto (entry) - * @proto (entry, event_type) - * @param uint32 entry : the low GUID of a [Player] whose handlers will be cleared - * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterPlayerGossipEvent] - */ - int ClearPlayerGossipEvents(lua_State* L) - { - typedef EntryKey Key; - - if (lua_isnoneornil(L, 2)) - { - uint32 entry = ALE::CHECKVAL(L, 1); - - ALE* E = ALE::GetALE(L); - for (uint32 i = 1; i < Hooks::GOSSIP_EVENT_COUNT; ++i) - E->PlayerGossipBindings->Clear(Key((Hooks::GossipEvents)i, entry)); - } - else - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 event_type = ALE::CHECKVAL(L, 2); - ALE::GetALE(L)->PlayerGossipBindings->Clear(Key((Hooks::GossipEvents)event_type, entry)); - } - return 0; - } - - /** - * Unbinds event handlers for either all server events, or one type of event. - * - * If `event_type` is `nil`, all server 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:RegisterServerEvent] - */ - int ClearServerEvents(lua_State* L) - { - typedef EventKey Key; - - if (lua_isnoneornil(L, 1)) - { - ALE::GetALE(L)->ServerEventBindings->Clear(); - } - else - { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->ServerEventBindings->Clear(Key((Hooks::ServerEvents)event_type)); - } - return 0; - } - - /** - * Unbinds event handlers for either all of a non-instanced [Map]'s events, or one type of event. - * - * If `event_type` is `nil`, all the non-instanced [Map]'s event handlers are cleared. - * - * Otherwise, only event handlers for `event_type` are cleared. - * - * @proto (map_id) - * @proto (map_id, event_type) - * @param uint32 map_id : the ID of a [Map] - * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterPlayerGossipEvent] - */ - int ClearMapEvents(lua_State* L) - { - typedef EntryKey Key; - - if (lua_isnoneornil(L, 2)) - { - uint32 entry = ALE::CHECKVAL(L, 1); - - ALE* E = ALE::GetALE(L); - for (uint32 i = 1; i < Hooks::INSTANCE_EVENT_COUNT; ++i) - E->MapEventBindings->Clear(Key((Hooks::InstanceEvents)i, entry)); - } - else - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 event_type = ALE::CHECKVAL(L, 2); - ALE::GetALE(L)->MapEventBindings->Clear(Key((Hooks::InstanceEvents)event_type, entry)); - } - - return 0; - } - - /** - * Unbinds event handlers for either all of an instanced [Map]'s events, or one type of event. - * - * If `event_type` is `nil`, all the instanced [Map]'s event handlers are cleared. - * - * Otherwise, only event handlers for `event_type` are cleared. - * - * @proto (instance_id) - * @proto (instance_id, event_type) - * @param uint32 entry : the ID of an instance of a [Map] - * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterInstanceEvent] - */ - int ClearInstanceEvents(lua_State* L) - { - typedef EntryKey Key; - - if (lua_isnoneornil(L, 2)) - { - uint32 entry = ALE::CHECKVAL(L, 1); - - ALE* E = ALE::GetALE(L); - for (uint32 i = 1; i < Hooks::INSTANCE_EVENT_COUNT; ++i) - E->InstanceEventBindings->Clear(Key((Hooks::InstanceEvents)i, entry)); - } - else - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 event_type = ALE::CHECKVAL(L, 2); - ALE::GetALE(L)->InstanceEventBindings->Clear(Key((Hooks::InstanceEvents)event_type, entry)); - } - - return 0; - } - - /** - * Unbinds event handlers for either all [Ticket] events, or one type of [Ticket] event. - * - * If `event_type` is `nil`, all [Ticket] 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:RegisterTicketEvent] - */ - int ClearTicketEvents(lua_State* L) - { - typedef EventKey Key; - - if (lua_isnoneornil(L, 1)) - { - ALE::GetALE(L)->TicketEventBindings->Clear(); - } - else - { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->TicketEventBindings->Clear(Key((Hooks::TicketEvents)event_type)); - } - return 0; - } - - /** - * Unbinds event handlers for either all of a [Spell]'s events, or one type of event. - * - * If `event_type` is `nil`, all the [Spell]'s event handlers are cleared. - * - * Otherwise, only event handlers for `event_type` are cleared. - * - * - * @proto (entry) - * @proto (entry, event_type) - * @param uint32 entry : the ID of a [Spell]s - * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterSpellEvent] - */ - int ClearSpellEvents(lua_State* L) - { - typedef EntryKey Key; - - if (lua_isnoneornil(L, 2)) - { - uint32 entry = ALE::CHECKVAL(L, 1); - - ALE* E = ALE::GetALE(L); - for (uint32 i = 1; i < Hooks::SPELL_EVENT_COUNT; ++i) - E->SpellEventBindings->Clear(Key((Hooks::SpellEvents)i, entry)); - } - else - { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 event_type = ALE::CHECKVAL(L, 2); - ALE::GetALE(L)->SpellEventBindings->Clear(Key((Hooks::SpellEvents)event_type, entry)); - } - 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 Key; - - if (lua_isnoneornil(L, 1)) - { - ALE::GetALE(L)->AllCreatureEventBindings->Clear(); - } - else - { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->AllCreatureEventBindings->Clear(Key((Hooks::AllCreatureEvents)event_type)); - } - return 0; - } - - /** - * Gets the faction which is the current owner of Halaa in Nagrand - * 0 = Alliance - * 1 = Horde - * - * 600 = slider max Alliance - * -600 = slider max Horde - * - * @return int16 the ID of the team to own Halaa - * @return float the slider position. - */ - int GetOwnerHalaa(lua_State* L) - { - OutdoorPvPNA* nagrandPvp = (OutdoorPvPNA*)sOutdoorPvPMgr->GetOutdoorPvPToZoneId(3518); - OPvPCapturePointNA* halaa = nagrandPvp->GetCapturePoint(); - ALE::Push(L, halaa->GetControllingFaction()); - ALE::Push(L, halaa->GetSlider()); - - return 2; - } - - /** - * Sets the owner of Halaa in Nagrand to the respective faction - * 0 = Alliance - * 1 = Horde - * - * @param uint16 teamId : the ID of the team to own Halaa - */ - int SetOwnerHalaa(lua_State* L) - { - uint16 teamId = ALE::CHECKVAL(L, 1); - - OutdoorPvPNA* nagrandPvp = (OutdoorPvPNA*)sOutdoorPvPMgr->GetOutdoorPvPToZoneId(3518); - OPvPCapturePointNA* halaa = nagrandPvp->GetCapturePoint(); - - if (teamId == 0) - { - halaa->SetSlider(599); - } - else if (teamId == 1) - { - halaa->SetSlider(-599); - } - else - { - return luaL_argerror(L, 1, "0 for Alliance or 1 for Horde expected"); - } - - return 0; - } - - /** - * Gets the localized OptionText and BoxText for a specific gossip menu option. - * If the text for the specified locale is not found, it returns the default text. - * - * @param uint32 menuId : The ID of the gossip menu. - * @param uint32 optionId : The ID of the gossip menu option. - * @param uint8 locale : The locale to retrieve the text for. 0 represents the default locale. - * - * @return string, string : The localized OptionText and BoxText for the gossip menu option, or the default text if no localization is found. - */ - int GetGossipMenuOptionLocale(lua_State* L) - { - uint32 menuId = ALE::CHECKVAL(L, 1); - uint32 optionId = ALE::CHECKVAL(L, 2); - uint8 locale = ALE::CHECKVAL(L, 3); - - std::string strOptionText; - std::string strBoxText; - - if (locale != DEFAULT_LOCALE) - { - if (GossipMenuItemsLocale const* gossipMenuLocale = sObjectMgr->GetGossipMenuItemsLocale(MAKE_PAIR32(menuId, optionId))) - { - ObjectMgr::GetLocaleString(gossipMenuLocale->OptionText, LocaleConstant(locale), strOptionText); - ObjectMgr::GetLocaleString(gossipMenuLocale->BoxText, LocaleConstant(locale), strBoxText); - } - } - - if (strOptionText.empty() || strBoxText.empty()) - { - GossipMenuItemsMapBounds bounds = sObjectMgr->GetGossipMenuItemsMapBounds(menuId); - for (auto itr = bounds.first; itr != bounds.second; ++itr) - { - if (itr->second.OptionID == optionId) - { - if (strOptionText.empty()) - strOptionText = itr->second.OptionText; - if (strBoxText.empty()) - strBoxText = itr->second.BoxText; - break; - } - } - } - - ALE::Push(L, strOptionText); - ALE::Push(L, strBoxText); - return 2; - } - - /** - * Return the entrance position (x, y, z, o) of the specified dungeon map id. - * - * @param uint32 mapId - * - * @return uint32 pos_x - * @return uint32 pos_y - * @return uint32 pos_z - * @return uint32 pos_o - */ - int GetMapEntrance(lua_State* L) - { - uint32 mapId = ALE::CHECKVAL(L, 1); - AreaTriggerTeleport const* at = sObjectMgr->GetMapEntranceTrigger(mapId); - - if (!at) - { - lua_pushnil(L); - return 1; - } - - ALE::Push(L, at->target_X); - ALE::Push(L, at->target_Y); - ALE::Push(L, at->target_Z); - ALE::Push(L, at->target_Orientation); - - return 5; - } - - /** - * Get the [SpellInfo] for the specified [Spell] id - * - * @param uint32 spellId : the ID of the spell - * @return [SpellInfo] spellInfo - */ - int GetSpellInfo(lua_State* L) - { - uint32 spellId = ALE::CHECKVAL(L, 1); - ALE::Push(L, sSpellMgr->GetSpellInfo(spellId)); - return 1; - - } - - /** - * Returns an entry from the specified DBC (DatabaseClient) store. - * - * This function looks up an entry in a DBC file by name and ID, and pushes it onto the Lua stack. - * - * @param string dbcName : The name of the DBC store (e.g., "ItemDisplayInfo") - * @param uint32 id : The ID used to look up within the specified DBC store - * - * @return [DBCStore] store : The requested DBC store instance - */ - int LookupEntry(lua_State* L) - { - const char* dbcName = ALE::CHECKVAL(L, 1); - uint32 id = ALE::CHECKVAL(L, 2); - - for (const auto& dbc : dbcRegistry) - { - if (dbc.name == dbcName) - { - const void* entry = dbc.lookupFunction(id); - if (!entry) - return 0; - - dbc.pushFunction(L, entry); - return 1; - } - } - - return luaL_error(L, "Invalid DBC name: %s", dbcName); - } -} -#endif + * @class GlobalMethods + * @brief Global Lua functions for Eclipse event system + * + * **Purpose:** + * Centralized namespace for ALL global Lua functions exposed by Eclipse. + * Keeps global API clean and organized in one place. + * + * **Exported Functions:** + * - RegisterServerEvent(eventId, callback, shots) + * - RegisterPlayerEvent(eventId, callback, shots) + * - CancelEvent(handlerId) + * - CancelServerEvent(eventId) + * - CancelPlayerEvent(eventId) + * + * **Architecture:** + * - All functions are stateless (delegate to EventManager singleton) + * - Thread-safe via EventManager's lock-free architecture + * - Move semantics for callback functions (zero-copy) + * + * **Usage in Lua:** + * ```lua + * local handlerId = RegisterPlayerEvent(2, function(eventId, player) + * print("Player logged in: " .. player:GetName()) + * end, 0) -- 0 = infinite shots + * + * CancelEvent(handlerId) -- Cancel specific handler + * CancelPlayerEvent(2) -- Cancel all login handlers + * ``` + * + * @note This namespace is registered to Lua via EventAPI::RegisterAPI() + */ + namespace GlobalMethods + { + // ======================================================================== + // EVENT REGISTRATION + // ======================================================================== + + /** + * @brief Register all global event functions to Lua state + * + * Centralized registration for all state.set_function bindings. + * Called by Methods::RegisterAllMethods(). + * + * Registers: + * - RegisterServerEvent + * - RegisterPlayerEvent + * - CancelEvent + * - CancelServerEvent + * - CancelPlayerEvent + * + * @param state Lua state to bind functions to + * + * @performance ~50µs (5 function pointer assignments) + */ + void RegisterGlobalEventFunctions(sol::state& state); + + /** + * @brief Register a server/world event handler + * + * Registers a Lua callback for world events (server start, config reload, etc.). + * + * @param event Event ID (WorldEvent enum as uint32) + * @param handler Lua callback function(eventId, ...) + * @param shots Number of times to call (0 = infinite) + * @return Handler ID for cancellation + * + * @performance O(1) - Lock-free vector append + * @thread-safety Thread-safe via EventManager + * + * @example Lua: + * ```lua + * RegisterServerEvent(1, function(eventId) + * print("Server event triggered!") + * end) + * ``` + */ + uint64 RegisterServerEvent(uint32 event, sol::protected_function handler, sol::optional shots); + + /** + * @brief Register a player event handler + * + * Registers a Lua callback for player events (login, logout, level up, etc.). + * + * @param event Event ID (PlayerEvent enum as uint32) + * @param handler Lua callback function(eventId, player, ...) + * @param shots Number of times to call (0 = infinite) + * @return Handler ID for cancellation + * + * @performance O(1) - Lock-free vector append + * @thread-safety Thread-safe via EventManager + * + * @example Lua: + * ```lua + * RegisterPlayerEvent(2, function(eventId, player) + * print(player:GetName() .. " logged in!") + * end) + * ``` + */ + uint64 RegisterPlayerEvent(uint32 event, sol::protected_function handler, sol::optional shots); + + // ======================================================================== + // EVENT CANCELLATION + // ======================================================================== + + /** + * @brief Cancel a specific event handler by ID + * + * Removes a single handler registered via RegisterXEvent(). + * + * @param handlerId Handler ID returned by RegisterXEvent + * @return true if handler was found and cancelled, false otherwise + * + * @performance O(n) where n = number of handlers for that event + * @thread-safety Thread-safe via EventManager + * + * @example Lua: + * ```lua + * local id = RegisterPlayerEvent(2, callback) + * CancelEvent(id) -- Remove this specific handler + * ``` + */ + bool CancelEvent(uint64 handlerId); + + /** + * @brief Cancel all handlers for a server event + * + * Removes ALL handlers registered for a specific server event ID. + * + * @param event Event ID (WorldEvent enum as uint32) + * + * @performance O(1) - Clears vector + * @thread-safety Thread-safe via EventManager + * + * @example Lua: + * ```lua + * CancelServerEvent(1) -- Remove all handlers for event 1 + * ``` + */ + void CancelServerEvent(uint32 event); + + /** + * @brief Cancel all handlers for a player event + * + * Removes ALL handlers registered for a specific player event ID. + * + * @param event Event ID (PlayerEvent enum as uint32) + * + * @performance O(1) - Clears vector + * @thread-safety Thread-safe via EventManager + * + * @example Lua: + * ```lua + * CancelPlayerEvent(2) -- Remove all login handlers + * ``` + */ + void CancelPlayerEvent(uint32 event); + + // ======================================================================== + // HELPER FUNCTIONS (Internal use) + // ======================================================================== + + /** + * @brief Convert server event ID to internal EventType + * @param event Event ID from Lua (uint32) + * @return Typed WorldEvent enum + */ + Core::WorldEvent ServerEventToType(uint32 event); + + /** + * @brief Convert player event ID to internal EventType + * @param event Event ID from Lua (uint32) + * @return Typed PlayerEvent enum + */ + Core::PlayerEvent PlayerEventToType(uint32 event); + + // ======================================================================== + // TIMED EVENTS (Global) + // ======================================================================== + + /** + * @brief Create a global timed event (delayed/repeating callback) + * + * Registers a callback to execute after a delay, optionally repeating. + * Uses TimedEventManager for precise timing. + * + * @param mgr TimedEventManager for this state (injected by EventAPI) + * @param callback Lua function to call + * @param delay Delay in milliseconds before first execution + * @param repeats Number of times to repeat (1 = once, 0 = infinite) + * @return Event ID for cancellation + * + * @performance ~100ns registration (lock-free vector append) + * @thread-safety Thread-safe via per-state manager isolation + * + * @example Lua: + * ```lua + * CreateLuaEvent(function() + * print("5 seconds elapsed!") + * end, 5000, 1) -- 5000ms delay, execute once + * ``` + */ + void RegisterCreateLuaEvent(sol::state& state, Core::TimedEventManager* mgr); + + /** + * @brief Remove a specific timed event by ID + * + * @param mgr TimedEventManager for this state + * @param eventId Event ID returned by CreateLuaEvent + * @return true if event was found and removed + */ + void RegisterRemoveTimedEvent(sol::state& state, Core::TimedEventManager* mgr); + + /** + * @brief Remove all global timed events + * + * Clears all events registered via CreateLuaEvent. + * Does NOT affect player/creature/gameobject events. + * + * @param mgr TimedEventManager for this state + */ + void RegisterRemoveAllTimedEvents(sol::state& state, Core::TimedEventManager* mgr); + + /** + * @brief Get count of active global timed events + * + * @param mgr TimedEventManager for this state + * @return Number of active global events + */ + void RegisterGetTimedEventCount(sol::state& state, Core::TimedEventManager* mgr); + + } // namespace GlobalMethods + +} // namespace Eclipse::Methods + +#endif // _ECLIPSE_GLOBAL_METHODS_H diff --git a/src/LuaEngine/methods/GroupMethods.h b/src/LuaEngine/methods/GroupMethods.h deleted file mode 100644 index 5c0fc37b74..0000000000 --- a/src/LuaEngine/methods/GroupMethods.h +++ /dev/null @@ -1,435 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef GROUPMETHODS_H -#define GROUPMETHODS_H - -/*** - * Represents a player group in the game, such as a party or raid. - * - * Inherits all methods from: none - */ -namespace LuaGroup -{ - /** - * Returns 'true' if the [Player] is the [Group] leader - * - * @param ObjectGuid guid : guid of a possible leader - * @return bool isLeader - */ - int IsLeader(lua_State* L, Group* group) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - ALE::Push(L, group->IsLeader(guid)); - return 1; - } - - /** - * Returns 'true' if the [Group] is full - * - * @return bool isFull - */ - int IsFull(lua_State* L, Group* group) - { - ALE::Push(L, group->IsFull()); - return 1; - } - - /** - * Returns 'true' if the [Group] is a LFG group - * - * @return bool isLFGGroup - */ - int IsLFGGroup(lua_State* L, Group* group) - { - ALE::Push(L, group->isLFGGroup()); - return 1; - } - - /** - * Returns 'true' if the [Group] is a raid [Group] - * - * @return bool isRaid - */ - int IsRaidGroup(lua_State* L, Group* group) - { - ALE::Push(L, group->isRaidGroup()); - return 1; - } - - /** - * Returns 'true' if the [Group] is a battleground [Group] - * - * @return bool isBG - */ - int IsBGGroup(lua_State* L, Group* group) - { - ALE::Push(L, group->isBGGroup()); - return 1; - } - - /** - * Returns 'true' if the [Player] is a member of this [Group] - * - * @param ObjectGuid guid : guid of a player - * @return bool isMember - */ - int IsMember(lua_State* L, Group* group) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - ALE::Push(L, group->IsMember(guid)); - return 1; - } - - /** - * Returns 'true' if the [Player] is an assistant of this [Group] - * - * @param ObjectGuid guid : guid of a player - * @return bool isAssistant - */ - int IsAssistant(lua_State* L, Group* group) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - ALE::Push(L, group->IsAssistant(guid)); - return 1; - } - - /** - * Returns 'true' if the [Player]s are in the same subgroup in this [Group] - * - * @param [Player] player1 : first [Player] to check - * @param [Player] player2 : second [Player] to check - * @return bool sameSubGroup - */ - int SameSubGroup(lua_State* L, Group* group) - { - Player* player1 = ALE::CHECKOBJ(L, 2); - Player* player2 = ALE::CHECKOBJ(L, 3); - ALE::Push(L, group->SameSubGroup(player1, player2)); - return 1; - } - - /** - * Returns 'true' if the subgroup has free slots in this [Group] - * - * @param uint8 subGroup : subGroup ID to check - * @return bool hasFreeSlot - */ - int HasFreeSlotSubGroup(lua_State* L, Group* group) - { - uint8 subGroup = ALE::CHECKVAL(L, 2); - - if (subGroup >= MAX_RAID_SUBGROUPS) - { - luaL_argerror(L, 2, "valid subGroup ID expected"); - return 0; - } - - ALE::Push(L, group->HasFreeSlotSubGroup(subGroup)); - return 1; - } - - /** - * Adds a new member to the [Group] - * - * @param [Player] player : [Player] to add to the group - * @return bool added : true if member was added - */ - int AddMember(lua_State* L, Group* group) - { - Player* player = ALE::CHECKOBJ(L, 2); - - if (player->GetGroup() || !group->IsCreated() || group->IsFull()) - { - ALE::Push(L, false); - return 1; - } - - if (player->GetGroupInvite()) - player->UninviteFromGroup(); - - bool success = group->AddMember(player); - if (success) - group->BroadcastGroupUpdate(); - - ALE::Push(L, success); - return 1; - } - - /*int IsLFGGroup(lua_State* L, Group* group) // TODO: Implementation - { - ALE::Push(L, group->isLFGGroup()); - return 1; - }*/ - - /*int IsBFGroup(lua_State* L, Group* group) // TODO: Implementation - { - ALE::Push(L, group->isBFGroup()); - return 1; - }*/ - - /** - * Returns a table with the [Player]s in this [Group] - * - * @return table groupPlayers : table of [Player]s - */ - int GetMembers(lua_State* L, Group* group) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (GroupReference* itr = group->GetFirstMember(); itr; itr = itr->next()) - { - Player* member = itr->GetSource(); - - if (!member || !member->GetSession()) - continue; - - ALE::Push(L, member); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns [Group] leader GUID - * - * @return ObjectGuid leaderGUID - */ - int GetLeaderGUID(lua_State* L, Group* group) - { - ALE::Push(L, group->GetLeaderGUID()); - return 1; - } - - /** - * Returns the [Group]'s GUID - * - * @return ObjectGuid groupGUID - */ - int GetGUID(lua_State* L, Group* group) - { - ALE::Push(L, group->GET_GUID()); - return 1; - } - - /** - * Returns a [Group] member's GUID by their name - * - * @param string name : the [Player]'s name - * @return ObjectGuid memberGUID - */ - int GetMemberGUID(lua_State* L, Group* group) - { - const char* name = ALE::CHECKVAL(L, 2); - - ALE::Push(L, group->GetMemberGUID(name)); - return 1; - } - - /** - * Returns the member count of this [Group] - * - * @return uint32 memberCount - */ - int GetMembersCount(lua_State* L, Group* group) - { - ALE::Push(L, group->GetMembersCount()); - return 1; - } - - /** - * Returns the type of this [Group] - * - *
-     * enum GroupType
-     * {
-     *     GROUPTYPE_NORMAL         = 0,
-     *     GROUPTYPE_BG             = 1,
-     *     GROUPTYPE_RAID           = 2,
-     *     GROUPTYPE_LFG_RESTRICTED = 4,
-     *     GROUPTYPE_LFG            = 8
-     * };
-     * 
- * - * @return [GroupType] groupType - */ - int GetGroupType(lua_State* L, Group* group) - { - ALE::Push(L, group->GetGroupType()); - return 1; - } - - /** - * Returns the [Player]'s subgroup ID of this [Group] - * - * @param ObjectGuid guid : guid of the player - * @return uint8 subGroupID : a valid subgroup ID or MAX_RAID_SUBGROUPS+1 - */ - int GetMemberGroup(lua_State* L, Group* group) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - ALE::Push(L, group->GetMemberGroup(guid)); - return 1; - } - - /** - * Sets the leader of this [Group] - * - * @param ObjectGuid guid : guid of the new leader - */ - int SetLeader(lua_State* L, Group* group) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - group->ChangeLeader(guid); - group->SendUpdate(); - return 0; - } - - /** - * Sends a specified [WorldPacket] to this [Group] - * - * @param [WorldPacket] packet : the [WorldPacket] to send - * @param bool ignorePlayersInBg : ignores [Player]s in a battleground - * @param ObjectGuid ignore : ignore a [Player] by their GUID - */ - int SendPacket(lua_State* L, Group* group) - { - WorldPacket* data = ALE::CHECKOBJ(L, 2); - bool ignorePlayersInBg = ALE::CHECKVAL(L, 3); - ObjectGuid ignore = ALE::CHECKVAL(L, 4); - - group->BroadcastPacket(data, ignorePlayersInBg, -1, ignore); - return 0; - } - - /** - * Removes a [Player] from this [Group] and returns 'true' if successful - * - *
-     * enum RemoveMethod
-     * {
-     *     GROUP_REMOVEMETHOD_DEFAULT  = 0,
-     *     GROUP_REMOVEMETHOD_KICK     = 1,
-     *     GROUP_REMOVEMETHOD_LEAVE    = 2,
-     *     GROUP_REMOVEMETHOD_KICK_LFG = 3
-     * };
-     * 
- * - * @param ObjectGuid guid : guid of the player to remove - * @param [RemoveMethod] method : method used to remove the player - * @return bool removed - */ - int RemoveMember(lua_State* L, Group* group) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - uint32 method = ALE::CHECKVAL(L, 3, 0); - - ALE::Push(L, group->RemoveMember(guid, (RemoveMethod)method)); - return 1; - } - - /** - * Disbands this [Group] - * - */ - int Disband(lua_State* /*L*/, Group* group) - { - group->Disband(); - return 0; - } - - /** - * Converts this [Group] to a raid [Group] - * - */ - int ConvertToRaid(lua_State* /*L*/, Group* group) - { - group->ConvertToRaid(); - return 0; - } - - /** - * Sets the member's subGroup - * - * @param ObjectGuid guid : guid of the player to move - * @param uint8 groupID : the subGroup's ID - */ - int SetMembersGroup(lua_State* L, Group* group) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - uint8 subGroup = ALE::CHECKVAL(L, 3); - - if (subGroup >= MAX_RAID_SUBGROUPS) - { - luaL_argerror(L, 3, "valid subGroup ID expected"); - return 0; - } - - if (!group->HasFreeSlotSubGroup(subGroup)) - return 0; - - group->ChangeMembersGroup(guid, subGroup); - return 0; - } - - /** - * Sets the target icon of an object for the [Group] - * - * @param uint8 icon : the icon (Skull, Square, etc) - * @param ObjectGuid target : GUID of the icon target, 0 is to clear the icon - * @param ObjectGuid setter : GUID of the icon setter - */ - int SetTargetIcon(lua_State* L, Group* group) - { - uint8 icon = ALE::CHECKVAL(L, 2); - ObjectGuid target = ALE::CHECKVAL(L, 3); - ObjectGuid setter = ALE::CHECKVAL(L, 4, ObjectGuid()); - - if (icon >= TARGETICONCOUNT) - return luaL_argerror(L, 2, "valid target icon expected"); - - group->SetTargetIcon(icon, setter, target); - return 0; - } - - /** - * Sets or removes a flag for a [Group] member - * - *
-     * enum GroupMemberFlags
-     * {
-     *     MEMBER_FLAG_ASSISTANT   = 0x01,
-     *     MEMBER_FLAG_MAINTANK    = 0x02,
-     *     MEMBER_FLAG_MAINASSIST  = 0x04,
-     * };
-     * 
- * - * @param ObjectGuid target : GUID of the target - * @param bool apply : add the `flag` if `true`, remove the `flag` otherwise - * @param [GroupMemberFlags] flag : the flag to set or unset - */ - int SetMemberFlag(lua_State* L, Group* group) - { - ObjectGuid target = ALE::CHECKVAL(L, 2); - bool apply = ALE::CHECKVAL(L, 3); - GroupMemberFlags flag = static_cast(ALE::CHECKVAL(L, 4)); - - group->SetGroupMemberFlag(target, apply, flag); - return 0; - } - - /*int ConvertToLFG(lua_State* L, Group* group) // TODO: Implementation - { - group->ConvertToLFG(); - return 0; - }*/ -}; - -#endif diff --git a/src/LuaEngine/methods/GuildMethods.h b/src/LuaEngine/methods/GuildMethods.h deleted file mode 100644 index 979f564a9e..0000000000 --- a/src/LuaEngine/methods/GuildMethods.h +++ /dev/null @@ -1,412 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef GUILDMETHODS_H -#define GUILDMETHODS_H - -/*** - * Represents a player guild. Used to manage guild members, ranks, guild bank. - * - * Inherits all methods from: none - */ -namespace LuaGuild -{ - /** - * Returns a table with the [Player]s in this [Guild] - * - * Only the players that are online and on some map. - * - * @return table guildPlayers : table of [Player]s - */ - int GetMembers(lua_State* L, Guild* guild) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - { - std::shared_lock lock(*HashMapHolder::GetLock()); - const HashMapHolder::MapType& m = eObjectAccessor()GetPlayers(); - for (HashMapHolder::MapType::const_iterator it = m.begin(); it != m.end(); ++it) - { - if (Player* player = it->second) - { - if (player->IsInWorld() && player->GetGuildId() == guild->GetId()) - { - ALE::Push(L, player); - lua_rawseti(L, tbl, ++i); - } - } - } - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns the member count of this [Guild] - * - * @return uint32 memberCount - */ - int GetMemberCount(lua_State* L, Guild* guild) - { - ALE::Push(L, guild->GetMemberCount()); - return 1; - } - - /** - * Finds and returns the [Guild] leader by their GUID if logged in - * - * @return [Player] leader - */ - int GetLeader(lua_State* L, Guild* guild) - { - ALE::Push(L, eObjectAccessor()FindPlayer(guild->GetLeaderGUID())); - return 1; - } - - /** - * Returns [Guild] leader GUID - * - * @return ObjectGuid leaderGUID - */ - int GetLeaderGUID(lua_State* L, Guild* guild) - { - ALE::Push(L, guild->GetLeaderGUID()); - return 1; - } - - /** - * Returns the [Guild]s entry ID - * - * @return uint32 entryId - */ - int GetId(lua_State* L, Guild* guild) - { - ALE::Push(L, guild->GetId()); - return 1; - } - - /** - * Returns the [Guild]s name - * - * @return string guildName - */ - int GetName(lua_State* L, Guild* guild) - { - ALE::Push(L, guild->GetName()); - return 1; - } - - /** - * Returns the [Guild]s current Message Of The Day - * - * @return string guildMOTD - */ - int GetMOTD(lua_State* L, Guild* guild) - { - ALE::Push(L, guild->GetMOTD()); - return 1; - } - - /** - * Returns the [Guild]s current info - * - * @return string guildInfo - */ - int GetInfo(lua_State* L, Guild* guild) - { - ALE::Push(L, guild->GetInfo()); - return 1; - } - - /** - * Sets the leader of this [Guild] - * - * @param [Player] leader : the [Player] leader to change - */ - int SetLeader(lua_State* L, Guild* guild) - { - Player* player = ALE::CHECKOBJ(L, 2); - - guild->HandleSetLeader(player->GetSession(), player->GetName()); - return 0; - } - - /** - * Sets the information of the bank tab specified - * - * @param uint8 tabId : the ID of the tab specified - * @param string info : the information to be set to the bank tab - */ - int SetBankTabText(lua_State* L, Guild* guild) - { - uint8 tabId = ALE::CHECKVAL(L, 2); - const char* text = ALE::CHECKVAL(L, 3); - guild->SetBankTabText(tabId, text); - return 0; - } - - // SendPacketToGuild(packet) - /** - * Sends a [WorldPacket] to all the [Player]s in the [Guild] - * - * @param [WorldPacket] packet : the [WorldPacket] to be sent to the [Player]s - */ - int SendPacket(lua_State* L, Guild* guild) - { - WorldPacket* data = ALE::CHECKOBJ(L, 2); - - guild->BroadcastPacket(data); - return 0; - } - - // SendPacketToRankedInGuild(packet, rankId) - /** - * Sends a [WorldPacket] to all the [Player]s at the specified rank in the [Guild] - * - * @param [WorldPacket] packet : the [WorldPacket] to be sent to the [Player]s - * @param uint8 rankId : the rank ID - */ - int SendPacketToRanked(lua_State* L, Guild* guild) - { - WorldPacket* data = ALE::CHECKOBJ(L, 2); - uint8 ranked = ALE::CHECKVAL(L, 3); - - guild->BroadcastPacketToRank(data, ranked); - return 0; - } - - /** - * Disbands the [Guild] - */ - int Disband(lua_State* /*L*/, Guild* guild) - { - guild->Disband(); - return 0; - } - - /** - * Adds the specified [Player] to the [Guild] at the specified rank. - * - * If no rank is specified, defaults to none. - * - * @param [Player] player : the [Player] to be added to the guild - * @param uint8 rankId : the rank ID - */ - int AddMember(lua_State* L, Guild* guild) - { - Player* player = ALE::CHECKOBJ(L, 2); - uint8 rankId = ALE::CHECKVAL(L, 3, GUILD_RANK_NONE); - - guild->AddMember(player->GET_GUID(), rankId); - return 0; - } - - /** - * Removes the specified [Player] from the [Guild]. - * - * @param [Player] player : the [Player] to be removed from the guild - * @param bool isDisbanding : default 'false', should only be set to 'true' if the guild is triggered to disband - */ - int DeleteMember(lua_State* L, Guild* guild) - { - Player* player = ALE::CHECKOBJ(L, 2); - bool isDisbanding = ALE::CHECKVAL(L, 3, false); - - guild->DeleteMember(player->GET_GUID(), isDisbanding); - return 0; - } - - /** - * Promotes/demotes the [Player] to the specified rank. - * - * @param [Player] player : the [Player] to be promoted/demoted - * @param uint8 rankId : the rank ID - */ - int SetMemberRank(lua_State* L, Guild* guild) - { - Player* player = ALE::CHECKOBJ(L, 2); - uint8 newRank = ALE::CHECKVAL(L, 3); - - guild->ChangeMemberRank(player->GET_GUID(), newRank); - return 0; - } - - /** - * Sets the new name of the specified [Guild]. - * - * @param string name : new name of this guild - */ - int SetName(lua_State* L, Guild* guild) - { - std::string name = ALE::CHECKVAL(L, 2); - - guild->SetName(name); - return 0; - } - - /** - * Update [Player] data in [Guild] member list. - * - * enum GuildMemberData - * { - * GUILD_MEMBER_DATA_ZONEID = 0 - * GUILD_MEMBER_DATA_LEVEL = 1 - * }; - * - * @param [Player] player : plkayer you need to update data - * @param [GuildMemberData] dataid : data you need to update - * @param uint32 value - */ - int UpdateMemberData(lua_State* L, Guild* guild) - { - Player* player = ALE::CHECKOBJ(L, 2); - uint8 dataid = ALE::CHECKVAL(L, 3); - uint32 value = ALE::CHECKVAL(L, 4); - - guild->UpdateMemberData(player, dataid, value); - return 0; - } - - /** - * Send message to [Guild] from specific [Player]. - * - * @param [Player] player : the [Player] is the author of the message - * @param bool officerOnly : send message only on officer channel - * @param string msg : the message you need to send - * @param uint32 lang : language the [Player] will speak - */ - int SendMessage(lua_State* L, Guild* guild) - { - Player* player = ALE::CHECKOBJ(L, 2); - bool officerOnly = ALE::CHECKVAL(L, 3, false); - std::string msg = ALE::CHECKVAL(L, 4); - uint32 language = ALE::CHECKVAL(L, 5, false); - - guild->BroadcastToGuild(player->GetSession(), officerOnly, msg, language); - return 0; - } - - /** - * Invites [Guild] members to events based on level and rank filters. - * - * @param [Player] player : who sends the invitation - * @param uint32 minLevel : the required min level - * @param uint32 maxLevel : the required max level - * @param uint32 minRank : the required min rank - */ - int MassInviteToEvent(lua_State* L, Guild* guild) - { - Player* player = ALE::CHECKOBJ(L, 2); - uint32 minLevel = ALE::CHECKVAL(L, 3); - uint32 maxLevel = ALE::CHECKVAL(L, 4); - uint32 minRank = ALE::CHECKVAL(L, 5); - - guild->MassInviteToEvent(player->GetSession(), minLevel, maxLevel, minRank); - return 0; - } - - /** - * Swap item from a specific tab and slot [Guild] bank to another one. - * - * @param [Player] player : who Swap the item - * @param uint8 tabId : source tab id - * @param uint8 slotId : source slot id - * @param uint8 destTabId : destination tab id - * @param uint8 destSlotId : destination slot id - * @param uint8 splitedAmount : if the item is stackable, how much should be swaped - */ - int SwapItems(lua_State* L, Guild* guild) - { - Player* player = ALE::CHECKOBJ(L, 2); - uint8 tabId = ALE::CHECKVAL(L, 3); - uint8 slotId = ALE::CHECKVAL(L, 4); - uint8 destTabId = ALE::CHECKVAL(L, 5); - uint8 destSlotId = ALE::CHECKVAL(L, 6); - uint32 splitedAmount = ALE::CHECKVAL(L, 7); - - guild->SwapItems(player, tabId, slotId, destTabId, destSlotId, splitedAmount); - return 0; - } - - /** - * Swap an item from a specific tab and location in the [guild] bank to the bags and locations in the inventory of a specific [player] and vice versa. - * - * @param [Player] player : who Swap the item - * @param bool toChar : the item goes to the [Player]'s inventory or comes from the [Player]'s inventory - * @param uint8 tabId : tab id - * @param uint8 slotId : slot id - * @param uint8 playerBag : bag id - * @param uint8 playerSlotId : slot id - * @param uint32 splitedAmount : if the item is stackable, how much should be swaped - */ - int SwapItemsWithInventory(lua_State* L, Guild* guild) - { - Player* player = ALE::CHECKOBJ(L, 2); - bool toChar = ALE::CHECKVAL(L, 3, false); - uint8 tabId = ALE::CHECKVAL(L, 4); - uint8 slotId = ALE::CHECKVAL(L, 5); - uint8 playerBag = ALE::CHECKVAL(L, 6); - uint8 playerSlotId = ALE::CHECKVAL(L, 7); - uint32 splitedAmount = ALE::CHECKVAL(L, 8); - - guild->SwapItemsWithInventory(player, toChar, tabId, slotId, playerBag, playerSlotId, splitedAmount); - return 0; - } - - /** - * Return the total bank money. - * - * @return number totalBankMoney - */ - int GetTotalBankMoney(lua_State* L, Guild* guild) - { - ALE::Push(L, guild->GetTotalBankMoney()); - return 1; - } - - /** - * Return the created date. - * - * @return uint64 created date - */ - int GetCreatedDate(lua_State* L, Guild* guild) - { - ALE::Push(L, guild->GetCreatedDate()); - return 1; - } - - /** - * Resets the number of item withdraw in all tab's for all [Guild] members. - */ - int ResetTimes(lua_State* /*L*/, Guild* guild) - { - guild->ResetTimes(); - return 0; - } - - /** - * Modify the [Guild] bank money. You can deposit or withdraw. - * - * @param uint64 amount : amount to add or remove - * @param bool add : true (add money) | false (withdraw money) - * @return bool is_applied - */ - int ModifyBankMoney(lua_State* L, Guild* guild) - { - uint64 amount = ALE::CHECKVAL(L, 2); - bool add = ALE::CHECKVAL(L, 2); - - CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); - ALE::Push(L, guild->ModifyBankMoney(trans, amount, add)); - - CharacterDatabase.CommitTransaction(trans); - return 1; - } -}; -#endif diff --git a/src/LuaEngine/methods/ItemMethods.h b/src/LuaEngine/methods/ItemMethods.h deleted file mode 100644 index 06ddf1d4da..0000000000 --- a/src/LuaEngine/methods/ItemMethods.h +++ /dev/null @@ -1,774 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef ITEMMETHODS_H -#define ITEMMETHODS_H - -/*** - * Represents an instance of an item in the game world. - * - * Inherits all methods from: [Object] - */ -namespace LuaItem -{ - /** - * Returns 'true' if the [Item] is soulbound, 'false' otherwise - * - * @return bool isSoulBound - */ - int IsSoulBound(lua_State* L, Item* item) - { - ALE::Push(L, item->IsSoulBound()); - return 1; - } - - /** - * Returns 'true' if the [Item] is account bound, 'false' otherwise - * - * @return bool isAccountBound - */ - int IsBoundAccountWide(lua_State* L, Item* item) - { - ALE::Push(L, item->IsBoundAccountWide()); - return 1; - } - - /** - * Returns 'true' if the [Item] is bound to a [Player] by an enchant, 'false' otehrwise - * - * @return bool isBoundByEnchant - */ - int IsBoundByEnchant(lua_State* L, Item* item) - { - ALE::Push(L, item->IsBoundByEnchant()); - return 1; - } - - /** - * Returns 'true' if the [Item] is not bound to the [Player] specified, 'false' otherwise - * - * @param [Player] player : the [Player] object to check the item against - * @return bool isNotBound - */ - int IsNotBoundToPlayer(lua_State* L, Item* item) - { - Player* player = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, item->IsBindedNotWith(player)); - return 1; - } - - /** - * Returns 'true' if the [Item] is locked, 'false' otherwise - * - * @return bool isLocked - */ - int IsLocked(lua_State* L, Item* item) - { - ALE::Push(L, item->IsLocked()); - return 1; - } - - /** - * Returns 'true' if the [Item] is a bag, 'false' otherwise - * - * @return bool isBag - */ - int IsBag(lua_State* L, Item* item) - { - ALE::Push(L, item->IsBag()); - return 1; - } - - /** - * Returns 'true' if the [Item] is a currency token, 'false' otherwise - * - * @return bool isCurrencyToken - */ - int IsCurrencyToken(lua_State* L, Item* item) - { - ALE::Push(L, item->IsCurrencyToken()); - return 1; - } - - /** - * Returns 'true' if the [Item] is a not an empty bag, 'false' otherwise - * - * @return bool isNotEmptyBag - */ - int IsNotEmptyBag(lua_State* L, Item* item) - { - ALE::Push(L, item->IsNotEmptyBag()); - return 1; - } - - /** - * Returns 'true' if the [Item] is broken, 'false' otherwise - * - * @return bool isBroken - */ - int IsBroken(lua_State* L, Item* item) - { - ALE::Push(L, item->IsBroken()); - return 1; - } - - /** - * Returns 'true' if the [Item] can be traded, 'false' otherwise - * - * @return bool isTradeable - */ - int CanBeTraded(lua_State* L, Item* item) - { - bool mail = ALE::CHECKVAL(L, 2, false); - ALE::Push(L, item->CanBeTraded(mail)); - return 1; - } - - /** - * Returns 'true' if the [Item] is currently in a trade window, 'false' otherwise - * - * @return bool isInTrade - */ - int IsInTrade(lua_State* L, Item* item) - { - ALE::Push(L, item->IsInTrade()); - return 1; - } - - /** - * Returns 'true' if the [Item] is currently in a bag, 'false' otherwise - * - * @return bool isInBag - */ - int IsInBag(lua_State* L, Item* item) - { - ALE::Push(L, item->IsInBag()); - return 1; - } - - /** - * Returns 'true' if the [Item] is currently equipped, 'false' otherwise - * - * @return bool isEquipped - */ - int IsEquipped(lua_State* L, Item* item) - { - ALE::Push(L, item->IsEquipped()); - return 1; - } - - /** - * Returns 'true' if the [Item] has the [Quest] specified tied to it, 'false' otherwise - * - * @param uint32 questId : the [Quest] id to be checked - * @return bool hasQuest - */ - int HasQuest(lua_State* L, Item* item) - { - uint32 quest = ALE::CHECKVAL(L, 2); - ALE::Push(L, item->hasQuest(quest)); - return 1; - } - - /** - * Returns 'true' if the [Item] is a potion, 'false' otherwise - * - * @return bool isPotion - */ - int IsPotion(lua_State* L, Item* item) - { - ALE::Push(L, item->IsPotion()); - return 1; - } - - /** - * Returns 'true' if the [Item] is a weapon vellum, 'false' otherwise - * - * @return bool isWeaponVellum - */ - int IsWeaponVellum(lua_State* L, Item* item) - { - ALE::Push(L, item->IsWeaponVellum()); - return 1; - } - - /** - * Returns 'true' if the [Item] is an armor vellum, 'false' otherwise - * - * @return bool isArmorVellum - */ - int IsArmorVellum(lua_State* L, Item* item) - { - ALE::Push(L, item->IsArmorVellum()); - return 1; - } - - /** - * Returns 'true' if the [Item] is a conjured consumable, 'false' otherwise - * - * @return bool isConjuredConsumable - */ - int IsConjuredConsumable(lua_State* L, Item* item) - { - ALE::Push(L, item->IsConjuredConsumable()); - return 1; - } - - /*int IsRefundExpired(lua_State* L, Item* item)// TODO: Implement core support - { - ALE::Push(L, item->IsRefundExpired()); - return 1; - }*/ - - /** - * Returns the chat link of the [Item] - * - *
-     * enum LocaleConstant
-     * {
-     *     LOCALE_enUS = 0,
-     *     LOCALE_koKR = 1,
-     *     LOCALE_frFR = 2,
-     *     LOCALE_deDE = 3,
-     *     LOCALE_zhCN = 4,
-     *     LOCALE_zhTW = 5,
-     *     LOCALE_esES = 6,
-     *     LOCALE_esMX = 7,
-     *     LOCALE_ruRU = 8
-     * };
-     * 
- * - * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the [Item]'s name in - * @return string itemLink - */ - int GetItemLink(lua_State* L, Item* item) - { - uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE); - if (locale >= TOTAL_LOCALES) - return luaL_argerror(L, 2, "valid LocaleConstant expected"); - - const ItemTemplate* temp = item->GetTemplate(); - std::string name = temp->Name1; - if (ItemLocale const* il = eObjectMgr->GetItemLocale(temp->ItemId)) - { - ObjectMgr::GetLocaleString(il->Name, static_cast(locale), name); - } - - if (int32 itemRandPropId = item->GetItemRandomPropertyId()) - { - std::array const* suffix = NULL; - if (itemRandPropId < 0) - { - const ItemRandomSuffixEntry* itemRandEntry = sItemRandomSuffixStore.LookupEntry(-item->GetItemRandomPropertyId()); - if (itemRandEntry) - suffix = &itemRandEntry->Name; - } - else - { - const ItemRandomPropertiesEntry* itemRandEntry = sItemRandomPropertiesStore.LookupEntry(item->GetItemRandomPropertyId()); - if (itemRandEntry) - suffix = &itemRandEntry->Name; - } - if (suffix) - { - const char* suffixName = (*suffix)[(name != temp->Name1) ? locale : uint8(DEFAULT_LOCALE)]; - if (strcmp(suffixName, "") != 0) - { - name += ' '; - name += suffixName; - } - } - } - - Player* owner = item->GetOwner(); - std::ostringstream oss; - oss << "|c" << std::hex << ItemQualityColors[temp->Quality] << std::dec << - "|Hitem:" << temp->ItemId << ":" << - item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT) << ":" << - item->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT) << ":" << - item->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT_2) << ":" << - item->GetEnchantmentId(SOCK_ENCHANTMENT_SLOT_3) << ":" << - item->GetEnchantmentId(BONUS_ENCHANTMENT_SLOT) << ":" << - item->GetItemRandomPropertyId() << ":" << item->GetItemSuffixFactor() << ":" << - (uint32)(owner ? owner->GetLevel() : 0) << "|h[" << name << "]|h|r"; - - ALE::Push(L, oss.str()); - return 1; - } - - /** - * Returns the GUID of the [Player] who owns the specified [Item]. - * - * @param [Item] item - * @return uint64 ownerGUID - */ - int GetOwnerGUID(lua_State* L, Item* item) - { - ALE::Push(L, item->GetOwnerGUID()); - return 1; - } - - /** - * Returns the [Player] who currently owns the [Item] - * - * @return [Player] player : the [Player] who owns the [Item] - */ - int GetOwner(lua_State* L, Item* item) - { - ALE::Push(L, item->GetOwner()); - return 1; - } - - /** - * Returns the [Item]s stack count - * - * @return uint32 count - */ - int GetCount(lua_State* L, Item* item) - { - ALE::Push(L, item->GetCount()); - return 1; - } - - /** - * Returns the [Item]s max stack count - * - * @return uint32 maxCount - */ - int GetMaxStackCount(lua_State* L, Item* item) - { - ALE::Push(L, item->GetMaxStackCount()); - return 1; - } - - /** - * Returns the [Item]s current slot - * - * @return uint8 slot - */ - int GetSlot(lua_State* L, Item* item) - { - ALE::Push(L, item->GetSlot()); - return 1; - } - - /** - * Returns the [Item]s current bag slot - * - * @return uint8 bagSlot - */ - int GetBagSlot(lua_State* L, Item* item) - { - ALE::Push(L, item->GetBagSlot()); - return 1; - } - - /** - * Returns the [Item]s enchantment ID by enchant slot specified - * - * @param [EnchantmentSlot] enchantSlot : the enchant slot specified - * @return uint32 enchantId : the id of the enchant slot specified - */ - int GetEnchantmentId(lua_State* L, Item* item) - { - uint32 enchant_slot = ALE::CHECKVAL(L, 2); - - if (enchant_slot >= MAX_INSPECTED_ENCHANTMENT_SLOT) - return luaL_argerror(L, 2, "valid EnchantmentSlot expected"); - - ALE::Push(L, item->GetEnchantmentId(EnchantmentSlot(enchant_slot))); - return 1; - } - - /** - * Returns the spell ID tied to the [Item] by spell index - * - * @param uint32 spellIndex : the spell index specified - * @return uint32 spellId : the id of the spell - */ - int GetSpellId(lua_State* L, Item* item) - { - uint32 index = ALE::CHECKVAL(L, 2); - if (index >= MAX_ITEM_PROTO_SPELLS) - return luaL_argerror(L, 2, "valid SpellIndex expected"); - - ALE::Push(L, item->GetTemplate()->Spells[index].SpellId); - return 1; - } - - /** - * Returns the spell trigger tied to the [Item] by spell index - * - * @param uint32 spellIndex : the spell index specified - * @return uint32 spellTrigger : the spell trigger of the specified index - */ - int GetSpellTrigger(lua_State* L, Item* item) - { - uint32 index = ALE::CHECKVAL(L, 2); - if (index >= MAX_ITEM_PROTO_SPELLS) - return luaL_argerror(L, 2, "valid SpellIndex expected"); - - ALE::Push(L, item->GetTemplate()->Spells[index].SpellTrigger); - return 1; - } - - /** - * Returns class of the [Item] - * - * @return uint32 class - */ - int GetClass(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->Class); - return 1; - } - - /** - * Returns subclass of the [Item] - * - * @return uint32 subClass - */ - int GetSubClass(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->SubClass); - return 1; - } - - /** - * Returns the name of the [Item] - * - * @return string name - */ - int GetName(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->Name1); - return 1; - } - - /** - * Returns the display ID of the [Item] - * - * @return uint32 displayId - */ - int GetDisplayId(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->DisplayInfoID); - return 1; - } - - /** - * Returns the quality of the [Item] - * - * @return uint32 quality - */ - int GetQuality(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->Quality); - return 1; - } - - /** - * Returns the default purchase count of the [Item] - * - * @return uint32 count - */ - int GetBuyCount(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->BuyCount); - return 1; - } - - /** - * Returns the purchase price of the [Item] - * - * @return uint32 price - */ - int GetBuyPrice(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->BuyPrice); - return 1; - } - - /** - * Returns the sell price of the [Item] - * - * @return uint32 price - */ - int GetSellPrice(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->SellPrice); - return 1; - } - - /** - * Returns the inventory type of the [Item] - * - * @return uint32 inventoryType - */ - int GetInventoryType(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->InventoryType); - return 1; - } - - /** - * Returns the [Player] classes allowed to use this [Item] - * - * @return uint32 allowableClass - */ - int GetAllowableClass(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->AllowableClass); - return 1; - } - - /** - * Returns the [Player] races allowed to use this [Item] - * - * @return uint32 allowableRace - */ - int GetAllowableRace(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->AllowableRace); - return 1; - } - - /** - * Returns the [Item]s level - * - * @return uint32 itemLevel - */ - int GetItemLevel(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->ItemLevel); - return 1; - } - - /** - * Returns the minimum level required to use this [Item] - * - * @return uint32 requiredLevel - */ - int GetRequiredLevel(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->RequiredLevel); - return 1; - } - - /** - * Returns the number of stat entries defined on the [Item]'s [ItemTemplate]. This reflects how many stat slots (e.g., Strength, Stamina, etc.) are defined for the item. - * - * @param [Item] item - * @return uint32 statsCount - */ - int GetStatsCount(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->StatsCount); - return 1; - } - - /** - * Returns the random property ID of this [Item] - * - * @return uint32 randomPropertyId - */ - int GetRandomProperty(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->RandomProperty); - return 1; - } - - /** - * Returns the random suffix ID of the specified [Item]. This corresponds to the `RandomSuffix` field from the item's [ItemTemplate], which controls the applied suffix (e.g., "of the Bear", "of the Eagle"). - * - * @param [Item] item - * @return uint32 randomSuffixId - */ - int GetRandomSuffix(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->RandomSuffix); - return 1; - } - - /** - * Returns the item set ID of this [Item] - * - * @return uint32 itemSetId - */ - int GetItemSet(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()->ItemSet); - return 1; - } - - /** - * Returns the bag size of this [Item], 0 if [Item] is not a bag - * - * @return uint32 bagSize - */ - int GetBagSize(lua_State* L, Item* item) - { - if (Bag* bag = item->ToBag()) - ALE::Push(L, bag->GetBagSize()); - else - ALE::Push(L, 0); - return 1; - } - - /** - * Returns the [ItemTemplate] for this [Item]. - * - * @return [ItemTemplate] itemTemplate - */ - int GetItemTemplate(lua_State* L, Item* item) - { - ALE::Push(L, item->GetTemplate()); - return 1; - } - - /** - * Sets the [Player] specified as the owner of the [Item] - * - * @param [Player] player : the [Player] specified - */ - int SetOwner(lua_State* L, Item* item) - { - Player* player = ALE::CHECKOBJ(L, 2); - item->SetOwnerGUID(player->GET_GUID()); - return 0; - } - - /** - * Sets the binding of the [Item] to 'true' or 'false' - * - * @param bool setBinding - */ - int SetBinding(lua_State* L, Item* item) - { - bool soulbound = ALE::CHECKVAL(L, 2); - - item->SetBinding(soulbound); - item->SetState(ITEM_CHANGED, item->GetOwner()); - - return 0; - } - - /** - * Sets the stack count of the [Item] - * - * @param uint32 count - */ - int SetCount(lua_State* L, Item* item) - { - uint32 count = ALE::CHECKVAL(L, 2); - item->SetCount(count); - return 0; - } - - /** - * Sets the specified enchantment of the [Item] to the specified slot - * - * @param uint32 enchantId : the ID of the enchant to be applied - * @param uint32 enchantSlot : the slot for the enchant to be applied to - * @return bool enchantmentSuccess : if enchantment is successfully set to specified slot, returns 'true', otherwise 'false' - */ - int SetEnchantment(lua_State* L, Item* item) - { - Player* owner = item->GetOwner(); - if (!owner) - { - ALE::Push(L, false); - return 1; - } - - uint32 enchant = ALE::CHECKVAL(L, 2); - if (!sSpellItemEnchantmentStore.LookupEntry(enchant)) - { - ALE::Push(L, false); - return 1; - } - - EnchantmentSlot slot = (EnchantmentSlot)ALE::CHECKVAL(L, 3); - if (slot >= MAX_INSPECTED_ENCHANTMENT_SLOT) - return luaL_argerror(L, 2, "valid EnchantmentSlot expected"); - - owner->ApplyEnchantment(item, slot, false); - item->SetEnchantment(slot, enchant, 0, 0); - owner->ApplyEnchantment(item, slot, true); - ALE::Push(L, true); - return 1; - } - - - /** - * Sets the random properties for the [Item] from a given random property ID. - * - * @param uint32 randomPropId : The ID of the random property to be applied. - */ - int SetRandomProperty(lua_State* L, Item* item) - { - uint32 randomPropId = ALE::CHECKVAL(L, 2); - item->SetItemRandomProperties(randomPropId); - return 0; - } - - /** - * Sets the random suffix for the [Item] from a given random suffix ID. - * - * @param uint32 randomSuffixId : The ID of the random suffix to be applied. - */ - int SetRandomSuffix(lua_State* L, Item* item) - { - uint32 randomPropId = ALE::CHECKVAL(L, 2); - item->SetItemRandomProperties(-randomPropId); - return 0; - } - - - /* OTHER */ - /** - * Removes an enchant from the [Item] by the specified slot - * - * @param uint32 enchantSlot : the slot for the enchant to be removed from - * @return bool enchantmentRemoved : if enchantment is successfully removed from specified slot, returns 'true', otherwise 'false' - */ - int ClearEnchantment(lua_State* L, Item* item) - { - Player* owner = item->GetOwner(); - if (!owner) - { - ALE::Push(L, false); - return 1; - } - - EnchantmentSlot slot = (EnchantmentSlot)ALE::CHECKVAL(L, 2); - if (slot >= MAX_INSPECTED_ENCHANTMENT_SLOT) - return luaL_argerror(L, 2, "valid EnchantmentSlot expected"); - - if (!item->GetEnchantmentId(slot)) - { - ALE::Push(L, false); - return 1; - } - - owner->ApplyEnchantment(item, slot, false); - item->ClearEnchantment(slot); - ALE::Push(L, true); - return 1; - } - - /** - * Saves the [Item] to the database - */ - int SaveToDB(lua_State* /*L*/, Item* item) - { - CharacterDatabaseTransaction trans = CharacterDatabaseTransaction(nullptr); - item->SaveToDB(trans); - return 0; - } -}; -#endif diff --git a/src/LuaEngine/methods/ItemTemplateMethods.h b/src/LuaEngine/methods/ItemTemplateMethods.h deleted file mode 100644 index 317ae91224..0000000000 --- a/src/LuaEngine/methods/ItemTemplateMethods.h +++ /dev/null @@ -1,224 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef ITEMTEMPLATEMETHODS_H -#define ITEMTEMPLATEMETHODS_H - -#include "Chat.h" - -/*** - * Represents item data defined in the database and DBCs, such as stats, quality, class restrictions, and display info. - * - * Used to access read-only metadata about items (not specific item instances in bags or equipment). - * - * Inherits all methods from: none - */ -namespace LuaItemTemplate -{ - /** - * Returns the [ItemTemplate]'s ID. - * - * @return uint32 itemId - */ - int GetItemId(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->ItemId); - return 1; - } - - /** - * Returns the [ItemTemplate]'s class. - * - * @return uint32 class - */ - int GetClass(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->Class); - return 1; - } - - /** - * Returns the [ItemTemplate]'s subclass. - * - * @return uint32 subClass - */ - int GetSubClass(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->SubClass); - return 1; - } - - /** - * Returns the [ItemTemplate]'s name in the [Player]'s locale. - * - * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the [ItemTemplate] name in (it's optional default: LOCALE_enUS) - * - * @return string name - */ - int GetName(lua_State* L, ItemTemplate* itemTemplate) - { - uint32 loc_idx = ALE::CHECKVAL(L, 2, LocaleConstant::LOCALE_enUS); - - const ItemLocale* itemLocale = eObjectMgr->GetItemLocale(itemTemplate->ItemId); - std::string name = itemTemplate->Name1; - - if (itemLocale && !itemLocale->Name[loc_idx].empty()) - name = itemLocale->Name[loc_idx]; - - ALE::Push(L, name); - return 1; - } - - /** - * Returns the [ItemTemplate]'s display ID. - * - * @return uint32 displayId - */ - int GetDisplayId(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->DisplayInfoID); - return 1; - } - - /** - * Returns the [ItemTemplate]'s quality. - * - * @return uint32 quality - */ - int GetQuality(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->Quality); - return 1; - } - - /** - * Returns the [ItemTemplate]'s flags. - * - * @return uint32 flags - */ - int GetFlags(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->Flags); - return 1; - } - - /** - * Returns the [ItemTemplate]'s extra flags. - * - * @return uint32 flags - */ - int GetExtraFlags(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->Flags2); - return 1; - } - - /** - * Returns the [ItemTemplate]'s default purchase count. - * - * @return uint32 buyCount - */ - int GetBuyCount(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->BuyCount); - return 1; - } - - /** - * Returns the [ItemTemplate]'s purchase price. - * - * @return int32 buyPrice - */ - int GetBuyPrice(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->BuyPrice); - return 1; - } - - /** - * Returns the [ItemTemplate]'s sell price. - * - * @return uint32 sellPrice - */ - int GetSellPrice(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->SellPrice); - return 1; - } - - /** - * Returns the [ItemTemplate]'s inventory type. - * - * @return uint32 inventoryType - */ - int GetInventoryType(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->InventoryType); - return 1; - } - - /** - * Returns the [Player] classes allowed to use this [ItemTemplate]. - * - * @return uint32 allowableClass - */ - int GetAllowableClass(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->AllowableClass); - return 1; - } - - /** - * Returns the [Player] races allowed to use this [ItemTemplate]. - * - * @return uint32 allowableRace - */ - int GetAllowableRace(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->AllowableRace); - return 1; - } - - /** - * Returns the [ItemTemplate]'s item level. - * - * @return uint32 itemLevel - */ - int GetItemLevel(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->ItemLevel); - return 1; - } - - /** - * Returns the minimum level required to use this [ItemTemplate]. - * - * @return uint32 requiredLevel - */ - int GetRequiredLevel(lua_State* L, ItemTemplate* itemTemplate) - { - ALE::Push(L, itemTemplate->RequiredLevel); - return 1; - } - - /** - * Returns the icon is used by this [ItemTemplate]. - * - * @return string itemIcon - */ - int GetIcon(lua_State* L, ItemTemplate* itemTemplate) - { - uint32 display_id = itemTemplate->DisplayInfoID; - - ItemDisplayInfoEntry const* displayInfo = sItemDisplayInfoStore.LookupEntry(display_id); - const char* icon = displayInfo->inventoryIcon; - - ALE::Push(L, icon); - return 1; - } -} - -#endif diff --git a/src/LuaEngine/methods/LootMethods.h b/src/LuaEngine/methods/LootMethods.h deleted file mode 100644 index a48ff2d1a1..0000000000 --- a/src/LuaEngine/methods/LootMethods.h +++ /dev/null @@ -1,605 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef LOOTMETHODS_H -#define LOOTMETHODS_H - -/*** - * Represents loot that can be obtained from various sources like creatures, gameobjects, or items. - * - * Contains information about items that can be looted, their quantities, money, and loot state. - * - * Inherits all methods from: none - */ -namespace LuaLoot -{ - /** - * Returns `true` if all loot has been taken from this [Loot], returns `false` otherwise. - * - * @return bool isLooted - */ - int IsLooted(lua_State* L, Loot* loot) - { - ALE::Push(L, loot->isLooted()); - return 1; - } - - /** - * Adds an item to the [Loot] with the specified parameters. - * - * If an item with the same ID already exists and its count is less than 255, the count will be increased instead of adding a new entry. - * - * @param uint32 itemId : the ID of the item to add - * @param uint8 minCount : minimum count of the item - * @param uint8 maxCount : maximum count of the item - * @param float chance : chance for the item to drop (0-100) - * @param uint16 lootMode : loot mode for the item - * @param bool needsQuest = false : if `true`, the item requires a quest to be looted - * @param bool allowStacking = true : if `true`, allow items to stack in the loot window - */ - int AddItem(lua_State* L, Loot* loot) - { - uint32 itemid = ALE::CHECKVAL(L, 2); - uint8 min_count = ALE::CHECKVAL(L, 3); - uint8 max_count = ALE::CHECKVAL(L, 4); - float chance = ALE::CHECKVAL(L, 5); - uint16 loot_mode = ALE::CHECKVAL(L, 6); - bool needs_quest = ALE::CHECKVAL(L, 7, false); - bool allow_stacking = ALE::CHECKVAL(L, 8, true); - - if (allow_stacking) - { - auto& container = needs_quest ? loot->quest_items : loot->items; - - for (LootItem& lootitem : container) - { - if (lootitem.itemid == itemid && lootitem.count < 255) - { - uint32 add = std::max(1u, min_count); - uint32 newCount = std::min(255u, lootitem.count + add); - lootitem.count = static_cast(newCount); - return 0; - } - } - } - - LootStoreItem newLootStoreItem(itemid, 0, chance, needs_quest, loot_mode, 0, min_count, max_count); - loot->AddItem(newLootStoreItem); - - return 0; - } - - /** - * Returns `true` if the [Loot] contains the specified item, and returns `false` otherwise. - * - * @param uint32 itemId = 0 : the ID of the item to check for. If 0, checks if any item exists - * @param uint32 count = 0 : specific count to check for. If 0, ignores count - * @return bool hasItem - */ - int HasItem(lua_State* L, Loot* loot) - { - uint32 itemid = ALE::CHECKVAL(L, 2, false); - uint32 count = ALE::CHECKVAL(L, 3, false); - bool has_item = false; - - if (itemid) - { - for (const LootItem &lootitem : loot->items) - { - if (lootitem.itemid == itemid && (count == 0 || lootitem.count == count)) - { - has_item = true; - break; - } - } - } - else - { - for (const LootItem &lootitem : loot->items) - { - if (lootitem.itemid != 0) - { - has_item = true; - break; - } - } - } - - ALE::Push(L, has_item); - return 1; - } - - /** - * Removes the specified item from the [Loot]. - * - * If count is specified, removes only that amount. Otherwise removes all items with the ID. - * - * @param uint32 itemId : the ID of the item to remove - * @param bool isCountSpecified = false : if `true`, only removes the specified count - * @param uint32 count = 0 : amount to remove when isCountSpecified is true - */ - int RemoveItem(lua_State* L, Loot* loot) - { - uint32 itemid = ALE::CHECKVAL(L, 2); - bool isCountSpecified = ALE::CHECKVAL(L, 3, false); - uint32 count = isCountSpecified ? ALE::CHECKVAL(L, 4) : 0; - - auto removeFromContainer = [&](auto& container, uint32& remaining) - { - for (auto it = container.begin(); it != container.end(); ) - { - if (it->itemid == itemid) - { - if (isCountSpecified) - { - if (it->count > remaining) - { - it->count -= static_cast(remaining); - remaining = 0; - break; - } - else - { - remaining -= it->count; - it = container.erase(it); - if (remaining == 0) - break; - continue; - } - } - else - { - it = container.erase(it); - continue; - } - } - ++it; - } - }; - - // Remove from regular items - removeFromContainer(loot->items, count); - - // Remove from quest items as well - if (!isCountSpecified || count > 0) - removeFromContainer(loot->quest_items, count); - - return 0; - } - - /** - * Returns the amount of money in this [Loot]. - * - * @return uint32 money : the amount of money in copper - */ - int GetMoney(lua_State* L, Loot* loot) - { - ALE::Push(L, loot->gold); - return 1; - } - - /** - * Sets the amount of money in this [Loot]. - * - * @param uint32 money : the amount of money to set in copper - */ - int SetMoney(lua_State* L, Loot* loot) - { - uint32 gold = ALE::CHECKVAL(L, 2); - - loot->gold = gold; - return 0; - } - - /** - * Generates a random amount of money for this [Loot] within the specified range. - * - * @param uint32 minGold : minimum amount of money in copper - * @param uint32 maxGold : maximum amount of money in copper - */ - int GenerateMoney(lua_State* L, Loot* loot) - { - uint32 min_gold = ALE::CHECKVAL(L, 2); - uint32 max_gold = ALE::CHECKVAL(L, 3); - - loot->generateMoneyLoot(min_gold, max_gold); - return 0; - } - - /** - * Clears all items and money from this [Loot]. - */ - int Clear(lua_State* /*L*/, Loot* loot) - { - loot->clear(); - return 0; - } - - /** - * Sets the number of unlooted items in this [Loot]. - * - * @param uint32 count : the number of unlooted items - */ - int SetUnlootedCount(lua_State* L, Loot* loot) - { - uint32 count = ALE::CHECKVAL(L, 2); - - loot->unlootedCount = count; - return 0; - } - - /** - * Returns the number of unlooted items in this [Loot]. - * - * @return uint32 unlootedCount - */ - int GetUnlootedCount(lua_State* L, Loot* loot) - { - ALE::Push(L, loot->unlootedCount); - return 1; - } - - /** - * Returns a table containing all items in this [Loot]. - * - * Each item is represented as a table with the following fields: - * - id: item ID - * - index: item index in the loot list - * - count: quantity of the item - * - needs_quest: whether the item requires a quest - * - is_looted: whether the item has already been looted - * - roll_winner_guid: GUID of the player who won the item roll - * - * @return table items : array of item tables - */ - int GetItems(lua_State* L, Loot* loot) - { - lua_createtable(L, loot->items.size(), 0); - int tbl = lua_gettop(L); - - for (unsigned int i = 0; i < loot->items.size(); i++) - { - lua_newtable(L); - - ALE::Push(L, loot->items[i].itemid); - lua_setfield(L, -2, "id"); - - ALE::Push(L, loot->items[i].itemIndex); - lua_setfield(L, -2, "index"); - - ALE::Push(L, loot->items[i].count); - lua_setfield(L, -2, "count"); - - ALE::Push(L, loot->items[i].needs_quest); - lua_setfield(L, -2, "needs_quest"); - - ALE::Push(L, loot->items[i].is_looted); - lua_setfield(L, -2, "is_looted"); - - ALE::Push(L, loot->items[i].rollWinnerGUID); - lua_setfield(L, -2, "roll_winner_guid"); - - lua_rawseti(L, tbl, i + 1); - } - - lua_settop(L, tbl); - return 1; - } - - /** - * Returns a table containing all quest items in this [Loot]. - * - * Each quest item is represented as a table with the following fields: - * - id: item ID - * - index: item index in the quest loot list - * - count: quantity of the item - * - needs_quest: whether the item requires a quest - * - is_looted: whether the item has already been looted - * - roll_winner_guid: GUID of the player who won the item roll - * - * @return table quest_items : array of quest item tables - */ - int GetQuestItems(lua_State* L, Loot* loot) - { - lua_createtable(L, loot->quest_items.size(), 0); - int tbl = lua_gettop(L); - - for (unsigned int i = 0; i < loot->quest_items.size(); i++) - { - lua_newtable(L); - - ALE::Push(L, loot->quest_items[i].itemid); - lua_setfield(L, -2, "id"); - - ALE::Push(L, loot->quest_items[i].itemIndex); - lua_setfield(L, -2, "index"); - - ALE::Push(L, loot->quest_items[i].count); - lua_setfield(L, -2, "count"); - - ALE::Push(L, loot->quest_items[i].needs_quest); - lua_setfield(L, -2, "needs_quest"); - - ALE::Push(L, loot->quest_items[i].is_looted); - lua_setfield(L, -2, "is_looted"); - - ALE::Push(L, loot->quest_items[i].rollWinnerGUID); - lua_setfield(L, -2, "roll_winner_guid"); - - lua_rawseti(L, tbl, i + 1); - } - - lua_settop(L, tbl); - return 1; - } - - /** - * Updates the index of all items in this [Loot] to match their position in the list. - * - * This should be called after removing items to ensure indices are sequential. - */ - int UpdateItemIndex(lua_State* /*L*/, Loot* loot) - { - uint32 index = 0; - - for (unsigned int i = 0; i < loot->items.size(); ++i) - loot->items[i].itemIndex = index++; - - for (unsigned int i = 0; i < loot->quest_items.size(); ++i) - loot->quest_items[i].itemIndex = index++; - - return 0; - } - - /** - * Sets the looted status of a specific item in this [Loot]. - * - * @param uint32 itemId : the ID of the item - * @param uint32 count : specific count to match. If 0, ignores count - * @param bool looted = true : `true` to mark as looted, `false` to mark as unlooted - */ - int SetItemLooted(lua_State* L, Loot* loot) - { - uint32 itemid = ALE::CHECKVAL(L, 2); - uint32 count = ALE::CHECKVAL(L, 3); - bool looted = ALE::CHECKVAL(L, 4, true); - - for (auto &lootItem : loot->items) - { - if (lootItem.itemid == itemid && (count == 0 || lootItem.count == count)) - { - lootItem.is_looted = looted; - break; - } - } - return 0; - } - - /** - * Returns `true` if the [Loot] is completely empty (no items and no money), returns `false` otherwise. - * - * @return bool isEmpty - */ - int IsEmpty(lua_State* L, Loot* loot) - { - ALE::Push(L, loot->empty()); - return 1; - } - - /** - * Returns the [Loot] type. - * - * @return [LootType] lootType - */ - int GetLootType(lua_State* L, Loot* loot) - { - ALE::Push(L, loot->loot_type); - return 1; - } - - /** - * Sets the [Loot] type. - * - *
-     * enum LootType
-     * {
-     *     LOOT_NONE                           = 0,
-     *     LOOT_CORPSE                         = 1,
-     *     LOOT_PICKPOCKETING                  = 2,
-     *     LOOT_FISHING                        = 3,
-     *     LOOT_DISENCHANTING                  = 4,
-     *     LOOT_SKINNING                       = 6,
-     *     LOOT_PROSPECTING                    = 7,
-     *     LOOT_MILLING                        = 8,
-     *     LOOT_FISHINGHOLE                    = 20,
-     *     LOOT_INSIGNIA                       = 21,
-     *     LOOT_FISHING_JUNK                   = 22
-     * };
-     * 
- * - * @param [LootType] lootType : the loot type to set - */ - int SetLootType(lua_State* L, Loot* loot) - { - uint32 lootType = ALE::CHECKVAL(L, 2); - loot->loot_type = static_cast(lootType); - return 0; - } - - /** - * Returns the [Player] GUID that owns this loot for round robin distribution. - * - * @return ObjectGuid roundRobinPlayer : the player GUID - */ - int GetRoundRobinPlayer(lua_State* L, Loot* loot) - { - ALE::Push(L, loot->roundRobinPlayer); - return 1; - } - - /** - * Sets the [Player] GUID for round robin loot distribution. - * - * @param ObjectGuid playerGUID : the player GUID - */ - int SetRoundRobinPlayer(lua_State* L, Loot* loot) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - loot->roundRobinPlayer = guid; - return 0; - } - - /** - * Returns the [Player] GUID that owns this loot. - * - * @return ObjectGuid lootOwner : the player GUID - */ - int GetLootOwner(lua_State* L, Loot* loot) - { - ALE::Push(L, loot->lootOwnerGUID); - return 1; - } - - /** - * Sets the [Player] GUID that owns this loot. - * - * @param ObjectGuid playerGUID : the player GUID - */ - int SetLootOwner(lua_State* L, Loot* loot) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - loot->lootOwnerGUID = guid; - return 0; - } - - /** - * Returns the container GUID that holds this loot. - * - * @return ObjectGuid containerGUID : the container GUID - */ - int GetContainer(lua_State* L, Loot* loot) - { - ALE::Push(L, loot->containerGUID); - return 1; - } - - /** - * Sets the container GUID that holds this loot. - * - * @param ObjectGuid containerGUID : the container GUID - */ - int SetContainer(lua_State* L, Loot* loot) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - loot->containerGUID = guid; - return 0; - } - - /** - * Returns the source [WorldObject] GUID for this loot. - * - * @return ObjectGuid sourceGUID : the source [WorldObject] GUID - */ - int GetSourceWorldObject(lua_State* L, Loot* loot) - { - ALE::Push(L, loot->sourceWorldObjectGUID); - return 1; - } - - /** - * Sets the source [WorldObject] GUID for this loot. - * - * @param ObjectGuid sourceGUID : the source [WorldObject] GUID - */ - int SetSourceWorldObject(lua_State* L, Loot* loot) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - loot->sourceWorldObjectGUID = guid; - return 0; - } - - /** - * Returns `true` if the [Loot] contains quest items and returns `false` otherwise. - * - * @return bool hasQuestItems - */ - int HasQuestItems(lua_State* L, Loot* loot) - { - ALE::Push(L, !loot->quest_items.empty()); - return 1; - } - - /** - * Returns `true` if the [Loot] has items available for all players and returns `false` otherwise. - * - * @return bool hasItemForAll - */ - int HasItemForAll(lua_State* L, Loot* loot) - { - ALE::Push(L, loot->hasItemForAll()); - return 1; - } - - /** - * Returns `true` if the [Loot] has items that are over the group loot threshold and returns `false` otherwise. - * - * @return bool hasOverThresholdItem - */ - int HasOverThresholdItem(lua_State* L, Loot* loot) - { - ALE::Push(L, loot->hasOverThresholdItem()); - return 1; - } - - /** - * Returns the total number of items (regular + quest items) in this [Loot]. - * - * @return uint32 itemCount - */ - int GetItemCount(lua_State* L, Loot* loot) - { - ALE::Push(L, static_cast(loot->items.size() + loot->quest_items.size())); - return 1; - } - - /** - * Returns the maximum loot slot index available for the specified [Player]. - * - * @param [Player] player : the player to check slots for - * @return uint32 maxSlot - */ - int GetMaxSlotForPlayer(lua_State* L, Loot* loot) - { - Player* player = ALE::CHECKOBJ(L, 2); - ALE::Push(L, loot->GetMaxSlotInLootFor(player)); - return 1; - } - - /** - * Adds a [Player] to the list of players currently looting this [Loot]. - * - * @param [Player] player : the player to add as a looter - */ - int AddLooter(lua_State* L, Loot* loot) - { - Player* player = ALE::CHECKOBJ(L, 2); - loot->AddLooter(player->GetGUID()); - return 0; - } - - /** - * Removes a [Player] from the list of players currently looting this [Loot]. - * - * @param [Player] player : the player to remove from looters - */ - int RemoveLooter(lua_State* L, Loot* loot) - { - Player* player = ALE::CHECKOBJ(L, 2); - loot->RemoveLooter(player->GetGUID()); - return 0; - } -}; -#endif // LOOTMETHODS_H diff --git a/src/LuaEngine/methods/MapMethods.h b/src/LuaEngine/methods/MapMethods.h deleted file mode 100644 index 04eba564c6..0000000000 --- a/src/LuaEngine/methods/MapMethods.h +++ /dev/null @@ -1,383 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef MAPMETHODS_H -#define MAPMETHODS_H - -#include "ALEInstanceAI.h" - -/*** - * A game map, e.g. Azeroth, Eastern Kingdoms, the Molten Core, etc. - * - * Inherits all methods from: none - */ -namespace LuaMap -{ - - /** - * Returns `true` if the [Map] is an arena [BattleGround], `false` otherwise. - * - * @return bool isArena - */ - int IsArena(lua_State* L, Map* map) - { - ALE::Push(L, map->IsBattleArena()); - return 1; - } - - /** - * Returns `true` if the [Map] is a non-arena [BattleGround], `false` otherwise. - * - * @return bool isBattleGround - */ - int IsBattleground(lua_State* L, Map* map) - { - ALE::Push(L, map->IsBattleground()); - return 1; - } - - /** - * Returns `true` if the [Map] is a dungeon, `false` otherwise. - * - * @return bool isDungeon - */ - int IsDungeon(lua_State* L, Map* map) - { - ALE::Push(L, map->IsDungeon()); - return 1; - } - - /** - * Returns `true` if the [Map] has no [Player]s, `false` otherwise. - * - * @return bool IsEmpty - */ - int IsEmpty(lua_State* L, Map* map) - { - ALE::Push(L, map->IsEmpty()); - return 1; - } - - /** - * Returns `true` if the [Map] is a heroic, `false` otherwise. - * - * @return bool isHeroic - */ - int IsHeroic(lua_State* L, Map* map) - { - ALE::Push(L, map->IsHeroic()); - return 1; - } - - /** - * Returns `true` if the [Map] is a raid, `false` otherwise. - * - * @return bool isRaid - */ - int IsRaid(lua_State* L, Map* map) - { - ALE::Push(L, map->IsRaid()); - return 1; - } - - /** - * Returns the name of the [Map]. - * - * @return string mapName - */ - int GetName(lua_State* L, Map* map) - { - ALE::Push(L, map->GetMapName()); - return 1; - } - - /** - * Returns the height of the [Map] at the given X and Y coordinates. - * - * In case of no height found nil is returned - * - * @param float x - * @param float y - * @return float z - */ - int GetHeight(lua_State* L, Map* map) - { - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 3); - uint32 phasemask = ALE::CHECKVAL(L, 4, 1); - float z = map->GetHeight(phasemask, x, y, MAX_HEIGHT); - if (z != INVALID_HEIGHT) - ALE::Push(L, z); - return 1; - } - - /** - * Returns the difficulty of the [Map]. - * - * Always returns 0 if the expansion is pre-TBC. - * - * @return int32 difficulty - */ - int GetDifficulty(lua_State* L, Map* map) - { - ALE::Push(L, map->GetDifficulty()); - return 1; - } - - /** - * Returns the instance ID of the [Map]. - * - * @return uint32 instanceId - */ - int GetInstanceId(lua_State* L, Map* map) - { - ALE::Push(L, map->GetInstanceId()); - return 1; - } - - /** - * Returns the player count currently on the [Map] (excluding GMs). - * - * @return uint32 playerCount - */ - int GetPlayerCount(lua_State* L, Map* map) - { - ALE::Push(L, map->GetPlayersCountExceptGMs()); - return 1; - } - - /** - * Returns the ID of the [Map]. - * - * @return uint32 mapId - */ - int GetMapId(lua_State* L, Map* map) - { - ALE::Push(L, map->GetId()); - return 1; - } - - /** - * Returns the area ID of the [Map] at the specified X, Y, and Z coordinates. - * - * @param float x - * @param float y - * @param float z - * @param uint32 phasemask = PHASEMASK_NORMAL - * @return uint32 areaId - */ - int GetAreaId(lua_State* L, Map* map) - { - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 3); - float z = ALE::CHECKVAL(L, 4); - float phasemask = ALE::CHECKVAL(L, 5, PHASEMASK_NORMAL); - - ALE::Push(L, map->GetAreaId(phasemask, x, y, z)); - return 1; - } - - /** - * Returns a [WorldObject] by its GUID from the map if it is spawned. - * - * @param ObjectGuid guid - * @return [WorldObject] object - */ - int GetWorldObject(lua_State* L, Map* map) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - - switch (guid.GetHigh()) - { - case HIGHGUID_PLAYER: - ALE::Push(L, eObjectAccessor()GetPlayer(map, guid)); - break; - case HIGHGUID_TRANSPORT: - case HIGHGUID_MO_TRANSPORT: - case HIGHGUID_GAMEOBJECT: - ALE::Push(L, map->GetGameObject(guid)); - break; - case HIGHGUID_VEHICLE: - case HIGHGUID_UNIT: - ALE::Push(L, map->GetCreature(guid)); - break; - case HIGHGUID_PET: - ALE::Push(L, map->GetPet(guid)); - break; - case HIGHGUID_DYNAMICOBJECT: - ALE::Push(L, map->GetDynamicObject(guid)); - break; - case HIGHGUID_CORPSE: - ALE::Push(L, map->GetCorpse(guid)); - break; - default: - break; - } - return 1; - } - - /** - * Sets the [Weather] type based on [WeatherType] and grade supplied. - * - * enum WeatherType - * { - * WEATHER_TYPE_FINE = 0, - * WEATHER_TYPE_RAIN = 1, - * WEATHER_TYPE_SNOW = 2, - * WEATHER_TYPE_STORM = 3, - * WEATHER_TYPE_THUNDERS = 86, - * WEATHER_TYPE_BLACKRAIN = 90 - * }; - * - * @param uint32 zone : id of the zone to set the weather for - * @param [WeatherType] type : the [WeatherType], see above available weather types - * @param float grade : the intensity/grade of the [Weather], ranges from 0 to 1 - */ - int SetWeather(lua_State* L, Map* map) - { - uint32 zoneId = ALE::CHECKVAL(L, 2); - uint32 weatherType = ALE::CHECKVAL(L, 3); - float grade = ALE::CHECKVAL(L, 4); - - Weather* weather = map->GetOrGenerateZoneDefaultWeather(zoneId); - if (weather) - weather->SetWeather((WeatherType)weatherType, grade); - return 0; - } - - /** - * Gets the instance data table for the [Map], if it exists. - * - * The instance must be scripted using ALE for this to succeed. - * If the instance is scripted in C++ this will return `nil`. - * - * @return table instance_data : instance data table, or `nil` - */ - int GetInstanceData(lua_State* L, Map* map) - { - ALEInstanceAI* iAI = NULL; - if (InstanceMap* inst = map->ToInstanceMap()) - iAI = dynamic_cast(inst->GetInstanceScript()); - - if (iAI) - ALE::GetALE(L)->PushInstanceData(L, iAI, false); - else - ALE::Push(L); // nil - - return 1; - } - - /** - * Saves the [Map]'s instance data to the database. - */ - int SaveInstanceData(lua_State* /*L*/, Map* map) - { - ALEInstanceAI* iAI = NULL; - if (InstanceMap* inst = map->ToInstanceMap()) - iAI = dynamic_cast(inst->GetInstanceScript()); - - if (iAI) - iAI->SaveToDB(); - - return 0; - } - - /** - * Returns a table with all the current [Player]s in the map - * - * enum TeamId - * { - * TEAM_ALLIANCE = 0, - * TEAM_HORDE = 1, - * TEAM_NEUTRAL = 2 - * }; - * - * @param [TeamId] team : optional check team of the [Player], Alliance, Horde or Neutral (All) - * @return table mapPlayers - */ - int GetPlayers(lua_State* L, Map* map) - { - uint32 team = ALE::CHECKVAL(L, 2, TEAM_NEUTRAL); - - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - Map::PlayerList const& players = map->GetPlayers(); - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - Player* player = itr->GetSource(); - if (!player) - continue; - if (player->GetSession() && (team >= TEAM_NEUTRAL || player->GetTeamId() == team)) - { - ALE::Push(L, player); - lua_rawseti(L, tbl, ++i); - } - } - - lua_settop(L, tbl); - return 1; - } - - /** - * Returns a table with all the current [Creature]s in the map - * - * @return table mapCreatures - */ - int GetCreatures(lua_State* L, Map* map) - { - const auto& creatures = map->GetCreatureBySpawnIdStore(); - - lua_createtable(L, creatures.size(), 0); - int tbl = lua_gettop(L); - - for (const auto& pair : creatures) - { - Creature* creature = pair.second; - - ALE::Push(L, creature); - lua_rawseti(L, tbl, creature->GetSpawnId()); - } - - lua_settop(L, tbl); - return 1; - } - - /** - * Returns a table with all the current [Creature]s in the specific area id - * - * @param number areaId : specific area id - * @return table mapCreatures - */ - int GetCreaturesByAreaId(lua_State* L, Map* map) - { - int32 areaId = ALE::CHECKVAL(L, 2, -1); - std::vector filteredCreatures; - - for (const auto& pair : map->GetCreatureBySpawnIdStore()) - { - Creature* creature = pair.second; - if (areaId == -1 || creature->GetAreaId() == (uint32)areaId) - { - filteredCreatures.push_back(creature); - } - } - - lua_createtable(L, filteredCreatures.size(), 0); - int tbl = lua_gettop(L); - - for (Creature* creature : filteredCreatures) - { - ALE::Push(L, creature); - lua_rawseti(L, tbl, creature->GetSpawnId()); - } - - lua_settop(L, tbl); - return 1; - } -}; -#endif diff --git a/src/LuaEngine/methods/ObjectMethods.h b/src/LuaEngine/methods/ObjectMethods.h deleted file mode 100644 index e99ce4f319..0000000000 --- a/src/LuaEngine/methods/ObjectMethods.h +++ /dev/null @@ -1,467 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef OBJECTMETHODS_H -#define OBJECTMETHODS_H - -/*** - * A basic game object (either an [Item] or a [WorldObject]). - * - * Objects in MaNGOS/Trinity are stored an a giant block of "values". - * Subclasses of Object, like [WorldObject], extend the block with more data specific to that subclass. - * Further subclasses, like [Player], extend it even further. - * - * A detailed map of all the fields in this data block can be found in the UpdateFields.h file of your emulator - * (it varies depending on the expansion supported). - * - * The GetValue methods in this class (e.g. [Object:GetInt32Value]) provide low-level access to the data block. - * Other methods, like [Object:HasFlag] and [Object:GetScale], merely wrap the GetValue methods and provide a simpler interface. - * - * Inherits all methods from: none - */ -namespace LuaObject -{ - /** - * Returns `true` if the specified flag is set, otherwise `false`. - * - * @param uint16 index : the index of the flags data in the [Object] - * @param uint32 flag : the flag to check for in the flags data - * @return bool hasFlag - */ - int HasFlag(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - uint32 flag = ALE::CHECKVAL(L, 3); - - ALE::Push(L, obj->HasFlag(index, flag)); - return 1; - } - - /** - * Returns `true` if the [Object] has been added to its [Map], otherwise `false`. - * - * @return bool inWorld - */ - int IsInWorld(lua_State* L, Object* obj) - { - ALE::Push(L, obj->IsInWorld()); - return 1; - } - - /** - * Returns 'true' if the [Object] is a player, 'false' otherwise. - * - * @return bool IsPlayer - */ - int IsPlayer(lua_State* L, Object* obj) - { - ALE::Push(L, obj->IsPlayer()); - return 1; - } - - /** - * Returns the data at the specified index, casted to a signed 32-bit integer. - * - * @param uint16 index - * @return int32 value - */ - int GetInt32Value(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - ALE::Push(L, obj->GetInt32Value(index)); - return 1; - } - - /** - * Returns the data at the specified index, casted to a unsigned 32-bit integer. - * - * @param uint16 index - * @return uint32 value - */ - int GetUInt32Value(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - ALE::Push(L, obj->GetUInt32Value(index)); - return 1; - } - - /** - * Returns the data at the specified index, casted to a single-precision floating point value. - * - * @param uint16 index - * @return float value - */ - int GetFloatValue(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - ALE::Push(L, obj->GetFloatValue(index)); - return 1; - } - - /** - * Returns the data at the specified index and offset, casted to an unsigned 8-bit integer. - * - * E.g. if you want the second byte at index 10, you would pass in 1 as the offset. - * - * @param uint16 index - * @param uint8 offset : should be 0, 1, 2, or 3 - * @return uint8 value - */ - int GetByteValue(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - uint8 offset = ALE::CHECKVAL(L, 3); - ALE::Push(L, obj->GetByteValue(index, offset)); - return 1; - } - - /** - * Returns the data at the specified index and offset, casted to a signed 16-bit integer. - * - * E.g. if you want the second half-word at index 10, you would pass in 1 as the offset. - * - * @param uint16 index - * @param uint8 offset : should be 0 or 1 - * @return uint16 value - */ - int GetUInt16Value(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - uint8 offset = ALE::CHECKVAL(L, 3); - ALE::Push(L, obj->GetUInt16Value(index, offset)); - return 1; - } - - /** - * Returns the scale/size of the [Object]. - * - * This affects the size of a [WorldObject] in-game, but [Item]s don't have a "scale". - * - * @return float scale - */ - int GetScale(lua_State* L, Object* obj) - { - ALE::Push(L, obj->GetFloatValue(OBJECT_FIELD_SCALE_X)); - return 1; - } - - /** - * Returns the entry of the [Object]. - * - * [Player]s do not have an "entry". - * - * @return uint32 entry - */ - int GetEntry(lua_State* L, Object* obj) - { - ALE::Push(L, obj->GetEntry()); - return 1; - } - - /** - * Returns the GUID of the [Object]. - * - * GUID is an unique identifier for the object. - * - * However on MaNGOS and cMangos creatures and gameobjects inside different maps can share - * the same GUID but not on the same map. - * - * On TrinityCore this value is unique across all maps - * - * @return ObjectGuid guid - */ - int GetGUID(lua_State* L, Object* obj) - { - ALE::Push(L, obj->GET_GUID()); - return 1; - } - - /** - * Returns the low-part of the [Object]'s GUID. - * - * On TrinityCore all low GUIDs are different for all objects of the same type. - * For example creatures in instances are assigned new GUIDs when the Map is created. - * - * On MaNGOS and cMaNGOS low GUIDs are unique only on the same map. - * For example creatures in instances use the same low GUID assigned for that spawn in the database. - * This is why to identify a creature you have to know the instanceId and low GUID. See [Map:GetIntstanceId] - * - * @return uint32 guidLow - */ - int GetGUIDLow(lua_State* L, Object* obj) - { - ALE::Push(L, obj->GetGUID().GetCounter()); - return 1; - } - - /** - * Returns the TypeId of the [Object]. - * - * enum TypeID - * { - * TYPEID_OBJECT = 0, - * TYPEID_ITEM = 1, - * TYPEID_CONTAINER = 2, - * TYPEID_UNIT = 3, - * TYPEID_PLAYER = 4, - * TYPEID_GAMEOBJECT = 5, - * TYPEID_DYNAMICOBJECT = 6, - * TYPEID_CORPSE = 7 - * }; - * - * @return uint8 typeID - */ - int GetTypeId(lua_State* L, Object* obj) - { - ALE::Push(L, obj->GetTypeId()); - return 1; - } - - /** - * Returns the data at the specified index, casted to an unsigned 64-bit integer. - * - * @param uint16 index - * @return uint64 value - */ - int GetUInt64Value(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - ALE::Push(L, obj->GetUInt64Value(index)); - return 1; - } - - /** - * Sets the specified flag in the data value at the specified index. - * - * If the flag was already set, it remains set. - * - * To remove a flag, use [Object:RemoveFlag]. - * - * @param uint16 index - * @param uint32 value - */ - int SetFlag(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - uint32 flag = ALE::CHECKVAL(L, 3); - - obj->SetFlag(index, flag); - return 0; - } - - /** - * Sets the data at the specified index to the given value, converted to a signed 32-bit integer. - * - * @param uint16 index - * @param int32 value - */ - int SetInt32Value(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - int32 value = ALE::CHECKVAL(L, 3); - obj->SetInt32Value(index, value); - return 0; - } - - /** - * Sets the data at the specified index to the given value, converted to an unsigned 32-bit integer. - * - * @param uint16 index - * @param uint32 value - */ - int SetUInt32Value(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - uint32 value = ALE::CHECKVAL(L, 3); - obj->SetUInt32Value(index, value); - return 0; - } - - /** - * Sets the data at the specified index to the given value, converted to an unsigned 32-bit integer. - * - * @param uint16 index - * @param uint32 value - */ - int UpdateUInt32Value(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - uint32 value = ALE::CHECKVAL(L, 3); - obj->UpdateUInt32Value(index, value); - return 0; - } - - /** - * Sets the data at the specified index to the given value, converted to a single-precision floating point value. - * - * @param uint16 index - * @param float value - */ - int SetFloatValue(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - float value = ALE::CHECKVAL(L, 3); - - obj->SetFloatValue(index, value); - return 0; - } - - /** - * Sets the data at the specified index and offset to the given value, converted to an unsigned 8-bit integer. - * - * @param uint16 index - * @param uint8 offset : should be 0, 1, 2, or 3 - * @param uint8 value - */ - int SetByteValue(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - uint8 offset = ALE::CHECKVAL(L, 3); - uint8 value = ALE::CHECKVAL(L, 4); - obj->SetByteValue(index, offset, value); - return 0; - } - - /** - * Sets the data at the specified index to the given value, converted to an unsigned 16-bit integer. - * - * @param uint16 index - * @param uint8 offset : should be 0 or 1 - * @param uint16 value - */ - int SetUInt16Value(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - uint8 offset = ALE::CHECKVAL(L, 3); - uint16 value = ALE::CHECKVAL(L, 4); - obj->SetUInt16Value(index, offset, value); - return 0; - } - - /** - * Sets the data at the specified index to the given value, converted to a signed 16-bit integer. - * - * @param uint16 index - * @param uint8 offset : should be 0 or 1 - * @param int16 value - */ - int SetInt16Value(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - uint8 offset = ALE::CHECKVAL(L, 3); - int16 value = ALE::CHECKVAL(L, 4); - obj->SetInt16Value(index, offset, value); - return 0; - } - - /** - * Sets the [Object]'s scale/size to the given value. - * - * @param float scale - */ - int SetScale(lua_State* L, Object* obj) - { - float size = ALE::CHECKVAL(L, 2); - - obj->SetObjectScale(size); - return 0; - } - - /** - * Sets the data at the specified index to the given value, converted to an unsigned 64-bit integer. - * - * @param uint16 index - * @param uint64 value - */ - int SetUInt64Value(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - uint64 value = ALE::CHECKVAL(L, 3); - obj->SetUInt64Value(index, value); - return 0; - } - - /** - * Removes a flag from the value at the specified index. - * - * @param uint16 index - * @param uint32 flag - */ - int RemoveFlag(lua_State* L, Object* obj) - { - uint16 index = ALE::CHECKVAL(L, 2); - uint32 flag = ALE::CHECKVAL(L, 3); - - obj->RemoveFlag(index, flag); - return 0; - } - - /** - * Attempts to convert the [Object] to a [Corpse]. - * - * If the [Object] is not a [Corpse], returns `nil`. - * - * @return [Corpse] corpse : the [Object] as a [Corpse], or `nil` - */ - int ToCorpse(lua_State* L, Object* obj) - { - ALE::Push(L, obj->ToCorpse()); - return 1; - } - - /** - * Attempts to convert the [Object] to a [GameObject]. - * - * If the [Object] is not a [GameObject], returns `nil`. - * - * @return [GameObject] gameObject : the [Object] as a [GameObject], or `nil` - */ - int ToGameObject(lua_State* L, Object* obj) - { - ALE::Push(L, obj->ToGameObject()); - return 1; - } - - /** - * Attempts to convert the [Object] to a [Unit]. - * - * If the [Object] is not a [Unit], returns `nil`. - * - * @return [Unit] unit : the [Object] as a [Unit], or `nil` - */ - int ToUnit(lua_State* L, Object* obj) - { - ALE::Push(L, obj->ToUnit()); - return 1; - } - - /** - * Attempts to convert the [Object] to a [Creature]. - * - * If the [Object] is not a [Creature], returns `nil`. - * - * @return [Creature] creature : the [Object] as a [Creature], or `nil` - */ - int ToCreature(lua_State* L, Object* obj) - { - ALE::Push(L, obj->ToCreature()); - return 1; - } - - /** - * Attempts to convert the [Object] to a [Player]. - * - * If the [Object] is not a [Player], returns `nil`. - * - * @return [Player] player : the [Object] as a [Player], or `nil` - */ - int ToPlayer(lua_State* L, Object* obj) - { - ALE::Push(L, obj->ToPlayer()); - return 1; - } -}; -#endif diff --git a/src/LuaEngine/methods/PetMethods.h b/src/LuaEngine/methods/PetMethods.h deleted file mode 100644 index 790da82379..0000000000 --- a/src/LuaEngine/methods/PetMethods.h +++ /dev/null @@ -1,665 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef PETMETHODS_H -#define PETMETHODS_H - -/*** - * Non-[Player] controlled companions that fight alongside their owners. - * - * Includes hunter pets, warlock demons, death knight ghouls, and other summoned creatures. - * [Pet]s can be temporary or permanent and have various AI behaviors and spell abilities. - * - * Inherits all methods from: [Object], [WorldObject], [Unit], [Guardian] - */ -namespace LuaPet -{ - /** - * Returns the [Pet]'s type. - * - *
-     * enum PetType
-     * {
-     *      SUMMON_PET                  = 0,
-     *      HUNTER_PET                  = 1,
-     *      MAX_PET_TYPE                = 4
-     * };
-     * 
- * - * @return [PetType] petType - */ - int GetPetType(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->getPetType()); - return 1; - } - - /** - * Sets the [Pet]'s type. - * - *
-     * enum PetType
-     * {
-     *      SUMMON_PET                  = 0,
-     *      HUNTER_PET                  = 1,
-     *      MAX_PET_TYPE                = 4
-     * };
-     * 
- * - * @param [PetType] petType : the pet type to set - */ - int SetPetType(lua_State* L, Pet* pet) - { - uint32 petType = ALE::CHECKVAL(L, 2); - pet->setPetType(static_cast(petType)); - return 0; - } - - /** - * Returns `true` if the [Pet] is controlled by a player, returns `false` otherwise. - * - * @return bool isControlled - */ - int IsControlled(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->isControlled()); - return 1; - } - - /** - * Returns `true` if the [Pet] is temporarily summoned, returns `false` otherwise. - * - * @return bool isTemporary - */ - int IsTemporarySummoned(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->isTemporarySummoned()); - return 1; - } - - /** - * Returns `true` if the [Pet] is a permanent pet for the specified [Player], returns `false` otherwise. - * - * @param [Player] owner : the player to check ownership for - * @return bool isPermanent - */ - int IsPermanentPetFor(lua_State* L, Pet* pet) - { - Player* owner = ALE::CHECKOBJ(L, 2); - ALE::Push(L, pet->IsPermanentPetFor(owner)); - return 1; - } - - /** - * Creates the [Pet]'s base stats and properties from an existing [Creature]. - * - * @param [Creature] creature : the creature to base the pet on - * @return bool success : `true` if successful, `false` otherwise - */ - int CreateBaseAtCreature(lua_State* L, Pet* pet) - { - Creature* creature = ALE::CHECKOBJ(L, 2); - ALE::Push(L, pet->CreateBaseAtCreature(creature)); - return 1; - } - - /** - * Returns the [Pet]'s remaining duration in milliseconds. - * - * @return uint32 duration : remaining time in milliseconds, 0 if permanent - */ - int GetDuration(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->GetDuration().count()); - return 1; - } - - /** - * Sets the [Pet]'s duration in milliseconds. - * - * @param uint32 duration : duration in milliseconds, 0 for permanent - */ - int SetDuration(lua_State* L, Pet* pet) - { - uint32 duration = ALE::CHECKVAL(L, 2); - pet->SetDuration(Milliseconds(duration)); - return 0; - } - - /** - * Returns the [Pet]'s current happiness state. - * - *
-     * enum HappinessState
-     * {
-     *      UNHAPPY                     = 1,
-     *      CONTENT                     = 2,
-     *      HAPPY                       = 3
-     * };
-     * 
- * - * @return [HappinessState] happinessState - */ - int GetHappinessState(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->GetHappinessState()); - return 1; - } - - /** - * Gives experience points to the [Pet]. - * - * @param uint32 xp : amount of experience to give - */ - int GivePetXP(lua_State* L, Pet* pet) - { - uint32 xp = ALE::CHECKVAL(L, 2); - pet->GivePetXP(xp); - return 0; - } - - /** - * Sets the [Pet]'s level directly. - * - * @param uint8 level : the level to set - */ - int GivePetLevel(lua_State* L, Pet* pet) - { - uint8 level = ALE::CHECKVAL(L, 2); - pet->GivePetLevel(level); - return 0; - } - - /** - * Synchronizes the [Pet]'s level with its owner's level. - * - * The pet's level will be adjusted based on the owner's level and pet scaling rules. - */ - int SynchronizeLevelWithOwner(lua_State* /*L*/, Pet* pet) - { - pet->SynchronizeLevelWithOwner(); - return 0; - } - - /** - * Returns `true` if the [Pet] can eat the specified [Item], returns `false` otherwise. - * - * @param [Item] item : the item to check - * @return bool canEat - */ - int HaveInDiet(lua_State* L, Pet* pet) - { - Item* item = ALE::CHECKOBJ(L, 2); - ALE::Push(L, pet->HaveInDiet(item->GetTemplate())); - return 1; - } - - /** - * Returns the food benefit level for an item of the specified level. - * - * @param uint32 itemLevel : the level of the food item - * @return uint32 benefitLevel - */ - int GetCurrentFoodBenefitLevel(lua_State* L, Pet* pet) - { - uint32 itemLevel = ALE::CHECKVAL(L, 2); - ALE::Push(L, pet->GetCurrentFoodBenefitLevel(itemLevel)); - return 1; - } - - /** - * Toggles autocast on or off for the specified spell. - * - * @param uint32 spellId : the spell ID to toggle autocast for - * @param bool apply : `true` to enable autocast, `false` to disable - */ - int ToggleAutocast(lua_State* L, Pet* pet) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - bool apply = ALE::CHECKVAL(L, 3); - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); - if (spellInfo) - pet->ToggleAutocast(spellInfo, apply); - - return 0; - } - - /** - * Makes the [Pet] learn all passive spells it should know. - * - * This includes racial passives and pet-specific passive abilities. - */ - int LearnPetPassives(lua_State* /*L*/, Pet* pet) - { - pet->LearnPetPassives(); - return 0; - } - - /** - * Queues a spell to be cast when the [Pet] becomes available. - * - * @param uint32 spellId : the spell ID to cast - * @param [Unit] target : the target for the spell - * @param bool isPositive = false : whether the spell is beneficial - */ - int CastWhenWillAvailable(lua_State* L, Pet* pet) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - Unit* target = ALE::CHECKOBJ(L, 3); - ObjectGuid oldTarget = ObjectGuid::Empty; - bool isPositive = ALE::CHECKVAL(L, 4, false); - - pet->CastWhenWillAvailable(spellId, target, oldTarget, isPositive); - return 0; - } - - /** - * Clears any queued spell that was set to cast when available. - */ - int ClearCastWhenWillAvailable(lua_State* /*L*/, Pet* pet) - { - pet->ClearCastWhenWillAvailable(); - return 0; - } - - /** - * Adds a spell to the [Pet]'s spellbook. - * - *
-     * enum ActiveStates : uint8
-     * {
-     *     ACT_PASSIVE  = 0x01,                                    // 0x01 - passive
-     *     ACT_DISABLED = 0x81,                                    // 0x80 - castable
-     *     ACT_ENABLED  = 0xC1,                                    // 0x40 | 0x80 - auto cast + castable
-     *     ACT_COMMAND  = 0x07,                                    // 0x01 | 0x02 | 0x04
-     *     ACT_REACTION = 0x06,                                    // 0x02 | 0x04
-     *     ACT_DECIDE   = 0x00                                     // custom
-     * };
-     * 
- * - *
-     * enum PetSpellState
-     * {
-     *     PETSPELL_UNCHANGED          = 0,
-     *     PETSPELL_CHANGED            = 1,
-     *     PETSPELL_NEW                = 2,
-     *     PETSPELL_REMOVED            = 3
-     * };
-     * 
- * - *
-     * enum PetSpellType
-     * {
-     *     PETSPELL_NORMAL             = 0,
-     *     PETSPELL_FAMILY             = 1,
-     *     PETSPELL_TALENT             = 2
-     * };
-     * 
- * - * @param uint32 spellId : the spell ID to add - * @param [ActiveStates] active : the spell's active state by default is ACT_DECIDE - * @param [PetSpellState] state : the spell's state by default is PETSPELL_NEW - * @param [PetSpellType] type : the spell's type by default is PETSPELL_NORMAL - * @return bool success : `true` if the spell was added successfully - */ - int AddSpell(lua_State* L, Pet* pet) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - uint32 active = ALE::CHECKVAL(L, 3, ACT_DECIDE); - uint32 state = ALE::CHECKVAL(L, 4, PETSPELL_NEW); - uint32 type = ALE::CHECKVAL(L, 5, PETSPELL_NORMAL); - - ALE::Push(L, pet->addSpell(spellId, static_cast(active), static_cast(state), static_cast(type))); - return 1; - } - - /** - * Makes the [Pet] learn a spell. - * - * @param uint32 spellId : the spell ID to learn - * @return bool success : `true` if the spell was learned successfully - */ - int LearnSpell(lua_State* L, Pet* pet) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - ALE::Push(L, pet->learnSpell(spellId)); - return 1; - } - - /** - * Makes the [Pet] learn the highest available rank of a spell. - * - * @param uint32 spellId : the base spell ID - */ - int LearnSpellHighRank(lua_State* L, Pet* pet) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - pet->learnSpellHighRank(spellId); - return 0; - } - - /** - * Initializes level-up spells for the [Pet]'s current level. - * - * This teaches the pet all spells it should know at its current level. - */ - int InitLevelupSpellsForLevel(lua_State* /*L*/, Pet* pet) - { - pet->InitLevelupSpellsForLevel(); - return 0; - } - - /** - * Makes the [Pet] unlearn a spell. - * - * @param uint32 spellId : the spell ID to unlearn - * @param bool learnPrev : if `true`, learns the previous rank by default is false - * @param bool clearAb : if `true`, clears the spell from action bar by default is true - * @return bool success : `true` if the spell was unlearned successfully - */ - int UnlearnSpell(lua_State* L, Pet* pet) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - bool learnPrev = ALE::CHECKVAL(L, 3, false); - bool clearAb = ALE::CHECKVAL(L, 4, true); - - ALE::Push(L, pet->unlearnSpell(spellId, learnPrev, clearAb)); - return 1; - } - - /** - * Removes a spell from the [Pet]'s spellbook. - * - * @param uint32 spellId : the spell ID to remove - * @param bool learnPrev : if `true`, learns the previous rank by default is false - * @param bool clearAb : if `true`, clears the spell from action bar by default is true - * @return bool success : `true` if the spell was removed successfully - */ - int RemoveSpell(lua_State* L, Pet* pet) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - bool learnPrev = ALE::CHECKVAL(L, 3, false); - bool clearAb = ALE::CHECKVAL(L, 4, true); - - ALE::Push(L, pet->removeSpell(spellId, learnPrev, clearAb)); - return 1; - } - - /** - * Cleans up the [Pet]'s action bar, removing invalid spells. - */ - int CleanupActionBar(lua_State* /*L*/, Pet* pet) - { - pet->CleanupActionBar(); - return 0; - } - - /** - * Generates action bar data for the [Pet]. - * - * @return string actionBarData : the action bar data as a string - */ - int GenerateActionBarData(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->GenerateActionBarData()); - return 1; - } - - /** - * Initializes the [Pet]'s creation spells. - * - * This sets up the basic spells the pet should have when first created. - */ - int InitPetCreateSpells(lua_State* /*L*/, Pet* pet) - { - pet->InitPetCreateSpells(); - return 0; - } - - /** - * Resets all of the [Pet]'s talents. - * - * @return bool success : `true` if talents were reset successfully - */ - int ResetTalents(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->resetTalents()); - return 1; - } - - /** - * Initializes talents for the [Pet]'s current level. - * - * This assigns talent points based on the pet's level. - */ - int InitTalentForLevel(lua_State* /*L*/, Pet* pet) - { - pet->InitTalentForLevel(); - return 0; - } - - /** - * Returns the maximum number of talent points available at the specified level. - * - * @param uint8 level : the level to check - * @return uint8 maxTalentPoints - */ - int GetMaxTalentPointsForLevel(lua_State* L, Pet* pet) - { - uint8 level = ALE::CHECKVAL(L, 2); - ALE::Push(L, pet->GetMaxTalentPointsForLevel(level)); - return 1; - } - - /** - * Returns the number of unspent talent points the [Pet] has. - * - * @return uint8 freeTalentPoints - */ - int GetFreeTalentPoints(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->GetFreeTalentPoints()); - return 1; - } - - /** - * Sets the number of unspent talent points for the [Pet]. - * - * @param uint8 points : the number of free talent points to set - */ - int SetFreeTalentPoints(lua_State* L, Pet* pet) - { - uint8 points = ALE::CHECKVAL(L, 2); - pet->SetFreeTalentPoints(points); - return 0; - } - - /** - * Returns the number of talents the [Pet] has used. - * - * @return uint32 usedTalentCount - */ - int GetUsedTalentCount(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->m_usedTalentCount); - return 1; - } - - /** - * Sets the number of talents the [Pet] has used. - * - * @param uint32 count : the number of used talents to set - */ - int SetUsedTalentCount(lua_State* L, Pet* pet) - { - uint32 count = ALE::CHECKVAL(L, 2); - pet->m_usedTalentCount = count; - return 0; - } - - /** - * Returns the aura update mask for raid members. - * - * @return uint64 auraUpdateMask - */ - int GetAuraUpdateMaskForRaid(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->GetAuraUpdateMaskForRaid()); - return 1; - } - - /** - * Sets an aura slot in the raid update mask. - * - * @param uint8 slot : the aura slot to set - */ - int SetAuraUpdateMaskForRaid(lua_State* L, Pet* pet) - { - uint8 slot = ALE::CHECKVAL(L, 2); - pet->SetAuraUpdateMaskForRaid(slot); - return 0; - } - - /** - * Resets the aura update mask for raid members. - */ - int ResetAuraUpdateMaskForRaid(lua_State* /*L*/, Pet* pet) - { - pet->ResetAuraUpdateMaskForRaid(); - return 0; - } - - /** - * Returns the [Player] who owns this [Pet]. - * - * @return [Player] owner : the pet's owner - */ - int GetOwner(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->GetOwner()); - return 1; - } - - /** - * Returns `true` if the [Pet] has a temporary spell queued, returns `false` otherwise. - * - * @return bool hasTempSpell - */ - int HasTempSpell(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->HasTempSpell()); - return 1; - } - - /** - * Returns `true` if the [Pet] is marked as removed, returns `false` otherwise. - * - * @return bool isRemoved - */ - int IsRemoved(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->m_removed); - return 1; - } - - /** - * Sets whether the [Pet] is marked as removed. - * - * @param bool removed : `true` to mark as removed, `false` otherwise - */ - int SetRemoved(lua_State* L, Pet* pet) - { - bool removed = ALE::CHECKVAL(L, 2); - pet->m_removed = removed; - return 0; - } - - /** - * Returns the number of auto-spells the [Pet] has. - * - * @return uint8 autoSpellCount - */ - int GetPetAutoSpellSize(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->GetPetAutoSpellSize()); - return 1; - } - - /** - * Returns the auto-spell at the specified position. - * - * @param uint8 pos : the position in the auto-spell list - * @return uint32 spellId : the spell ID, or 0 if invalid position - */ - int GetPetAutoSpellOnPos(lua_State* L, Pet* pet) - { - uint8 pos = ALE::CHECKVAL(L, 2); - ALE::Push(L, pet->GetPetAutoSpellOnPos(pos)); - return 1; - } - - /** - * Saves the [Pet] to the database. - * - *
-     * enum PetSaveMode
-     * {
-     *     PET_SAVE_AS_DELETED         = -1,                        // not saved in fact
-     *     PET_SAVE_AS_CURRENT         =  0,                        // in current slot (with player)
-     *     PET_SAVE_FIRST_STABLE_SLOT  =  1,
-     *     PET_SAVE_LAST_STABLE_SLOT   =  MAX_PET_STABLES,          // last in DB stable slot index (including), all higher have same meaning as PET_SAVE_NOT_IN_SLOT
-     *     PET_SAVE_NOT_IN_SLOT        =  100                       // for avoid conflict with stable size grow will use 100
-     * };
-     * 
- * - * @param [PetSaveMode] mode : the save mode to use - */ - int SavePetToDB(lua_State* L, Pet* pet) - { - uint32 mode = ALE::CHECKVAL(L, 2); - pet->SavePetToDB(static_cast(mode)); - return 0; - } - - /** - * Removes the [Pet] from the world. - * - *
-     * enum PetSaveMode
-     * {
-     *     PET_SAVE_AS_DELETED         = -1,                        // not saved in fact
-     *     PET_SAVE_AS_CURRENT         =  0,                        // in current slot (with player)
-     *     PET_SAVE_FIRST_STABLE_SLOT  =  1,
-     *     PET_SAVE_LAST_STABLE_SLOT   =  MAX_PET_STABLES,          // last in DB stable slot index (including), all higher have same meaning as PET_SAVE_NOT_IN_SLOT
-     *     PET_SAVE_NOT_IN_SLOT        =  100                       // for avoid conflict with stable size grow will use 100
-     * };
-     * 
- * - * @param [PetSaveMode] mode : how to handle the removal - * @param bool returnReagent = false : if `true`, returns reagents used to summon - */ - int Remove(lua_State* L, Pet* pet) - { - uint32 mode = ALE::CHECKVAL(L, 2); - bool returnReagent = ALE::CHECKVAL(L, 3, false); - pet->Remove(static_cast(mode), returnReagent); - return 0; - } - - /** - * Returns `true` if the [Pet] is currently being loaded from the database, returns `false` otherwise. - * - * @return bool isBeingLoaded - */ - int IsBeingLoaded(lua_State* L, Pet* pet) - { - ALE::Push(L, pet->isBeingLoaded()); - return 1; - } -}; -#endif // PETMETHODS_H - diff --git a/src/LuaEngine/methods/PlayerMethods.h b/src/LuaEngine/methods/PlayerMethods.h deleted file mode 100644 index 87cc921f8a..0000000000 --- a/src/LuaEngine/methods/PlayerMethods.h +++ /dev/null @@ -1,4986 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef PLAYERMETHODS_H -#define PLAYERMETHODS_H - -#include "Chat.h" -#include "GameTime.h" -#include "GossipDef.h" - -/*** - * Inherits all methods from: [Object], [WorldObject], [Unit] - */ -namespace LuaPlayer -{ - /** - * Returns `true` if the [Player] can Titan Grip, `false` otherwise. - * - * @return bool canTitanGrip - */ - int CanTitanGrip(lua_State* L, Player* player) - { - ALE::Push(L, player->CanTitanGrip()); - return 1; - } - - /** - * Returns `true` if the [Player] has a talent by ID in specified spec, `false` otherwise. - * - * @param uint32 spellId : talent spellId to check - * @param uint8 spec : specified spec. 0 for primary, 1 for secondary. - * @return bool hasTalent - */ - int HasTalent(lua_State* L, Player* player) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - uint8 maxSpecs = MAX_TALENT_SPECS; - uint8 spec = ALE::CHECKVAL(L, 3); - if (spec >= maxSpecs) - return 1; - ALE::Push(L, player->HasTalent(spellId, spec)); - return 1; - } - - /** - * Returns `true` if the [Player] has completed the specified achievement, `false` otherwise. - * - * @param uint32 achievementId - * @return bool hasAchieved - */ - int HasAchieved(lua_State* L, Player* player) - { - uint32 achievementId = ALE::CHECKVAL(L, 2); - ALE::Push(L, player->HasAchieved(achievementId)); - return 1; - } - - /** - * Returns the progress of the [Player] for the specified achievement criteria. - * - * @param uint32 criteriaId - * @return uint32 progress : progress value or nil - */ - int GetAchievementCriteriaProgress(lua_State* L, Player* player) - { - uint32 criteriaId = ALE::CHECKVAL(L, 2); - const AchievementCriteriaEntry* criteria = sAchievementCriteriaStore.LookupEntry(criteriaId); - CriteriaProgress* progress = player->GetAchievementMgr()->GetCriteriaProgress(criteria); - if (progress) - { - ALE::Push(L, progress->counter); - } - else - { - ALE::Push(L, (void*)nullptr); - } - return 1; - } - - /** - * Returns `true` if the [Player] has an active [Quest] by specific ID, `false` otherwise. - * - * @param uint32 questId - * @return bool hasQuest - */ - int HasQuest(lua_State* L, Player* player) - { - uint32 quest = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->IsActiveQuest(quest)); - return 1; - } - - /** - * Returns `true` if the [Player] has a skill by specific ID, `false` otherwise. - * - * @param uint32 skill - * @return bool hasSkill - */ - int HasSkill(lua_State* L, Player* player) - { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->HasSkill(skill)); - return 1; - } - - /** - * Returns `true` if the [Player] has a [Spell] by specific ID, `false` otherwise. - * - * @param uint32 spellId - * @return bool hasSpell - */ - int HasSpell(lua_State* L, Player* player) - { - uint32 id = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->HasSpell(id)); - return 1; - } - - /** - * Returns true if [Player] has specified login flag - * - * @param uint32 flag - * @return bool hasLoginFlag - */ - int HasAtLoginFlag(lua_State* L, Player* player) - { - uint32 flag = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->HasAtLoginFlag((AtLoginFlags)flag)); - return 1; - } - - /** - * Returns true if [Player] has [Quest] for [GameObject] - * - * @param int32 entry : entry of a [GameObject] - * @return bool hasQuest - */ - int HasQuestForGO(lua_State* L, Player* player) - { - int32 entry = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->HasQuestForGO(entry)); - return 1; - } - - /** - * Returns `true` if the [Player] has a title by specific ID, `false` otherwise. - * - * @param uint32 titleId - * @return bool hasTitle - */ - int HasTitle(lua_State* L, Player* player) - { - uint32 id = ALE::CHECKVAL(L, 2); - CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id); - if (titleInfo) - ALE::Push(L, player->HasTitle(titleInfo)); - return 1; - } - - /** - * Returns `true` if the [Player] has the given amount of item entry specified, `false` otherwise. - * - * @param uint32 itemId : entry of the item - * @param uint32 count = 1 : amount of items the player needs should have - * @param bool check_bank = false : determines if the item can be in player bank - * @return bool hasItem - */ - int HasItem(lua_State* L, Player* player) - { - uint32 itemId = ALE::CHECKVAL(L, 2); - uint32 count = ALE::CHECKVAL(L, 3, 1); - bool check_bank = ALE::CHECKVAL(L, 4, false); - ALE::Push(L, player->HasItemCount(itemId, count, check_bank)); - return 1; - } - - /** - * Returns `true` if the [Player] has a quest for the item entry specified, `false` otherwise. - * - * @param uint32 entry : entry of the item - * @return bool hasQuest - */ - int HasQuestForItem(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->HasQuestForItem(entry)); - return 1; - } - - /** - * Returns `true` if the [Player] can use the item or item entry specified, `false` otherwise. - * - * @proto canUse = (item) - * @proto canUse = (entry) - * @param [Item] item : an instance of an item - * @param uint32 entry : entry of the item - * @return bool canUse - */ - int CanUseItem(lua_State* L, Player* player) - { - Item* item = ALE::CHECKOBJ(L, 2, false); - if (item) - ALE::Push(L, player->CanUseItem(item) == EQUIP_ERR_OK); - else - { - uint32 entry = ALE::CHECKVAL(L, 2); - const ItemTemplate* temp = eObjectMgr->GetItemTemplate(entry); - if (temp) - ALE::Push(L, player->CanUseItem(temp) == EQUIP_ERR_OK); - else - ALE::Push(L, false); - } - return 1; - } - - /** - * Returns `true` if the [Spell] specified by ID is currently on cooldown for the [Player], `false` otherwise. - * - * @param uint32 spellId - * @return bool hasSpellCooldown - */ - int HasSpellCooldown(lua_State* L, Player* player) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->HasSpellCooldown(spellId)); - return 1; - } - - /** - * Returns `true` if the [Player] can share [Quest] specified by ID, `false` otherwise. - * - * @param uint32 entryId - * @return bool hasSpellCooldown - */ - int CanShareQuest(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->CanShareQuest(entry)); - return 1; - } - - /** - * Returns `true` if the [Player] can currently communicate through chat, `false` otherwise. - * - * @return bool canSpeak - */ - int CanSpeak(lua_State* L, Player* player) - { - ALE::Push(L, player->CanSpeak()); - return 1; - } - - /** - * Returns `true` if the [Player] has permission to uninvite others from the current group, `false` otherwise. - * - * @return bool canUninviteFromGroup - */ - int CanUninviteFromGroup(lua_State* L, Player* player) - { - ALE::Push(L, player->CanUninviteFromGroup() == ERR_PARTY_RESULT_OK); - return 1; - } - - /** - * Returns `true` if the [Player] can fly, `false` otherwise. - * - * @return bool canFly - */ - int CanFly(lua_State* L, Player* player) - { - ALE::Push(L, player->CanFly()); - return 1; - } - - /** - * Returns `true` if the [Player] is currently in water, `false` otherwise. - * - * @return bool isInWater - */ - int IsInWater(lua_State* L, Player* player) - { - ALE::Push(L, player->IsInWater()); - return 1; - } - - /** - * Returns `true` if the [Player] is currently moving, `false` otherwise. - * - * @return bool isMoving - */ - int IsMoving(lua_State* L, Player* player) // enable for unit when mangos support it - { - ALE::Push(L, player->isMoving()); - return 1; - } - - /** - * Returns `true` if the [Player] is currently flying, `false` otherwise. - * - * @return bool isFlying - */ - int IsFlying(lua_State* L, Player* player) // enable for unit when mangos support it - { - ALE::Push(L, player->IsFlying()); - return 1; - } - - /** - * Returns `true` if the [Player] has a Tank Specialization, `false` otherwise. - * - * @return bool HasTankSpec - */ - int HasTankSpec(lua_State* L, Player* player) - { - ALE::Push(L, player->HasTankSpec()); - return 1; - } - - /** - * Returns `true` if the [Player] has a Melee Specialization, `false` otherwise. - * - * @return bool HasMeleeSpec - */ - int HasMeleeSpec(lua_State* L, Player* player) - { - ALE::Push(L, player->HasMeleeSpec()); - return 1; - } - - /** - * Returns `true` if the [Player] has a Caster Specialization, `false` otherwise. - * - * @return bool HasCasterSpec - */ - int HasCasterSpec(lua_State* L, Player* player) - { - ALE::Push(L, player->HasCasterSpec()); - return 1; - } - - /** - * Returns `true` if the [Player] has a Heal Specialization, `false` otherwise. - * - * @return bool HasHealSpec - */ - int HasHealSpec(lua_State* L, Player* player) - { - ALE::Push(L, player->HasHealSpec()); - return 1; - } - - /** - * Returns `true` if the [Player] is in a [Group], `false` otherwise. - * - * @return bool isInGroup - */ - int IsInGroup(lua_State* L, Player* player) - { - ALE::Push(L, (player->GetGroup() != NULL)); - return 1; - } - - /** - * Returns `true` if the [Player] is in a [Guild], `false` otherwise. - * - * @return bool isInGuild - */ - int IsInGuild(lua_State* L, Player* player) - { - ALE::Push(L, (player->GetGuildId() != 0)); - return 1; - } - - /** - * Returns `true` if the [Player] is a Game Master, `false` otherwise. - * - * Note: This is only true when GM tag is activated! For alternative see [Player:GetGMRank] - * - * @return bool isGM - */ - int IsGM(lua_State* L, Player* player) - { - ALE::Push(L, player->IsGameMaster()); - return 1; - } - - /** - * Returns `true` if the [Player] is in an arena team specified by type, `false` otherwise. - * - * @param uint32 type - * @return bool isInArenaTeam - */ - int IsInArenaTeam(lua_State* L, Player* player) - { - uint32 type = ALE::CHECKVAL(L, 2); - if (type < MAX_ARENA_SLOT && player->GetArenaTeamId(type)) - ALE::Push(L, true); - else - ALE::Push(L, false); - return 1; - } - - /** - * Returns `true` if the [Player] is immune to everything. - * - * @return bool isImmune - */ - int IsImmuneToDamage(lua_State* L, Player* player) - { - ALE::Push(L, player->isTotalImmune()); - return 1; - } - - /** - * Returns `true` if the [Player] satisfies all requirements to complete the quest entry. - * - * @param uint32 questId - * @return bool canCompleteRepeatableQuest - */ - int CanCompleteRepeatableQuest(lua_State* L, Player* player) - { - uint32 questId = ALE::CHECKVAL(L, 2); - const Quest* quest = sObjectMgr->GetQuestTemplate(questId); // Retrieve the Quest object - if (!quest) - { - ALE::Push(L, false); - return 1; - } - - ALE::Push(L, player->CanCompleteRepeatableQuest(quest)); - return 1; - } - - /** - * Returns `true` if the [Player] satisfies all requirements to reward the quest entry. - * - * @param uint32 questId - * @return bool canRewardQuest - */ - int CanRewardQuest(lua_State* L, Player* player) - { - uint32 questId = ALE::CHECKVAL(L, 2); - const Quest* quest = sObjectMgr->GetQuestTemplate(questId); // Retrieve the Quest object - if (!quest) - { - ALE::Push(L, false); - return 1; - } - - ALE::Push(L, player->CanRewardQuest(quest, true)); // Modify the second argument as needed - return 1; - } - - /** - * Returns `true` if the [Player] satisfies all requirements to complete the quest entry. - * - * @param uint32 entry - * @return bool canComplete - */ - int CanCompleteQuest(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->CanCompleteQuest(entry)); - return 1; - } - - /** - * Returns `true` if the [Player] is a part of the Horde faction, `false` otherwise. - * - * @return bool isHorde - */ - int IsHorde(lua_State* L, Player* player) - { - ALE::Push(L, (player->GetTeamId() == TEAM_HORDE)); - return 1; - } - - /** - * Returns `true` if the [Player] is a part of the Alliance faction, `false` otherwise. - * - * @return bool isAlliance - */ - int IsAlliance(lua_State* L, Player* player) - { - ALE::Push(L, (player->GetTeamId() == TEAM_ALLIANCE)); - return 1; - } - - /** - * Returns `true` if the [Player] is 'Do Not Disturb' flagged, `false` otherwise. - * - * @return bool isDND - */ - int IsDND(lua_State* L, Player* player) - { - ALE::Push(L, player->isDND()); - return 1; - } - - /** - * Returns `true` if the [Player] is 'Away From Keyboard' flagged, `false` otherwise. - * - * @return bool isAFK - */ - int IsAFK(lua_State* L, Player* player) - { - ALE::Push(L, player->isAFK()); - return 1; - } - - /** - * Returns `true` if the [Player] is currently falling, `false` otherwise. - * - * @return bool isFalling - */ - int IsFalling(lua_State* L, Player* player) - { - ALE::Push(L, player->IsFalling()); - return 1; - } - - /** - * Returns `true` if the [Player] is in the same group and visible to the specified [Player], `false` otherwise. - * - * @param [Player] player : the source player - * @param [Player] target : the player to check visibility from - * @return bool isGroupVisible - */ - int IsGroupVisibleFor(lua_State* L, Player* player) - { - Player* target = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->IsGroupVisibleFor(target)); - return 1; - } - - /** - * Returns `true` if the [Player] is currently in the same raid as another [Player] by object, `false` otherwise. - * - * @param [Player] player - * @return bool isInSameRaidWith - */ - int IsInSameRaidWith(lua_State* L, Player* player) - { - Player* target = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->IsInSameRaidWith(target)); - return 1; - } - - /** - * Returns `true` if the [Player] is currently in the same [Group] as another [Player] by object, `false` otherwise. - * - * @param [Player] player - * @return bool isInSameGroupWith - */ - int IsInSameGroupWith(lua_State* L, Player* player) - { - Player* target = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->IsInSameGroupWith(target)); - return 1; - } - - /** - * Returns `true` if the [Player] is eligible for Honor or XP gain by [Unit] specified, `false` otherwise. - * - * @param [Unit] unit - * @return bool isHonorOrXPTarget - */ - int IsHonorOrXPTarget(lua_State* L, Player* player) - { - Unit* victim = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, player->isHonorOrXPTarget(victim)); - return 1; - } - - /** - * Returns `true` if the [Player] can see anoter [Player] specified by object, `false` otherwise. - * - * @param [Player] player - * @return bool isVisibleForPlayer - */ - int IsVisibleForPlayer(lua_State* L, Player* player) - { - Player* target = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, player->IsVisibleGloballyFor(target)); - return 1; - } - - /** - * Returns `true` if the [Player] is currently visible to other players, `false` if hidden via GM invisibility. - * - * @param [Player] player - * @return bool isVisible - */ - int IsGMVisible(lua_State* L, Player* player) - { - ALE::Push(L, player->isGMVisible()); - return 1; - } - - /** - * Returns `true` if the [Player] has taxi cheat activated, `false` otherwise. - * - * @return bool isTaxiCheater - */ - int IsTaxiCheater(lua_State* L, Player* player) - { - ALE::Push(L, player->isTaxiCheater()); - return 1; - } - - /** - * Returns `true` if the [Player] has GM chat enabled, `false` otherwise. - * - * @param [Player] player - * @return bool isGMChat - */ - int IsGMChat(lua_State* L, Player* player) - { - ALE::Push(L, player->isGMChat()); - return 1; - } - - /** - * Returns `true` if the [Player] is accepting whispers, `false` otherwise. - * - * @return bool isAcceptingWhispers - */ - int IsAcceptingWhispers(lua_State* L, Player* player) - { - ALE::Push(L, player->isAcceptWhispers()); - return 1; - } - - /** - * Returns `true` if the [Player] is currently rested, `false` otherwise. - * - * @return bool isRested - */ - int IsRested(lua_State* L, Player* player) - { - ALE::Push(L, player->GetRestBonus() > 0.0f); - return 1; - } - - /** - * Returns `true` if the [Player] is currently in a [BattleGround] queue, `false` otherwise. - * - * @return bool inBattlegroundQueue - */ - int InBattlegroundQueue(lua_State* L, Player* player) - { - ALE::Push(L, player->InBattlegroundQueue()); - return 1; - } - - /** - * Returns `true` if the [Player] is currently in an arena, `false` otherwise. - * - * @return bool inArena - */ - int InArena(lua_State* L, Player* player) - { - ALE::Push(L, player->InArena()); - return 1; - } - - /** - * Returns `true` if the [Player] is currently in a [BattleGround], `false` otherwise. - * - * @return bool inBattleGround - */ - int InBattleground(lua_State* L, Player* player) - { - ALE::Push(L, player->InBattleground()); - return 1; - } - - /** - * Returns `true` if the [Player] can block incomming attacks, `false` otherwise. - * - * @return bool canBlock - */ - int CanBlock(lua_State* L, Player* player) - { - ALE::Push(L, player->CanBlock()); - return 1; - } - - /** - * Returns `true` if the [Player] can parry incomming attacks, `false` otherwise. - * - * @return bool canParry - */ - int CanParry(lua_State* L, Player* player) - { - ALE::Push(L, player->CanParry()); - return 1; - } - - /** - * Returns the amount of available specs the [Player] currently has - * - * @return uint8 specCount - */ - int GetSpecsCount(lua_State* L, Player* player) - { - ALE::Push(L, player->GetSpecsCount()); - return 1; - } - - /** - * Returns the [Player]s active spec ID - * - * @return uint32 specId - */ - int GetActiveSpec(lua_State* L, Player* player) - { - ALE::Push(L, player->GetActiveSpec()); - return 1; - } - - /** - * Returns the normal phase of the player instead of the actual phase possibly containing GM phase - * - * @return uint32 phasemask - */ - int GetPhaseMaskForSpawn(lua_State* L, Player* player) - { - ALE::Push(L, player->GetPhaseMaskForSpawn()); - return 1; - } - - /** - * Returns the [Player]s current amount of Achievement Points - * - * @return uint32 achievementPoints - */ - int GetAchievementPoints(lua_State* L, Player* player) - { - uint32 count = 0; - const CompletedAchievementMap& completedAchievements = player->GetAchievementMgr()->GetCompletedAchievements(); - for (auto& pair : completedAchievements) - { - AchievementEntry const* achievement = sAchievementStore.LookupEntry(pair.first); - if (achievement) - { - count += achievement->points; - } - } - - ALE::Push(L, count); - return 1; - } - - /** - * Returns the [Player]s current amount of Achievements Completed - * - * @return uint32 achievementsCount - */ - int GetCompletedAchievementsCount(lua_State* L, Player* player) - { - uint32 count = 0; - bool countFeatsOfStrength = ALE::CHECKVAL(L, 2, false); - const CompletedAchievementMap& completedAchievements = player->GetAchievementMgr()->GetCompletedAchievements(); - for (auto& pair : completedAchievements) - { - AchievementEntry const* achievement = sAchievementStore.LookupEntry(pair.first); - if (achievement && (achievement->categoryId != 81 || countFeatsOfStrength)) - { - count++; - } - } - - ALE::Push(L, count); - return 1; - } - - /** - * Returns the [Player]s current amount of Arena Points - * - * @return uint32 arenaPoints - */ - int GetArenaPoints(lua_State* L, Player* player) - { - ALE::Push(L, player->GetArenaPoints()); - return 1; - } - - /** - * Returns the [Player]s current amount of Honor Points - * - * @return uint32 honorPoints - */ - int GetHonorPoints(lua_State* L, Player* player) - { - ALE::Push(L, player->GetHonorPoints()); - return 1; - } - - /** - * Returns the [Player]s current shield block value - * - * @return uint32 blockValue - */ - int GetShieldBlockValue(lua_State* L, Player* player) - { - ALE::Push(L, player->GetShieldBlockValue()); - return 1; - } - - /** - * Returns the [Player]s cooldown delay by specified [Spell] ID - * - * @param uint32 spellId - * @return uint32 spellCooldownDelay - */ - int GetSpellCooldownDelay(lua_State* L, Player* player) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - - ALE::Push(L, uint32(player->GetSpellCooldownDelay(spellId))); - return 1; - } - - /** - * Returns the [Player]s current latency in MS - * - * @return uint32 latency - */ - int GetLatency(lua_State* L, Player* player) - { - ALE::Push(L, player->GetSession()->GetLatency()); - return 1; - } - - /** - * Returns the faction ID the [Player] is currently flagged as champion for - * - * @return uint32 championingFaction - */ - int GetChampioningFaction(lua_State* L, Player* player) - { - ALE::Push(L, player->GetChampioningFaction()); - return 1; - } - - /** - * Returns [Player]s original sub group - * - * @return uint8 subGroup - */ - int GetOriginalSubGroup(lua_State* L, Player* player) - { - ALE::Push(L, player->GetOriginalSubGroup()); - return 1; - } - - /** - * Returns [Player]s original [Group] object - * - * @return [Group] group - */ - int GetOriginalGroup(lua_State* L, Player* player) - { - ALE::Push(L, player->GetOriginalGroup()); - return 1; - } - - /** - * Returns a random Raid Member [Player] object within radius specified of [Player] - * - * @param float radius - * @return [Player] player - */ - int GetNextRandomRaidMember(lua_State* L, Player* player) - { - float radius = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetNextRandomRaidMember(radius)); - return 1; - } - - /** - * Returns [Player]s current sub group - * - * @return uint8 subGroup - */ - int GetSubGroup(lua_State* L, Player* player) - { - ALE::Push(L, player->GetSubGroup()); - return 1; - } - - /** - * Returns [Group] invitation - * - * @return [Group] group - */ - int GetGroupInvite(lua_State* L, Player* player) - { - ALE::Push(L, player->GetGroupInvite()); - return 1; - } - - /** - * Returns the [Player]'s experience points - * - * @return uint32 xp - */ - int GetXP(lua_State* L, Player* player) - { - ALE::Push(L, player->GetUInt32Value(PLAYER_XP)); - return 1; - } - - /** - * Returns rested experience bonus - * - * @param uint32 xp - * @return uint32 xpBonus - */ - int GetXPRestBonus(lua_State* L, Player* player) - { - uint32 xp = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetXPRestBonus(xp)); - return 1; - } - - /** - * Returns the [Player]s current [BattleGround] type ID - * - * @return [BattleGroundTypeId] typeId - */ - int GetBattlegroundTypeId(lua_State* L, Player* player) - { - ALE::Push(L, player->GetBattlegroundTypeId()); - return 1; - } - - /** - * Returns the [Player]s current [BattleGround] ID - * - * @return uint32 battleGroundId - */ - int GetBattlegroundId(lua_State* L, Player* player) - { - ALE::Push(L, player->GetBattlegroundId()); - return 1; - } - - /** - * Returns the [Player]s reputation rank of faction specified - * - * @param uint32 faction - * @return [ReputationRank] rank - */ - int GetReputationRank(lua_State* L, Player* player) - { - uint32 faction = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetReputationRank(faction)); - return 1; - } - - /** - * Returns the [Player]s current level of intoxication - * - * @return uint16 drunkValue - */ - int GetDrunkValue(lua_State* L, Player* player) - { - ALE::Push(L, player->GetDrunkValue()); - return 1; - } - - /** - * Returns skill temporary bonus value - * - * @param uint32 skill - * @param int16 bonusVal - */ - int GetSkillTempBonusValue(lua_State* L, Player* player) - { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetSkillTempBonusValue(skill)); - return 1; - } - - /** - * Returns skill permanent bonus value - * - * @param uint32 skill - * @param int16 bonusVal - */ - int GetSkillPermBonusValue(lua_State* L, Player* player) - { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetSkillPermBonusValue(skill)); - return 1; - } - - /** - * Returns skill value without bonus' - * - * @param uint32 skill - * @return uint16 pureVal - */ - int GetPureSkillValue(lua_State* L, Player* player) - { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetPureSkillValue(skill)); - return 1; - } - - /** - * Returns base skill value - * - * @param uint32 skill - * @return uint16 baseVal - */ - int GetBaseSkillValue(lua_State* L, Player* player) - { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetBaseSkillValue(skill)); - return 1; - } - - /** - * Returns skill value - * - * @param uint32 skill - * @return uint16 val - */ - int GetSkillValue(lua_State* L, Player* player) - { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetSkillValue(skill)); - return 1; - } - - /** - * Returns max value of specified skill without bonus' - * - * @param uint32 skill - * @return uint16 pureVal - */ - int GetPureMaxSkillValue(lua_State* L, Player* player) - { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetPureMaxSkillValue(skill)); - return 1; - } - - /** - * Returns max value of specified skill - * - * @param uint32 skill - * @return uint16 val - */ - int GetMaxSkillValue(lua_State* L, Player* player) - { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetMaxSkillValue(skill)); - return 1; - } - - /** - * Returns mana bonus from amount of intellect - * - * @return float bonus - */ - int GetManaBonusFromIntellect(lua_State* L, Player* player) - { - ALE::Push(L, player->GetManaBonusFromIntellect()); - return 1; - } - - /** - * Returns health bonus from amount of stamina - * - * @return float bonus - */ - int GetHealthBonusFromStamina(lua_State* L, Player* player) - { - ALE::Push(L, player->GetHealthBonusFromStamina()); - return 1; - } - - /** - * Returns raid or dungeon difficulty - * - * @param bool isRaid = true : argument is TrinityCore only - * @return int32 difficulty - */ - int GetDifficulty(lua_State* L, Player* player) - { - bool isRaid = ALE::CHECKVAL(L, 2, true); - ALE::Push(L, player->GetDifficulty(isRaid)); - return 1; - } - - /** - * Returns the [Player]s current guild rank - * - * @return uint32 guildRank - */ - int GetGuildRank(lua_State* L, Player* player) // TODO: Move to Guild Methods - { - ALE::Push(L, player->GetRank()); - return 1; - } - - /** - * Returns the [Player]s free talent point amount - * - * @return uint32 freeTalentPointAmt - */ - int GetFreeTalentPoints(lua_State* L, Player* player) - { - ALE::Push(L, player->GetFreeTalentPoints()); - return 1; - } - - /** - * Returns the name of the [Player]s current [Guild] - * - * @return string guildName - */ - int GetGuildName(lua_State* L, Player* player) - { - if (!player->GetGuildId()) - return 1; - ALE::Push(L, eGuildMgr->GetGuildNameById(player->GetGuildId())); - return 1; - } - - /** - * Returns the amount of reputation the [Player] has with the faction specified - * - * @param uint32 faction - * @return int32 reputationAmt - */ - int GetReputation(lua_State* L, Player* player) - { - uint32 faction = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetReputationMgr().GetReputation(faction)); - return 1; - } - - /** - * Returns [Unit] target combo points are on - * - * @return [Unit] target - */ - int GetComboTarget(lua_State* L, Player* player) - { - ALE::Push(L, player->GetComboTarget()); - return 1; - } - - /** - * Returns [Player]'s combo points - * - * @return uint8 comboPoints - */ - int GetComboPoints(lua_State* L, Player* player) - { - ALE::Push(L, player->GetComboPoints()); - return 1; - } - - /** - * Returns the amount of time the [Player] has spent ingame - * - * @return uint32 inGameTime - */ - int GetInGameTime(lua_State* L, Player* player) - { - ALE::Push(L, player->GetInGameTime()); - return 1; - } - - /** - * Returns the status of the [Player]s [Quest] specified by entry ID - * - * @param uint32 questId - * @return [QuestStatus] questStatus - */ - int GetQuestStatus(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetQuestStatus(entry)); - return 1; - } - - /** - * Returns `true` if the [Player]s [Quest] specified by entry ID has been rewarded, `false` otherwise. - * - * @param uint32 questId - * @return bool questRewardStatus - */ - int GetQuestRewardStatus(lua_State* L, Player* player) - { - uint32 questId = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetQuestRewardStatus(questId)); - return 1; - } - - /** - * Returns [Quest] required [Creature] or [GameObject] count - * - * @param uint32 quest : entry of a quest - * @param int32 entry : entry of required [Creature] - * @return uint16 count - */ - int GetReqKillOrCastCurrentCount(lua_State* L, Player* player) - { - uint32 questId = ALE::CHECKVAL(L, 2); - int32 entry = ALE::CHECKVAL(L, 3); - - ALE::Push(L, player->GetReqKillOrCastCurrentCount(questId, entry)); - return 1; - } - - /** - * Returns the quest level of the [Player]s [Quest] specified by object - * - * @param uint32 questId - * @return [QuestStatus] questRewardStatus - */ - int GetQuestLevel(lua_State* L, Player* player) - { - Quest* quest = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, player->GetQuestLevel(quest)); - return 1; - } - - /** - * Returns a [Player]s [Item] object by gear slot specified - * - * @param uint8 slot - * @return [Item] item - */ - int GetEquippedItemBySlot(lua_State* L, Player* player) - { - uint8 slot = ALE::CHECKVAL(L, 2); - if (slot >= EQUIPMENT_SLOT_END) - return 1; - - Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); - ALE::Push(L, item); - return 1; - } - - /** - * Returns the [Player]s current resting bonus - * - * @return float restBonus - */ - int GetRestBonus(lua_State* L, Player* player) - { - ALE::Push(L, player->GetRestBonus()); - return 1; - } - - /** - * Returns active GM chat tag - * - * @return uint8 tag - */ - int GetChatTag(lua_State* L, Player* player) - { - ALE::Push(L, player->GetChatTag()); - return 1; - } - - /** - * Returns an item in given bag on given slot. - * - *
-     * Possible and most commonly used combinations:
-     *
-     * bag = 255
-     * slots 0-18 equipment
-     * slots 19-22 equipped bag slots
-     * slots 23-38 backpack
-     * slots 39-66 bank main slots
-     * slots 67-74 bank bag slots
-     * slots 86-117 keyring
-     *
-     * bag = 19-22
-     * slots 0-35 for equipped bags
-     *
-     * bag = 67-74
-     * slots 0-35 for bank bags
-     * 
- * - * @param uint8 bag : the bag the [Item] is in, you can get this with [Item:GetBagSlot] - * @param uint8 slot : the slot the [Item] is in within the bag, you can get this with [Item:GetSlot] - * @return [Item] item : [Item] or nil - */ - int GetItemByPos(lua_State* L, Player* player) - { - uint8 bag = ALE::CHECKVAL(L, 2); - uint8 slot = ALE::CHECKVAL(L, 3); - - ALE::Push(L, player->GetItemByPos(bag, slot)); - return 1; - } - - /** - * Returns an [Item] from the player by guid. - * - * The item can be equipped, in bags or in bank. - * - * @param ObjectGuid guid : an item guid - * @return [Item] item - */ - int GetItemByGUID(lua_State* L, Player* player) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetItemByGuid(guid)); - return 1; - } - - /** - * Returns the amount of mails in the player's mailbox. - * - * @return uint32 mailCount - */ - int GetMailCount(lua_State* L, Player* player) - { - const CharacterCacheEntry* cache = sCharacterCache->GetCharacterCacheByGuid(player->GetGUID()); - if (cache) - { - ALE::Push(L, static_cast(cache->MailCount)); - } - else - { - ALE::Push(L, player->GetMailSize()); - } - - return 1; - } - - /** - * Returns a mailed [Item] by guid. - * - * @param ObjectGuid guid : an item guid - * @return [Item] item - */ - int GetMailItem(lua_State* L, Player* player) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetMItem(guid.GetCounter())); - return 1; - } - - /** - * Returns an [Item] from the player by entry. - * - * The item can be equipped, in bags or in bank. - * - * @param uint32 entryId - * @return [Item] item - */ - int GetItemByEntry(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetItemByEntry(entry)); - return 1; - } - - /** - * Returns the database textID of the [WorldObject]'s gossip header text for the [Player] - * - * @param [WorldObject] object - * @return uint32 textId : key to npc_text database table - */ - int GetGossipTextId(lua_State* L, Player* player) - { - WorldObject* obj = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->GetGossipTextId(obj)); - return 1; - } - - /** - * Returns the [Player]s currently selected [Unit] object - * - * @return [Unit] unit - */ - int GetSelection(lua_State* L, Player* player) - { - ALE::Push(L, player->GetSelectedUnit()); - return 1; - } - - /** - * Returns the [Player]s GM Rank - * - * @return [AccountTypes] gmRank - */ - int GetGMRank(lua_State* L, Player* player) - { - ALE::Push(L, player->GetSession()->GetSecurity()); - return 1; - } - - /** - * Returns the [Player]s amount of money in copper - * - * @return uint32 coinage - */ - int GetCoinage(lua_State* L, Player* player) - { - ALE::Push(L, player->GetMoney()); - return 1; - } - - /** - * Returns the [Player]s current [Guild] ID - * - * @return uint32 guildId - */ - int GetGuildId(lua_State* L, Player* player) - { - ALE::Push(L, player->GetGuildId()); - return 1; - } - - /** - * Returns the [Player]s [TeamId] - * - * @return [TeamId] teamId - */ - int GetTeam(lua_State* L, Player* player) - { - ALE::Push(L, player->GetTeamId()); - return 1; - } - - /** - * Returns amount of the specified [Item] the [Player] has. - * - * @param uint32 entry : entry of the item - * @param bool checkinBank = false : also counts the items in player's bank if true - * @return uint32 itemamount - */ - int GetItemCount(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - bool checkinBank = ALE::CHECKVAL(L, 3, false); - ALE::Push(L, player->GetItemCount(entry, checkinBank)); - return 1; - } - - /** - * Returns the [Player]s lifetime Honorable Kills - * - * @return uint32 lifeTimeKils - */ - int GetLifetimeKills(lua_State* L, Player* player) - { - ALE::Push(L, player->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS)); - return 1; - } - - /** - * Returns the [Player]s IP address - * - * @return string ip - */ - int GetPlayerIP(lua_State* L, Player* player) - { - ALE::Push(L, player->GetSession()->GetRemoteAddress()); - return 1; - } - - /** - * Returns the [Player]s time played at current level - * - * @return uint32 currLevelPlayTime - */ - int GetLevelPlayedTime(lua_State* L, Player* player) - { - ALE::Push(L, player->GetLevelPlayedTime()); - return 1; - } - - /** - * Returns the [Player]s total time played - * - * @return uint32 totalPlayTime - */ - int GetTotalPlayedTime(lua_State* L, Player* player) - { - ALE::Push(L, player->GetTotalPlayedTime()); - return 1; - } - - /** - * Returns the [Player]s [Guild] object - * - * @return [Guild] guild - */ - int GetGuild(lua_State* L, Player* player) - { - ALE::Push(L, eGuildMgr->GetGuildById(player->GetGuildId())); - return 1; - } - - /** - * Returns the [Player]s [Group] object - * - * @return [Group] group - */ - int GetGroup(lua_State* L, Player* player) - { - ALE::Push(L, player->GetGroup()); - return 1; - } - - /** - * Returns the [Player]s account ID - * - * @return uint32 accountId - */ - int GetAccountId(lua_State* L, Player* player) - { - ALE::Push(L, player->GetSession()->GetAccountId()); - return 1; - } - - /** - * Returns the [Player]s account name - * - * @return string accountName - */ - int GetAccountName(lua_State* L, Player* player) - { - std::string accName; - if (AccountMgr::GetName(player->GetSession()->GetAccountId(), accName)) - ALE::Push(L, accName); - return 1; - } - - /** - * Returns the [Player]s completed quest count - * - * @return int32 questcount - */ - int GetCompletedQuestsCount(lua_State* L, Player* player) - { - uint32 count = player->GetRewardedQuestCount(); - - ALE::Push(L, count); - return 1; - } - - /** - * Returns the [Player]s [Corpse] object - * - * @return [Corpse] corpse - */ - int GetCorpse(lua_State* L, Player* player) - { - ALE::Push(L, player->GetCorpse()); - return 1; - } - - /** - * Returns the [Player]s database locale index - * - * @return int localeIndex - */ - int GetDbLocaleIndex(lua_State* L, Player* player) - { - ALE::Push(L, player->GetSession()->GetSessionDbLocaleIndex()); - return 1; - } - - /** - * Returns the [Player]s game client locale - * - * @return [LocaleConstant] locale - */ - int GetDbcLocale(lua_State* L, Player* player) - { - ALE::Push(L, player->GetSession()->GetSessionDbcLocale()); - return 1; - } - - /** - * Returns known taxi nodes (flight paths) that the player has unlocked. - * - * @return table nodes : A table containing the IDs of the known taxi nodes - */ - int GetKnownTaxiNodes(lua_State* L, Player* player) - { - if (!player) - return 0; - - lua_newtable(L); - - ByteBuffer data; - player->m_taxi.AppendTaximaskTo(data, false); - - for (uint8 i = 0; i < TaxiMaskSize; i++) - { - uint32 mask; - data >> mask; - - for (uint8 bit = 0; bit < 32; bit++) - { - if (mask & (1 << bit)) - { - uint32 nodeId = (i * 32) + bit + 1; - lua_pushinteger(L, nodeId); - lua_rawseti(L, -2, lua_rawlen(L, -2) + 1); - } - } - } - - return 1; - } - - /*int GetRecruiterId(lua_State* L, Player* player) - { - ALE::Push(L, player->GetSession()->GetRecruiterId()); - return 1; - }*/ - - /*int GetSelectedPlayer(lua_State* L, Player* player) - { - ALE::Push(L, player->GetSelectedPlayer()); - return 1; - }*/ - - /*int GetSelectedUnit(lua_State* L, Player* player) - { - ALE::Push(L, player->GetSelectedUnit()); - return 1; - }*/ - - /*int GetNearbyGameObject(lua_State* L, Player* player) - { - ALE::Push(L, ChatHandler(player->GetSession()).GetNearbyGameObject()); - return 1; - }*/ - - /** - * Locks the player controls and disallows all movement and casting. - * - * @param bool apply = true : lock if true and unlock if false - */ - int SetPlayerLock(lua_State* L, Player* player) - { - bool apply = ALE::CHECKVAL(L, 2, true); - - if (apply) - { - player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED | UNIT_FLAG_SILENCED); - player->SetClientControl(player, 0); - } - else - { - player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED | UNIT_FLAG_SILENCED); - player->SetClientControl(player, 1); - } - return 0; - } - - /** - * Sets the [Player]s login flag to the flag specified - * - * @param uint32 flag - */ - int SetAtLoginFlag(lua_State* L, Player* player) - { - uint32 flag = ALE::CHECKVAL(L, 2); - - player->SetAtLoginFlag((AtLoginFlags)flag); - return 0; - } - - /** - * Sets the [Player]s sheathe state to the state specified - * - * @param uint32 sheatheState - */ - int SetSheath(lua_State* L, Player* player) - { - uint32 sheathed = ALE::CHECKVAL(L, 2); - if (sheathed >= MAX_SHEATH_STATE) - return 0; - - player->SetSheath((SheathState)sheathed); - return 0; - } - - /** - * Sets the [Player]s intoxication level to the level specified - * - * @param uint8 drunkValue - */ - int SetDrunkValue(lua_State* L, Player* player) - { - uint8 newDrunkValue = ALE::CHECKVAL(L, 2); - - player->SetDrunkValue(newDrunkValue); - return 0; - } - - /** - * Sets the [Player]s faction standing to that of the race specified - * - * @param uint8 raceId - */ - int SetFactionForRace(lua_State* L, Player* player) - { - uint8 race = ALE::CHECKVAL(L, 2); - - player->SetFactionForRace(race); - return 0; - } - - /** - * Sets (increases) skill of the [Player] - * - * @param uint16 id - * @param uint16 step - * @param uint16 currVal - * @param uint16 maxVal - */ - int SetSkill(lua_State* L, Player* player) - { - uint16 id = ALE::CHECKVAL(L, 2); - uint16 step = ALE::CHECKVAL(L, 3); - uint16 currVal = ALE::CHECKVAL(L, 4); - uint16 maxVal = ALE::CHECKVAL(L, 5); - - player->SetSkill(id, currVal, maxVal, step); - return 0; - } - - /** - * Sets the [Player]s guild rank to the rank specified - * - * @param uint8 rank - */ - int SetGuildRank(lua_State* L, Player* player) // TODO: Move to Guild Methods - { - uint8 rank = ALE::CHECKVAL(L, 2); - - if (!player->GetGuildId()) - return 0; - - player->SetRank(rank); - return 0; - } - - /** - * Sets the [Player]s free talent points to the amount specified for the current spec - * - * @param uint32 talentPointAmt - */ - int SetFreeTalentPoints(lua_State* L, Player* player) - { - uint32 points = ALE::CHECKVAL(L, 2); - - player->SetFreeTalentPoints(points); - player->SendTalentsInfoData(false); - return 0; - } - - /** - * Sets the [Player]s reputation amount for the faction specified - * - * @param uint32 factionId - * @param int32 reputationValue - */ - int SetReputation(lua_State* L, Player* player) - { - uint32 faction = ALE::CHECKVAL(L, 2); - int32 value = ALE::CHECKVAL(L, 3); - - FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction); - player->GetReputationMgr().SetReputation(factionEntry, value); - return 0; - } - - /** - * Sets [Quest] state - * - * @param uint32 entry : entry of a quest - * @param uint32 status - */ - int SetQuestStatus(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - uint32 status = ALE::CHECKVAL(L, 3); - if (status >= MAX_QUEST_STATUS) - return 0; - - player->SetQuestStatus(entry, (QuestStatus)status); - return 0; - } - - /** - * Sets the [Player]s rest bonus to the amount specified - * - * @param float restBonus - */ - int SetRestBonus(lua_State* L, Player* player) - { - float bonus = ALE::CHECKVAL(L, 2); - - player->SetRestBonus(bonus); - return 0; - } - - /** - * Toggles whether the [Player] accepts whispers or not - * - * @param bool acceptWhispers = true - */ - int SetAcceptWhispers(lua_State* L, Player* player) - { - bool on = ALE::CHECKVAL(L, 2, true); - - player->SetAcceptWhispers(on); - return 0; - } - - /** - * Toggles PvP Death - * - * @param bool on = true - */ - int SetPvPDeath(lua_State* L, Player* player) - { - bool on = ALE::CHECKVAL(L, 2, true); - - player->SetPvPDeath(on); - return 0; - } - - /** - * Toggles whether the [Player] has GM visibility on or off - * - * @param bool gmVisible = true - */ - int SetGMVisible(lua_State* L, Player* player) - { - bool on = ALE::CHECKVAL(L, 2, true); - - player->SetGMVisible(on); - return 0; - } - - /** - * Sets the player's known taxi nodes (flight paths). - * - * @param table nodes : A table containing the taxi node IDs to set as known - */ - int SetKnownTaxiNodes(lua_State* L, Player* player) - { - if (!player) - return 0; - - if (!lua_istable(L, 2)) - return 0; - - lua_pushnil(L); - - while (lua_next(L, 2) != 0) - { - uint32 nodeId = luaL_checkinteger(L, -1); - - if (nodeId > 0) - player->m_taxi.SetTaximaskNode(nodeId); - - lua_pop(L, 1); - } - - return 0; - } - - /** - * Toggles whether the [Player] has taxi cheat enabled or not - * - * @param bool taxiCheat = true - */ - int SetTaxiCheat(lua_State* L, Player* player) - { - bool on = ALE::CHECKVAL(L, 2, true); - - player->SetTaxiCheater(on); - return 0; - } - - /** - * Toggle Blizz (GM) tag - * - * @param bool on = true - */ - int SetGMChat(lua_State* L, Player* player) - { - bool on = ALE::CHECKVAL(L, 2, true); - - player->SetGMChat(on); - return 0; - } - - /** - * Toggles the [Player]s GM mode on or off - * - * @param bool setGmMode = true - */ - int SetGameMaster(lua_State* L, Player* player) - { - bool on = ALE::CHECKVAL(L, 2, true); - - player->SetGameMaster(on); - return 0; - } - - /** - * Sets the [Player]s gender to gender specified - * - * - GENDER_MALE = 0 - * - GENDER_FEMALE = 1 - * - * @param [Gender] gender - */ - int SetGender(lua_State* L, Player* player) - { - uint32 _gender = ALE::CHECKVAL(L, 2); - - Gender gender; - switch (_gender) - { - case 0: - gender = GENDER_MALE; - break; - case 1: - gender = GENDER_FEMALE; - break; - default: - return luaL_argerror(L, 2, "valid Gender expected"); - } - - player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender); - player->SetByteValue(PLAYER_BYTES_3, 0, gender); - player->InitDisplayIds(); - return 0; - } - - /** - * Sets the [Player]s Arena Points to the amount specified - * - * @param uint32 arenaPoints - */ - int SetArenaPoints(lua_State* L, Player* player) - { - uint32 arenaP = ALE::CHECKVAL(L, 2); - player->SetArenaPoints(arenaP); - return 0; - } - - /** - * Sets the [Player]s Honor Points to the amount specified - * - * @param uint32 honorPoints - */ - int SetHonorPoints(lua_State* L, Player* player) - { - uint32 honorP = ALE::CHECKVAL(L, 2); - player->SetHonorPoints(honorP); - return 0; - } - - /** - * Sets the [Player]s amount of Lifetime Honorable Kills to the value specified - * - * @param uint32 honorableKills - */ - int SetLifetimeKills(lua_State* L, Player* player) - { - uint32 val = ALE::CHECKVAL(L, 2); - player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, val); - return 0; - } - - /** - * Sets the [Player]s amount of money to copper specified - * - * @param uint32 copperAmt - */ - int SetCoinage(lua_State* L, Player* player) - { - uint32 amt = ALE::CHECKVAL(L, 2); - player->SetMoney(amt); - return 0; - } - - /** - * Sets the [Player]s home location to the location specified - * - * @param float x : X Coordinate - * @param float y : Y Coordinate - * @param float z : Z Coordinate - * @param uint32 mapId : Map ID - * @param uint32 areaId : Area ID - */ - int SetBindPoint(lua_State* L, Player* player) - { - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 3); - float z = ALE::CHECKVAL(L, 4); - uint32 mapId = ALE::CHECKVAL(L, 5); - uint32 areaId = ALE::CHECKVAL(L, 6); - - WorldLocation loc(mapId, x, y, z); - player->SetHomebind(loc, areaId); - return 0; - } - - /** - * Adds the specified title to the [Player]s list of known titles - * - * @param uint32 titleId - */ - int SetKnownTitle(lua_State* L, Player* player) - { - uint32 id = ALE::CHECKVAL(L, 2); - CharTitlesEntry const* t = sCharTitlesStore.LookupEntry(id); - if (t) - player->SetTitle(t, false); - return 0; - } - - /** - * Adds the specified achievement to the [Player]s - * - * @param uint32 achievementid - */ - int SetAchievement(lua_State* L, Player* player) - { - uint32 id = ALE::CHECKVAL(L, 2); - AchievementEntry const* t = sAchievementStore.LookupEntry(id); - if (t) - player->CompletedAchievement(t); - return 0; - } - - /*int SetMovement(lua_State* L, Player* player) - { - int32 pType = ALE::CHECKVAL(L, 2); - - player->SetMovement((PlayerMovementType)pType); - return 0; - }*/ - - /** - * Reset the [Player]s completed achievements - */ - int ResetAchievements(lua_State* /*L*/, Player* player) - { - player->ResetAchievements(); - return 0; - } - - /** - * Shows the mailbox window to the player from specified guid. - * - * @param ObjectGuid guid = playerguid : guid of the mailbox window sender - */ - int SendShowMailBox(lua_State* L, Player* player) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2, player->GET_GUID()); - - player->GetSession()->SendShowMailBox(guid); - return 0; - } - - /** - * Adds or detracts from the [Player]s current Arena Points - * - * @param int32 amount - */ - int ModifyArenaPoints(lua_State* L, Player* player) - { - int32 amount = ALE::CHECKVAL(L, 2); - - player->ModifyArenaPoints(amount); - return 0; - } - - /** - * Adds or detracts from the [Player]s current Honor Points - * - * @param int32 amount - */ - int ModifyHonorPoints(lua_State* L, Player* player) - { - int32 amount = ALE::CHECKVAL(L, 2); - - player->ModifyHonorPoints(amount); - return 0; - } - - /** - * Saves the [Player] to the database - */ - int SaveToDB(lua_State* /*L*/, Player* player) - { - player->SaveToDB(false, false); - return 0; - } - - /** - * Sends a summon request to the player from the given summoner - * - * @param [Unit] summoner - */ - int SummonPlayer(lua_State* L, Player* player) - { - Unit* summoner = ALE::CHECKOBJ(L, 2); - - float x, y, z; - summoner->GetPosition(x,y,z); - player->SetSummonPoint(summoner->GetMapId(), x, y, z); - - WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4); - data << summoner->GET_GUID(); - data << uint32(summoner->GetZoneId()); - data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); - player->GetSession()->SendPacket(&data); - return 0; - } - - /** - * Mutes the [Player] for the amount of seconds specified - * - * @param uint32 muteTime - */ - int Mute(lua_State* L, Player* player) - { - uint32 muteseconds = ALE::CHECKVAL(L, 2); - /*const char* reason = luaL_checkstring(E, 2);*/ // Mangos does not have a reason field in database. - - time_t muteTime = GameTime::GetGameTime().count() + muteseconds; - player->GetSession()->m_muteTime = muteTime; - LoginDatabase.Execute("UPDATE account SET mutetime = {} WHERE id = {}", muteTime, player->GetSession()->GetAccountId()); - return 0; - } - - /** - * Rewards the given quest entry for the [Player] if he has completed it. - * - * @param uint32 entry : quest entry - */ - int RewardQuest(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - Quest const* quest = eObjectMgr->GetQuestTemplate(entry); - - // If player doesn't have the quest - if (!quest || player->GetQuestStatus(entry) != QUEST_STATUS_COMPLETE) - return 0; - - player->RewardQuest(quest, 0, player); - return 0; - } - - /** - * Sends an auction house window to the [Player] from the [Unit] specified - * - * @param [Unit] sender - */ - int SendAuctionMenu(lua_State* L, Player* player) - { - Unit* unit = ALE::CHECKOBJ(L, 2); - - AuctionHouseEntry const* ahEntry = AuctionHouseMgr::GetAuctionHouseEntryFromFactionTemplate(unit->GetFaction()); - if (!ahEntry) - return 0; - - WorldPacket data(MSG_AUCTION_HELLO, 12); - data << unit->GET_GUID(); - data << uint32(ahEntry->houseId); - data << uint8(1); - player->GetSession()->SendPacket(&data); - return 0; - } - - /** - * Sends a flightmaster window to the [Player] from the [Creature] specified - * - * @param [Creature] sender - */ - int SendTaxiMenu(lua_State* L, Player* player) - { - Creature* creature = ALE::CHECKOBJ(L, 2); - - player->GetSession()->SendTaxiMenu(creature); - return 0; - } - - /** - * Sends a spirit resurrection request to the [Player] - */ - int SendSpiritResurrect(lua_State* /*L*/, Player* player) - { - player->GetSession()->SendSpiritResurrect(); - return 0; - } - - /** - * Sends a tabard vendor window to the [Player] from the [WorldObject] specified - * - * @param [WorldObject] sender - */ - int SendTabardVendorActivate(lua_State* L, Player* player) - { - WorldObject* obj = ALE::CHECKOBJ(L, 2); - - player->GetSession()->SendTabardVendorActivate(obj->GET_GUID()); - return 0; - } - - /** - * Sends a bank window to the [Player] from the [WorldObject] specified. - * - * @param [WorldObject] sender - */ - int SendShowBank(lua_State* L, Player* player) - { - WorldObject* obj = ALE::CHECKOBJ(L, 2); - - player->GetSession()->SendShowBank(obj->GET_GUID()); - return 0; - } - - /** - * Sends a vendor window to the [Player] from the [WorldObject] specified. - * - * @param [WorldObject] sender - */ - int SendListInventory(lua_State* L, Player* player) - { - WorldObject* obj = ALE::CHECKOBJ(L, 2); - uint32 vendorId = ALE::CHECKVAL(L, 3, 0); - - player->GetSession()->SendListInventory(obj->GET_GUID(), vendorId); - return 0; - } - - /** - * Sends a trainer window to the [Player] from the [Creature] specified - * - * @param [Creature] sender - */ - int SendTrainerList(lua_State* L, Player* player) - { - Creature* obj = ALE::CHECKOBJ(L, 2); - - player->GetSession()->SendTrainerList(obj->GET_GUID()); - return 0; - } - - /** - * Sends a guild invitation from the [Player]s [Guild] to the [Player] object specified - * - * @param [Player] invitee - */ - int SendGuildInvite(lua_State* L, Player* player) - { - Player* plr = ALE::CHECKOBJ(L, 2); - - if (Guild* guild = player->GetGuild()) - guild->HandleInviteMember(player->GetSession(), plr->GetName()); - return 0; - } - - /** - * Sends an update for the world state to the [Player] - * - * @param uint32 field - * @param uint32 value - */ - int SendUpdateWorldState(lua_State* L, Player* player) - { - uint32 field = ALE::CHECKVAL(L, 2); - uint32 value = ALE::CHECKVAL(L, 3); - - player->SendUpdateWorldState(field, value); - return 0; - } - - /** - * Forces the [Player] to log out - * - * @param bool saveToDb = true - */ - int LogoutPlayer(lua_State* L, Player* player) - { - bool save = ALE::CHECKVAL(L, 2, true); - - player->GetSession()->LogoutPlayer(save); - return 0; - } - - /** - * Forcefully removes the [Player] from a [BattleGround] raid group - */ - int RemoveFromBattlegroundRaid(lua_State* /*L*/, Player* player) - { - player->RemoveFromBattlegroundOrBattlefieldRaid(); - return 0; - } - - /** - * Unbinds the [Player] from his instances except the one he currently is in. - * - * Difficulty is not used on classic. - * - * @param uint32 map = true - * @param uint32 difficulty = 0 - */ - int UnbindInstance(lua_State* L, Player* player) - { - uint32 map = ALE::CHECKVAL(L, 2); - uint32 difficulty = ALE::CHECKVAL(L, 3, 0); - - if (difficulty < MAX_DIFFICULTY) - sInstanceSaveMgr->PlayerUnbindInstance(player->GetGUID(), map, Difficulty(difficulty), true, player); - return 0; - } - - /** - * Unbinds the [Player] from his instances except the one he currently is in. - */ - int UnbindAllInstances(lua_State* /*L*/, Player* player) - { - for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) - { - const BoundInstancesMap& binds = sInstanceSaveMgr->PlayerGetBoundInstances(player->GetGUID(), Difficulty(i)); - for (BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end();) - { - if (itr->first != player->GetMapId()) - { - sInstanceSaveMgr->PlayerUnbindInstance(player->GetGUID(), itr->first, Difficulty(i), true, player); - itr = binds.begin(); - } - else - { - ++itr; - } - } - } - - return 0; - } - - /** - * Forces the [Player] to leave a [BattleGround] - * - * @param bool teleToEntry = true - */ - int LeaveBattleground(lua_State* L, Player* player) - { - (void)L; // ensure that the variable is referenced in order to pass compiler checks - player->LeaveBattleground(); - return 0; - } - - /** - * Repairs [Item] at specified position. - * - * @param uint16 position - * @param bool cost = true - * @param float discountMod = 1.0 - */ - int DurabilityRepair(lua_State* L, Player* player) - { - uint16 position = ALE::CHECKVAL(L, 2); - bool takeCost = ALE::CHECKVAL(L, 3, true); - float discountMod = ALE::CHECKVAL(L, 4, 1.0f); - - player->DurabilityRepair(position, takeCost, discountMod, false); - return 0; - } - - /** - * Repairs all [Item]s. - * - * @param bool takeCost = true - * @param float discountMod = 1.0 - * @param bool guidBank = false - */ - int DurabilityRepairAll(lua_State* L, Player* player) - { - bool takeCost = ALE::CHECKVAL(L, 2, true); - float discountMod = ALE::CHECKVAL(L, 3, 1.0f); - bool guildBank = ALE::CHECKVAL(L, 4, false); - - player->DurabilityRepairAll(takeCost, discountMod, guildBank); - return 0; - } - - /** - * Sets durability loss for an [Item] in the specified slot - * - * @param int32 slot - */ - int DurabilityPointLossForEquipSlot(lua_State* L, Player* player) - { - int32 slot = ALE::CHECKVAL(L, 2); - - if (slot >= EQUIPMENT_SLOT_START && slot < EQUIPMENT_SLOT_END) - player->DurabilityPointLossForEquipSlot((EquipmentSlots)slot); - return 0; - } - - /** - * Sets durability loss on all [Item]s equipped - * - * If inventory is true, sets durability loss for [Item]s in bags - * - * @param int32 points - * @param bool inventory = true - */ - int DurabilityPointsLossAll(lua_State* L, Player* player) - { - int32 points = ALE::CHECKVAL(L, 2); - bool inventory = ALE::CHECKVAL(L, 3, true); - - player->DurabilityPointsLossAll(points, inventory); - return 0; - } - - /** - * Sets durability loss for the specified [Item] - * - * @param [Item] item - * @param int32 points - */ - int DurabilityPointsLoss(lua_State* L, Player* player) - { - Item* item = ALE::CHECKOBJ(L, 2); - int32 points = ALE::CHECKVAL(L, 3); - - player->DurabilityPointsLoss(item, points); - return 0; - } - - /** - * Damages specified [Item] - * - * @param [Item] item - * @param double percent - */ - int DurabilityLoss(lua_State* L, Player* player) - { - Item* item = ALE::CHECKOBJ(L, 2); - double percent = ALE::CHECKVAL(L, 3); - - player->DurabilityLoss(item, percent); - return 0; - } - - /** - * Damages all [Item]s equipped. If inventory is true, damages [Item]s in bags - * - * @param double percent - * @param bool inventory = true - */ - int DurabilityLossAll(lua_State* L, Player* player) - { - double percent = ALE::CHECKVAL(L, 2); - bool inventory = ALE::CHECKVAL(L, 3, true); - - player->DurabilityLossAll(percent, inventory); - return 0; - } - - /** - * Kills the [Player] - */ - int KillPlayer(lua_State* /*L*/, Player* player) - { - player->KillPlayer(); - return 0; - } - - /** - * Forces the [Player] to leave a [Group] - */ - int RemoveFromGroup(lua_State* /*L*/, Player* player) - { - if (!player->GetGroup()) - return 0; - - player->RemoveFromGroup(); - return 0; - } - - /** - * Returns the [Player]s accumulated talent reset cost - * - * @return uint32 resetCost - */ - int ResetTalentsCost(lua_State* L, Player* player) - { - ALE::Push(L, player->resetTalentsCost()); - return 1; - } - - /** - * Resets the [Player]s talents - * - * @param bool noCost = true - */ - int ResetTalents(lua_State* L, Player* player) - { - bool no_cost = ALE::CHECKVAL(L, 2, true); - - player->resetTalents(no_cost); - player->SendTalentsInfoData(false); - return 0; - } - - /** - * Removes the [Spell] from the [Player] - * - * @param uint32 entry : entry of a [Spell] - */ - int RemoveSpell(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - player->removeSpell(entry, SPEC_MASK_ALL, false); - return 0; - } - - /** - * Clears the [Player]s combo points - */ - int ClearComboPoints(lua_State* /*L*/, Player* player) - { - player->ClearComboPoints(); - return 0; - } - - /** - * Adds combo points to the [Player] - * - * @param [Unit] target - * @param int8 count - */ - int AddComboPoints(lua_State* L, Player* player) - { - Unit* target = ALE::CHECKOBJ(L, 2); - int8 count = ALE::CHECKVAL(L, 3); - - player->AddComboPoints(target, count); - return 0; - } - - /** - * Gives [Quest] monster talked to credit - * - * @param uint32 entry : entry of a [Creature] - * @param [Creature] creature - */ - int TalkedToCreature(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - Creature* creature = ALE::CHECKOBJ(L, 3); - - player->TalkedToCreature(entry, creature->GET_GUID()); - return 0; - } - - /** - * Gives [Quest] monster killed credit - * - * @param uint32 entry : entry of a [Creature] - */ - int KilledMonsterCredit(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - player->KilledMonsterCredit(entry, player->GET_GUID()); - return 0; - } - - /** - * Completes a [Quest] if in a [Group] - * - * @param uint32 quest : entry of a quest - * @param [WorldObject] obj - */ - int GroupEventHappens(lua_State* L, Player* player) - { - uint32 questId = ALE::CHECKVAL(L, 2); - WorldObject* obj = ALE::CHECKOBJ(L, 3); - - player->GroupEventHappens(questId, obj); - return 0; - } - - /** - * Completes the [Quest] if a [Quest] area is explored, or completes the [Quest] - * - * @param uint32 quest : entry of a [Quest] - */ - int AreaExploredOrEventHappens(lua_State* L, Player* player) - { - uint32 questId = ALE::CHECKVAL(L, 2); - - player->AreaExploredOrEventHappens(questId); - return 0; - } - - /** - * Sets the given [Quest] entry failed for the [Player]. - * - * @param uint32 entry : entry of a [Quest] - */ - int FailQuest(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - player->FailQuest(entry); - return 0; - } - - /** - * Sets the given quest entry incomplete for the [Player]. - * - * @param uint32 entry : quest entry - */ - int IncompleteQuest(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - player->IncompleteQuest(entry); - return 0; - } - - /** - * Completes the given quest entry for the [Player] and tries to satisfy all quest requirements. - * - * The player should have the quest to complete it. - * - * @param uint32 entry : quest entry - */ - int CompleteQuest(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - Quest const* quest = eObjectMgr->GetQuestTemplate(entry); - - // If player doesn't have the quest - if (!quest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE) - return 0; - - // Add quest items for quests that require items - for (uint8 x = 0; x < QUEST_ITEM_OBJECTIVES_COUNT; ++x) - { - uint32 id = quest->RequiredItemId[x]; - uint32 count = quest->RequiredItemCount[x]; - - if (!id || !count) - continue; - - uint32 curItemCount = player->GetItemCount(id, true); - - ItemPosCountVec dest; - uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, id, count - curItemCount); - if (msg == EQUIP_ERR_OK) - { - Item* item = player->StoreNewItem(dest, id, true); - player->SendNewItem(item, count - curItemCount, true, false); - } - } - - // All creature/GO slain/cast (not required, but otherwise it will display "Creature slain 0/10") - for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) - { - int32 creature = quest->RequiredNpcOrGo[i]; - uint32 creatureCount = quest->RequiredNpcOrGoCount[i]; - - if (creature > 0) - { - if (CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature)) - for (uint16 z = 0; z < creatureCount; ++z) - player->KilledMonster(creatureInfo, ObjectGuid::Empty); - } - else if (creature < 0) - for (uint16 z = 0; z < creatureCount; ++z) - player->KillCreditGO(creature); - } - - - // If the quest requires reputation to complete - if (uint32 repFaction = quest->GetRepObjectiveFaction()) - { - uint32 repValue = quest->GetRepObjectiveValue(); - uint32 curRep = player->GetReputationMgr().GetReputation(repFaction); - if (curRep < repValue) - if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(repFaction)) - player->GetReputationMgr().SetReputation(factionEntry, repValue); - } - - // If the quest requires a SECOND reputation to complete - if (uint32 repFaction = quest->GetRepObjectiveFaction2()) - { - uint32 repValue2 = quest->GetRepObjectiveValue2(); - uint32 curRep = player->GetReputationMgr().GetReputation(repFaction); - if (curRep < repValue2) - if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(repFaction)) - player->GetReputationMgr().SetReputation(factionEntry, repValue2); - } - - // If the quest requires money - int32 ReqOrRewMoney = quest->GetRewOrReqMoney(); - if (ReqOrRewMoney < 0) - player->ModifyMoney(-ReqOrRewMoney); - - player->CompleteQuest(entry); - return 0; - } - - /** - * Tries to add the given quest entry for the [Player]. - * - * @param uint32 entry : quest entry - */ - int AddQuest(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - Quest const* quest = eObjectMgr->GetQuestTemplate(entry); - if (!quest) - return 0; - - // check item starting quest (it can work incorrectly if added without item in inventory) - ItemTemplateContainer const* itc = sObjectMgr->GetItemTemplateStore(); - ItemTemplateContainer::const_iterator result = find_if(itc->begin(), itc->end(), Finder(entry, &ItemTemplate::StartQuest)); - - if (result != itc->end()) - return 0; - - // ok, normal (creature/GO starting) quest - if (player->CanAddQuest(quest, true)) - player->AddQuestAndCheckCompletion(quest, NULL); - - return 0; - } - - /** - * Removes the given quest entry from the [Player]. - * - * @param uint32 entry : quest entry - */ - int RemoveQuest(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - Quest const* quest = eObjectMgr->GetQuestTemplate(entry); - - if (!quest) - return 0; - - // remove all quest entries for 'entry' from quest log - for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot) - { - uint32 logQuest = player->GetQuestSlotQuestId(slot); - if (logQuest == entry) - { - player->SetQuestSlot(slot, 0); - - // we ignore unequippable quest items in this case, its' still be equipped - player->TakeQuestSourceItem(logQuest, false); - - if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) - { - player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest(); - player->UpdatePvPState(); - } - } - } - - player->RemoveActiveQuest(entry, false); - player->RemoveRewardedQuest(entry); - return 0; - } - - /** - * Sends whisper text from the [Player] - * - * @param string text - * @param uint32 lang : language the [Player] will speak - * @param [Player] receiver : is the [Player] that will receive the whisper, if TrinityCore - * @param ObjectGuid guid : is the GUID of a [Player] that will receive the whisper, not TrinityCore - */ - int Whisper(lua_State* L, Player* player) - { - std::string text = ALE::CHECKVAL(L, 2); - uint32 lang = ALE::CHECKVAL(L, 3); - Player* receiver = ALE::CHECKOBJ(L, 4); - player->Whisper(text, (Language)lang, receiver); - return 0; - } - - /** - * Sends a text emote from the [Player] - * - * @param string emoteText - */ - int TextEmote(lua_State* L, Player* player) - { - std::string text = ALE::CHECKVAL(L, 2); - - player->TextEmote(text); - return 0; - } - - /** - * Sends yell text from the [Player] - * - * @param string text : text for the [Player] to yells - * @param uint32 lang : language the [Player] will speak - */ - int Yell(lua_State* L, Player* player) - { - std::string text = ALE::CHECKVAL(L, 2); - uint32 lang = ALE::CHECKVAL(L, 3); - player->Yell(text, (Language)lang); - return 0; - } - - /** - * Sends say text from the [Player] - * - * @param string text : text for the [Player] to say - * @param uint32 lang : language the [Player] will speak - */ - int Say(lua_State* L, Player* player) - { - std::string text = ALE::CHECKVAL(L, 2); - uint32 lang = ALE::CHECKVAL(L, 3); - player->Say(text, (Language)lang); - return 0; - } - - /** - * Gives the [Player] experience - * - * @param uint32 xp : experience to give - * @param [Unit] victim = nil - */ - int GiveXP(lua_State* L, Player* player) - { - uint32 xp = ALE::CHECKVAL(L, 2); - Unit* victim = ALE::CHECKOBJ(L, 3, false); - - player->GiveXP(xp, victim); - return 0; - } - - /** - * Toggle the [Player]s 'Do Not Disturb' flag - */ - int ToggleDND(lua_State* /*L*/, Player* player) - { - player->ToggleDND(); - return 0; - } - - /** - * Toggle the [Player]s 'Away From Keyboard' flag - */ - int ToggleAFK(lua_State* /*L*/, Player* player) - { - player->ToggleAFK(); - return 0; - } - - /** - * Equips the given item or item entry to the given slot. Returns the equipped item or nil. - * - * enum EquipmentSlots // 19 slots - * { - * EQUIPMENT_SLOT_START = 0, - * EQUIPMENT_SLOT_HEAD = 0, - * EQUIPMENT_SLOT_NECK = 1, - * EQUIPMENT_SLOT_SHOULDERS = 2, - * EQUIPMENT_SLOT_BODY = 3, - * EQUIPMENT_SLOT_CHEST = 4, - * EQUIPMENT_SLOT_WAIST = 5, - * EQUIPMENT_SLOT_LEGS = 6, - * EQUIPMENT_SLOT_FEET = 7, - * EQUIPMENT_SLOT_WRISTS = 8, - * EQUIPMENT_SLOT_HANDS = 9, - * EQUIPMENT_SLOT_FINGER1 = 10, - * EQUIPMENT_SLOT_FINGER2 = 11, - * EQUIPMENT_SLOT_TRINKET1 = 12, - * EQUIPMENT_SLOT_TRINKET2 = 13, - * EQUIPMENT_SLOT_BACK = 14, - * EQUIPMENT_SLOT_MAINHAND = 15, - * EQUIPMENT_SLOT_OFFHAND = 16, - * EQUIPMENT_SLOT_RANGED = 17, - * EQUIPMENT_SLOT_TABARD = 18, - * EQUIPMENT_SLOT_END = 19 - * }; - * - * enum InventorySlots // 4 slots - * { - * INVENTORY_SLOT_BAG_START = 19, - * INVENTORY_SLOT_BAG_END = 23 - * }; - * - * @proto equippedItem = (item, slot) - * @proto equippedItem = (entry, slot) - * @param [Item] item : item to equip - * @param uint32 entry : entry of the item to equip - * @param uint32 slot : equipment slot to equip the item to The slot can be [EquipmentSlots] or [InventorySlots] - * @return [Item] equippedItem : item or nil if equipping failed - */ - int EquipItem(lua_State* L, Player* player) - { - uint16 dest = 0; - Item* item = ALE::CHECKOBJ(L, 2, false); - uint32 slot = ALE::CHECKVAL(L, 3); - - if (slot >= INVENTORY_SLOT_BAG_END) - return 1; - - if (!item) - { - uint32 entry = ALE::CHECKVAL(L, 2); - item = Item::CreateItem(entry, 1, player); - if (!item) - return 1; - - InventoryResult result = player->CanEquipItem(slot, dest, item, false); - if (result != EQUIP_ERR_OK) - { - delete item; - return 1; - } - player->ItemAddedQuestCheck(entry, 1); - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, entry, 1); - } - else - { - InventoryResult result = player->CanEquipItem(slot, dest, item, false); - if (result != EQUIP_ERR_OK) - return 1; - player->RemoveItem(item->GetBagSlot(), item->GetSlot(), true); - } - - ALE::Push(L, player->EquipItem(dest, item, true)); - player->AutoUnequipOffhandIfNeed(); - return 1; - } - - /** - * Returns true if the player can equip the given [Item] or item entry to the given slot, false otherwise. - * - * @proto canEquip = (item, slot) - * @proto canEquip = (entry, slot) - * @param [Item] item : item to equip - * @param uint32 entry : entry of the item to equip - * @param uint32 slot : equipment slot to test - * @return bool canEquip - */ - int CanEquipItem(lua_State* L, Player* player) - { - Item* item = ALE::CHECKOBJ(L, 2, false); - uint32 slot = ALE::CHECKVAL(L, 3); - if (slot >= EQUIPMENT_SLOT_END) - { - ALE::Push(L, false); - return 1; - } - - if (!item) - { - uint32 entry = ALE::CHECKVAL(L, 2); - uint16 dest; - InventoryResult msg = player->CanEquipNewItem(slot, dest, entry, false); - if (msg != EQUIP_ERR_OK) - { - ALE::Push(L, false); - return 1; - } - } - else - { - uint16 dest; - InventoryResult msg = player->CanEquipItem(slot, dest, item, false); - if (msg != EQUIP_ERR_OK) - { - ALE::Push(L, false); - return 1; - } - } - ALE::Push(L, true); - return 1; - } - - /** - * Removes a title by ID from the [Player]s list of known titles - * - * @param uint32 titleId - */ - int UnsetKnownTitle(lua_State* L, Player* player) - { - uint32 id = ALE::CHECKVAL(L, 2); - CharTitlesEntry const* t = sCharTitlesStore.LookupEntry(id); - if (t) - player->SetTitle(t, true); - return 0; - } - - /** - * Advances all of the [Player]s weapon skills to the maximum amount available - */ - int AdvanceSkillsToMax(lua_State* /*L*/, Player* player) - { - player->UpdateSkillsToMaxSkillsForLevel(); - return 0; - } - - /** - * Advances all of the [Player]s skills to the amount specified - * - * @param uint32 skillStep - */ - int AdvanceAllSkills(lua_State* L, Player* player) - { - uint32 step = ALE::CHECKVAL(L, 2); - - if (!step) - return 0; - - for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i) - { - if (SkillLineEntry const* entry = sSkillLineStore.LookupEntry(i)) - { - if (entry->categoryId == SKILL_CATEGORY_LANGUAGES || entry->categoryId == SKILL_CATEGORY_GENERIC) - continue; - - if (player->HasSkill(entry->id)) - player->UpdateSkill(entry->id, step); - } - } - - return 0; - } - - /** - * Updates a skill for the [Player] and advances it by the specified step. - * - * @param uint32 skillId : the skill to update - * @param uint32 step : the step to advance the skill by - * @return bool success : true if the skill was updated successfully - */ - int AdvanceSkill(lua_State* L, Player* player) - { - uint32 _skillId = ALE::CHECKVAL(L, 2); - uint32 _step = ALE::CHECKVAL(L, 3); - bool success = false; - if (_skillId && _step && player->HasSkill(_skillId)) - { - success = player->UpdateSkill(_skillId, _step); - } - ALE::Push(L, success); - return 1; - } - - /** - * Teleports a [Player] to the location specified - * - * @param uint32 mappId - * @param float xCoord - * @param float yCoord - * @param float zCoord - * @param float orientation - */ - int Teleport(lua_State* L, Player* player) - { - uint32 mapId = ALE::CHECKVAL(L, 2); - float x = ALE::CHECKVAL(L, 3); - float y = ALE::CHECKVAL(L, 4); - float z = ALE::CHECKVAL(L, 5); - float o = ALE::CHECKVAL(L, 6); - - if (player->IsInFlight()) - { - player->GetMotionMaster()->MovementExpired(); - player->m_taxi.ClearTaxiDestinations(); - } - - ALE::Push(L, player->TeleportTo(mapId, x, y, z, o)); - return 1; - } - - /** - * Adds a specified number of lifetime honorable kills to the [Player]. - * - * @param [Player] player - * @param uint32 kills - */ - int AddLifetimeKills(lua_State* L, Player* player) - { - uint32 val = ALE::CHECKVAL(L, 2); - uint32 currentKills = player->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS); - player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, currentKills + val); - return 0; - } - - /** - * Adds the given amount of the specified item entry to the player. - * - * @param uint32 entry : entry of the item to add - * @param uint32 itemCount = 1 : amount of the item to add - * @return [Item] item : the item that was added or nil - */ - int AddItem(lua_State* L, Player* player) - { - uint32 itemId = ALE::CHECKVAL(L, 2); - uint32 itemCount = ALE::CHECKVAL(L, 3, 1); - - uint32 noSpaceForCount = 0; - ItemPosCountVec dest; - InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, itemCount, &noSpaceForCount); - if (msg != EQUIP_ERR_OK) - itemCount -= noSpaceForCount; - - if (itemCount == 0 || dest.empty()) - return 1; - - Item* item = player->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); - if (item) - player->SendNewItem(item, itemCount, true, false); - ALE::Push(L, item); - - return 1; - } - - /** - * Removes the given amount of the specified [Item] from the player. - * - * @proto (item, itemCount) - * @proto (entry, itemCount) - * @param [Item] item : item to remove - * @param uint32 entry : entry of the item to remove - * @param uint32 itemCount = 1 : amount of the item to remove - */ - int RemoveItem(lua_State* L, Player* player) - { - Item* item = ALE::CHECKOBJ(L, 2, false); - uint32 itemCount = ALE::CHECKVAL(L, 3); - if (!item) - { - uint32 itemId = ALE::CHECKVAL(L, 2); - player->DestroyItemCount(itemId, itemCount, true); - } - else - { - bool all = itemCount >= item->GetCount(); - player->DestroyItemCount(item, itemCount, true); - if (all) - ALE::CHECKOBJ(L, 2)->Invalidate(); - } - return 0; - } - - /** - * Removes specified amount of lifetime kills - * - * @param uint32 val : kills to remove - */ - int RemoveLifetimeKills(lua_State* L, Player* player) - { - uint32 val = ALE::CHECKVAL(L, 2); - uint32 currentKills = player->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS); - if (val > currentKills) - val = currentKills; - player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, currentKills - val); - return 0; - } - - /** - * Resets cooldown of the specified spell - * - * @param uint32 spellId - * @param bool update = true - */ - int ResetSpellCooldown(lua_State* L, Player* player) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - bool update = ALE::CHECKVAL(L, 3, true); - player->RemoveSpellCooldown(spellId, update); - return 0; - } - - /** - * Resets cooldown of the specified category - * - * @param uint32 category - * @param bool update = true - */ - int ResetTypeCooldowns(lua_State* L, Player* player) - { - uint32 category = ALE::CHECKVAL(L, 2); - bool update = ALE::CHECKVAL(L, 3, true); - (void)update; // ensure that the variable is referenced in order to pass compiler checks - - player->RemoveCategoryCooldown(category); - return 0; - } - - /** - * Resets all of the [Player]'s cooldowns - */ - int ResetAllCooldowns(lua_State* /*L*/, Player* player) - { - player->RemoveAllSpellCooldown(); - return 0; - } - - /** - * Sends a Broadcast Message to the [Player] - * - * @param string message - */ - int SendBroadcastMessage(lua_State* L, Player* player) - { - const char* message = ALE::CHECKVAL(L, 2); - if (std::string(message).length() > 0) - ChatHandler(player->GetSession()).SendSysMessage(message); - return 0; - } - - /** - * Sends an Area Trigger Message to the [Player] - * - * @param string message - */ - int SendAreaTriggerMessage(lua_State* L, Player* player) - { - std::string msg = ALE::CHECKVAL(L, 2); - if (msg.length() > 0) - player->GetSession()->SendAreaTriggerMessage("{}", msg.c_str()); - return 0; - } - - /** - * Sends a Notification to the [Player] - * - * @param string message - */ - int SendNotification(lua_State* L, Player* player) - { - std::string msg = ALE::CHECKVAL(L, 2); - if (msg.length() > 0) - ChatHandler(player->GetSession()).SendNotification("{}", msg); - return 0; - } - - /** - * Sends a [WorldPacket] to the [Player] - * - * @param [WorldPacket] packet - * @param bool selfOnly = true - */ - int SendPacket(lua_State* L, Player* player) - { - WorldPacket* data = ALE::CHECKOBJ(L, 2); - bool selfOnly = ALE::CHECKVAL(L, 3, true); - if (selfOnly) - player->GetSession()->SendPacket(data); - else - player->SendMessageToSet(data, true); - return 0; - } - - /** - * Sends addon message to the [Player] receiver - * - * @param string prefix - * @param string message - * @param [ChatMsg] channel - * @param [Player] receiver - * - */ - int SendAddonMessage(lua_State* L, Player* player) - { - std::string prefix = ALE::CHECKVAL(L, 2); - std::string message = ALE::CHECKVAL(L, 3); - uint8 channel = ALE::CHECKVAL(L, 4); - Player* receiver = ALE::CHECKOBJ(L, 5); - - std::string fullmsg = prefix + "\t" + message; - - WorldPacket data(SMSG_MESSAGECHAT, 100); - data << uint8(channel); - data << int32(LANG_ADDON); - data << player->GET_GUID(); - data << uint32(0); - data << receiver->GET_GUID(); - data << uint32(fullmsg.length() + 1); - data << fullmsg; - data << uint8(0); - receiver->GetSession()->SendPacket(&data); - return 0; - } - - /** - * Kicks the [Player] from the server - */ - int KickPlayer(lua_State* /*L*/, Player* player) - { - player->GetSession()->KickPlayer(); - return 0; - } - - /** - * Adds or subtracts from the [Player]s money in copper - * - * @param int32 copperAmt : negative to remove, positive to add - */ - int ModifyMoney(lua_State* L, Player* player) - { - int32 amt = ALE::CHECKVAL(L, 2); - - player->ModifyMoney(amt); - return 1; - } - - /** - * Teaches the [Player] the [Spell] specified by entry ID - * - * @param uint32 spellId - */ - int LearnSpell(lua_State* L, Player* player) - { - uint32 id = ALE::CHECKVAL(L, 2); - player->learnSpell(id); - return 0; - } - - /** - * Learn the [Player] the talent specified by talent_id and talentRank - * - * @param uint32 talent_id - * @param uint32 talentRank - */ - int LearnTalent(lua_State* L, Player* player) - { - uint32 id = ALE::CHECKVAL(L, 2); - uint32 rank = ALE::CHECKVAL(L, 3); - - player->LearnTalent(id, rank); - player->SendTalentsInfoData(false); - - return 0; - } - /** - * Run a chat command as if the player typed it into the chat - * - * @param string command: text to display in chat or console - */ - int RunCommand(lua_State* L, Player* player) - { - auto command = ALE::CHECKVAL(L, 2); - - // In _ParseCommands which is used below no leading . or ! is allowed for the command string. - if (command[0] == '.' || command[0] == '!') { - command = command.substr(1); - } - - auto handler = ChatHandler(player->GetSession()); - handler._ParseCommands(command); - - return 0; - } - - /** - * Adds a glyph specified by `glyphId` to the [Player]'s current talent specialization into the slot with the index `slotIndex` - * - * @param uint32 glyphId - * @param uint32 slotIndex - */ - int SetGlyph(lua_State* L, Player* player) - { - uint32 glyphId = ALE::CHECKVAL(L, 2); - uint32 slotIndex = ALE::CHECKVAL(L, 3); - - player->SetGlyph(slotIndex, glyphId, true); - player->SendTalentsInfoData(false); // Also handles GlyphData - - return 0; - } - - /** - * Returns the glyph ID in the specified glyph slot of the [Player]'s current talent specialization. - * - * @param [uint32] slotIndex - * @return [uint32] glyphId - */ - int GetGlyph(lua_State* L, Player* player) - { - auto slotIndex = ALE::CHECKVAL(L, 2); - ALE::Push(L,player->GetGlyph(slotIndex)); - return 1; - } - - /** - * Remove cooldowns on spells that have less than 10 minutes of cooldown from the [Player], similarly to when you enter an arena. - */ - int RemoveArenaSpellCooldowns(lua_State* /*L*/, Player* player) - { - player->RemoveArenaSpellCooldowns(); - return 0; - } - - /** - * Resurrects the [Player]. - * - * @param float healthPercent = 100.0f - * @param bool ressSickness = false - */ - int ResurrectPlayer(lua_State* L, Player* player) - { - float percent = ALE::CHECKVAL(L, 2, 100.0f); - bool sickness = ALE::CHECKVAL(L, 3, false); - player->ResurrectPlayer(percent, sickness); - player->SpawnCorpseBones(); - return 0; - } - - /** - * Adds a new item to the gossip menu shown to the [Player] on next call to [Player:GossipSendMenu]. - * - * sender and intid are numbers which are passed directly to the gossip selection handler. Internally they are partly used for the database gossip handling. - * code specifies whether to show a box to insert text to. The player inserted text is passed to the gossip selection handler. - * money specifies an amount of money the player needs to have to click the option. An error message is shown if the player doesn't have enough money. - * Note that the money amount is only checked client side and is not removed from the player either. You will need to check again in your code before taking action. - * - * See also: [Player:GossipSendMenu], [Player:GossipAddQuests], [Player:GossipComplete], [Player:GossipClearMenu] - * - * @param uint32 icon : number that specifies used icon - * @param string msg : label on the gossip item - * @param uint32 sender : number passed to gossip handlers - * @param uint32 intid : number passed to gossip handlers - * @param bool code = false : show text input on click if true - * @param string popup = nil : if non empty string, a popup with given text shown on click - * @param uint32 money = 0 : required money in copper - */ - int GossipMenuAddItem(lua_State* L, Player* player) - { - uint32 _icon = ALE::CHECKVAL(L, 2); - const char* msg = ALE::CHECKVAL(L, 3); - uint32 _sender = ALE::CHECKVAL(L, 4); - uint32 _intid = ALE::CHECKVAL(L, 5); - bool _code = ALE::CHECKVAL(L, 6, false); - const char* _promptMsg = ALE::CHECKVAL(L, 7, ""); - uint32 _money = ALE::CHECKVAL(L, 8, 0); - if (player->PlayerTalkClass->GetGossipMenu().GetMenuItemCount() < GOSSIP_MAX_MENU_ITEMS) - { - player->PlayerTalkClass->GetGossipMenu().AddMenuItem(-1, _icon, msg, _sender, _intid, _promptMsg, _money, - _code); - } - else - { - return luaL_error(L, "GossipMenuItem not added. Reached Max amount of possible GossipMenuItems in this GossipMenu"); - } - return 0; - } - - /** - * Closes the [Player]s currently open Gossip Menu. - * - * See also: [Player:GossipMenuAddItem], [Player:GossipAddQuests], [Player:GossipSendMenu], [Player:GossipClearMenu] - */ - int GossipComplete(lua_State* /*L*/, Player* player) - { - player->PlayerTalkClass->SendCloseGossip(); - return 0; - } - - /** - * Sends the current gossip items of the player to him as a gossip menu with header text from the given textId. - * - * If sender is a [Player] then menu_id is mandatory, otherwise it is not used for anything. - * menu_id is the ID used to trigger the OnGossipSelect registered for players. See [Global:RegisterPlayerGossipEvent] - * - * See also: [Player:GossipMenuAddItem], [Player:GossipAddQuests], [Player:GossipComplete], [Player:GossipClearMenu] - * - * @proto (npc_text, sender) - * @proto (npc_text, sender, menu_id) - * @param uint32 npc_text : entry ID of a header text in npc_text database table, common default is 100 - * @param [Object] sender : object acting as the source of the sent gossip menu - * @param uint32 menu_id : if sender is a [Player] then menu_id is mandatory - */ - int GossipSendMenu(lua_State* L, Player* player) - { - uint32 npc_text = ALE::CHECKVAL(L, 2); - Object* sender = ALE::CHECKOBJ(L, 3); - if (sender->GetTypeId() == TYPEID_PLAYER) - { - uint32 menu_id = ALE::CHECKVAL(L, 4); - player->PlayerTalkClass->GetGossipMenu().SetMenuId(menu_id); - } - player->PlayerTalkClass->SendGossipMenu(npc_text, sender->GET_GUID()); - return 0; - } - - /** - * Clears the [Player]s current gossip item list. - * - * See also: [Player:GossipMenuAddItem], [Player:GossipSendMenu], [Player:GossipAddQuests], [Player:GossipComplete] - * - * Note: This is needed when you show a gossip menu without using gossip hello or select hooks which do this automatically. - * Usually this is needed when using [Player] is the sender of a Gossip Menu. - */ - int GossipClearMenu(lua_State* /*L*/, Player* player) - { - player->PlayerTalkClass->ClearMenus(); - return 0; - } - - /** - * Attempts to start the taxi/flying to the given pathID - * - * @param uint32 pathId : pathId from DBC or [Global:AddTaxiPath] - */ - int StartTaxi(lua_State* L, Player* player) - { - uint32 pathId = ALE::CHECKVAL(L, 2); - - player->ActivateTaxiPathTo(pathId); - return 0; - } - - /** - * Sends POI to the location on your map - * - * @param float x - * @param float y - * @param uint32 icon : map icon to show - * @param uint32 flags - * @param uint32 data - * @param string iconText - */ - int GossipSendPOI(lua_State* L, Player* player) - { - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 3); - uint32 icon = ALE::CHECKVAL(L, 4); - uint32 flags = ALE::CHECKVAL(L, 5); - uint32 data = ALE::CHECKVAL(L, 6); - std::string iconText = ALE::CHECKVAL(L, 7); - - WorldPacket packet(SMSG_GOSSIP_POI, 4 + 4 + 4 + 4 + 4 + 10); - packet << flags; - packet << x; - packet << y; - packet << icon; - packet << data; - packet << iconText; - player->GetSession()->SendPacket(&packet); - return 0; - } - - /** - * Adds the gossip items to the [Player]'s gossip for the quests the given [WorldObject] can offer to the player. - * - * @param [WorldObject] source : a questgiver with quests - */ - int GossipAddQuests(lua_State* L, Player* player) - { - WorldObject* source = ALE::CHECKOBJ(L, 2); - - if (source->GetTypeId() == TYPEID_UNIT) - { - if (source->GetUInt32Value(UNIT_NPC_FLAGS) & UNIT_NPC_FLAG_QUESTGIVER) - player->PrepareQuestMenu(source->GET_GUID()); - } - else if (source->GetTypeId() == TYPEID_GAMEOBJECT) - { - if (source->ToGameObject()->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) - player->PrepareQuestMenu(source->GET_GUID()); - } - return 0; - } - - /** - * Shows a quest accepting window to the [Player] for the given quest. - * - * @param uint32 questId : entry of a quest - * @param bool activateAccept = true : auto finish the quest - */ - int SendQuestTemplate(lua_State* L, Player* player) - { - uint32 questId = ALE::CHECKVAL(L, 2); - bool activateAccept = ALE::CHECKVAL(L, 3, true); - - Quest const* quest = eObjectMgr->GetQuestTemplate(questId); - if (!quest) - return 0; - - player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GET_GUID(), activateAccept); - return 0; - } - - /** - * Converts [Player]'s corpse to bones - */ - int SpawnBones(lua_State* /*L*/, Player* player) - { - player->SpawnCorpseBones(); - return 0; - } - - /** - * Loots [Player]'s bones for insignia - * - * @param [Player] looter - */ - int RemovedInsignia(lua_State* L, Player* player) - { - Player* looter = ALE::CHECKOBJ(L, 2); - player->RemovedInsignia(looter); - return 0; - } - - /** - * Makes the [Player] invite another player to a group. - * - * @param [Player] invited : player to invite to group - * @return bool success : true if the player was invited to a group - */ - int GroupInvite(lua_State* L, Player* player) - { - Player* invited = ALE::CHECKOBJ(L, 2); - - if (invited->GetGroup() || invited->GetGroupInvite()) - { - ALE::Push(L, false); - return 1; - } - - // Get correct existing group if any - Group* group = player->GetGroup(); - if (group && group->isBGGroup()) - group = player->GetOriginalGroup(); - - bool success = false; - - // Try invite if group found - if (group) - success = !group->IsFull() && group->AddInvite(invited); - else - { - // Create new group if one not found - group = new Group; - success = group->AddLeaderInvite(player) && group->AddInvite(invited); - if (!success) - delete group; - } - - if (success) - { - WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size - data << uint8(1); // invited/already in group flag - data << player->GetName(); // max len 48 - data << uint32(0); // unk - data << uint8(0); // count - data << uint32(0); // unk - invited->GetSession()->SendPacket(&data); - } - - ALE::Push(L, success); - return 1; - } - - /** - * Creates a new [Group] with the creator [Player] as leader. - * - * @param [Player] invited : player to add to group - * @return [Group] createdGroup : the created group or nil - */ - int GroupCreate(lua_State* L, Player* player) - { - Player* invited = ALE::CHECKOBJ(L, 2); - - if (player->GetGroup() || invited->GetGroup()) - return 0; - - if (player->GetGroupInvite()) - player->UninviteFromGroup(); - if (invited->GetGroupInvite()) - invited->UninviteFromGroup(); - - // Try create new group - Group* group = new Group; - if (!group->AddLeaderInvite(player)) - { - delete group; - return 0; - } - - // Forming a new group, create it - if (!group->IsCreated()) - { - group->RemoveInvite(player); - group->Create(player); - sGroupMgr->AddGroup(group); - } - - if (!group->AddMember(invited)) - return 0; - group->BroadcastGroupUpdate(); - ALE::Push(L, group); - return 1; - } - - /** - * Starts a cinematic for the [Player] - * - * @param uint32 CinematicSequenceId : entry of a cinematic - */ - int SendCinematicStart(lua_State* L, Player* player) - { - uint32 CinematicSequenceId = ALE::CHECKVAL(L, 2); - - player->SendCinematicStart(CinematicSequenceId); - return 0; - } - - /** - * Starts a movie for the [Player] - * - * @param uint32 MovieId : entry of a movie - */ - int SendMovieStart(lua_State* L, Player* player) - { - uint32 MovieId = ALE::CHECKVAL(L, 2); - - player->SendMovieStart(MovieId); - return 0; - } - - /** - * Sets a setting value for the [Player] - * - * @param string source - * @param uint32 index - * @param uint32 value - */ - int UpdatePlayerSetting(lua_State* L, Player* player) - { - std::string source = ALE::CHECKVAL(L, 2); - uint32 index = ALE::CHECKVAL(L, 3); - uint32 value = ALE::CHECKVAL(L, 4); - player->UpdatePlayerSetting(source, index, value); - return 0; - } - - /** - * Gets a setting value for the [Player] - * - * @param string source - * @param uint32 index - */ - int GetPlayerSettingValue(lua_State* L, Player* player) - { - std::string source = ALE::CHECKVAL(L, 2); - uint32 index = ALE::CHECKVAL(L, 3); - uint32 value = player->GetPlayerSetting(source, index).value; - ALE::Push(L, value); - return 1; - } - - /** - * Returns the [Player] that is currently trading with this [Player] - * - * @return [Player] trader : the player trading, or nil - */ - int GetTrader(lua_State* L, Player* player) - { - ALE::Push(L, player->GetTrader()); - return 1; - } - - /** - * The [Player] sets the spell power - * - * @param int value : The spell power value to set - * @param bool apply = false : Whether the spell power should be applied or removed - */ - int SetSpellPower(lua_State* L, Player* player) - { - int value = ALE::CHECKVAL(L, 2); - bool apply = ALE::CHECKVAL(L, 3, false); - - player->ApplySpellPowerBonus(value, apply); - return 0; - } - - /*int BindToInstance(lua_State* L, Player* player) - { - player->BindToInstance(); - return 0; - }*/ - - /*int AddTalent(lua_State* L, Player* player) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - uint8 spec = ALE::CHECKVAL(L, 3); - bool learning = ALE::CHECKVAL(L, 4, true); - if (spec >= MAX_TALENT_SPECS) - ALE::Push(L, false); - else - ALE::Push(L, player->AddTalent(spellId, spec, learning)); - return 1; - }*/ - - /*int GainSpellComboPoints(lua_State* L, Player* player) - { - int8 count = ALE::CHECKVAL(L, 2); - - player->GainSpellComboPoints(count); - return 0; - }*/ - - /*int KillGOCredit(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - ObjectGuid guid = ALE::CHECKVAL(L, 3); - player->KillCreditGO(entry, guid); - return 0; - }*/ - - /*int KilledPlayerCredit(lua_State* L, Player* player) - { - player->KilledPlayerCredit(); - return 0; - }*/ - - /*int RemoveRewardedQuest(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - player->RemoveRewardedQuest(entry); - return 0; - }*/ - - /*int RemoveActiveQuest(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - - player->RemoveActiveQuest(entry); - return 0; - }*/ - - /*int SummonPet(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - float x = ALE::CHECKVAL(L, 3); - float y = ALE::CHECKVAL(L, 4); - float z = ALE::CHECKVAL(L, 5); - float o = ALE::CHECKVAL(L, 6); - uint32 petType = ALE::CHECKVAL(L, 7); - uint32 despwtime = ALE::CHECKVAL(L, 8); - - if (petType >= MAX_PET_TYPE) - return 0; - - player->SummonPet(entry, x, y, z, o, (PetType)petType, despwtime); - return 0; - }*/ - - /*int RemovePet(lua_State* L, Player* player) - { - int mode = ALE::CHECKVAL(L, 2, PET_SAVE_AS_DELETED); - bool returnreagent = ALE::CHECKVAL(L, 2, false); - - if (!player->GetPet()) - return 0; - - player->RemovePet(player->GetPet(), (PetSaveMode)mode, returnreagent); - return 0; - }*/ - - /** - * Set bonus talent count to a specific count for the [Player] - * - * @param uint32 value : bonus talent points - */ - int SetBonusTalentCount(lua_State* L, Player* player) - { - uint32 value = ALE::CHECKVAL(L, 2); - - player->SetBonusTalentCount(value); - return 0; - } - - /** - * Get bonus talents count from the [Player] - * - * @return uint32 bonusTalent - */ - int GetBonusTalentCount(lua_State* L, Player* player) - { - ALE::Push(L, player->GetBonusTalentCount()); - return 1; - } - - /** - * Returns the [Player] spells list - * - * @return table playerSpells - */ - int GetSpells(lua_State* L, Player* player) - { - std::list list; - lua_createtable(L, list.size(), 0); - int tbl = lua_gettop(L); - uint32 i = 0; - - PlayerSpellMap spellMap = player->GetSpellMap(); - for (PlayerSpellMap::const_iterator itr = spellMap.begin(); itr != spellMap.end(); ++itr) - { - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first); - ALE::Push(L, spellInfo->Id); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); - return 1; - } - - /** - * Add bonus talents count to the [Player] - * - * @param uint32 count = count of bonus talent - */ - int AddBonusTalent(lua_State* L, Player* player) - { - uint32 count = ALE::CHECKVAL(L, 2); - - player->AddBonusTalent(count); - return 0; - } - - /** - * Remove bonus talents count to the [Player] - * - * @param uint32 count = count of bonus talent - */ - int RemoveBonusTalent(lua_State* L, Player* player) - { - uint32 count = ALE::CHECKVAL(L, 2); - - player->RemoveBonusTalent(count); - return 0; - } - - /** - * Returns the [Player] homebind location. - * - * @return table homebind : a table containing the player's homebind information: - * - uint32 mapId: The ID of the map where the player is bound. - * - float x: The X coordinate of the homebind location. - * - float y: The Y coordinate of the homebind location. - * - float z: The Z coordinate of the homebind location. - */ - int GetHomebind(lua_State* L, Player* player) - { - lua_newtable(L); - lua_pushinteger(L, player->m_homebindMapId); - lua_setfield(L, -2, "mapId"); - - lua_pushnumber(L, player->m_homebindX); - lua_setfield(L, -2, "x"); - - lua_pushnumber(L, player->m_homebindY); - lua_setfield(L, -2, "y"); - - lua_pushnumber(L, player->m_homebindZ); - lua_setfield(L, -2, "z"); - - return 1; - } - - /** - * Teleports [Player] to a predefined location based on the teleport name. - * - * @param string tele : The name of the predefined teleport location. - */ - int TeleportTo(lua_State* L, Player* player) - { - std::string tele = ALE::CHECKVAL(L, 2); - const GameTele* game_tele = sObjectMgr->GetGameTele(tele); - - if (player->IsInFlight()) - { - player->GetMotionMaster()->MovementExpired(); - player->m_taxi.ClearTaxiDestinations(); - } - - player->TeleportTo(game_tele->mapId, game_tele->position_x, game_tele->position_y, game_tele->position_z, game_tele->orientation); - return 0; - } - - /** - * Returns the [Player]'s current [Pet], if any. - * - * @return [Pet] pet : the player's pet, or `nil` if no pet - */ - int GetPet(lua_State* L, Player* player) - { - ALE::Push(L, player->GetPet()); - return 1; - } - - /** - * Returns `true` if the [Player] is at maximum level, `false` otherwise. - * - * @return bool isMaxLevel - */ - int IsMaxLevel(lua_State* L, Player* player) - { - ALE::Push(L, player->IsMaxLevel()); - return 1; - } - - /** - * Summons a [Pet] at the specified location. - * - * @param uint32 entry : the creature entry ID to summon - * @param float x : X coordinate - * @param float y : Y coordinate - * @param float z : Z coordinate - * @param float ang : orientation angle - * @param [PetType] petType : the type of pet to summon - * @param uint32 duration = 0 : duration in milliseconds, 0 for permanent - * @param uint32 healthPct = 0 : initial health percentage - * @return [Pet] pet : the summoned pet, or `nil` if failed - */ - int SummonPet(lua_State* L, Player* player) - { - uint32 entry = ALE::CHECKVAL(L, 2); - float x = ALE::CHECKVAL(L, 3); - float y = ALE::CHECKVAL(L, 4); - float z = ALE::CHECKVAL(L, 5); - float ang = ALE::CHECKVAL(L, 6); - uint32 petType = ALE::CHECKVAL(L, 7); - uint32 duration = ALE::CHECKVAL(L, 8, 0); - uint32 healthPct = ALE::CHECKVAL(L, 9, 0); - - Pet* pet = player->SummonPet(entry, x, y, z, ang, static_cast(petType), Milliseconds(duration), healthPct); - ALE::Push(L, pet); - return 1; - } - - /** - * Returns the average item level of the [Player]'s equipment. - * - * @return float averageItemLevel - */ - int GetAverageItemLevel(lua_State* L, Player* player) - { - ALE::Push(L, player->GetAverageItemLevel()); - return 1; - } - - /** - * Creates a tamed [Pet] from a [Creature] or creature entry. - * - * Can be called with either: - * - `player:CreatePet(creatureEntry)` - creates pet from entry ID - * - `player:CreatePet(creature, spellID)` - tames existing creature - * - * @param uint32 creatureEntry : creature entry ID (first form) - * @param [Creature] creature : target creature to tame (second form) - * @param uint32 spellID = 0 : spell used for taming (second form) - * @return [Pet] pet : the created pet, or `nil` if failed - */ - int CreatePet(lua_State* L, Player* player) - { - if (lua_gettop(L) == 2) - { - uint32 creatureEntry = ALE::CHECKVAL(L, 2); - Pet* pet = player->CreatePet(creatureEntry); - ALE::Push(L, pet); - } - else - { - Creature* creatureTarget = ALE::CHECKOBJ(L, 2); - uint32 spellID = ALE::CHECKVAL(L, 3, 0); - Pet* pet = player->CreatePet(creatureTarget, spellID); - ALE::Push(L, pet); - } - return 1; - } - - /** - * Returns `true` if the [Player] has completed the daily quest, `false` otherwise. - * - * @param uint32 questId - * @return bool isDailyQuestDone - */ - int IsDailyQuestDone(lua_State* L, Player* player) - { - uint32 questId = ALE::CHECKVAL(L, 2); - ALE::Push(L, player->IsDailyQuestDone(questId)); - return 1; - } - - /** - * Temporarily unsummons the [Player]'s current [Pet]. - * - * The pet can be resummoned later. Used during teleportation, mounting, etc. - */ - int UnsummonPetTemporarily(lua_State* /*L*/, Player* player) - { - player->UnsummonPetTemporaryIfAny(); - return 0; - } - - /** - * Sets the specified player flag on the [Player]. - * - * @param uint32 flag : the player flag to set - */ - int SetPlayerFlag(lua_State* L, Player* player) - { - uint32 flag = ALE::CHECKVAL(L, 2); - player->SetPlayerFlag((PlayerFlags)flag); - return 0; - } - - /** - * Removes the specified [Pet] from the [Player]. - * - * @param [Pet] pet : the pet to remove - * @param [PetSaveMode] mode : how to handle pet removal - * @param bool returnReagent = false : if `true`, returns reagents used to summon - */ - int RemovePet(lua_State* L, Player* player) - { - Pet* pet = ALE::CHECKOBJ(L, 2); - uint32 mode = ALE::CHECKVAL(L, 3); - bool returnReagent = ALE::CHECKVAL(L, 4, false); - player->RemovePet(pet, static_cast(mode), returnReagent); - return 1; - } - - /** - * Removes the specified player flag from the [Player]. - * - * @param uint32 flag : the player flag to remove - */ - int RemovePlayerFlag(lua_State* L, Player* player) - { - uint32 flag = ALE::CHECKVAL(L, 2); - player->RemovePlayerFlag((PlayerFlags)flag); - return 0; - } - - /** - * Returns `true` if the [Player] can resurrect their [Pet] and returns `false` otherwise. - * - * @return bool canResurrect - */ - int CanPetResurrect(lua_State* L, Player* player) - { - ALE::Push(L, player->CanPetResurrect()); - return 1; - } - - /** - * Returns a random number between the specified minimum and maximum values. - * - * @param uint32 minimum : the minimum value - * @param uint32 maximum : the maximum value - * @return uint32 randomValue : a random number between min and max - */ - int DoRandomRoll(lua_State* L, Player* player) - { - uint32 minimum = ALE::CHECKVAL(L, 2); - uint32 maximum = ALE::CHECKVAL(L, 3); - ALE::Push(L, player->DoRandomRoll(minimum, maximum)); - return 1; - } - - /** - * Returns `true` if the [Player] is flagged for PvP, `false` otherwise. - * - * @return bool isPvP - */ - int IsPvP(lua_State* L, Player* player) - { - ALE::Push(L, player->IsPvP()); - return 1; - } - - /** - * Returns `true` if the [Player] is flagged for Free-for-all PvP, `false` otherwise. - * - * @return bool isFFAPvP - */ - int IsFFAPvP(lua_State* L, Player* player) - { - ALE::Push(L, player->IsFFAPvP()); - return 1; - } - - /** - * Returns `true` if the [Player] is using the Looking for Group system, `false` otherwise. - * - * @return bool isUsingLfg - */ - int IsUsingLfg(lua_State* L, Player* player) - { - ALE::Push(L, player->IsUsingLfg()); - return 1; - } - - /** - * Returns `true` if the [Player] is in a random LFG dungeon, `false` otherwise. - * - * @return bool inRandomLfgDungeon - */ - int InRandomLfgDungeon(lua_State* L, Player* player) - { - ALE::Push(L, player->inRandomLfgDungeon()); - return 1; - } - - /** - * Returns `true` if the [Player] can interact with the specified quest giver, `false` otherwise. - * - * @param [Object] questGiver : the quest giver object - * @return bool canInteract - */ - int CanInteractWithQuestGiver(lua_State* L, Player* player) - { - Object* questGiver = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->CanInteractWithQuestGiver(questGiver)); - return 1; - } - - /** - * Returns `true` if the [Player] can see the specified quest start, `false` otherwise. - * - * @param [Quest] quest : the quest to check - * @return bool canSeeStartQuest - */ - int CanSeeStartQuest(lua_State* L, Player* player) - { - Quest const* quest = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->CanSeeStartQuest(quest)); - return 1; - } - - /** - * Returns `true` if the [Player] has a [Pet] (active or stored) and returns `false` otherwise. - * - * @return bool hasExistingPet - */ - int IsExistPet(lua_State* L, Player* player) - { - ALE::Push(L, player->IsExistPet()); - return 1; - } - - /** - * Returns `true` if the [Player] can take the specified quest, `false` otherwise. - * - * @param [Quest] quest : the quest to check - * @param bool msg : whether to send error messages - * @return bool canTakeQuest - */ - int CanTakeQuest(lua_State* L, Player* player) - { - Quest const* quest = ALE::CHECKOBJ(L, 2); - bool msg = ALE::CHECKVAL(L, 3, true); - ALE::Push(L, player->CanTakeQuest(quest, msg)); - return 1; - } - - /** - * Resets the [Player]'s pet talents. - * - */ - int ResetPetTalents(lua_State* /*L*/, Player* player) - { - player->ResetPetTalents(); - return 0; - } - - /** - * Returns `true` if the [Player] can add the specified quest, `false` otherwise. - * - * @param [Quest] quest : the quest to check - * @param bool msg : whether to send error messages - * @return bool canAddQuest - */ - int CanAddQuest(lua_State* L, Player* player) - { - Quest const* quest = ALE::CHECKOBJ(L, 2); - bool msg = ALE::CHECKVAL(L, 3, true); - ALE::Push(L, player->CanAddQuest(quest, msg)); - return 1; - } - - /** - * Returns the barber shop cost for the specified style changes. - * - * @param uint8 newhairstyle : the new hair style - * @param uint8 newhaircolor : the new hair color - * @param uint8 newfacialhair : the new facial hair - * @return uint32 cost : the cost in copper - */ - int GetBarberShopCost(lua_State* L, Player* player) - { - uint8 newhairstyle = ALE::CHECKVAL(L, 2); - uint8 newhaircolor = ALE::CHECKVAL(L, 3); - uint8 newfacialhair = ALE::CHECKVAL(L, 4); - ALE::Push(L, player->GetBarberShopCost(newhairstyle, newhaircolor, newfacialhair)); - return 1; - } - - /** - * Returns the sight range of the [Player] for the specified target. - * - * @param [WorldObject] target : the target to check sight range for (optional) - * @return float sightRange - */ - int GetSightRange(lua_State* L, Player* player) - { - WorldObject* target = ALE::CHECKOBJ(L, 2, false); - ALE::Push(L, player->GetSightRange(target)); - return 1; - } - - /** - * Calculates reputation gain for the [Player]. - * - * @param uint32 source : reputation source - * @param uint32 creatureOrQuestLevel : creature or quest level - * @param float rep : base reputation - * @param uint32 faction : faction ID - * @param bool noQuestBonus : whether to skip quest bonus - * @return float reputationGain - */ - int CalculateReputationGain(lua_State* L, Player* player) - { - uint32 source = ALE::CHECKVAL(L, 2); - uint32 creatureOrQuestLevel = ALE::CHECKVAL(L, 3); - float rep = ALE::CHECKVAL(L, 4); - uint32 faction = ALE::CHECKVAL(L, 5); - bool noQuestBonus = ALE::CHECKVAL(L, 6, false); - - ALE::Push(L, player->CalculateReputationGain((ReputationSource)source, creatureOrQuestLevel, rep, faction, noQuestBonus)); - return 1; - } - - /** - * Applies environmental damage to the [Player]. - * - * @param uint32 type : environmental damage type - * @param uint32 damage : damage amount - * @return uint32 actualDamage : the actual damage dealt - */ - int EnvironmentalDamage(lua_State* L, Player* player) - { - uint32 type = ALE::CHECKVAL(L, 2); - uint32 damage = ALE::CHECKVAL(L, 3); - ALE::Push(L, player->EnvironmentalDamage((EnviromentalDamage)type, damage)); - return 1; - } - - /** - * Initializes taxi nodes for the [Player]'s current level. - */ - int InitTaxiNodesForLevel(lua_State* /*L*/, Player* player) - { - player->InitTaxiNodesForLevel(); - return 0; - } - - /** - * Learns a pet talent for the specified [Pet] of the [Player]. - * - * @param ObjectGuid petGuid : GUID of the pet to learn the talent for - * @param uint32 talentId : ID of the talent to learn - * @param uint32 talentRank : rank of the talent to learn - */ - int LearnPetTalent(lua_State* L, Player* player) - { - ObjectGuid petGuid = ALE::CHECKVAL(L, 2); - uint32 talentId = ALE::CHECKVAL(L, 3); - uint32 talentRank = ALE::CHECKVAL(L, 4); - player->LearnPetTalent(petGuid, talentId, talentRank); - return 0; - } - - /** - * Returns `true` if the [Player] has a title by bit index, `false` otherwise. - * - * @param uint32 bitIndex : the title bit index to check - * @return bool hasTitle - */ - int HasTitleByIndex(lua_State* L, Player* player) - { - uint32 bitIndex = ALE::CHECKVAL(L, 2); - ALE::Push(L, player->HasTitle(bitIndex)); - return 1; - } - - /** - * Returns `true` if the [Player] is at group reward distance from the target, `false` otherwise. - * - * @param [WorldObject] target : the target to check distance to - * @return bool isAtGroupRewardDistance - */ - int IsAtGroupRewardDistance(lua_State* L, Player* player) - { - WorldObject const* target = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->IsAtGroupRewardDistance(target)); - return 1; - } - - /** - * Returns `true` if the [Player] is at loot reward distance from the target, `false` otherwise. - * - * @param [WorldObject] target : the target to check distance to - * @return bool isAtLootRewardDistance - */ - int IsAtLootRewardDistance(lua_State* L, Player* player) - { - WorldObject const* target = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->IsAtLootRewardDistance(target)); - return 1; - } - - /** - * Abandons a quest from the [Player]'s quest log. - * - * @param uint32 questId : the quest entry ID to abandon - */ - int AbandonQuest(lua_State* L, Player* player) - { - uint32 questId = ALE::CHECKVAL(L, 2); - player->AbandonQuest(questId); - return 0; - } - - /** - * Returns `true` if the [Player] can tame exotic pets, and `false` otherwise. - * - * @return bool canTameExoticPets : `true` if the player can tame exotic pets, `false` otherwise - */ - int CanTameExoticPets(lua_State* L, Player* player) - { - ALE::Push(L, player->CanTameExoticPets()); - return 1; - } - - /** - * Returns the [Player]'s weapon proficiency flags. - * - * @return uint32 proficiencyFlags : bitmask of weapon proficiencies - */ - int GetWeaponProficiency(lua_State* L, Player* player) - { - ALE::Push(L, player->GetWeaponProficiency()); - return 1; - } - - /** - * Returns the temporary unsummoned pet number for the [Player]. - * - * @return uint32 petNumber : the temporary unsummoned pet number - */ - int GetTemporaryUnsummonedPetNumber(lua_State* L, Player* player) - { - ALE::Push(L, player->GetTemporaryUnsummonedPetNumber()); - return 1; - } - - /** - * Returns the [Player]'s armor proficiency flags. - * - * @return uint32 proficiencyFlags : bitmask of armor proficiencies - */ - int GetArmorProficiency(lua_State* L, Player* player) - { - ALE::Push(L, player->GetArmorProficiency()); - return 1; - } - - /** - * Sets the temporary unsummoned pet number for the [Player]. - * - * @param uint32 petNumber : the pet number to set - */ - int SetTemporaryUnsummonedPetNumber(lua_State* L, Player* player) - { - uint32 petNumber = ALE::CHECKVAL(L, 2); - player->SetTemporaryUnsummonedPetNumber(petNumber); - return 0; - } - - /** - * Adds weapon proficiency to the [Player]. - * - * @param uint32 flag : weapon proficiency flag to add - */ - int AddWeaponProficiency(lua_State* L, Player* player) - { - uint32 flag = ALE::CHECKVAL(L, 2); - player->AddWeaponProficiency(flag); - return 0; - } - - /** - * Resummons the [Player]'s pet if it was temporarily unsummoned. - * - */ - int ResummonPetTemporaryUnSummonedIfAny(lua_State* /*L*/, Player* player) - { - player->ResummonPetTemporaryUnSummonedIfAny(); - return 0; - } - - /** - * Adds armor proficiency to the [Player]. - * - * @param uint32 flag : armor proficiency flag to add - */ - int AddArmorProficiency(lua_State* L, Player* player) - { - uint32 flag = ALE::CHECKVAL(L, 2); - player->AddArmorProficiency(flag); - return 0; - } - - /** - * Returns `true` if the [Player] needs to temporarily unsummon their [Pet], and `false` otherwise. - * - * - * @return bool isPetNeedBeTemporaryUnsummoned : `true` if the pet needs to be temporarily unsummoned, `false` otherwise - */ - int IsPetNeedBeTemporaryUnsummoned(lua_State* L, Player* player) - { - ALE::Push(L, player->IsPetNeedBeTemporaryUnsummoned()); - return 1; - } - - /** - * Sets the [Player]'s ammo item. - * - * @param uint32 itemEntry : ammo item entry ID - */ - int SetAmmo(lua_State* L, Player* player) - { - uint32 itemEntry = ALE::CHECKVAL(L, 2); - player->SetAmmo(itemEntry); - return 0; - } - - /** - * Removes the [Player]'s ammo. - */ - int RemoveAmmo(lua_State* /*L*/, Player* player) - { - player->RemoveAmmo(); - return 0; - } - - /** - * Returns the [Player]'s ammo DPS. - * - * @return float ammoDPS : damage per second from ammo - */ - int GetAmmoDPS(lua_State* L, Player* player) - { - ALE::Push(L, player->GetAmmoDPS()); - return 1; - } - - /** - * Returns `true` if the [Player] can resummon a [Pet] with the specified spell ID, and `false` otherwise. - * - * @param uint32 spellId : the spell ID to check - * @return bool canResummon : `true` if the player can resummon the pet, `false` otherwise - */ - int CanResummonPet(lua_State* L, Player* player) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - ALE::Push(L, player->CanResummonPet(spellId)); - return 1; - } - - /** - * Returns the [Player]'s shield item. - * - * @return [Item] shield : the equipped shield or nil - */ - int GetShield(lua_State* L, Player* player) - { - ALE::Push(L, player->GetShield()); - return 1; - } - - /** - * Returns the last pet number for the [Player]. - * - * @return uint32 petNumber : the last pet number - */ - int GetLastPetNumber(lua_State* L, Player* player) - { - ALE::Push(L, player->GetLastPetNumber()); - return 1; - } - - /** - * Returns `true` if the [Player] can teleport, `false` otherwise. - * - * @return bool canTeleport - */ - int CanTeleport(lua_State* L, Player* player) - { - ALE::Push(L, player->CanTeleport()); - return 1; - } - - /** - * Sets the last pet number for the [Player]. - * - * @param uint32 petNumber : the pet number to set - */ - int SetLastPetNumber(lua_State* L, Player* player) - { - uint32 petNumber = ALE::CHECKVAL(L, 2); - player->SetLastPetNumber(petNumber); - return 0; - } - - /** - * Sets whether the [Player] can teleport. - * - * @param bool canTeleport : true to allow teleportation, false to disallow - */ - int SetCanTeleport(lua_State* L, Player* player) - { - bool canTeleport = ALE::CHECKVAL(L, 2); - player->SetCanTeleport(canTeleport); - return 0; - } - - /** - * Returns the spell ID of the [Player]'s last [Pet] summoning spell. - * - * @return uint32 petSpell : the pet spell ID - */ - int GetLastPetSpell(lua_State* L, Player* player) - { - ALE::Push(L, player->GetLastPetSpell()); - return 1; - } - - /** - * Returns the [Player]'s runes state for Death Knights. - * - * @return uint32 runesState : current runes state bitmask - */ - int GetRunesState(lua_State* L, Player* player) - { - ALE::Push(L, player->GetRunesState()); - return 1; - } - - /** - * Sets the spell ID of the [Player]'s last [Pet] summoning spell. - * - * @param uint32 petSpell : the pet spell ID to set - */ - int SetLastPetSpell(lua_State* L, Player* player) - { - uint32 petSpell = ALE::CHECKVAL(L, 2); - player->SetLastPetSpell(petSpell); - return 0; - } - - /** - * Returns `true` if the [Player] is a spectator, `false` otherwise. - * - * @return bool isSpectator - */ - int IsSpectator(lua_State* L, Player* player) - { - ALE::Push(L, player->IsSpectator()); - return 1; - } - - /** - * Sets the [Player] as spectator. - * - * @param bool isSpectator : true to set as spectator, false otherwise - */ - int SetIsSpectator(lua_State* L, Player* player) - { - bool isSpectator = ALE::CHECKVAL(L, 2); - player->SetIsSpectator(isSpectator); - return 0; - } - - /** - * Returns `true` if the [Player] can see Death Knight [Pet]s, and `false` otherwise. - * - * @return bool canSeeDKPet - */ - int CanSeeDKPet(lua_State* L, Player* player) - { - ALE::Push(L, player->CanSeeDKPet()); - return 1; - } - - /** - * Returns the [Player]'s current viewpoint target. - * - * @return [WorldObject] viewpoint : the object the player is viewing from - */ - int GetViewpoint(lua_State* L, Player* player) - { - ALE::Push(L, player->GetViewpoint()); - return 1; - } - - /** - * Sets whether the [Player] can see Death Knight [Pet]s. - * - * @param bool show : `true` to show DK pets, `false` to hide them - */ - int SetShowDKPet(lua_State* L, Player* player) - { - bool show = ALE::CHECKVAL(L, 2); - player->SetShowDKPet(show); - return 0; - } - - /** - * Sets the [Player]'s viewpoint to the specified target. - * - * @param [WorldObject] target : the object to view from - */ - int SetViewpoint(lua_State* L, Player* player) - { - WorldObject* target = ALE::CHECKOBJ(L, 2); - bool apply = ALE::CHECKVAL(L, 3, false); - player->SetViewpoint(target, apply); - return 0; - } - - /** - * Toggles instant flight mode for the [Player]. - */ - int ToggleInstantFlight(lua_State* /*L*/, Player* player) - { - player->ToggleInstantFlight(); - return 0; - } - - /** - * Returns the [Player]'s character creation time. - * - * @return uint32 creationTime : Unix timestamp of character creation - */ - int GetCreationTime(lua_State* L, Player* player) - { - ALE::Push(L, static_cast(player->GetCreationTime().count())); - return 1; - } - - /** - * Sets the [Player]'s character creation time. - * - * @param uint32 creationTime : Unix timestamp to set as creation time - */ - int SetCreationTime(lua_State* L, Player* player) - { - uint32 creationTime = ALE::CHECKVAL(L, 2); - player->SetCreationTime(Seconds(creationTime)); - return 0; - } - - /** - * Returns the [Player]'s dodge chance from agility. - * - * @return float dodgeChance : dodge percentage from agility stat - */ - int GetDodgeFromAgility(lua_State* L, Player* player) - { - float diminishing, nondiminishing; - player->GetDodgeFromAgility(diminishing, nondiminishing); - ALE::Push(L, diminishing + nondiminishing); - return 1; - } - - /** - * Returns the [Player]'s melee critical hit chance from agility. - * - * @return float critChance : melee crit percentage from agility stat - */ - int GetMeleeCritFromAgility(lua_State* L, Player* player) - { - ALE::Push(L, player->GetMeleeCritFromAgility()); - return 1; - } - - /** - * Returns the [Player]'s spell critical hit chance from intellect. - * - * @return float critChance : spell crit percentage from intellect stat - */ - int GetSpellCritFromIntellect(lua_State* L, Player* player) - { - ALE::Push(L, player->GetSpellCritFromIntellect()); - return 1; - } - - /** - * Returns an item from the [Player]'s inventory by slot. - * - * @param uint32 slot : inventory slot number - * @return [Item] item : the item in the specified slot or nil - */ - int GetInventoryItem(lua_State* L, Player* player) - { - uint32 slot = ALE::CHECKVAL(L, 2); - if (slot >= INVENTORY_SLOT_ITEM_END) - return 1; - ALE::Push(L, player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)); - return 1; - } - - /** - * Returns an item from the [Player]'s bank by slot. - * - * @param uint32 slot : bank slot number - * @return [Item] item : the item in the specified bank slot or nil - */ - int GetBankItem(lua_State* L, Player* player) - { - uint32 slot = ALE::CHECKVAL(L, 2); - if (slot >= BANK_SLOT_ITEM_END) - return 1; - ALE::Push(L, player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot + BANK_SLOT_ITEM_START)); - return 1; - } - - /** - * Returns the [Quest] ID for the quest in the specified quest log slot. - * - * @param uint16 slot : quest log slot - * @return uint32 questId : quest ID or 0 if slot is invalid - */ - int GetQuestSlotQuestId(lua_State* L, Player* player) - { - uint16 slot = ALE::CHECKVAL(L, 2); - if (slot > MAX_QUEST_LOG_SIZE) - return 0; - - ALE::Push(L, player->GetQuestSlotQuestId(slot)); - return 1; - } - - /** - * Sets whether the [Player] can fly. - * - * @param bool activate = false : true to enable flying, false to disable - */ - int SetCanFly(lua_State* L, Player* player) - { - bool activate = ALE::CHECKVAL(L, 2, false); - player->SetCanFly(activate); - return 0; - } - - /** - * Applies a rating modifier to the [Player]. - * - * @param int32 stat : combat rating type (see CombatRating enum) - * @param float value : rating value to apply - * @param bool apply = false : true to apply the modifier, false to remove it - * - * enum CombatRating // 24 stat - * { - * CR_WEAPON_SKILL = 0, - * CR_DEFENSE_SKILL = 1, - * CR_DODGE = 2, - * CR_PARRY = 3, - * CR_BLOCK = 4, - * CR_HIT_MELEE = 5, - * CR_HIT_RANGED = 6, - * CR_HIT_SPELL = 7, - * CR_CRIT_MELEE = 8, - * CR_CRIT_RANGED = 9, - * CR_CRIT_SPELL = 10, - * CR_HIT_TAKEN_MELEE = 11, - * CR_HIT_TAKEN_RANGED = 12, - * CR_HIT_TAKEN_SPELL = 13, - * CR_CRIT_TAKEN_MELEE = 14, - * CR_CRIT_TAKEN_RANGED = 15, - * CR_CRIT_TAKEN_SPELL = 16, - * CR_HASTE_MELEE = 17, - * CR_HASTE_RANGED = 18, - * CR_HASTE_SPELL = 19, - * CR_WEAPON_SKILL_MAINHAND = 20, - * CR_WEAPON_SKILL_OFFHAND = 21, - * CR_WEAPON_SKILL_RANGED = 22, - * CR_EXPERTISE = 23, - * CR_ARMOR_PENETRATION = 24 - * }; - * - */ - - int ApplyRatingMod(lua_State* L, Player* player) - { - int32 stat = ALE::CHECKVAL(L, 2); - - float value = ALE::CHECKVAL(L, 3); - bool apply = ALE::CHECKVAL(L, 4, false); - - player->ApplyRatingMod(CombatRating(stat), value, apply); - return 0; - } -}; -#endif - diff --git a/src/LuaEngine/methods/QuestMethods.h b/src/LuaEngine/methods/QuestMethods.h deleted file mode 100644 index 7969cad751..0000000000 --- a/src/LuaEngine/methods/QuestMethods.h +++ /dev/null @@ -1,179 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef QUESTMETHODS_H -#define QUESTMETHODS_H - -/*** - * Represents a quest in the game, including its objectives, rewards, and conditions. - * - * Inherits all methods from: none - */ -namespace LuaQuest -{ - /** - * Returns 'true' if the [Quest] has the specified flag, false otherwise. - * Below flags are based off of 3.3.5a. Subject to change. - * - *
-     * enum QuestFlags
-     * {
-     *     // Flags used at server and sent to client
-     *     QUEST_FLAGS_NONE                    = 0x0,
-     *     QUEST_FLAGS_STAY_ALIVE              = 0x1,       // Not used currently
-     *     QUEST_FLAGS_PARTY_ACCEPT            = 0x2,       // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT
-     *     QUEST_FLAGS_EXPLORATION             = 0x4,       // Not used currently
-     *     QUEST_FLAGS_SHARABLE                = 0x8,       // Can be shared: Player::CanShareQuest()
-     *     QUEST_FLAGS_HAS_CONDITION           = 0x10,      // Not used currently
-     *     QUEST_FLAGS_HIDE_REWARD_POI         = 0x20,      // Not used currently: Unsure of content
-     *     QUEST_FLAGS_RAID                    = 0x40,      // Not used currently
-     *     QUEST_FLAGS_TBC                     = 0x80,      // Not used currently: Available if TBC expansion enabled only
-     *     QUEST_FLAGS_NO_MONEY_FROM_XP        = 0x100,     // Not used currently: Experience is not converted to gold at max level
-     *     QUEST_FLAGS_HIDDEN_REWARDS          = 0x200,     // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE))
-     *     QUEST_FLAGS_TRACKING                = 0x400,     // These quests are automatically rewarded on quest complete and they will never appear in quest log client side.
-     *     QUEST_FLAGS_DEPRECATE_REPUTATION    = 0x800,     // Not used currently
-     *     QUEST_FLAGS_DAILY                   = 0x1000,    // Used to know quest is Daily one
-     *     QUEST_FLAGS_FLAGS_PVP               = 0x2000,    // Having this quest in log forces PvP flag
-     *     QUEST_FLAGS_UNAVAILABLE             = 0x4000,    // Used on quests that are not generically available
-     *     QUEST_FLAGS_WEEKLY                  = 0x8000,
-     *     QUEST_FLAGS_AUTOCOMPLETE            = 0x10000,   // auto complete
-     *     QUEST_FLAGS_DISPLAY_ITEM_IN_TRACKER = 0x20000,   // Displays usable item in quest tracker
-     *     QUEST_FLAGS_OBJ_TEXT                = 0x40000,   // use Objective text as Complete text
-     *     QUEST_FLAGS_AUTO_ACCEPT             = 0x80000,   // The client recognizes this flag as auto-accept. However, NONE of the current quests (3.3.5a) have this flag. Maybe blizz used to use it, or will use it in the future.
-     *
-     *     // ... 4.x added flags up to 0x80000000 - all unknown for now
-     * };
-     * 
- * - * @param [QuestFlags] flag : all available flags can be seen above - * @return bool hasFlag - */ - int HasFlag(lua_State* L, Quest* quest) - { - uint32 flag = ALE::CHECKVAL(L, 2); - ALE::Push(L, quest->HasFlag(flag)); - return 1; - } - - /** - * Returns 'true' if the [Quest] is a daily quest, false otherwise. - * - * @return bool isDaily - */ - int IsDaily(lua_State* L, Quest* quest) - { - ALE::Push(L, quest->IsDaily()); - return 1; - } - - /** - * Returns 'true' if the [Quest] is repeatable, false otherwise. - * - * @return bool isRepeatable - */ - int IsRepeatable(lua_State* L, Quest* quest) - { - ALE::Push(L, quest->IsRepeatable()); - return 1; - } - - /** - * Returns entry ID of the [Quest]. - * - * @return uint32 entryId - */ - int GetId(lua_State* L, Quest* quest) - { - ALE::Push(L, quest->GetQuestId()); - return 1; - } - - /** - * Returns the [Quest]'s level. - * - * @return uint32 level - */ - int GetLevel(lua_State* L, Quest* quest) - { - ALE::Push(L, quest->GetQuestLevel()); - return 1; - } - - /** - * Returns the minimum level required to pick up the [Quest]. - * - * @return uint32 minLevel - */ - int GetMinLevel(lua_State* L, Quest* quest) - { - ALE::Push(L, quest->GetMinLevel()); - return 1; - } - - /** - * Returns the next [Quest] entry ID. - * - * @return int32 entryId - */ - int GetNextQuestId(lua_State* L, Quest* quest) - { - ALE::Push(L, quest->GetNextQuestId()); - return 1; - } - - /** - * Returns the previous [Quest] entry ID. - * - * @return int32 entryId - */ - int GetPrevQuestId(lua_State* L, Quest* quest) - { - ALE::Push(L, quest->GetPrevQuestId()); - return 1; - } - - /** - * Returns the next [Quest] entry ID in the specific [Quest] chain. - * - * @return int32 entryId - */ - int GetNextQuestInChain(lua_State* L, Quest* quest) - { - ALE::Push(L, quest->GetNextQuestInChain()); - return 1; - } - - /** - * Returns the [Quest]'s flags. - * - * @return [QuestFlags] flags - */ - int GetFlags(lua_State* L, Quest* quest) - { - ALE::Push(L, quest->GetFlags()); - return 1; - } - - /** - * Returns the [Quest]'s type. - * - * TODO: Document types available. - * - * @return uint32 type - */ - int GetType(lua_State* L, Quest* quest) - { - ALE::Push(L, quest->GetType()); - return 1; - } - - /*int GetMaxLevel(lua_State* L, Quest* quest) - { - ALE::Push(L, quest->GetMaxLevel()); - return 1; - }*/ -}; -#endif diff --git a/src/LuaEngine/methods/RollMethods.h b/src/LuaEngine/methods/RollMethods.h deleted file mode 100644 index fdcbd0bb36..0000000000 --- a/src/LuaEngine/methods/RollMethods.h +++ /dev/null @@ -1,219 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef ROLLMETHODS_H -#define ROLLMETHODS_H - -#include "Group.h" - -/*** - * Represents a group loot roll session for an item, including player votes and roll statistics. - * - * Provides access to the item being rolled, player vote types, and counts of each roll type (Need, Greed, Pass). - * - * Inherits all methods from: none - */ -namespace LuaRoll -{ - /** - * Returns the rolled [Item]'s GUID. - * - * @return ObjectGuid guid - */ - int GetItemGUID(lua_State* L, Roll* roll) - { - ALE::Push(L, roll->itemGUID.GetCounter()); - return 1; - } - - /** - * Returns the rolled [Item]'s entry. - * - * @return uint32 entry - */ - int GetItemId(lua_State* L, Roll* roll) - { - ALE::Push(L, roll->itemid); - return 1; - } - - /** - * Returns the rolled [Item]'s random property ID. - * - * @return int32 randomPropId - */ - int GetItemRandomPropId(lua_State* L, Roll* roll) - { - ALE::Push(L, roll->itemRandomPropId); - return 1; - } - - /** - * Returns the rolled [Item]'s random suffix ID. - * - * @return uint32 randomSuffix - */ - int GetItemRandomSuffix(lua_State* L, Roll* roll) - { - ALE::Push(L, roll->itemRandomSuffix); - return 1; - } - - /** - * Returns the rolled [Item]'s count. - * - * @return uint8 count - */ - int GetItemCount(lua_State* L, Roll* roll) - { - ALE::Push(L, roll->itemCount); - return 1; - } - - /** - * Returns the vote type for a [Player] on this [Roll]. - * See [Roll:GetPlayerVoteGUIDs] to obtain the GUIDs of the [Player]s who rolled. - * - *
-     * enum RollVote
-     * {
-     *     PASS              = 0,
-     *     NEED              = 1,
-     *     GREED             = 2,
-     *     DISENCHANT        = 3,
-     *     NOT_EMITED_YET    = 4,
-     *     NOT_VALID         = 5
-     * };
-     * 
- * - * @param ObjectGuid guid - * @return [RollVote] vote - */ - int GetPlayerVote(lua_State* L, Roll* roll) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - - bool found = false; - for (std::pair& pair : roll->playerVote) - { - if (pair.first == guid) - { - ALE::Push(L, pair.second); - found = true; - } - } - - if (!found) - { - ALE::Push(L); - } - - return 1; - } - - /** - * Returns the GUIDs of the [Player]s who rolled. - * See [Roll:GetPlayerVote] to obtain the vote type of a [Player]. - * - * @return table guids - */ - int GetPlayerVoteGUIDs(lua_State* L, Roll* roll) - { - lua_newtable(L); - int table = lua_gettop(L); - uint32 i = 1; - for (std::pair& pair : roll->playerVote) - { - ALE::Push(L, pair.first); - lua_rawseti(L, table, i); - ++i; - } - - lua_settop(L, table); // push table to top of stack - return 1; - } - - /** - * Returns the total number of players who rolled. - * - * @return uint8 playersCount - */ - int GetTotalPlayersRolling(lua_State* L, Roll* roll) - { - ALE::Push(L, roll->totalPlayersRolling); - return 1; - } - - /** - * Returns the total number of players who rolled need. - * - * @return uint8 playersCount - */ - int GetTotalNeed(lua_State* L, Roll* roll) - { - ALE::Push(L, roll->totalNeed); - return 1; - } - - /** - * Returns the total number of players who rolled greed. - * - * @return uint8 playersCount - */ - int GetTotalGreed(lua_State* L, Roll* roll) - { - ALE::Push(L, roll->totalGreed); - return 1; - } - - /** - * Returns the total number of players who passed. - * - * @return uint8 playersCount - */ - int GetTotalPass(lua_State* L, Roll* roll) - { - ALE::Push(L, roll->totalPass); - return 1; - } - - /** - * Returns the rolled [Item]'s slot in the loot window. - * - * @return uint8 slot - */ - int GetItemSlot(lua_State* L, Roll* roll) - { - ALE::Push(L, roll->itemSlot); - return 1; - } - - /** - * Returns the mask applied to this [Roll]. - * - *
-     * enum RollMask
-     * {
-     *     ROLL_FLAG_TYPE_PASS                 = 0x01,
-     *     ROLL_FLAG_TYPE_NEED                 = 0x02,
-     *     ROLL_FLAG_TYPE_GREED                = 0x04,
-     *     ROLL_FLAG_TYPE_DISENCHANT           = 0x08,
-     * 
-     *     ROLL_ALL_TYPE_NO_DISENCHANT         = 0x07,
-     *     ROLL_ALL_TYPE_MASK                  = 0x0F
-     * };
-     * 
- * - * @return [RollMask] rollMask - */ - int GetRollVoteMask(lua_State* L, Roll* roll) - { - ALE::Push(L, roll->rollVoteMask); - return 1; - } -} - -#endif diff --git a/src/LuaEngine/methods/SpellEntryMethods.h b/src/LuaEngine/methods/SpellEntryMethods.h deleted file mode 100644 index 615c2e50e4..0000000000 --- a/src/LuaEngine/methods/SpellEntryMethods.h +++ /dev/null @@ -1,2405 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef SPELLENTRYMETHODS_H -#define SPELLENTRYMETHODS_H - -/*** - * Represents spell data loaded from the DBCs, including effects, costs, attributes, and requirements. - * - * Used for inspecting the properties of any spell in the game, such as mana cost, targets, or effects. - * - * Inherits all methods from: none - */ -namespace LuaSpellEntry -{ - /** - * Returns the ID of the [SpellEntry]. - * - * @return uint32 id - */ - int GetId(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->Id); - return 1; - } - - /** - * Returns the category ID for the [SpellEntry]. - * - * @return uint32 categoryId - */ - int GetCategory(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->Category); - return 1; - } - - /** - * Returns the dispel ID for the [SpellEntry]. - * - * @return uint32 dispelId - */ - int GetDispel(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->Dispel); - return 1; - } - - /** - * Returns the mechanic ID for the [SpellEntry]. - * - * @return uint32 mechanicId - */ - int GetMechanic(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->Mechanic); - return 1; - } - - /** - * Returns the attribute bitflags for the [SpellEntry]. - * - * @return uint32 attribute : bitmask, but returned as uint32 - */ - int GetAttributes(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->Attributes); - return 1; - } - - /** - * Returns the attributeEx bitflags for the [SpellEntry]. - * - * @return uint32 attributeEx : bitmask, but returned as uint32 - */ - int GetAttributesEx(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->AttributesEx); - return 1; - } - - /** - * Returns the attributeEx2 bitflags for the [SpellEntry]. - * - * @return uint32 attributeEx2 : bitmask, but returned as uint32 - */ - int GetAttributesEx2(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->AttributesEx2); - return 1; - } - - /** - * Returns the attributeEx3 bitflags for the [SpellEntry]. - * - * @return uint32 attributeEx3 : bitmask, but returned as uint32 - */ - int GetAttributesEx3(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->AttributesEx3); - return 1; - } - - /** - * Returns the attributeEx4 bitflags for the [SpellEntry]. - * - * @return uint32 attributeEx4 : bitmask, but returned as uint32 - */ - int GetAttributesEx4(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->AttributesEx4); - return 1; - } - - /** - * Returns the attributeEx5 bitflags for the [SpellEntry]. - * - * @return uint32 attributeEx5 : bitmask, but returned as uint32 - */ - int GetAttributesEx5(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->AttributesEx5); - return 1; - } - - /** - * Returns the attributeEx6 bitflags for the [SpellEntry]. - * - * @return uint32 attributeEx6 : bitmask, but returned as uint32 - */ - int GetAttributesEx6(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->AttributesEx6); - return 1; - } - - /** - * Returns the attributeEx7 bitflags for the [SpellEntry]. - * - * @return uint32 attributeEx7 : bitmask, but returned as uint32 - */ - int GetAttributesEx7(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->AttributesEx7); - return 1; - } - - /** - * Returns the stance bitflags for the [SpellEntry]. - * - * @return uint32 stance : bitmask, but returned as uint32 - */ - int GetStances(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->Stances); - return 1; - } - - /** - * Returns the stance restriction bitmask for which the [SpellEntry] cannot be used. - * - * This mask indicates which shapeshift forms (stances) prevent the spell from being cast. - * - * @return uint32 stancesNotMask - */ - int GetStancesNot(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->StancesNot); - return 1; - } - - /** - * Returns the target bitmasks for the [SpellEntry]. - * - * @return uint32 target : bitmasks, but returned as uint32. - */ - int GetTargets(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->Targets); - return 1; - } - - /** - * Returns the target creature type bitmasks for the [SpellEntry]. - * - * @return uint32 targetCreatureType : bitmasks, but returned as uint32. - */ - int GetTargetCreatureType(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->TargetCreatureType); - return 1; - } - - /** - * Returns the SpellFocus ID required to cast this [SpellEntry]. - * - * Some spells require proximity to a specific game object (e.g., a brazier or altar). - * - * @return uint32 spellFocusId - */ - int GetRequiresSpellFocus(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->RequiresSpellFocus); - return 1; - } - - /** - * Returns the facing flags for this [SpellEntry]. - * - * Indicates whether the caster must be facing the target or meet other orientation constraints. - * - * @return uint32 facingFlags - */ - int GetFacingCasterFlags(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->FacingCasterFlags); - return 1; - } - - /** - * Returns the required caster aura state for this [SpellEntry]. - * - * The spell can only be cast if the caster has a specific aura state active. - * - * @return uint32 casterAuraState - */ - int GetCasterAuraState(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->CasterAuraState); - return 1; - } - - /** - * Returns the required target aura state for this [SpellEntry]. - * - * The spell can only be cast if the target has a specific aura state active. - * - * @return uint32 targetAuraState - */ - int GetTargetAuraState(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->TargetAuraState); - return 1; - } - - /** - * Returns the forbidden caster aura state for this [SpellEntry]. - * - * The spell cannot be cast if the caster has this aura state active. - * - * @return uint32 casterAuraStateNot - */ - int GetCasterAuraStateNot(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->CasterAuraStateNot); - return 1; - } - - /** - * Returns the forbidden target aura state for this [SpellEntry]. - * - * The spell cannot be cast if the target has this aura state active. - * - * @return uint32 targetAuraStateNot - */ - int GetTargetAuraStateNot(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->TargetAuraStateNot); - return 1; - } - - /** - * Returns the required aura spell ID that must be on the caster. - * - * The spell can only be cast if the caster has an aura from this spell. - * - * @return uint32 casterAuraSpellId - */ - int GetCasterAuraSpell(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->CasterAuraSpell); - return 1; - } - - /** - * Returns the required aura spell ID that must be on the target. - * - * The spell can only be cast if the target has an aura from this spell. - * - * @return uint32 targetAuraSpellId - */ - int GetTargetAuraSpell(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->TargetAuraSpell); - return 1; - } - - /** - * Returns the aura spell ID that must NOT be on the caster. - * - * The spell cannot be cast if the caster has an aura from this spell. - * - * @return uint32 excludeCasterAuraSpellId - */ - int GetExcludeCasterAuraSpell(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->ExcludeCasterAuraSpell); - return 1; - } - - /** - * Returns the aura spell ID that must NOT be on the target. - * - * The spell cannot be cast if the target has an aura from this spell. - * - * @return uint32 excludeTargetAuraSpellId - */ - int GetExcludeTargetAuraSpell(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->ExcludeTargetAuraSpell); - return 1; - } - - /** - * Returns the casting time index of this [SpellEntry]. - * - * This index is used to look up the base casting time in SpellCastTimes.dbc. - * - * @return uint32 castingTimeIndex - */ - int GetCastingTimeIndex(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->CastingTimeIndex); - return 1; - } - - /** - * Returns the recovery time for the [SpellEntry]. - * - * @return uint32 recoveryTime - */ - int GetRecoveryTime(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->RecoveryTime); - return 1; - } - - /** - * Returns the category recovery time for the [SpellEntry]. - * - * @return uint32 categoryRecoveryTime : in milliseconds, returned as uint32 - */ - int GetCategoryRecoveryTime(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->CategoryRecoveryTime); - return 1; - } - - /** - * Returns the interrupt flags for this [SpellEntry]. - * - * Determines what can interrupt this spell while casting (e.g., movement, taking damage). - * - * @return uint32 interruptFlags - */ - int GetInterruptFlags(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->InterruptFlags); - return 1; - } - - /** - * Returns the aura interrupt flags for this [SpellEntry]. - * - * Indicates what actions will break or remove the aura applied by this spell. - * - * @return uint32 auraInterruptFlags - */ - int GetAuraInterruptFlags(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->AuraInterruptFlags); - return 1; - } - - /** - * Returns the channel interrupt flags for this [SpellEntry]. - * - * Specifies conditions under which a channeled spell will be interrupted (e.g., moving or turning). - * - * @return uint32 channelInterruptFlags - */ - int GetChannelInterruptFlags(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->ChannelInterruptFlags); - return 1; - } - - /** - * Returns the proc flags for this [SpellEntry]. - * - * Determines the types of actions or triggers that can cause this spell to proc. - * - * @return uint32 procFlags - */ - int GetProcFlags(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->ProcFlags); - return 1; - } - - /** - * Returns the proc chance of [SpellEntry]. - * - * @return uint32 procChance - */ - int GetProcChance(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->ProcChance); - return 1; - } - - /** - * Returns the proc charges of [SpellEntry]. - * - * @return uint32 procCharges - */ - int GetProcCharges(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->ProcCharges); - return 1; - } - - /** - * Returns the max level for the [SpellEntry]. - * - * @return uint32 maxLevel : the [SpellEntry] max level. - */ - int GetMaxLevel(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->MaxLevel); - return 1; - } - - /** - * Returns the base level required for the [SpellEntry]. - * - * @return uint32 baseLevel - */ - int GetBaseLevel(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->BaseLevel); - return 1; - } - - /** - * Returns the spell level for the [SpellEntry]. - * - * @return uint32 spellLevel - */ - int GetSpellLevel(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->SpellLevel); - return 1; - } - - /** - * Returns the duration index for the [SpellEntry]. - * - * @return uint32 durationIndex - */ - int GetDurationIndex(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->DurationIndex); - return 1; - } - - /** - * Returns the power type ID for the [SpellEntry]. - * - * @return uint32 powerTypeId - */ - int GetPowerType(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->PowerType); - return 1; - } - - /** - * Returns the mana cost for the [SpellEntry]. - * - * @return uint32 manaCost - */ - int GetManaCost(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->ManaCost); - return 1; - } - - /** - * Returns the mana cost per level for [SpellEntry]. - * - * @return uint32 manaCostPerLevel - */ - int GetManaCostPerlevel(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->ManaCostPerlevel); - return 1; - } - - /** - * Returns the mana per second for [SpellEntry]. - * - * @return uint32 manaPerSecond - */ - int GetManaPerSecond(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->ManaPerSecond); - return 1; - } - - /** - * Returns the mana per second per level for [SpellEntry]. - * - * @return uint32 manaPerSecondPerLevel - */ - int GetManaPerSecondPerLevel(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->ManaPerSecondPerLevel); - return 1; - } - - /** - * Returns the range index for [SpellEntry]. - * - * @return uint32 rangeIndex - */ - int GetRangeIndex(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->RangeIndex); - return 1; - } - - /** - * Returns speed for [SpellEntry]. - * - * @return uint32 speed - */ - int GetSpeed(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->Speed); - return 1; - } - - /** - * Returns the stack amount for [SpellEntry]. - * - * @return uint32 stackAmount - */ - int GetStackAmount(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->StackAmount); - return 1; - } - - /** - * Returns a table with all totem values for [SpellEntry]. - * - * @return table totem - */ - int GetTotem(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->Totem.size(); ++index) - { - ALE::Push(L, entry->Totem[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all reagent values for [SpellEntry]. - * - * @return table reagent - */ - int GetReagent(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->Reagent.size(); ++index) - { - ALE::Push(L, entry->Reagent[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all reagent count values for [SpellEntry]. - * - * @return table reagentCount - */ - int GetReagentCount(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->ReagentCount.size(); ++index) - { - ALE::Push(L, entry->ReagentCount[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns the equipped item class ID for [SpellEntry]. - * - * @return uint32 equippedItemClassId - */ - int GetEquippedItemClass(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->EquippedItemClass); - return 1; - } - - /** - * Returns the equipped item sub class masks for [SpellEntry]. - * - * @return uint32 equippedItemSubClassMasks : bitmasks, returned as uint32. - */ - int GetEquippedItemSubClassMask(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->EquippedItemSubClassMask); - return 1; - } - - /** - * Returns the equipped item inventory type masks for [SpellEntry]. - * - * @return uint32 equippedItemInventoryTypeMasks : bitmasks, returned as uint32. - */ - int GetEquippedItemInventoryTypeMask(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->EquippedItemInventoryTypeMask); - return 1; - } - - /** - * Returns a table with all spell effect IDs for [SpellEntry]. - * - * @return table effect - */ - int GetEffect(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->Effect.size(); ++index) - { - ALE::Push(L, entry->Effect[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect die sides values for [SpellEntry]. - * - * @return table effectDieSides - */ - int GetEffectDieSides(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectDieSides.size(); ++index) - { - ALE::Push(L, entry->EffectDieSides[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect real points per level values for [SpellEntry]. - * - * @return table effectRealPointsPerLevel - */ - int GetEffectRealPointsPerLevel(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectRealPointsPerLevel.size(); ++index) - { - ALE::Push(L, entry->EffectRealPointsPerLevel[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect base points values for [SpellEntry]. - * - * @return table effectBasePoints - */ - int GetEffectBasePoints(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectBasePoints.size(); ++index) - { - ALE::Push(L, entry->EffectBasePoints[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect mechanic IDs for [SpellEntry]. - * - * @return table effectMechanic - */ - int GetEffectMechanic(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectMechanic.size(); ++index) - { - ALE::Push(L, entry->EffectMechanic[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect implicit target a IDs for [SpellEntry]. - * - * @return table effectImplicitTargetA - */ - int GetEffectImplicitTargetA(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectImplicitTargetA.size(); ++index) - { - ALE::Push(L, entry->EffectImplicitTargetA[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect implicit target b IDs for [SpellEntry]. - * - * @return table effectImplicitTargetB - */ - int GetEffectImplicitTargetB(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectImplicitTargetB.size(); ++index) - { - ALE::Push(L, entry->EffectImplicitTargetB[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect radius index for [SpellEntry]. - * - * @return table effectRadiusIndex - */ - int GetEffectRadiusIndex(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectRadiusIndex.size(); ++index) - { - ALE::Push(L, entry->EffectRadiusIndex[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect apply aura IDs for [SpellEntry]. - * - * @return table effectApplyAura - */ - int GetEffectApplyAuraName(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectApplyAuraName.size(); ++index) - { - ALE::Push(L, entry->EffectApplyAuraName[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect amplitude values for [SpellEntry]. - * - * @return table effectAmplitude - */ - int GetEffectAmplitude(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectAmplitude.size(); ++index) - { - ALE::Push(L, entry->EffectAmplitude[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect value multiplier for [SpellEntry]. - * - * @return table effectValueMultiplier - */ - int GetEffectValueMultiplier(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectValueMultiplier.size(); ++index) - { - ALE::Push(L, entry->EffectValueMultiplier[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect chain target values for [SpellEntry]. - * - * @return table effectChainTarget - */ - int GetEffectChainTarget(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectChainTarget.size(); ++index) - { - ALE::Push(L, entry->EffectChainTarget[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect item type values for [SpellEntry]. - * - * @return table effectItemType - */ - int GetEffectItemType(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectItemType.size(); ++index) - { - ALE::Push(L, entry->EffectItemType[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect misc value A for [SpellEntry]. - * - * @return table effectMiscValueA - */ - int GetEffectMiscValue(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectMiscValue.size(); ++index) - { - ALE::Push(L, entry->EffectMiscValue[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect misc value B for [SpellEntry]. - * - * @return table effectMiscValueB - */ - int GetEffectMiscValueB(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectMiscValueB.size(); ++index) - { - ALE::Push(L, entry->EffectMiscValueB[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect trigger spell for [SpellEntry]. - * - * @return table effectTriggerSpell - */ - int GetEffectTriggerSpell(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectTriggerSpell.size(); ++index) - { - ALE::Push(L, entry->EffectTriggerSpell[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with all effect points per combo point of [SpellEntry] - * - * @return table effectPointsPerComboPoint : returns a table containing all the effect points per combo point values of [SpellEntry] - */ - int GetEffectPointsPerComboPoint(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectPointsPerComboPoint.size(); ++index) - { - ALE::Push(L, entry->EffectPointsPerComboPoint[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table of [SpellFamilyFlags] for each effect of this [SpellEntry]. - * - * These flags are used to categorize spell effects for use with spell group logic. - * The table contains up to 3 bitmask entries, one per effect. - * - * @return table effectSpellClassMask : table of [SpellFamilyFlags] per effect - */ - int GetEffectSpellClassMask(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectSpellClassMask.size(); ++index) - { - ALE::Push(L, entry->EffectSpellClassMask[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with both spell visuals of [SpellEntry] - * - * @return table spellVisuals : returns a table containing both spellVisuals for [SpellEntry]. - */ - int GetSpellVisual(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->SpellVisual.size(); ++index) - { - ALE::Push(L, entry->SpellVisual[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns the spell icon ID for the [SpellEntry]. - * - * @return uint32 spellIconId - */ - int GetSpellIconID(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->SpellIconID); - return 1; - } - - /** - * Returns the active icon ID for the [SpellEntry]. - * - * @return uint32 activeIconId - */ - int GetActiveIconID(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->ActiveIconID); - return 1; - } - - /** - * Returns the spell Priority for the [SpellEntry]. - * - * @return uint32 spellPriority - */ - int GetSpellPriority(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->SpellPriority); - return 1; - } - - /** - * Returns a table of the [SpellEntry] names of all locals. - * - * @return table spellNames - */ - int GetSpellName(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->SpellName.size(); ++index) - { - ALE::Push(L, entry->SpellName[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table of the [SpellEntry] ranks. - * - * @return table spellRanks - */ - int GetRank(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->Rank.size(); ++index) - { - ALE::Push(L, entry->Rank[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns the mana cost percentage of [SpellEntry]. - * - * @return uint32 manaCostPercentage : the mana cost in percentage, returned as uint32. - */ - int GetManaCostPercentage(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->ManaCostPercentage); - return 1; - } - - /** - * Returns the global cooldown time value for [SpellEntry]. - * - * @return uint32 globalCooldownTime - */ - int GetStartRecoveryCategory(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->StartRecoveryCategory); - return 1; - } - - /** - * Returns the global cooldown category value for [SpellEntry]. - * - * @return uint32 globalCooldownCategory - */ - int GetStartRecoveryTime(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->StartRecoveryTime); - return 1; - } - - /** - * Returns the max target level value for [SpellEntry]. - * - * @return uint32 maxTargetLevel - */ - int GetMaxTargetLevel(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->MaxTargetLevel); - return 1; - } - - /** - * Returns the spell family name of this [SpellEntry]. - * - * This identifies the broader category or class of spells (e.g., Mage, Warrior, Rogue). - * - * @return uint32 spellFamilyName - */ - int GetSpellFamilyName(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->SpellFamilyName); - return 1; - } - - /** - * Returns the spell family flags of this [SpellEntry]. - * - * These bitflags represent specific characteristics or subcategories of spells within a family. - * - * @return uint64 spellFamilyFlags - */ - int GetSpellFamilyFlags(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->SpellFamilyFlags); - return 1; - } - - /** - * Returns the max affected targets value [SpellEntry]. - * - * @return uint32 maxAffectedTargets - */ - int GetMaxAffectedTargets(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->MaxAffectedTargets); - return 1; - } - - /** - * Returns the spell damage type ID [SpellEntry]. - * - * @return uint32 spellDamageTypeId - */ - int GetDmgClass(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->DmgClass); - return 1; - } - - /** - * Returns the prevention type ID [SpellEntry]. - * - * @return uint32 preventionTypeId - */ - int GetPreventionType(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->PreventionType); - return 1; - } - - /** - * Returns a table with all effect damage multiplier values [SpellEntry]. - * - * @return table effectDamageMultipliers - */ - int GetEffectDamageMultiplier(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectDamageMultiplier.size(); ++index) - { - ALE::Push(L, entry->EffectDamageMultiplier[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns a table with totem categories IDs [SpellEntry]. - * - * @return table totemCategory - */ - int GetTotemCategory(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->TotemCategory.size(); ++index) - { - ALE::Push(L, entry->TotemCategory[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Returns the Area Group ID associated with this [SpellEntry]. - * - * AreaGroupId is used to restrict spell usage to specific zones or areas. - * - * @return uint32 areaGroupId - */ - int GetAreaGroupId(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->AreaGroupId); - return 1; - } - - /** - * Returns the school mask of [SpellEntry]. - * - * @return uint32 schoolMask : bitmask, returned as uint32. - */ - int GetSchoolMask(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->SchoolMask); - return 1; - } - - /** - * Returns the rune cost id for the [SpellEntry]. - * - * @return uint32 runeCostId - */ - int GetRuneCostID(lua_State* L, SpellEntry* entry) - { - ALE::Push(L, entry->RuneCostID); - return 1; - } - - /** - * Returns a table with all effect bonus multiplier values [SpellEntry]. - * - * @return table effectBonusMultipliers - */ - int GetEffectBonusMultiplier(lua_State* L, SpellEntry* entry) - { - lua_newtable(L); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (size_t index = 0; index < entry->EffectBonusMultiplier.size(); ++index) - { - ALE::Push(L, entry->EffectBonusMultiplier[index]); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); // push table to top of stack - return 1; - } - - /** - * Sets the category for the [SpellEntry]. - * - * @param uint32 category : the new category value - */ - int SetCategory(lua_State* L, SpellEntry* entry) - { - uint32 category = ALE::CHECKVAL(L, 2); - entry->Category = category; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->CategoryEntry = category ? sSpellCategoryStore.LookupEntry(category) : nullptr; - } - - return 0; - } - - /** - * Sets the dispel type for the [SpellEntry]. - * - * @param uint32 dispel : the new dispel type value - */ - int SetDispel(lua_State* L, SpellEntry* entry) - { - uint32 dispel = ALE::CHECKVAL(L, 2); - entry->Dispel = dispel; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->Dispel = dispel; - } - - return 0; - } - - /** - * Sets the mechanic for the [SpellEntry]. - * - * @param uint32 mechanic : the new mechanic value - */ - int SetMechanic(lua_State* L, SpellEntry* entry) - { - uint32 mechanic = ALE::CHECKVAL(L, 2); - entry->Mechanic = mechanic; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->Mechanic = mechanic; - } - - return 0; - } - - /** - * Sets the attributes for the [SpellEntry]. - * - * @param uint32 attributes : the new attributes bitmask - */ - int SetAttributes(lua_State* L, SpellEntry* entry) - { - uint32 attributes = ALE::CHECKVAL(L, 2); - entry->Attributes = attributes; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->Attributes = attributes; - } - - return 0; - } - - /** - * Sets the attributesEx for the [SpellEntry]. - * - * @param uint32 attributesEx : the new attributesEx bitmask - */ - int SetAttributesEx(lua_State* L, SpellEntry* entry) - { - uint32 attributesEx = ALE::CHECKVAL(L, 2); - entry->AttributesEx = attributesEx; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->AttributesEx = attributesEx; - } - - return 0; - } - - /** - * Sets the attributesEx2 for the [SpellEntry]. - * - * @param uint32 attributesEx2 : the new attributesEx2 bitmask - */ - int SetAttributesEx2(lua_State* L, SpellEntry* entry) - { - uint32 attributesEx2 = ALE::CHECKVAL(L, 2); - entry->AttributesEx2 = attributesEx2; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->AttributesEx2 = attributesEx2; - } - - return 0; - } - - /** - * Sets the attributesEx3 for the [SpellEntry]. - * - * @param uint32 attributesEx3 : the new attributesEx3 bitmask - */ - int SetAttributesEx3(lua_State* L, SpellEntry* entry) - { - uint32 attributesEx3 = ALE::CHECKVAL(L, 2); - entry->AttributesEx3 = attributesEx3; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->AttributesEx3 = attributesEx3; - } - - return 0; - } - - /** - * Sets the attributesEx4 for the [SpellEntry]. - * - * @param uint32 attributesEx4 : the new attributesEx4 bitmask - */ - int SetAttributesEx4(lua_State* L, SpellEntry* entry) - { - uint32 attributesEx4 = ALE::CHECKVAL(L, 2); - entry->AttributesEx4 = attributesEx4; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->AttributesEx4 = attributesEx4; - } - - return 0; - } - - /** - * Sets the attributesEx5 for the [SpellEntry]. - * - * @param uint32 attributesEx5 : the new attributesEx5 bitmask - */ - int SetAttributesEx5(lua_State* L, SpellEntry* entry) - { - uint32 attributesEx5 = ALE::CHECKVAL(L, 2); - entry->AttributesEx5 = attributesEx5; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->AttributesEx5 = attributesEx5; - } - - return 0; - } - - /** - * Sets the attributesEx6 for the [SpellEntry]. - * - * @param uint32 attributesEx6 : the new attributesEx6 bitmask - */ - int SetAttributesEx6(lua_State* L, SpellEntry* entry) - { - uint32 attributesEx6 = ALE::CHECKVAL(L, 2); - entry->AttributesEx6 = attributesEx6; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->AttributesEx6 = attributesEx6; - } - - return 0; - } - - /** - * Sets the attributesEx7 for the [SpellEntry]. - * - * @param uint32 attributesEx7 : the new attributesEx7 bitmask - */ - int SetAttributesEx7(lua_State* L, SpellEntry* entry) - { - uint32 attributesEx7 = ALE::CHECKVAL(L, 2); - entry->AttributesEx7 = attributesEx7; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->AttributesEx7 = attributesEx7; - } - - return 0; - } - - /** - * Sets the stances for the [SpellEntry]. - * - * @param uint32 stances : the new stances bitmask - */ - int SetStances(lua_State* L, SpellEntry* entry) - { - uint32 stances = ALE::CHECKVAL(L, 2); - entry->Stances = stances; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->Stances = stances; - } - - return 0; - } - - /** - * Sets the stancesNot for the [SpellEntry]. - * - * @param uint32 stancesNot : the new stancesNot bitmask - */ - int SetStancesNot(lua_State* L, SpellEntry* entry) - { - uint32 stancesNot = ALE::CHECKVAL(L, 2); - entry->StancesNot = stancesNot; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->StancesNot = stancesNot; - } - - return 0; - } - - /** - * Sets the targets for the [SpellEntry]. - * - * @param uint32 targets : the new targets bitmask - */ - int SetTargets(lua_State* L, SpellEntry* entry) - { - uint32 targets = ALE::CHECKVAL(L, 2); - entry->Targets = targets; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->Targets = targets; - } - - return 0; - } - - /** - * Sets the target creature type for the [SpellEntry]. - * - * @param uint32 targetCreatureType : the new target creature type bitmask - */ - int SetTargetCreatureType(lua_State* L, SpellEntry* entry) - { - uint32 targetCreatureType = ALE::CHECKVAL(L, 2); - entry->TargetCreatureType = targetCreatureType; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->TargetCreatureType = targetCreatureType; - } - - return 0; - } - - /** - * Sets the requires spell focus for the [SpellEntry]. - * - * @param uint32 requiresSpellFocus : the new requires spell focus value - */ - int SetRequiresSpellFocus(lua_State* L, SpellEntry* entry) - { - uint32 requiresSpellFocus = ALE::CHECKVAL(L, 2); - entry->RequiresSpellFocus = requiresSpellFocus; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->RequiresSpellFocus = requiresSpellFocus; - } - - return 0; - } - - /** - * Sets the facing caster flags for the [SpellEntry]. - * - * @param uint32 facingCasterFlags : the new facing caster flags value - */ - int SetFacingCasterFlags(lua_State* L, SpellEntry* entry) - { - uint32 facingCasterFlags = ALE::CHECKVAL(L, 2); - entry->FacingCasterFlags = facingCasterFlags; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->FacingCasterFlags = facingCasterFlags; - } - - return 0; - } - - /** - * Sets the caster aura state for the [SpellEntry]. - * - * @param uint32 casterAuraState : the new caster aura state value - */ - int SetCasterAuraState(lua_State* L, SpellEntry* entry) - { - uint32 casterAuraState = ALE::CHECKVAL(L, 2); - entry->CasterAuraState = casterAuraState; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->CasterAuraState = casterAuraState; - } - - return 0; - } - - /** - * Sets the target aura state for the [SpellEntry]. - * - * @param uint32 targetAuraState : the new target aura state value - */ - int SetTargetAuraState(lua_State* L, SpellEntry* entry) - { - uint32 targetAuraState = ALE::CHECKVAL(L, 2); - entry->TargetAuraState = targetAuraState; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->TargetAuraState = targetAuraState; - } - - return 0; - } - - /** - * Sets the caster aura state not for the [SpellEntry]. - * - * @param uint32 casterAuraStateNot : the new caster aura state not value - */ - int SetCasterAuraStateNot(lua_State* L, SpellEntry* entry) - { - uint32 casterAuraStateNot = ALE::CHECKVAL(L, 2); - entry->CasterAuraStateNot = casterAuraStateNot; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->CasterAuraStateNot = casterAuraStateNot; - } - - return 0; - } - - /** - * Sets the target aura state not for the [SpellEntry]. - * - * @param uint32 targetAuraStateNot : the new target aura state not value - */ - int SetTargetAuraStateNot(lua_State* L, SpellEntry* entry) - { - uint32 targetAuraStateNot = ALE::CHECKVAL(L, 2); - entry->TargetAuraStateNot = targetAuraStateNot; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->TargetAuraStateNot = targetAuraStateNot; - } - - return 0; - } - - /** - * Sets the caster aura spell for the [SpellEntry]. - * - * @param uint32 casterAuraSpell : the new caster aura spell ID - */ - int SetCasterAuraSpell(lua_State* L, SpellEntry* entry) - { - uint32 casterAuraSpell = ALE::CHECKVAL(L, 2); - entry->CasterAuraSpell = casterAuraSpell; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->CasterAuraSpell = casterAuraSpell; - } - - return 0; - } - - /** - * Sets the target aura spell for the [SpellEntry]. - * - * @param uint32 targetAuraSpell : the new target aura spell ID - */ - int SetTargetAuraSpell(lua_State* L, SpellEntry* entry) - { - uint32 targetAuraSpell = ALE::CHECKVAL(L, 2); - entry->TargetAuraSpell = targetAuraSpell; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->TargetAuraSpell = targetAuraSpell; - } - - return 0; - } - - /** - * Sets the exclude caster aura spell for the [SpellEntry]. - * - * @param uint32 excludeCasterAuraSpell : the new exclude caster aura spell ID - */ - int SetExcludeCasterAuraSpell(lua_State* L, SpellEntry* entry) - { - uint32 excludeCasterAuraSpell = ALE::CHECKVAL(L, 2); - entry->ExcludeCasterAuraSpell = excludeCasterAuraSpell; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->ExcludeCasterAuraSpell = excludeCasterAuraSpell; - } - - return 0; - } - - /** - * Sets the exclude target aura spell for the [SpellEntry]. - * - * @param uint32 excludeTargetAuraSpell : the new exclude target aura spell ID - */ - int SetExcludeTargetAuraSpell(lua_State* L, SpellEntry* entry) - { - uint32 excludeTargetAuraSpell = ALE::CHECKVAL(L, 2); - entry->ExcludeTargetAuraSpell = excludeTargetAuraSpell; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->ExcludeTargetAuraSpell = excludeTargetAuraSpell; - } - - return 0; - } - - /** - * Sets the recovery time for the [SpellEntry]. - * - * @param uint32 recoveryTime : the new recovery time value - */ - int SetRecoveryTime(lua_State* L, SpellEntry* entry) - { - uint32 recoveryTime = ALE::CHECKVAL(L, 2); - entry->RecoveryTime = recoveryTime; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->RecoveryTime = recoveryTime; - } - - return 0; - } - - /** - * Sets the category recovery time for the [SpellEntry]. - * - * @param uint32 categoryRecoveryTime : the new category recovery time value in milliseconds - */ - int SetCategoryRecoveryTime(lua_State* L, SpellEntry* entry) - { - uint32 categoryRecoveryTime = ALE::CHECKVAL(L, 2); - entry->CategoryRecoveryTime = categoryRecoveryTime; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->CategoryRecoveryTime = categoryRecoveryTime; - } - - return 0; - } - - /** - * Sets the interrupt flags for the [SpellEntry]. - * - * @param uint32 interruptFlags : the new interrupt flags bitmask - */ - int SetInterruptFlags(lua_State* L, SpellEntry* entry) - { - uint32 interruptFlags = ALE::CHECKVAL(L, 2); - entry->InterruptFlags = interruptFlags; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->InterruptFlags = interruptFlags; - } - - return 0; - } - - /** - * Sets the aura interrupt flags for the [SpellEntry]. - * - * @param uint32 auraInterruptFlags : the new aura interrupt flags bitmask - */ - int SetAuraInterruptFlags(lua_State* L, SpellEntry* entry) - { - uint32 auraInterruptFlags = ALE::CHECKVAL(L, 2); - entry->AuraInterruptFlags = auraInterruptFlags; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->AuraInterruptFlags = auraInterruptFlags; - } - - return 0; - } - - /** - * Sets the channel interrupt flags for the [SpellEntry]. - * - * @param uint32 channelInterruptFlags : the new channel interrupt flags bitmask - */ - int SetChannelInterruptFlags(lua_State* L, SpellEntry* entry) - { - uint32 channelInterruptFlags = ALE::CHECKVAL(L, 2); - entry->ChannelInterruptFlags = channelInterruptFlags; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->ChannelInterruptFlags = channelInterruptFlags; - } - - return 0; - } - - /** - * Sets the proc flags for the [SpellEntry]. - * - * @param uint32 procFlags : the new proc flags bitmask - */ - int SetProcFlags(lua_State* L, SpellEntry* entry) - { - uint32 procFlags = ALE::CHECKVAL(L, 2); - entry->ProcFlags = procFlags; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->ProcFlags = procFlags; - } - - return 0; - } - - /** - * Sets the proc chance for the [SpellEntry]. - * - * @param uint32 procChance : the new proc chance value - */ - int SetProcChance(lua_State* L, SpellEntry* entry) - { - uint32 procChance = ALE::CHECKVAL(L, 2); - entry->ProcChance = procChance; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->ProcChance = procChance; - } - - return 0; - } - - /** - * Sets the proc charges for the [SpellEntry]. - * - * @param uint32 procCharges : the new proc charges value - */ - int SetProcCharges(lua_State* L, SpellEntry* entry) - { - uint32 procCharges = ALE::CHECKVAL(L, 2); - entry->ProcCharges = procCharges; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->ProcCharges = procCharges; - } - - return 0; - } - - /** - * Sets the max level for the [SpellEntry]. - * - * @param uint32 maxLevel : the new max level value - */ - int SetMaxLevel(lua_State* L, SpellEntry* entry) - { - uint32 maxLevel = ALE::CHECKVAL(L, 2); - entry->MaxLevel = maxLevel; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->MaxLevel = maxLevel; - } - - return 0; - } - - /** - * Sets the base level for the [SpellEntry]. - * - * @param uint32 baseLevel : the new base level value - */ - int SetBaseLevel(lua_State* L, SpellEntry* entry) - { - uint32 baseLevel = ALE::CHECKVAL(L, 2); - entry->BaseLevel = baseLevel; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->BaseLevel = baseLevel; - } - - return 0; - } - - /** - * Sets the spell level for the [SpellEntry]. - * - * @param uint32 spellLevel : the new spell level value - */ - int SetSpellLevel(lua_State* L, SpellEntry* entry) - { - uint32 spellLevel = ALE::CHECKVAL(L, 2); - entry->SpellLevel = spellLevel; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->SpellLevel = spellLevel; - } - - return 0; - } - - /** - * Sets the mana cost for the [SpellEntry]. - * - * @param uint32 manaCost : the new mana cost value - */ - int SetManaCost(lua_State* L, SpellEntry* entry) - { - uint32 manaCost = ALE::CHECKVAL(L, 2); - entry->ManaCost = manaCost; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->ManaCost = manaCost; - } - - return 0; - } - - /** - * Sets the power type for the [SpellEntry]. - * - * @param uint32 powerType : the new power type ID - */ - int SetPowerType(lua_State* L, SpellEntry* entry) - { - uint32 powerType = ALE::CHECKVAL(L, 2); - entry->PowerType = powerType; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->PowerType = powerType; - } - - return 0; - } - - /** - * Sets the mana cost per level for the [SpellEntry]. - * - * @param uint32 manaCostPerlevel : the new mana cost per level value - */ - int SetManaCostPerlevel(lua_State* L, SpellEntry* entry) - { - uint32 manaCostPerlevel = ALE::CHECKVAL(L, 2); - entry->ManaCostPerlevel = manaCostPerlevel; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->ManaCostPerlevel = manaCostPerlevel; - } - - return 0; - } - - /** - * Sets the mana per second for the [SpellEntry]. - * - * @param uint32 manaPerSecond : the new mana per second value - */ - int SetManaPerSecond(lua_State* L, SpellEntry* entry) - { - uint32 manaPerSecond = ALE::CHECKVAL(L, 2); - entry->ManaPerSecond = manaPerSecond; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->ManaPerSecond = manaPerSecond; - } - - return 0; - } - - /** - * Sets the mana per second per level for the [SpellEntry]. - * - * @param uint32 manaPerSecondPerLevel : the new mana per second per level value - */ - int SetManaPerSecondPerLevel(lua_State* L, SpellEntry* entry) - { - uint32 manaPerSecondPerLevel = ALE::CHECKVAL(L, 2); - entry->ManaPerSecondPerLevel = manaPerSecondPerLevel; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->ManaPerSecondPerLevel = manaPerSecondPerLevel; - } - - return 0; - } - - /** - * Sets the speed for the [SpellEntry]. - * - * @param float speed : the new speed value - */ - int SetSpeed(lua_State* L, SpellEntry* entry) - { - float speed = ALE::CHECKVAL(L, 2); - entry->Speed = speed; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->Speed = speed; - } - - return 0; - } - - /** - * Sets the stack amount for the [SpellEntry]. - * - * @param uint32 stackAmount : the new stack amount value - */ - int SetStackAmount(lua_State* L, SpellEntry* entry) - { - uint32 stackAmount = ALE::CHECKVAL(L, 2); - entry->StackAmount = stackAmount; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->StackAmount = stackAmount; - } - - return 0; - } - - /** - * Sets the equipped item class for the [SpellEntry]. - * - * @param int32 equippedItemClass : the new equipped item class value - */ - int SetEquippedItemClass(lua_State* L, SpellEntry* entry) - { - int32 equippedItemClass = ALE::CHECKVAL(L, 2); - entry->EquippedItemClass = equippedItemClass; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->EquippedItemClass = equippedItemClass; - } - - return 0; - } - - /** - * Sets the equipped item sub class mask for the [SpellEntry]. - * - * @param int32 equippedItemSubClassMask : the new equipped item sub class mask bitmasks - */ - int SetEquippedItemSubClassMask(lua_State* L, SpellEntry* entry) - { - int32 equippedItemSubClassMask = ALE::CHECKVAL(L, 2); - entry->EquippedItemSubClassMask = equippedItemSubClassMask; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->EquippedItemSubClassMask = equippedItemSubClassMask; - } - - return 0; - } - - /** - * Sets the equipped item inventory type mask for the [SpellEntry]. - * - * @param int32 equippedItemInventoryTypeMask : the new equipped item inventory type mask bitmasks - */ - int SetEquippedItemInventoryTypeMask(lua_State* L, SpellEntry* entry) - { - int32 equippedItemInventoryTypeMask = ALE::CHECKVAL(L, 2); - entry->EquippedItemInventoryTypeMask = equippedItemInventoryTypeMask; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->EquippedItemInventoryTypeMask = equippedItemInventoryTypeMask; - } - - return 0; - } - - /** - * Sets the spell icon ID for the [SpellEntry]. - * - * @param uint32 spellIconID : the new spell icon ID value - */ - int SetSpellIconID(lua_State* L, SpellEntry* entry) - { - uint32 spellIconID = ALE::CHECKVAL(L, 2); - entry->SpellIconID = spellIconID; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->SpellIconID = spellIconID; - } - - return 0; - } - - /** - * Sets the active icon ID for the [SpellEntry]. - * - * @param uint32 activeIconID : the new active icon ID value - */ - int SetActiveIconID(lua_State* L, SpellEntry* entry) - { - uint32 activeIconID = ALE::CHECKVAL(L, 2); - entry->ActiveIconID = activeIconID; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->ActiveIconID = activeIconID; - } - - return 0; - } - - /** - * Sets the spell priority for the [SpellEntry]. - * - * @param uint32 spellPriority : the new spell priority value - */ - int SetSpellPriority(lua_State* L, SpellEntry* entry) - { - uint32 spellPriority = ALE::CHECKVAL(L, 2); - entry->SpellPriority = spellPriority; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->SpellPriority = spellPriority; - } - - return 0; - } - - /** - * Sets the mana cost percentage for the [SpellEntry]. - * - * @param uint32 manaCostPercentage : the new mana cost percentage value - */ - int SetManaCostPercentage(lua_State* L, SpellEntry* entry) - { - uint32 manaCostPercentage = ALE::CHECKVAL(L, 2); - entry->ManaCostPercentage = manaCostPercentage; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->ManaCostPercentage = manaCostPercentage; - } - - return 0; - } - - /** - * Sets the start recovery category for the [SpellEntry]. - * - * @param uint32 startRecoveryCategory : the new start recovery category value - */ - int SetStartRecoveryCategory(lua_State* L, SpellEntry* entry) - { - uint32 startRecoveryCategory = ALE::CHECKVAL(L, 2); - entry->StartRecoveryCategory = startRecoveryCategory; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->StartRecoveryCategory = startRecoveryCategory; - } - - return 0; - } - - /** - * Sets the start recovery time for the [SpellEntry]. - * - * @param uint32 startRecoveryTime : the new start recovery time value - */ - int SetStartRecoveryTime(lua_State* L, SpellEntry* entry) - { - uint32 startRecoveryTime = ALE::CHECKVAL(L, 2); - entry->StartRecoveryTime = startRecoveryTime; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->StartRecoveryTime = startRecoveryTime; - } - - return 0; - } - - /** - * Sets the max target level for the [SpellEntry]. - * - * @param uint32 maxTargetLevel : the new max target level value - */ - int SetMaxTargetLevel(lua_State* L, SpellEntry* entry) - { - uint32 maxTargetLevel = ALE::CHECKVAL(L, 2); - entry->MaxTargetLevel = maxTargetLevel; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->MaxTargetLevel = maxTargetLevel; - } - - return 0; - } - - /** - * Sets the spell family name for the [SpellEntry]. - * - * @param uint32 spellFamilyName : the new spell family name value - */ - int SetSpellFamilyName(lua_State* L, SpellEntry* entry) - { - uint32 spellFamilyName = ALE::CHECKVAL(L, 2); - entry->SpellFamilyName = spellFamilyName; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->SpellFamilyName = spellFamilyName; - } - - return 0; - } - - /** - * Sets the max affected targets for the [SpellEntry]. - * - * @param uint32 maxAffectedTargets : the new max affected targets value - */ - int SetMaxAffectedTargets(lua_State* L, SpellEntry* entry) - { - uint32 maxAffectedTargets = ALE::CHECKVAL(L, 2); - entry->MaxAffectedTargets = maxAffectedTargets; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->MaxAffectedTargets = maxAffectedTargets; - } - - return 0; - } - - /** - * Sets the damage class for the [SpellEntry]. - * - * @param uint32 dmgClass : the new damage class ID value - */ - int SetDmgClass(lua_State* L, SpellEntry* entry) - { - uint32 dmgClass = ALE::CHECKVAL(L, 2); - entry->DmgClass = dmgClass; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->DmgClass = dmgClass; - } - - return 0; - } - - /** - * Sets the prevention type for the [SpellEntry]. - * - * @param uint32 preventionType : the new prevention type ID value - */ - int SetPreventionType(lua_State* L, SpellEntry* entry) - { - uint32 preventionType = ALE::CHECKVAL(L, 2); - entry->PreventionType = preventionType; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->PreventionType = preventionType; - } - - return 0; - } - - /** - * Sets the school mask for the [SpellEntry]. - * - * @param uint32 schoolMask : the new school mask bitmask value - */ - int SetSchoolMask(lua_State* L, SpellEntry* entry) - { - uint32 schoolMask = ALE::CHECKVAL(L, 2); - entry->SchoolMask = schoolMask; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->SchoolMask = schoolMask; - } - - return 0; - } - - /** - * Sets the rune cost ID for the [SpellEntry]. - * - * @param uint32 runeCostID : the new rune cost ID value - */ - int SetRuneCostID(lua_State* L, SpellEntry* entry) - { - uint32 runeCostID = ALE::CHECKVAL(L, 2); - entry->RuneCostID = runeCostID; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) - { - const_cast(spellInfo)->RuneCostID = runeCostID; - } - - return 0; - } -} - -#endif diff --git a/src/LuaEngine/methods/SpellInfoMethods.h b/src/LuaEngine/methods/SpellInfoMethods.h deleted file mode 100644 index 3b69015718..0000000000 --- a/src/LuaEngine/methods/SpellInfoMethods.h +++ /dev/null @@ -1,990 +0,0 @@ -/* -* Copyright (C) 2010 - 2024 ALE Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef SPELLINFOMETHODS_H -#define SPELLINFOMETHODS_H - -/*** - * Represents spell metadata used for behavior, targeting, attributes, mechanics, auras, and conditions. - * - * Unlike [SpellEntry], this class includes helper functions and logic used to determine spell behavior in-game. - * Used for checking if a spell is passive, area-targeted, profession-related, or has specific effects or auras. - * - * Inherits all methods from: none - */ -namespace LuaSpellInfo -{ - - /** - * Returns the name of the [SpellInfo] - * - *
-     * enum LocaleConstant
-     * {
-     *     LOCALE_enUS = 0,
-     *     LOCALE_koKR = 1,
-     *     LOCALE_frFR = 2,
-     *     LOCALE_deDE = 3,
-     *     LOCALE_zhCN = 4,
-     *     LOCALE_zhTW = 5,
-     *     LOCALE_esES = 6,
-     *     LOCALE_esMX = 7,
-     *     LOCALE_ruRU = 8
-     * };
-     * 
- * - * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the [SpellInfo]'s name - * @return [string] name - */ - int GetName(lua_State* L, SpellInfo* spell_info) - { - uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE); - ALE::Push(L, spell_info->SpellName[static_cast(locale)]); - return 1; - } - - /** - * Checks if the [SpellInfo] has a specific attribute. - * - * Attributes are characteristics or properties that spells can possess. - * Attributes are divided into different categories (from 0 to 8 in this context). - * - * Here is how each attribute is inspected: - * - *
-     * 0 : SpellAttr0
-     * 1 : SpellAttr1
-     * 2 : SpellAttr2
-     * 3 : SpellAttr3
-     * 4 : SpellAttr4
-     * 5 : SpellAttr5
-     * 6 : SpellAttr6
-     * 7 : SpellAttr7
-     * -1 : SpellCustomAttributes
-     * 
- * - * @param [int8] attributeType : the type of the attribute. - * @param [uint32] attribute : the specific attribute to check. - * @return [bool] has_attribute - */ - int HasAttribute(lua_State* L, SpellInfo* spell_info) - { - int8 attributeType = ALE::CHECKVAL(L, 2); - uint32 attribute = ALE::CHECKVAL(L, 3); - - bool hasAttribute = false; - if ( attributeType == -1 ) { - hasAttribute = spell_info->HasAttribute(static_cast(attribute)); ; - }else{ - switch(attributeType) - { - case 0: - hasAttribute = spell_info->HasAttribute(static_cast(attribute)); - break; - case 1: - hasAttribute = spell_info->HasAttribute(static_cast(attribute)); - break; - case 2: - hasAttribute = spell_info->HasAttribute(static_cast(attribute)); - break; - case 3: - hasAttribute = spell_info->HasAttribute(static_cast(attribute)); - break; - case 4: - hasAttribute = spell_info->HasAttribute(static_cast(attribute)); - break; - case 5: - hasAttribute = spell_info->HasAttribute(static_cast(attribute)); - break; - case 6: - hasAttribute = spell_info->HasAttribute(static_cast(attribute)); - break; - case 7: - hasAttribute = spell_info->HasAttribute(static_cast(attribute)); - break; - case -1: - break; - } - } - - ALE::Push(L, hasAttribute); - return 1; - } - - /** - * Retrieves the attributes of the [SpellInfo] based on the attribute type. - * - * Attributes are properties or traits of a spell. There are different categories (0 to 8 in this case) of attributes. - * - * How each type of attribute is extracted: - * - *
-     * 0 : Attributes
-     * 1 : AttributesEx
-     * 2 : AttributesEx2
-     * 3 : AttributesEx3
-     * 4 : AttributesEx4
-     * 5 : AttributesEx5
-     * 6 : AttributesEx6
-     * 7 : AttributesEx7
-     * -1 : AttributesCu
-     * 
- * - * @param [int8] attributeType : The type of the attribute. - * @return [uint32] attributes - */ - int GetAttributes(lua_State* L, SpellInfo* spell_info) - { - int8 attributeType = ALE::CHECKVAL(L, 2); - uint32 attributes; - - if ( attributeType == -1 ) { - attributes = spell_info->AttributesCu; - } - else { - switch(attributeType) - { - case 0: - attributes = spell_info->Attributes; - break; - case 1: - attributes = spell_info->AttributesEx; - break; - case 2: - attributes = spell_info->AttributesEx2; - break; - case 3: - attributes = spell_info->AttributesEx3; - break; - case 4: - attributes = spell_info->AttributesEx4; - break; - case 5: - attributes = spell_info->AttributesEx5; - break; - case 6: - attributes = spell_info->AttributesEx6; - break; - case 7: - attributes = spell_info->AttributesEx7; - break; - } - } - - ALE::Push(L, attributes); - return 1; - } - - /** - * Determines whether the [SpellInfo] affects an area (AOE - Area of Effect) - * - * The affected area will depend upon the specifics of the spell. - * A target can be an individual unit, player, or an area, and the spellInfo stores these details. - * - * The function checks the spell's attributes to determine if the spell is designed to affect an area or not. - * The outcome relies on spell's attributes field. - * - * @return [bool] is_affecting_area - */ - int IsAffectingArea(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsAffectingArea()); - return 1; - } - - /** - * Retrieves the category of the [SpellInfo]. - * - * A spell's category is a way of grouping similar spells together. - * It might define the spell's nature or its effect. - * For instance, damage spells, heal spells, and crowd-control spells might each have a different category. - * - * @return [uint32] category - */ - int GetCategory(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->GetCategory()); - return 1; - } - - /** - * Checks if the [SpellInfo] has a specific effect. - * - * A spell can have various effects such as damage, healing, or status changes. - * These effects are identified by a predefined set of constants represented by the 'SpellEffects' enumeration. - * - * @param [uint8] effect : The specific effect to check. - * @return [bool] has_effect - */ - int HasEffect(lua_State* L, SpellInfo* spell_info) - { - uint8 effect = ALE::CHECKVAL(L, 2); - ALE::Push(L, spell_info->HasEffect(static_cast(effect))); - return 1; - } - - /** - * Checks if the [SpellInfo] has a specific aura. - * - * An aura represents a status change or modification due to a spell or ability. - * These auras are identified by a predefined set of constants represented by the 'AuraType' enumeration. - * - * @param [uint32] aura : The specific aura to check. - * @return [bool] has_aura - */ - int HasAura(lua_State* L, SpellInfo* spell_info) - { - uint32 aura = ALE::CHECKVAL(L, 2); - ALE::Push(L, spell_info->HasAura(static_cast(aura))); - return 1; - } - - /** - * Checks if the [SpellInfo] has an area aura effect. - * - * Area aura is a type of spell effect that affects multiple targets within a certain area. - * - * @return [bool] has_area_aura_effect - */ - int HasAreaAuraEffect(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->HasAreaAuraEffect()); - return 1; - } - - - /** - * Checks if the [SpellInfo] is an explicit discovery. - * - * An "explicit discovery" may refer to a spell that is not intuitive or is hidden and must be specifically - * discovered by the player through some sort of action or event. - * - * @return [bool] is_explicit_discovery - */ - int IsExplicitDiscovery(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsExplicitDiscovery()); - return 1; - } - - /** - * Checks if the [SpellInfo] is related to loot crafting. - * - * Loot crafting can refer to the process wherein a player uses collected in-game items (loot) - * to craft or create new items, abilities, or spells. - * - * @return [bool] is_loot_crafting - */ - int IsLootCrafting(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsLootCrafting()); - return 1; - } - - /** - * Checks if the [SpellInfo] is related to a Profession skill or Riding skill. - * - * Profession skills may refer to a set of abilities related to a particular trade or activity, such as blacksmithing or alchemy. - * Riding skills are those related to the ability to ride mounts. - * - * @return [bool] is_profression_or_riding - */ - int IsProfessionOrRiding(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsProfessionOrRiding()); - return 1; - } - - /** - * Checks if the [SpellInfo] is related to a profession skill. - * - * Profession skills may refer to abilities related to a specific occupation or trade, - * such as blacksmithing, alchemy, fishing, etc. - * - * @return [bool] is_profession - */ - int IsProfession(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsProfession()); - return 1; - } - - /** - * Checks if the [SpellInfo] is related to a primary profession skill. - * - * Primary profession skills usually refer to main occupations or trades of the player character, - * such as blacksmithing, alchemy, mining, etc. - * - * @return [bool] is_primary_profession - */ - int IsPrimaryProfession(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsPrimaryProfession()); - return 1; - } - - /** - * Checks if the [SpellInfo] represents the first rank of a primary profession skill. - * - * Primary profession skills usually refer to main occupations or trades of the player character. - * The first rank typically indicates the introductory level of the profession. - * - * @return [bool] is_primary_profession_first_rank - */ - int IsPrimaryProfessionFirstRank(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsPrimaryProfessionFirstRank()); - return 1; - } - - /** - * Checks if the [SpellInfo] represents an ability learned with a profession skill. - * - * Certain abilities or skills (like crafting item or gathering materials) - * can be learned as part of a profession. - * - * @return [bool] is_ability_learned_with_profession - */ - int IsAbilityLearnedWithProfession(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsAbilityLearnedWithProfession()); - return 1; - } - - /** - * Checks if the [SpellInfo] represents an ability of a specific skill type. - * - * This function allows checking if a spell or ability belongs to a specific skill type. - * The skill type is often represented as an integral value (in this case, uint32), - * where each value may correspond to a different skill category such as crafting, combat, magic, etc. - * - * @param [uint32] skillType: The skill type to check against. Should be an integral value representing the skill type. - * @return [bool] is_ability_of_skill_type - */ - int IsAbilityOfSkillType(lua_State* L, SpellInfo* spell_info) - { - uint32 skillType = ALE::CHECKVAL(L, 2); - ALE::Push(L, spell_info->IsAbilityOfSkillType(skillType)); - return 1; - } - - /** - * Determines if the [SpellInfo] represents a spell or ability that targets an area. - * - * Spells or abilities that target an area are typically designed to affect multiple targets within a specified range. - * - * @return [bool] is_targeting_area - */ - int IsTargetingArea(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsTargetingArea()); - return 1; - } - - /** - * Checks if the [SpellInfo] requires an explicit unit target. - * - * Certain spells or abilities can only be cast or used when a specific unit (like a player character, NPC, or enemy) is targeted. - * This function checks if the spell or ability represented by [SpellInfo] has this requirement. - * - * @return [bool] needs_explicit_unit_target - */ - int NeedsExplicitUnitTarget(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->NeedsExplicitUnitTarget()); - return 1; - } - - /** - * Checks if the [SpellInfo] requires to be triggered by the caster of another specified [SpellInfo]. - * - * Certain spells or abilities can only be activated or become effective when they are triggered by the caster - * of another specific spell (the `triggeringSpell`). This function examines if the spell or ability represented - * by [SpellInfo] has such requirement. - * - * @param [SpellInfo] triggeringSpell : the spell by the casting of which the ability or spell represented by [SpellInfo] is triggered - * @return [bool] needs_to_be_triggered_by_caster - */ - int NeedsToBeTriggeredByCaster(lua_State* L, SpellInfo* spell_info) - { - const SpellInfo* triggeringSpell = ALE::CHECKOBJ(L, 2); - ALE::Push(L, spell_info->NeedsToBeTriggeredByCaster(triggeringSpell)); - return 1; - } - - /** - * Checks if the [SpellInfo] represents a self-casting spell or ability. - * - * Self-casting spells or abilities are those that the casters use on themselves. This can include - * defensive spells, healing spells, buffs, or any other type of effect that a player character or - * NPC applies on themselves. - * - * @return [bool] is_self_cast - */ - int IsSelfCast(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsSelfCast()); - return 1; - } - - /** - * Checks if the [SpellInfo] represents a passive spell or ability. - * - * Passive spells or abilities are those that are always in effect, without the need for the player or - * NPC to manually activate them. They usually provide their bonus or effect as long as certain conditions are met. - * - * @return [bool] is_passive - */ - int IsPassive(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsPassive()); - return 1; - } - - /** - * Checks if the [SpellInfo] represents a spell or ability that can be set to autocast. - * - * Autocasting is a feature that allows certain abilities or spells to be cast automatically by the game's - * AI when certain conditions are met. This function checks if the spell or ability represented by [SpellInfo] - * can be set to autocast. - * - * @return [bool] is_autocastable - */ - int IsAutocastable(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsAutocastable()); - return 1; - } - - /** - * Determines if the [SpellInfo] represents a spell or ability that stack with different ranks. - * - * Some spells or abilities can accumulate or "stack" their effects with multiple activations - * and these effects can sometimes vary based on the rank or level of the spell. This function checks - * if the spell represented by [SpellInfo] has this capacity. - * - * @return [bool] is_stackable_with_ranks - */ - int IsStackableWithRanks(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsStackableWithRanks()); - return 1; - } - - /** - * Checks if the [SpellInfo] represents a passive spell or ability that is stackable with different ranks. - * - * Some passive spells or abilities are designed to stack their effects with multiple activations, and these effects - * can also vary depending on the rank of the spell. This function assesses whether the spell or ability represented - * by [SpellInfo] has this property. - * - * @return [bool] is_passive_stackable_with_ranks - */ - int IsPassiveStackableWithRanks(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsPassiveStackableWithRanks()); - return 1; - } - - /** - * Checks if the [SpellInfo] represents a multi-slot aura spell or effect. - * - * A multi-slot aura is one that takes up more than one slot or position in the game's effect array or system. - * This function checks if the spell or ability represented by [SpellInfo] has this property. - * - * @return [bool] is_multi_slot_aura - */ - int IsMultiSlotAura(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsMultiSlotAura()); - return 1; - } - - /** - * Returns a boolean indicating whether the cooldown has started on the event associated with the [SpellInfo] - * - * @return [bool] is_cooldown_started_on_event - */ - int IsCooldownStartedOnEvent(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsCooldownStartedOnEvent()); - return 1; - } - - /** - * Returns a boolean indicating whether the death is persistent for the given [SpellInfo] - * - * @return [bool] is_death_persistant - */ - int IsDeathPersistent(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsDeathPersistent()); - return 1; - } - - /** - * Returns a boolean indicating whether the [SpellInfo] requires a dead target - * - * @return [bool] : true if the [SpellInfo] requires a dead target; false otherwise - */ - int IsRequiringDeadTarget(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsRequiringDeadTarget()); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] allows casting on dead targets, `false` otherwise. - * - * @return bool allowsDeadTarget - */ - int IsAllowingDeadTarget(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsAllowingDeadTarget()); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] can be cast while in combat, `false` otherwise. - * - * @return bool usableInCombat - */ - int CanBeUsedInCombat(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->CanBeUsedInCombat()); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] is considered a positive (beneficial) spell, `false` otherwise. - * - * @return bool isPositive - */ - int IsPositive(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsPositive()); - return 1; - } - - /** - * Returns `true` if the specified effect index of the [SpellInfo] is positive, `false` otherwise. - * - * @param uint8 effIndex - * @return bool isPositiveEffect - */ - int IsPositiveEffect(lua_State* L, SpellInfo* spell_info) - { - uint8 effIndex = ALE::CHECKVAL(L, 2); - ALE::Push(L, spell_info->IsPositiveEffect(effIndex)); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] is a channeled spell, `false` otherwise. - * - * @return bool isChanneled - */ - int IsChanneled(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsChanneled()); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] requires combo points to cast, `false` otherwise. - * - * @return bool needsComboPoints - */ - int NeedsComboPoints(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->NeedsComboPoints()); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] breaks stealth when cast, `false` otherwise. - * - * @return bool breaksStealth - */ - int IsBreakingStealth(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsBreakingStealth()); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] is a ranged weapon attack (e.g., shoot, throw), `false` otherwise. - * - * @return bool isRangedWeaponSpell - */ - int IsRangedWeaponSpell(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsRangedWeaponSpell()); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] is an auto-repeat ranged spell (e.g., auto-shot), `false` otherwise. - * - * @return bool isAutoRepeat - */ - int IsAutoRepeatRangedSpell(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsAutoRepeatRangedSpell()); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] is affected by spell modifiers (e.g., talents, auras), `false` otherwise. - * - * @return bool isAffectedByMods - */ - int IsAffectedBySpellMods(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsAffectedBySpellMods()); - return 1; - } - - /* int IsAffectedBySpellMod(lua_State* L, SpellInfo* spell_info) - { - const SpellInfo* auraSpellInfo = ALE::CHECKOBJ(L, 2); - ALE::Push(L, spell_info->IsAffectedBySpellMod(auraSpellInfo)); - return 1; - } - */ - - /** - * Returns `true` if the [SpellInfo] can pierce through an immunity aura defined by the given [SpellInfo], `false` otherwise. - * - * @param [SpellInfo] auraSpellInfo : the spell representing the immunity aura - * @return bool canPierce - */ - int CanPierceImmuneAura(lua_State* L, SpellInfo* spell_info) - { - const SpellInfo* auraSpellInfo = ALE::CHECKOBJ(L, 2); - ALE::Push(L, spell_info->CanPierceImmuneAura(auraSpellInfo)); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] can dispel the specified aura [SpellInfo], `false` otherwise. - * - * @param [SpellInfo] auraSpellInfo : the aura spell to check - * @return bool canDispel - */ - int CanDispelAura(lua_State* L, SpellInfo* spell_info) - { - const SpellInfo* auraSpellInfo = ALE::CHECKOBJ(L, 2); - ALE::Push(L, spell_info->CanDispelAura(auraSpellInfo)); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] only affects a single target, `false` if it affects multiple or area targets. - * - * @return bool isSingleTarget - */ - int IsSingleTarget(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->IsSingleTarget()); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] is mutually exclusive with the specified [SpellInfo] due to specific aura exclusivity rules. - * - * @param [SpellInfo] otherSpellInfo : the spell to compare exclusivity with - * @return bool isExclusive - */ - int IsAuraExclusiveBySpecificWith(lua_State* L, SpellInfo* spell_info) - { - const SpellInfo* spellInfo = ALE::CHECKOBJ(L, 2); - ALE::Push(L, spell_info->IsAuraExclusiveBySpecificWith(spellInfo)); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] is exclusive with the specified [SpellInfo] per caster, based on aura exclusivity rules. - * - * @param [SpellInfo] otherSpellInfo : the spell to compare exclusivity with - * @return bool isExclusivePerCaster - */ - int IsAuraExclusiveBySpecificPerCasterWith(lua_State* L, SpellInfo* spell_info) - { - const SpellInfo* spellInfo = ALE::CHECKOBJ(L, 2); - ALE::Push(L, spell_info->IsAuraExclusiveBySpecificPerCasterWith(spellInfo)); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] can be cast while in the specified shapeshift form. - * - * @param uint32 form : the shapeshift form to check - * @return bool isAllowed - */ - int CheckShapeshift(lua_State* L, SpellInfo* spell_info) - { - uint32 form = ALE::CHECKVAL(L, 2); - ALE::Push(L, spell_info->CheckShapeshift(form)); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] can be cast in the specified location. - * - * @param uint32 map_id : required map ID - * @param uint32 zone_id : required zone ID - * @param uint32 area_id : required area ID - * @param [Player] player : the [Player] casting the spell - * @param bool strict = false : whether all conditions must strictly match - * @return bool isAllowed - */ - int CheckLocation(lua_State* L, SpellInfo* spell_info) - { - uint32 map_id = ALE::CHECKVAL(L, 2); - uint32 zone_id = ALE::CHECKVAL(L, 3); - uint32 area_id = ALE::CHECKVAL(L, 4); - Player* player = ALE::CHECKOBJ(L, 5); - bool strict = ALE::CHECKVAL(L, 6, false); - - ALE::Push(L, spell_info->CheckLocation(map_id, zone_id, area_id, player, strict)); - return 1; - } - - /** - * Returns `true` if the target is valid for the [SpellInfo]. - * - * @param [Unit] caster : the [Unit] casting the spell - * @param [WorldObject] target : the intended target - * @param bool implicit = true : whether implicit target checks should apply - * @return bool isValid - */ - int CheckTarget(lua_State* L, SpellInfo* spell_info) - { - const Unit* caster = ALE::CHECKOBJ(L, 2); - const WorldObject* target = ALE::CHECKOBJ(L, 3); - bool implicit = ALE::CHECKVAL(L, 4, true); - - ALE::Push(L, spell_info->CheckTarget(caster, target, implicit)); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] can be explicitly cast on the given [target] with the optional [Item]. - * - * @param [Unit] caster : the [Unit] attempting to cast the spell - * @param [WorldObject] target : the intended target of the spell - * @param [Item] item : optional item used in the cast - * @return bool isValid - */ - int CheckExplicitTarget(lua_State* L, SpellInfo* spell_info) - { - const Unit* caster = ALE::CHECKOBJ(L, 2); - const WorldObject* target = ALE::CHECKOBJ(L, 3); - const Item* item = ALE::CHECKOBJ(L, 4, true); - - ALE::Push(L, spell_info->CheckExplicitTarget(caster, target, item)); - return 1; - } - - /** - * Returns `true` if the [SpellInfo] can affect the [Unit] based on its creature type. - * - * @param [Unit] target : the [Unit] whose creature type is evaluated - * @return bool isValid - */ - int CheckTargetCreatureType(lua_State* L, SpellInfo* spell_info) - { - const Unit* target = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, spell_info->CheckTargetCreatureType(target)); - return 1; - } - - /** - * Returns the school mask of the [SpellInfo]. - * - * The school mask is a bitmask representing the spell's school(s), such as arcane, fire, frost, etc. - * - * @return uint32 schoolMask - */ - int GetSchoolMask(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->GetSchoolMask()); - return 1; - } - - /** - * Returns a combined mechanic mask of all effects for the [SpellInfo]. - * - * The mechanic mask is a bitmask representing all mechanics applied by the spell’s effects. - * - * @return uint32 mechanicMask - */ - int GetAllEffectsMechanicMask(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->GetAllEffectsMechanicMask()); - return 1; - } - - /** - * Returns the mechanic mask of a specific effect of the [SpellInfo]. - * - * @param uint32 effIndex - * @return uint32 mechanicMask - */ - int GetEffectMechanicMask(lua_State* L, SpellInfo* spell_info) - { - uint32 effIndex = ALE::CHECKVAL(L, 2); - - ALE::Push(L, spell_info->GetEffectMechanicMask(static_cast(effIndex))); - return 1; - } - - /** - * Returns the mechanic mask for the [SpellInfo] based on an effect bitmask. - * - * @param uint32 effectmask : bitmask of effects to include - * @return uint32 mechanicMask - */ - int GetSpellMechanicMaskByEffectMask(lua_State* L, SpellInfo* spell_info) - { - uint32 effectmask = ALE::CHECKVAL(L, 2); - - ALE::Push(L, spell_info->GetSpellMechanicMaskByEffectMask(effectmask)); - return 1; - } - - /** - * Returns the mechanic of the specified effect index in the [SpellInfo]. - * - * @param uint32 effIndex - * @return uint32 mechanic - */ - int GetEffectMechanic(lua_State* L, SpellInfo* spell_info) - { - uint32 effIndex = ALE::CHECKVAL(L, 2); - - ALE::Push(L, spell_info->GetEffectMechanic(static_cast(effIndex))); - return 1; - } - - /** - * Returns the dispel mask for the [SpellInfo]. - * - * The dispel mask is a bitmask representing the types of dispels that can remove the spell's effects. - * - * @param uint32 type : optional type of dispel to check. If not provided, uses the spell's own dispel type. - * @return uint32 dispelMask - */ - int GetDispelMask(lua_State* L, SpellInfo* spell_info) - { - uint32 type = ALE::CHECKVAL(L, 2, false); - - ALE::Push(L, type != 0 ? spell_info->GetDispelMask(static_cast(type)) : spell_info->GetDispelMask()); - return 1; - } - - /** - * Returns the explicit target mask of the [SpellInfo]. - * - * This mask defines what types of targets the spell can explicitly target. - * - * @return uint32 targetMask - */ - int GetExplicitTargetMask(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->GetExplicitTargetMask()); - return 1; - } - - /** - * Returns the aura state requirement for the [SpellInfo]. - * - * Used to check whether a specific aura state must be active to cast the spell. - * - * @return uint32 auraState - */ - int GetAuraState(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->GetAuraState()); - return 1; - } - - /** - * Returns the spell specific type of the [SpellInfo]. - * - * Useful for identifying special types such as food, bandages, portals, etc. - * - * @return uint32 spellSpecific - */ - int GetSpellSpecific(lua_State* L, SpellInfo* spell_info) - { - ALE::Push(L, spell_info->GetSpellSpecific()); - return 1; - } - - /** - * Retrieves the MiscValueA of a spell effect at the specified index. - * - * MiscValueA contains additional information about the effect, such as: - * - Which stat is affected for stat modifiers - * - School mask for resistance changes - * - Item class for item creation effects - * - And more depending on the effect type - * - * @param uint8 effectIndex : The index of the effect (0, 1, or 2) - * @return int32 miscValueA : The MiscValueA value, or 0 if the effect doesn't exist - */ - int GetEffectMiscValueA(lua_State* L, SpellInfo* spell_info) - { - uint8 effectIndex = ALE::CHECKVAL(L, 2); - - if (effectIndex >= MAX_SPELL_EFFECTS) - { - ALE::Push(L, 0); - return 1; - } - - if (spell_info->Effects[effectIndex].Effect == 0) - { - ALE::Push(L, 0); - return 1; - } - - ALE::Push(L, spell_info->Effects[effectIndex].MiscValue); - return 1; - } - - /** - * Retrieves the MiscValueB of a spell effect at the specified index. - * - * MiscValueB contains secondary information about the effect. - * - * @param uint8 effectIndex : The index of the effect (0, 1, or 2) - * @return int32 miscValueB : The MiscValueB value, or 0 if the effect doesn't exist - */ - int GetEffectMiscValueB(lua_State* L, SpellInfo* spell_info) - { - uint8 effectIndex = ALE::CHECKVAL(L, 2); - - if (effectIndex >= MAX_SPELL_EFFECTS) - { - ALE::Push(L, 0); - return 1; - } - - if (spell_info->Effects[effectIndex].Effect == 0) - { - ALE::Push(L, 0); - return 1; - } - - ALE::Push(L, spell_info->Effects[effectIndex].MiscValueB); - return 1; - } -} -#endif diff --git a/src/LuaEngine/methods/SpellMethods.h b/src/LuaEngine/methods/SpellMethods.h deleted file mode 100644 index 52c14ef79a..0000000000 --- a/src/LuaEngine/methods/SpellMethods.h +++ /dev/null @@ -1,196 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef SPELLMETHODS_H -#define SPELLMETHODS_H - -/*** - * An instance of a spell, created when the spell is cast by a [Unit]. - * - * Inherits all methods from: none - */ -namespace LuaSpell -{ - /** - * Returns `true` if the [Spell] is automatically repeating, `false` otherwise. - * - * @return bool isAutoRepeating - */ - int IsAutoRepeat(lua_State* L, Spell* spell) - { - ALE::Push(L, spell->IsAutoRepeat()); - return 1; - } - - /** - * Returns the [Unit] that casted the [Spell]. - * - * @return [Unit] caster - */ - int GetCaster(lua_State* L, Spell* spell) - { - ALE::Push(L, spell->GetCaster()); - return 1; - } - - /** - * Returns the cast time of the [Spell]. - * - * @return int32 castTime - */ - int GetCastTime(lua_State* L, Spell* spell) - { - ALE::Push(L, spell->GetCastTime()); - return 1; - } - - /** - * Returns the entry ID of the [Spell]. - * - * @return uint32 entryId - */ - int GetEntry(lua_State* L, Spell* spell) - { - ALE::Push(L, spell->m_spellInfo->Id); - return 1; - } - - /** - * Returns the power cost of the [Spell]. - * - * @return uint32 powerCost - */ - int GetPowerCost(lua_State* L, Spell* spell) - { - ALE::Push(L, spell->GetPowerCost()); - return 1; - } - - /** - * Returns the reagents needed for the [Spell]. - * - * @return table reagents : a table containing the [ItemTemplate]s and amount of reagents needed for the [Spell] - */ - int GetReagentCost(lua_State* L, Spell* spell) - { - auto spellInfo = spell->GetSpellInfo(); - auto reagents = spellInfo->Reagent; - auto reagentCounts = spellInfo->ReagentCount; - lua_newtable(L); - for (auto i = 0; i < MAX_SPELL_REAGENTS; ++i) - { - if (reagents[i] <= 0) - continue; - auto reagent = eObjectMgr->GetItemTemplate(reagents[i]); - auto count = reagentCounts[i]; - ALE::Push(L, reagent); - ALE::Push(L, count); - lua_settable(L, -3); - } - return 1; - } - - /** - * Returns the spell duration of the [Spell]. - * - * @return int32 duration - */ - int GetDuration(lua_State* L, Spell* spell) - { - ALE::Push(L, spell->GetSpellInfo()->GetDuration()); - return 1; - } - - /** - * Returns the target destination coordinates of the [Spell]. - * - * @return float x : x coordinate of the [Spell] - * @return float y : y coordinate of the [Spell] - * @return float z : z coordinate of the [Spell] - */ - int GetTargetDest(lua_State* L, Spell* spell) - { - if (!spell->m_targets.HasDst()) - return 3; - float x, y, z; - spell->m_targets.GetDstPos()->GetPosition(x, y, z); - - ALE::Push(L, x); - ALE::Push(L, y); - ALE::Push(L, z); - return 3; - } - - /** - * Returns the target [Object] of the [Spell]. - * - * The target can be any of the following [Object] types: - * - [Player] - * - [Creature] - * - [GameObject] - * - [Item] - * - [Corpse] - * - * @return [Object] target - */ - int GetTarget(lua_State* L, Spell* spell) - { - if (GameObject* target = spell->m_targets.GetGOTarget()) - ALE::Push(L, target); - else if (Item* target = spell->m_targets.GetItemTarget()) - ALE::Push(L, target); - else if (Corpse* target = spell->m_targets.GetCorpseTarget()) - ALE::Push(L, target); - else if (Unit* target = spell->m_targets.GetUnitTarget()) - ALE::Push(L, target); - else if (WorldObject* target = spell->m_targets.GetObjectTarget()) - ALE::Push(L, target); - return 1; - } - - /** - * Sets the [Spell] to automatically repeat. - * - * @param bool repeat : set variable to 'true' for spell to automatically repeat - */ - int SetAutoRepeat(lua_State* L, Spell* spell) - { - bool repeat = ALE::CHECKVAL(L, 2); - spell->SetAutoRepeat(repeat); - return 0; - } - - /** - * Casts the [Spell]. - * - * @param bool skipCheck = false : skips initial checks to see if the [Spell] can be casted or not, this is optional - */ - int Cast(lua_State* L, Spell* spell) - { - bool skipCheck = ALE::CHECKVAL(L, 2, false); - spell->cast(skipCheck); - return 0; - } - - /** - * Cancels the [Spell]. - */ - int Cancel(lua_State* /*L*/, Spell* spell) - { - spell->cancel(); - return 0; - } - - /** - * Finishes the [Spell]. - */ - int Finish(lua_State* /*L*/, Spell* spell) - { - spell->finish(); - return 0; - } -}; -#endif diff --git a/src/LuaEngine/methods/TicketMethods.h b/src/LuaEngine/methods/TicketMethods.h deleted file mode 100644 index c158142910..0000000000 --- a/src/LuaEngine/methods/TicketMethods.h +++ /dev/null @@ -1,323 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef TICKETMETHODS_H -#define TICKETMETHODS_H - -/*** - * Represents a support ticket created by a [Player] using the in-game ticket system. - * - * Inherits all methods from: none - */ -namespace LuaTicket -{ - /** - * Returns true if the [Ticket] is closed or false. - * - * @return bool isClosed - */ - int IsClosed(lua_State* L, GmTicket* ticket) - { - ALE::Push(L, ticket->IsClosed()); - return 1; - } - - /** - * Returns true if the [Ticket] is completed or false. - * - * @return bool isCompleted - */ - int IsCompleted(lua_State* L, GmTicket* ticket) - { - ALE::Push(L, ticket->IsCompleted()); - return 1; - } - - /** - * Return true if this GUID is the same as the [Player] who created the [Ticket] or false. - * - * @param ObjectGuid playerGuid - * - * @return bool isSamePlayer - */ - int IsFromPlayer(lua_State* L, GmTicket* ticket) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - - ALE::Push(L, ticket->IsFromPlayer(guid)); - return 1; - } - - /** - * Return true if the [Ticket] is assigned or false. - * - * @return bool isAssigned - */ - int IsAssigned(lua_State* L, GmTicket* ticket) - { - ALE::Push(L, ticket->IsAssigned()); - return 1; - } - - /** - * Return true if the [Ticket] is assigned to the [Player] or false. - * - * @param ObjectGuid playerGuid - * - * @return bool isAssignedTo - */ - int IsAssignedTo(lua_State* L, GmTicket* ticket) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - - ALE::Push(L, ticket->IsAssignedTo(guid)); - return 1; - } - - /** - * Return true if the [Ticket] is not assigned to the [Player] or false. - * - * @param ObjectGuid playerGuid - * - * @return bool isAssignedNotTo - */ - int IsAssignedNotTo(lua_State* L, GmTicket* ticket) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - - ALE::Push(L, ticket->IsAssignedNotTo(guid)); - return 1; - } - - /** - * Return the [Ticket] id. - * - * @return uint32 ticketId - */ - int GetId(lua_State* L, GmTicket* ticket) - { - ALE::Push(L, ticket->GetId()); - return 1; - } - - /** - * Return the [Player] from the [Ticket]. - * - * @return [Player] player - */ - int GetPlayer(lua_State* L, GmTicket* ticket) - { - ALE::Push(L, ticket->GetPlayer()); - return 1; - } - - /** - * Return the [Player] name from the [Ticket]. - * - * @return string playerName - */ - int GetPlayerName(lua_State* L, GmTicket* ticket) - { - ALE::Push(L, ticket->GetPlayerName()); - return 1; - } - - /** - * Returns the message sent in the [Ticket]. - * - * @return string message - */ - int GetMessage(lua_State* L, GmTicket* ticket) - { - ALE::Push(L, ticket->GetMessage()); - return 1; - } - - /** - * Returns the assigned [Player]. - * - * @return [Player] assignedPlayer - */ - int GetAssignedPlayer(lua_State* L, GmTicket* ticket) - { - ALE::Push(L, ticket->GetAssignedPlayer()); - return 1; - } - - /** - * Returns the assigned guid. - * - * @return uint32 assignedGuid - */ - int GetAssignedToGUID(lua_State* L, GmTicket* ticket) - { - ALE::Push(L, ticket->GetAssignedToGUID()); - return 1; - } - - /** - * Returns the last modified time from the [Ticket]. - * - * @return uint64 lastModifiedTime - */ - int GetLastModifiedTime(lua_State* L, GmTicket* ticket) - { - ALE::Push(L, ticket->GetLastModifiedTime()); - return 1; - } - - /** - * Assign the [Ticket] to a player via his GUID. - * - * @param ObjectGuid playerGuid - * @param bool isAdmin : true if the [Player] is an Admin or false (default false) - */ - int SetAssignedTo(lua_State* L, GmTicket* ticket) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - bool is_admin = ALE::CHECKVAL(L, 2, false); - ticket->SetAssignedTo(guid, is_admin); - return 0; - } - - /** - * Set [Ticket] resolved by player via his GUID. - * - * @param ObjectGuid playerGuid - */ - int SetResolvedBy(lua_State* L, GmTicket* ticket) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - ticket->SetResolvedBy(guid); - return 0; - } - - /** - * Set [Ticket] completed. - * - */ - int SetCompleted(lua_State* /*L*/, GmTicket* ticket) - { - ticket->SetCompleted(); - return 0; - } - - /** - * Set [Ticket] message. - * - * @param string message: desired message - * - */ - int SetMessage(lua_State* L, GmTicket* ticket) - { - std::string message = ALE::CHECKVAL(L, 2); - - ticket->SetMessage(message); - return 0; - } - - /** - * Set [Ticket] comment. - * - * @param string comment: desired comment - * - */ - int SetComment(lua_State* L, GmTicket* ticket) - { - std::string comment = ALE::CHECKVAL(L, 2); - - ticket->SetComment(comment); - return 0; - } - - /** - * Set [Ticket] as viewed. - * - */ - int SetViewed(lua_State* /*L*/, GmTicket* ticket) - { - ticket->SetViewed(); - return 0; - } - - /** - * Set [Ticket] as unassigned. - * - */ - int SetUnassigned(lua_State* /*L*/, GmTicket* ticket) - { - ticket->SetUnassigned(); - return 0; - } - - /** - * Set the new [Ticket] creation position. - * - * @param uint32 mapId - * @param float x - * @param float y - * @param float z - * - */ - int SetPosition(lua_State* L, GmTicket* ticket) - { - uint32 mapId = ALE::CHECKVAL(L, 2); - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 2); - float z = ALE::CHECKVAL(L, 2); - - ticket->SetPosition(mapId, x, y, z); - return 0; - } - - /** - * Adds a response to the [Ticket]. - * - * @param string response: desired response - * - */ - int AppendResponse(lua_State* L, GmTicket* ticket) - { - std::string response = ALE::CHECKVAL(L, 2); - - ticket->AppendResponse(response); - return 0; - } - - /** - * Return the [Ticket] response. - * - * @return string response - */ - int GetResponse(lua_State* L, GmTicket* ticket) - { - ALE::Push(L, ticket->GetResponse()); - return 1; - } - - /** - * Delete the [Ticket] response. - * - */ - int DeleteResponse(lua_State* /*L*/, GmTicket* ticket) - { - ticket->DeleteResponse(); - return 0; - } - - /** - * Return the [Ticket] chatlog. - * - * @return string chatlog - */ - int GetChatLog(lua_State* L, GmTicket* ticket) - { - ALE::Push(L, ticket->GetChatLog()); - return 1; - } -}; -#endif - diff --git a/src/LuaEngine/methods/UnitMethods.h b/src/LuaEngine/methods/UnitMethods.h deleted file mode 100644 index 9e135f4e96..0000000000 --- a/src/LuaEngine/methods/UnitMethods.h +++ /dev/null @@ -1,2760 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef UNITMETHODS_H -#define UNITMETHODS_H - -/*** - * Represents a non-[Player] controlled [Unit] (i.e. NPCs). - * - * Inherits all methods from: [Object], [WorldObject] - */ -namespace LuaUnit -{ - /** - * Sets a mechanic immunity for the [Unit]. - * - *
-    *   MECHANIC_NONE             = 0,
-    *   MECHANIC_CHARM            = 1,
-    *   MECHANIC_DISORIENTED      = 2,
-    *   MECHANIC_DISARM           = 3,
-    *   MECHANIC_DISTRACT         = 4,
-    *   MECHANIC_FEAR             = 5,
-    *   MECHANIC_GRIP             = 6,
-    *   MECHANIC_ROOT             = 7,
-    *   MECHANIC_SLOW_ATTACK      = 8,
-    *   MECHANIC_SILENCE          = 9,
-    *   MECHANIC_SLEEP            = 10,
-    *   MECHANIC_SNARE            = 11,
-    *   MECHANIC_STUN             = 12,
-    *   MECHANIC_FREEZE           = 13,
-    *   MECHANIC_KNOCKOUT         = 14,
-    *   MECHANIC_BLEED            = 15,
-    *   MECHANIC_BANDAGE          = 16,
-    *   MECHANIC_POLYMORPH        = 17,
-    *   MECHANIC_BANISH           = 18,
-    *   MECHANIC_SHIELD           = 19,
-    *   MECHANIC_SHACKLE          = 20,
-    *   MECHANIC_MOUNT            = 21,
-    *   MECHANIC_INFECTED         = 22,
-    *   MECHANIC_TURN             = 23,
-    *   MECHANIC_HORROR           = 24,
-    *   MECHANIC_INVULNERABILITY  = 25,
-    *   MECHANIC_INTERRUPT        = 26,
-    *   MECHANIC_DAZE             = 27,
-    *   MECHANIC_DISCOVERY        = 28,
-    *   MECHANIC_IMMUNE_SHIELD    = 29,     // Divine (Blessing) Shield/Protection and Ice Block
-    *   MECHANIC_SAPPED           = 30,
-    *   MECHANIC_ENRAGED          = 31
-    * 
- * - * @param int32 immunity : new value for the immunity mask - * @param bool apply = true : if true, the immunity is applied, otherwise it is removed - */ - int SetImmuneTo(lua_State* L, Unit* unit) - { - int32 immunity = ALE::CHECKVAL(L, 2); - bool apply = ALE::CHECKVAL(L, 3, true); - - unit->ApplySpellImmune(0, 5, immunity, apply); - return 0; - } - - /** - * The [Unit] modifies a specific stat - * - * @param int32 stat : The stat to modify - * @param int8 type : The type of modifier to apply - * @param float value : The value to apply to the stat - * @param bool apply = false : Whether the modifier should be applied or removed - * @return bool : Whether the stat modification was successful - */ - int HandleStatFlatModifier(lua_State* L, Unit* unit) - { - int32 stat = ALE::CHECKVAL(L, 2); - int8 type = ALE::CHECKVAL(L, 3); - - float value = ALE::CHECKVAL(L, 4); - bool apply = ALE::CHECKVAL(L, 5, false); - - ALE::Push(L, unit->HandleStatFlatModifier(UnitMods(UNIT_MOD_STAT_START + stat), (UnitModifierFlatType)type, value, apply)); - return 1; - } - - /** - * The [Unit] tries to attack a given target - * - * @param [Unit] who : [Unit] to attack - * @param bool meleeAttack = false: attack with melee or not - * @return didAttack : if the [Unit] did not attack - */ - int Attack(lua_State* L, Unit* unit) - { - Unit* who = ALE::CHECKOBJ(L, 2); - bool meleeAttack = ALE::CHECKVAL(L, 3, false); - - ALE::Push(L, unit->Attack(who, meleeAttack)); - return 1; - } - - /** - * The [Unit] stops attacking its target - * - * @return bool isAttacking : if the [Unit] wasn't attacking already - */ - int AttackStop(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->AttackStop()); - return 1; - } - - /** - * Returns true if the [Unit] is standing. - * - * @return bool isStanding - */ - int IsStandState(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsStandState()); - return 1; - } - - /** - * Returns true if the [Unit] is mounted. - * - * @return bool isMounted - */ - int IsMounted(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsMounted()); - return 1; - } - - /** - * Returns true if the [Unit] is rooted. - * - * @return bool isRooted - */ - int IsRooted(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->HasRootAura() || unit->HasUnitMovementFlag(MOVEMENTFLAG_ROOT)); - - return 1; - } - - /** - * Returns true if the [Unit] has full health. - * - * @return bool hasFullHealth - */ - int IsFullHealth(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsFullHealth()); - return 1; - } - - /** - * Returns true if the [Unit] is in an accessible place for the given [Creature]. - * - * @param [WorldObject] obj - * @param float radius - * @return bool isAccessible - */ - int IsInAccessiblePlaceFor(lua_State* L, Unit* unit) - { - Creature* creature = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, unit->isInAccessiblePlaceFor(creature)); - - return 1; - } - - /** - * Returns true if the [Unit] an auctioneer. - * - * @return bool isAuctioneer - */ - int IsAuctioneer(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsAuctioner()); - - return 1; - } - - /** - * Returns true if the [Unit] a guild master. - * - * @return bool isGuildMaster - */ - int IsGuildMaster(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsGuildMaster()); - return 1; - } - - /** - * Returns true if the [Unit] an innkeeper. - * - * @return bool isInnkeeper - */ - int IsInnkeeper(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsInnkeeper()); - return 1; - } - - /** - * Returns true if the [Unit] a trainer. - * - * @return bool isTrainer - */ - int IsTrainer(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsTrainer()); - return 1; - } - - /** - * Returns true if the [Unit] is able to show a gossip window. - * - * @return bool hasGossip - */ - int IsGossip(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsGossip()); - return 1; - } - - /** - * Returns true if the [Unit] is a taxi master. - * - * @return bool isTaxi - */ - int IsTaxi(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsTaxi()); - return 1; - } - - /** - * Returns true if the [Unit] is a spirit healer. - * - * @return bool isSpiritHealer - */ - int IsSpiritHealer(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsSpiritHealer()); - return 1; - } - - /** - * Returns true if the [Unit] is a spirit guide. - * - * @return bool isSpiritGuide - */ - int IsSpiritGuide(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsSpiritGuide()); - return 1; - } - - /** - * Returns true if the [Unit] is a tabard designer. - * - * @return bool isTabardDesigner - */ - int IsTabardDesigner(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsTabardDesigner()); - return 1; - } - - /** - * Returns true if the [Unit] provides services like vendor, training and auction. - * - * @return bool isTabardDesigner - */ - int IsServiceProvider(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsServiceProvider()); - return 1; - } - - /** - * Returns true if the [Unit] is a spirit guide or spirit healer. - * - * @return bool isSpiritService - */ - int IsSpiritService(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsSpiritService()); - return 1; - } - - /** - * Returns true if the [Unit] is alive. - * - * @return bool isAlive - */ - int IsAlive(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsAlive()); - return 1; - } - - /** - * Returns true if the [Unit] is dead. - * - * @return bool isDead - */ - int IsDead(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->isDead()); - return 1; - } - - /** - * Returns true if the [Unit] is dying. - * - * @return bool isDying - */ - int IsDying(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->isDying()); - return 1; - } - - /** - * Returns true if the [Unit] is a banker. - * - * @return bool isBanker - */ - int IsBanker(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsBanker()); - return 1; - } - - /** - * Returns true if the [Unit] is a vendor. - * - * @return bool isVendor - */ - int IsVendor(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsVendor()); - return 1; - } - - /** - * Returns true if the [Unit] is a battle master. - * - * @return bool isBattleMaster - */ - int IsBattleMaster(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsBattleMaster()); - return 1; - } - - /** - * Returns true if the [Unit] is a charmed. - * - * @return bool isCharmed - */ - int IsCharmed(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsCharmed()); - return 1; - } - - /** - * Returns true if the [Unit] is an armorer and can repair equipment. - * - * @return bool isArmorer - */ - int IsArmorer(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsArmorer()); - return 1; - } - - /** - * Returns true if the [Unit] is attacking a player. - * - * @return bool isAttackingPlayer - */ - int IsAttackingPlayer(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->isAttackingPlayer()); - return 1; - } - - /** - * Returns true if the [Unit] flagged for PvP. - * - * @return bool isPvP - */ - int IsPvPFlagged(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsPvP()); - return 1; - } - - /** - * Returns true if the [Unit] is on a [Vehicle]. - * - * @return bool isOnVehicle - */ - int IsOnVehicle(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetVehicle()); - return 1; - } - - /** - * Returns true if the [Unit] is in combat. - * - * @return bool inCombat - */ - int IsInCombat(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsInCombat()); - return 1; - } - - /** - * Returns true if the [Unit] is under water. - * - * @return bool underWater - */ - int IsUnderWater(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsUnderWater()); - return 1; - } - - /** - * Returns true if the [Unit] is in water. - * - * @return bool inWater - */ - int IsInWater(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsInWater()); - return 1; - } - - /** - * Returns true if the [Unit] is not moving. - * - * @return bool notMoving - */ - int IsStopped(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsStopped()); - return 1; - } - - /** - * Returns true if the [Unit] is a quest giver. - * - * @return bool questGiver - */ - int IsQuestGiver(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsQuestGiver()); - return 1; - } - - /** - * Returns true if the [Unit]'s health is below the given percentage. - * - * @param int32 healthpct : percentage in integer from - * @return bool isBelow - */ - int HealthBelowPct(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->HealthBelowPct(ALE::CHECKVAL(L, 2))); - return 1; - } - - /** - * Returns true if the [Unit]'s health is above the given percentage. - * - * @param int32 healthpct : percentage in integer from - * @return bool isAbove - */ - int HealthAbovePct(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->HealthAbovePct(ALE::CHECKVAL(L, 2))); - return 1; - } - - /** - * Returns true if the [Unit] has an aura from the given spell entry. - * - * @param uint32 spell : entry of the aura spell - * @return bool hasAura - */ - int HasAura(lua_State* L, Unit* unit) - { - uint32 spell = ALE::CHECKVAL(L, 2); - - ALE::Push(L, unit->HasAura(spell)); - return 1; - } - - /** - * Returns true if the [Unit] is casting a spell - * - * @return bool isCasting - */ - int IsCasting(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->HasUnitState(UNIT_STATE_CASTING)); - return 1; - } - - /** - * Returns true if the [Unit] has the given unit state. - * - * @param [UnitState] state : an unit state - * @return bool hasState - */ - int HasUnitState(lua_State* L, Unit* unit) - { - uint32 state = ALE::CHECKVAL(L, 2); - ALE::Push(L, unit->HasUnitState(state)); - return 1; - } - - /*int IsVisible(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsVisible()); - return 1; - }*/ - - /*int IsMoving(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->isMoving()); - return 1; - }*/ - - /*int IsFlying(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->IsFlying()); - return 1; - }*/ - - /** - * Returns the [Unit]'s owner. - * - * @return [Unit] owner - */ - int GetOwner(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetOwner()); - return 1; - } - - /** - * Returns the [Unit]'s owner's GUID. - * - * @return ObjectGuid ownerGUID - */ - int GetOwnerGUID(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetOwnerGUID()); - return 1; - } - - /** - * Returns the [Unit]'s mount's modelID. - * - * @return uint32 mountId : displayId of the mount - */ - int GetMountId(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetMountID()); - return 1; - } - - /** - * Returns the [Unit]'s creator's GUID. - * - * @return ObjectGuid creatorGUID - */ - int GetCreatorGUID(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetCreatorGUID()); - return 1; - } - - /** - * Returns the [Unit]'s charmer's GUID. - * - * @return ObjectGuid charmerGUID - */ - int GetCharmerGUID(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetCharmerGUID()); - return 1; - } - - /** - * Returns the GUID of the [Unit]'s charmed entity. - * - * @return ObjectGuid charmedGUID - */ - int GetCharmGUID(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetCharmGUID()); - return 1; - } - - /** - * Returns the GUID of the [Unit]'s pet. - * - * @return ObjectGuid petGUID - */ - int GetPetGUID(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetPetGUID()); - return 1; - } - - /** - * Returns the GUID of the [Unit]'s charmer or owner. - * - * @return ObjectGuid controllerGUID - */ - int GetControllerGUID(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetCharmerOrOwnerGUID()); - return 1; - } - - /** - * Returns the GUID of the [Unit]'s charmer or owner or its own GUID. - * - * @return ObjectGuid controllerGUID - */ - int GetControllerGUIDS(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetCharmerOrOwnerOrOwnGUID()); - return 1; - } - - /** - * Returns [Unit]'s specified stat - * - * @param uint32 statType - * @return float stat - */ - int GetStat(lua_State* L, Unit* unit) - { - uint32 stat = ALE::CHECKVAL(L, 2); - - if (stat >= MAX_STATS) - return 1; - - ALE::Push(L, unit->GetStat((Stats)stat)); - return 1; - } - - /** - * Returns the [Unit]'s base spell power - * - * @param uint32 spellSchool - * @return uint32 spellPower - */ - int GetBaseSpellPower(lua_State* L, Unit* unit) - { - uint32 spellschool = ALE::CHECKVAL(L, 2); - - if (spellschool >= MAX_SPELL_SCHOOL) - return 1; - - ALE::Push(L, unit->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + spellschool)); - return 1; - } - - /** - * Returns the [Unit]'s current victim target or nil. - * - * @return [Unit] victim - */ - int GetVictim(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetVictim()); - return 1; - } - - /** - * Returns the currently casted [Spell] of given type or nil. - * - *
-     * enum CurrentSpellTypes
-     * {
-     *     CURRENT_MELEE_SPELL             = 0,
-     *     CURRENT_GENERIC_SPELL           = 1,
-     *     CURRENT_CHANNELED_SPELL         = 2,
-     *     CURRENT_AUTOREPEAT_SPELL        = 3
-     * };
-     * 
- * - * @param [CurrentSpellTypes] spellType - * @return [Spell] castedSpell - */ - int GetCurrentSpell(lua_State* L, Unit* unit) - { - uint32 type = ALE::CHECKVAL(L, 2); - if (type >= CURRENT_MAX_SPELL) - return luaL_argerror(L, 2, "valid CurrentSpellTypes expected"); - - ALE::Push(L, unit->GetCurrentSpell(type)); - return 1; - } - - /** - * Returns the [Unit]'s current stand state. - * - * @return uint8 standState - */ - int GetStandState(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->getStandState()); - return 1; - } - - /** - * Returns the [Unit]'s current display ID. - * - * @return uint32 displayId - */ - int GetDisplayId(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetDisplayId()); - return 1; - } - - /** - * Returns the [Unit]'s native/original display ID. - * - * @return uint32 displayId - */ - int GetNativeDisplayId(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetNativeDisplayId()); - return 1; - } - - /** - * Returns the [Unit]'s level. - * - * @return uint8 level - */ - int GetLevel(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetLevel()); - return 1; - } - - /** - * Returns the [Unit]'s health amount. - * - * @return uint32 healthAmount - */ - int GetHealth(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetHealth()); - return 1; - } - - Powers PowerSelectorHelper(lua_State* L, Unit* unit, int powerType = -1) - { - if (powerType == -1) - return unit->getPowerType(); - - if (powerType < 0 || powerType >= int(MAX_POWERS)) - luaL_argerror(L, 2, "valid Powers expected"); - - return (Powers)powerType; - } - - /** - * Returns the [Unit]'s power amount for given power type. - * - * enum Powers - * { - * POWER_MANA = 0, - * POWER_RAGE = 1, - * POWER_FOCUS = 2, - * POWER_ENERGY = 3, - * POWER_HAPPINESS = 4, - * POWER_RUNE = 5, - * POWER_RUNIC_POWER = 6, - * MAX_POWERS = 7, - * POWER_ALL = 127, // default for class? - * POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) - * }; - * - * @param int type = -1 : a valid power type from [Powers] or -1 for the [Unit]'s current power type - * @return uint32 powerAmount - */ - int GetPower(lua_State* L, Unit* unit) - { - int type = ALE::CHECKVAL(L, 2, -1); - Powers power = PowerSelectorHelper(L, unit, type); - - ALE::Push(L, unit->GetPower(power)); - return 1; - } - - /** - * Returns the [Unit]'s max power amount for given power type. - * - * enum Powers - * { - * POWER_MANA = 0, - * POWER_RAGE = 1, - * POWER_FOCUS = 2, - * POWER_ENERGY = 3, - * POWER_HAPPINESS = 4, - * POWER_RUNE = 5, - * POWER_RUNIC_POWER = 6, - * MAX_POWERS = 7, - * POWER_ALL = 127, // default for class? - * POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) - * }; - * - * @param int type = -1 : a valid power type from [Powers] or -1 for the [Unit]'s current power type - * @return uint32 maxPowerAmount - */ - int GetMaxPower(lua_State* L, Unit* unit) - { - int type = ALE::CHECKVAL(L, 2, -1); - Powers power = PowerSelectorHelper(L, unit, type); - - ALE::Push(L, unit->GetMaxPower(power)); - return 1; - } - - /** - * Returns the [Unit]'s power percent for given power type. - * - * enum Powers - * { - * POWER_MANA = 0, - * POWER_RAGE = 1, - * POWER_FOCUS = 2, - * POWER_ENERGY = 3, - * POWER_HAPPINESS = 4, - * POWER_RUNE = 5, - * POWER_RUNIC_POWER = 6, - * MAX_POWERS = 7, - * POWER_ALL = 127, // default for class? - * POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) - * }; - * - * @param int type = -1 : a valid power type from [Powers] or -1 for the [Unit]'s current power type - * @return float powerPct - */ - int GetPowerPct(lua_State* L, Unit* unit) - { - int type = ALE::CHECKVAL(L, 2, -1); - Powers power = PowerSelectorHelper(L, unit, type); - - float percent = ((float)unit->GetPower(power) / (float)unit->GetMaxPower(power)) * 100.0f; - - ALE::Push(L, percent); - return 1; - } - - /** - * Returns the [Unit]'s current power type. - * - * enum Powers - * { - * POWER_MANA = 0, - * POWER_RAGE = 1, - * POWER_FOCUS = 2, - * POWER_ENERGY = 3, - * POWER_HAPPINESS = 4, - * POWER_RUNE = 5, - * POWER_RUNIC_POWER = 6, - * MAX_POWERS = 7, - * POWER_ALL = 127, // default for class? - * POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) - * }; - * - * @return [Powers] powerType - */ - int GetPowerType(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->getPowerType()); - return 1; - } - - /** - * Returns the [Unit]'s max health. - * - * @return uint32 maxHealth - */ - int GetMaxHealth(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetMaxHealth()); - return 1; - } - - /** - * Returns the [Unit]'s health percent. - * - * @return float healthPct - */ - int GetHealthPct(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetHealthPct()); - return 1; - } - - /** - * Returns the [Unit]'s gender. - * - * @return uint8 gender : 0 for male, 1 for female and 2 for none - */ - int GetGender(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->getGender()); - return 1; - } - - /** - * Returns the [Unit]'s race ID. - * - * @return [Races] race - */ - int GetRace(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->getRace()); - return 1; - } - - /** - * Returns the [Unit]'s class ID. - * - * @return [Classes] class - */ - int GetClass(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->getClass()); - return 1; - } - - /** - * Returns the race mask - * - * @return uint32 racemask - */ - int GetRaceMask(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->getRaceMask()); - return 1; - } - - /** - * Returns the class mask - * - * @return uint32 classmask - */ - int GetClassMask(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->getClassMask()); - return 1; - } - - /** - * Returns the [Unit]'s creature type ID (enumerated in CreatureType.dbc). - * - *
-     * enum CreatureType
-     * {
-     *     CREATURE_TYPE_BEAST            = 1,
-     *     CREATURE_TYPE_DRAGONKIN        = 2,
-     *     CREATURE_TYPE_DEMON            = 3,
-     *     CREATURE_TYPE_ELEMENTAL        = 4,
-     *     CREATURE_TYPE_GIANT            = 5,
-     *     CREATURE_TYPE_UNDEAD           = 6,
-     *     CREATURE_TYPE_HUMANOID         = 7,
-     *     CREATURE_TYPE_CRITTER          = 8,
-     *     CREATURE_TYPE_MECHANICAL       = 9,
-     *     CREATURE_TYPE_NOT_SPECIFIED    = 10,
-     *     CREATURE_TYPE_TOTEM            = 11,
-     *     CREATURE_TYPE_NON_COMBAT_PET   = 12,     // This and below is TBC+
-     *     CREATURE_TYPE_GAS_CLOUD        = 13
-     * };
-     * 
- * - * @return [CreatureType] creatureType - */ - int GetCreatureType(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetCreatureType()); - return 1; - } - - /** - * Returns the [Unit]'s class' name in given or default locale or nil. - * - *
-     * enum LocaleConstant
-     * {
-     *     LOCALE_enUS = 0,
-     *     LOCALE_koKR = 1,
-     *     LOCALE_frFR = 2,
-     *     LOCALE_deDE = 3,
-     *     LOCALE_zhCN = 4,
-     *     LOCALE_zhTW = 5,
-     *     LOCALE_esES = 6,
-     *     LOCALE_esMX = 7,
-     *     LOCALE_ruRU = 8
-     * };
-     * 
- * - * @param [LocaleConstant] locale = DEFAULT_LOCALE - * @return string className : class name or nil - */ - int GetClassAsString(lua_State* L, Unit* unit) - { - uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE); - if (locale >= TOTAL_LOCALES) - return luaL_argerror(L, 2, "valid LocaleConstant expected"); - - const ChrClassesEntry* entry = sChrClassesStore.LookupEntry(unit->getClass()); - if (!entry) - return 1; - - ALE::Push(L, entry->name[locale]); - return 1; - } - - /** - * Returns the [Unit]'s race's name in given or default locale or nil. - * - *
-     * enum LocaleConstant
-     * {
-     *     LOCALE_enUS = 0,
-     *     LOCALE_koKR = 1,
-     *     LOCALE_frFR = 2,
-     *     LOCALE_deDE = 3,
-     *     LOCALE_zhCN = 4,
-     *     LOCALE_zhTW = 5,
-     *     LOCALE_esES = 6,
-     *     LOCALE_esMX = 7,
-     *     LOCALE_ruRU = 8
-     * };
-     * 
- * - * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the race name in - * @return string raceName : race name or nil - */ - int GetRaceAsString(lua_State* L, Unit* unit) - { - uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE); - if (locale >= TOTAL_LOCALES) - return luaL_argerror(L, 2, "valid LocaleConstant expected"); - - const ChrRacesEntry* entry = sChrRacesStore.LookupEntry(unit->getRace()); - if (!entry) - return 1; - - ALE::Push(L, entry->name[locale]); - return 1; - } - - /** - * Returns the [Unit]'s faction ID. - * - * @return uint32 faction - */ - int GetFaction(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetFaction()); - return 1; - } - - /** - * Returns the [Aura] of the given spell entry on the [Unit] or nil. - * - * @param uint32 spellID : entry of the aura spell - * @return [Aura] aura : aura object or nil - */ - int GetAura(lua_State* L, Unit* unit) - { - uint32 spellID = ALE::CHECKVAL(L, 2); - ALE::Push(L, unit->GetAura(spellID)); - return 1; - } - - /** - * Returns a table containing friendly [Unit]'s within given range of the [Unit]. - * - * @param float range = 533.333 : search radius - * @return table friendyUnits : table filled with friendly units - */ - int GetFriendlyUnitsInRange(lua_State* L, Unit* unit) - { - float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS); - - std::list list; - - Acore::AnyFriendlyUnitInObjectRangeCheck checker(unit, unit, range); - Acore::UnitListSearcher searcher(unit, list, checker); - Cell::VisitObjects(unit, searcher, range); - - ALEUtil::ObjectGUIDCheck guidCheck(unit->GET_GUID()); - list.remove_if(guidCheck); - - lua_createtable(L, list.size(), 0); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) - { - ALE::Push(L, *it); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); - return 1; - } - - /** - * Returns a table containing unfriendly [Unit]'s within given range of the [Unit]. - * - * @param float range = 533.333 : search radius - * @return table unfriendyUnits : table filled with unfriendly units - */ - int GetUnfriendlyUnitsInRange(lua_State* L, Unit* unit) - { - float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS); - - std::list list; - Acore::AnyUnfriendlyUnitInObjectRangeCheck checker(unit, unit, range); - Acore::UnitListSearcher searcher(unit, list, checker); - Cell::VisitObjects(unit, searcher, range); - ALEUtil::ObjectGUIDCheck guidCheck(unit->GET_GUID()); - list.remove_if(guidCheck); - - lua_createtable(L, list.size(), 0); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) - { - ALE::Push(L, *it); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); - return 1; - } - - /** - * Returns [Unit]'s [Vehicle] methods - * - * @return [Vehicle] vehicle - */ - int GetVehicleKit(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetVehicleKit()); - return 1; - } - - /*int GetVehicle(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetVehicle()); - return 1; - }*/ - - /** - * Returns the Critter Guid - * - * @return ObjectGuid critterGuid - */ - int GetCritterGUID(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetCritterGUID()); - return 1; - } - - /** - * Returns the [Unit]'s speed of given [UnitMoveType]. - * - *
-     * enum UnitMoveType
-     * {
-     *     MOVE_WALK           = 0,
-     *     MOVE_RUN            = 1,
-     *     MOVE_RUN_BACK       = 2,
-     *     MOVE_SWIM           = 3,
-     *     MOVE_SWIM_BACK      = 4,
-     *     MOVE_TURN_RATE      = 5,
-     *     MOVE_FLIGHT         = 6,
-     *     MOVE_FLIGHT_BACK    = 7,
-     *     MOVE_PITCH_RATE     = 8
-     * };
-     * 
- * - * @param [UnitMoveType] type - * @return float speed - */ - int GetSpeed(lua_State* L, Unit* unit) - { - uint32 type = ALE::CHECKVAL(L, 2); - if (type >= MAX_MOVE_TYPE) - return luaL_argerror(L, 2, "valid UnitMoveType expected"); - - ALE::Push(L, unit->GetSpeed((UnitMoveType)type)); - - return 1; - } - - /** - * Returns the [Unit]'s speed rate of given [UnitMoveType]. - * - *
-    * enum UnitMoveType
-    * {
-    *     MOVE_WALK           = 0,
-    *     MOVE_RUN            = 1,
-    *     MOVE_RUN_BACK       = 2,
-    *     MOVE_SWIM           = 3,
-    *     MOVE_SWIM_BACK      = 4,
-    *     MOVE_TURN_RATE      = 5,
-    *     MOVE_FLIGHT         = 6,
-    *     MOVE_FLIGHT_BACK    = 7,
-    *     MOVE_PITCH_RATE     = 8
-    * };
-    * 
- * - * @param [UnitMoveType] type - * @return float speed - */ - int GetSpeedRate(lua_State* L, Unit* unit) - { - uint32 type = ALE::CHECKVAL(L, 2); - if (type >= MAX_MOVE_TYPE) - { - return luaL_argerror(L, 2, "valid UnitMoveType expected"); - } - - ALE::Push(L, unit->GetSpeedRate((UnitMoveType)type)); - - return 1; - } - - /** - * Returns the current movement type for this [Unit]. - * - *
-     * enum MovementGeneratorType
-     * {
-     *     IDLE_MOTION_TYPE                = 0,
-     *     RANDOM_MOTION_TYPE              = 1,
-     *     WAYPOINT_MOTION_TYPE            = 2,
-     *     MAX_DB_MOTION_TYPE              = 3,
-     *     ANIMAL_RANDOM_MOTION_TYPE       = 3, // TC
-     *
-     *     CONFUSED_MOTION_TYPE            = 4,
-     *     CHASE_MOTION_TYPE               = 5,
-     *     HOME_MOTION_TYPE                = 6,
-     *     FLIGHT_MOTION_TYPE              = 7,
-     *     POINT_MOTION_TYPE               = 8,
-     *     FLEEING_MOTION_TYPE             = 9,
-     *     DISTRACT_MOTION_TYPE            = 10,
-     *     ASSISTANCE_MOTION_TYPE          = 11,
-     *     ASSISTANCE_DISTRACT_MOTION_TYPE = 12,
-     *     TIMED_FLEEING_MOTION_TYPE       = 13,
-     *     FOLLOW_MOTION_TYPE              = 14,
-     *     EFFECT_MOTION_TYPE              = 15, // mangos
-     *     ROTATE_MOTION_TYPE              = 15, // TC
-     *     EFFECT_MOTION_TYPE              = 16, // TC
-     *     NULL_MOTION_TYPE                = 17, // TC
-     * };
-     * 
- * - * @return [MovementGeneratorType] movementType - */ - int GetMovementType(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->GetMotionMaster()->GetCurrentMovementGeneratorType()); - return 1; - } - - /** - * Returns the [Unit]'s attackers. - * - * @return table attackers : table of [Unit]s attacking the unit - */ - int GetAttackers(lua_State* L, Unit* unit) - { - const Unit::AttackerSet& attackers = unit->getAttackers(); - - lua_newtable(L); - int table = lua_gettop(L); - uint32 i = 1; - for (Unit* attacker : attackers) - { - if (!attacker) - { - continue; - } - - ALE::Push(L, attacker); - lua_rawseti(L, table, i); - ++i; - } - - lua_settop(L, table); // push table to top of stack - return 1; - } - - /** - * Sets the [Unit]'s owner GUID to given GUID. - * - * @param ObjectGuid guid : new owner guid - */ - int SetOwnerGUID(lua_State* L, Unit* unit) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - - unit->SetOwnerGUID(guid); - return 0; - } - - /** - * Sets the [Unit]'s PvP on or off. - * - * @param bool apply = true : true if set on, false if off - */ - int SetPvP(lua_State* L, Unit* unit) - { - bool apply = ALE::CHECKVAL(L, 2, true); - - unit->SetPvP(apply); - return 0; - } - - /** - * Sets the [Unit]'s sheath state. - * - * enum SheathState - * { - * SHEATH_STATE_UNARMED = 0, // non prepared weapon - * SHEATH_STATE_MELEE = 1, // prepared melee weapon - * SHEATH_STATE_RANGED = 2 // prepared ranged weapon - * }; - * - * @param [SheathState] sheathState : valid SheathState - */ - int SetSheath(lua_State* L, Unit* unit) - { - uint32 sheathed = ALE::CHECKVAL(L, 2); - if (sheathed >= MAX_SHEATH_STATE) - return luaL_argerror(L, 2, "valid SheathState expected"); - - unit->SetSheath((SheathState)sheathed); - return 0; - } - - /** - * Sets the [Unit]'s name internally. - * - * @param string name : new name - */ - int SetName(lua_State* L, Unit* unit) - { - const char* name = ALE::CHECKVAL(L, 2); - if (std::string(name).length() > 0) - unit->SetName(name); - return 0; - } - - /** - * Sets the [Unit]'s speed of given [UnitMoveType] to given speed. - * If forced, packets sent to clients forcing the visual change. - * - *
-     * enum UnitMoveType
-     * {
-     *     MOVE_WALK           = 0,
-     *     MOVE_RUN            = 1,
-     *     MOVE_RUN_BACK       = 2,
-     *     MOVE_SWIM           = 3,
-     *     MOVE_SWIM_BACK      = 4,
-     *     MOVE_TURN_RATE      = 5,
-     *     MOVE_FLIGHT         = 6,
-     *     MOVE_FLIGHT_BACK    = 7,
-     *     MOVE_PITCH_RATE     = 8
-     * };
-     * 
- * - * @param [UnitMoveType] type - * @param float rate - * @param bool forced = false - */ - int SetSpeed(lua_State* L, Unit* unit) - { - uint32 type = ALE::CHECKVAL(L, 2); - float rate = ALE::CHECKVAL(L, 3); - bool forced = ALE::CHECKVAL(L, 4, false); - if (type >= MAX_MOVE_TYPE) - return luaL_argerror(L, 2, "valid UnitMoveType expected"); - - unit->SetSpeed((UnitMoveType)type, rate, forced); - - return 0; - } - - /** - * Sets the [Unit]'s speed rate of given [UnitMoveType] to given rate. - * If forced, packets sent to clients forcing the visual change. - * - *
-     * enum UnitMoveType
-     * {
-     *     MOVE_WALK           = 0,
-     *     MOVE_RUN            = 1,
-     *     MOVE_RUN_BACK       = 2,
-     *     MOVE_SWIM           = 3,
-     *     MOVE_SWIM_BACK      = 4,
-     *     MOVE_TURN_RATE      = 5,
-     *     MOVE_FLIGHT         = 6,
-     *     MOVE_FLIGHT_BACK    = 7,
-     *     MOVE_PITCH_RATE     = 8
-     * };
-     * 
- * - * @param [UnitMoveType] type - * @param float rate - * @param bool forced = false - */ - int SetSpeedRate(lua_State* L, Unit* unit) - { - uint32 type = ALE::CHECKVAL(L, 2); - float rate = ALE::CHECKVAL(L, 3); - if (type >= MAX_MOVE_TYPE) - return luaL_argerror(L, 2, "valid UnitMoveType expected"); - - unit->SetSpeedRate((UnitMoveType)type, rate); - - return 0; - } - - /** - * Sets the [Unit]'s faction. - * - * @param uint32 faction : new faction ID - */ - int SetFaction(lua_State* L, Unit* unit) - { - uint32 factionId = ALE::CHECKVAL(L, 2); - - unit->SetFaction(factionId); - - return 0; - } - - /** - * Sets the [Unit]'s level. - * - * @param uint8 level : new level - */ - int SetLevel(lua_State* L, Unit* unit) - { - uint8 newlevel = ALE::CHECKVAL(L, 2); - - if (newlevel < 1) - return luaL_argerror(L, 2, "level cannot be below 1"); - - if (Player* player = unit->ToPlayer()) - { - player->GiveLevel(newlevel); - player->InitTalentForLevel(); - player->SetUInt32Value(PLAYER_XP, 0); - } - else - unit->SetLevel(newlevel); - - return 0; - } - - /** - * Sets the [Unit]'s health. - * - * @param uint32 health : new health - */ - int SetHealth(lua_State* L, Unit* unit) - { - uint32 amt = ALE::CHECKVAL(L, 2); - unit->SetHealth(amt); - return 0; - } - - /** - * Sets the [Unit]'s max health. - * - * @param uint32 maxHealth : new max health - */ - int SetMaxHealth(lua_State* L, Unit* unit) - { - uint32 amt = ALE::CHECKVAL(L, 2); - unit->SetMaxHealth(amt); - return 0; - } - - /** - * Sets the [Unit]'s power amount for the given power type. - * - * enum Powers - * { - * POWER_MANA = 0, - * POWER_RAGE = 1, - * POWER_FOCUS = 2, - * POWER_ENERGY = 3, - * POWER_HAPPINESS = 4, - * POWER_RUNE = 5, - * POWER_RUNIC_POWER = 6, - * MAX_POWERS = 7, - * POWER_ALL = 127, // default for class? - * POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) - * }; - * - * @param uint32 amount : new power amount - * @param int type = -1 : a valid power type from [Powers] or -1 for the [Unit]'s current power type - */ - int SetPower(lua_State* L, Unit* unit) - { - uint32 amt = ALE::CHECKVAL(L, 2); - int type = ALE::CHECKVAL(L, 3, -1); - Powers power = PowerSelectorHelper(L, unit, type); - - unit->SetPower(power, amt); - return 0; - } - - /** - * modifies the [Unit]'s power amount for the given power type. - * - * enum Powers - * { - * POWER_MANA = 0, - * POWER_RAGE = 1, - * POWER_FOCUS = 2, - * POWER_ENERGY = 3, - * POWER_HAPPINESS = 4, - * POWER_RUNE = 5, - * POWER_RUNIC_POWER = 6, - * MAX_POWERS = 7, - * POWER_ALL = 127, // default for class? - * POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) - * }; - * - * @param int32 amount : amount to modify - * @param int type = -1 : a valid power type from [Powers] or -1 for the [Unit]'s current power type - */ - int ModifyPower(lua_State* L, Unit* unit) - { - int32 amt = ALE::CHECKVAL(L, 2); - int type = ALE::CHECKVAL(L, 3, -1); - Powers power = PowerSelectorHelper(L, unit, type); - - unit->ModifyPower(power, amt); - return 0; - } - - /** - * Sets the [Unit]'s max power amount for the given power type. - * - * enum Powers - * { - * POWER_MANA = 0, - * POWER_RAGE = 1, - * POWER_FOCUS = 2, - * POWER_ENERGY = 3, - * POWER_HAPPINESS = 4, - * POWER_RUNE = 5, - * POWER_RUNIC_POWER = 6, - * MAX_POWERS = 7, - * POWER_ALL = 127, // default for class? - * POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) - * }; - * - * @param int type = -1 : a valid power type from [Powers] or -1 for the [Unit]'s current power type - * @param uint32 maxPower : new max power amount - */ - int SetMaxPower(lua_State* L, Unit* unit) - { - int type = ALE::CHECKVAL(L, 2, -1); - uint32 amt = ALE::CHECKVAL(L, 3); - Powers power = PowerSelectorHelper(L, unit, type); - - unit->SetMaxPower(power, amt); - return 0; - } - - /** - * Sets the [Unit]'s power type. - * - * enum Powers - * { - * POWER_MANA = 0, - * POWER_RAGE = 1, - * POWER_FOCUS = 2, - * POWER_ENERGY = 3, - * POWER_HAPPINESS = 4, - * POWER_RUNE = 5, - * POWER_RUNIC_POWER = 6, - * MAX_POWERS = 7, - * POWER_ALL = 127, // default for class? - * POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) - * }; - * - * @param [Powers] type : a valid power type - */ - int SetPowerType(lua_State* L, Unit* unit) - { - uint32 type = ALE::CHECKVAL(L, 2); - if (type >= int(MAX_POWERS)) - return luaL_argerror(L, 2, "valid Powers expected"); - - unit->setPowerType((Powers)type); - return 0; - } - - /** - * Sets the [Unit]'s modelID. - * - * @param uint32 displayId - */ - int SetDisplayId(lua_State* L, Unit* unit) - { - uint32 model = ALE::CHECKVAL(L, 2); - unit->SetDisplayId(model); - return 0; - } - - /** - * Sets the [Unit]'s native/default modelID. - * - * @param uint32 displayId - */ - int SetNativeDisplayId(lua_State* L, Unit* unit) - { - uint32 model = ALE::CHECKVAL(L, 2); - unit->SetNativeDisplayId(model); - return 0; - } - - /** - * Sets the [Unit]'s facing/orientation. - * - * @param uint32 orientation - */ - int SetFacing(lua_State* L, Unit* unit) - { - float o = ALE::CHECKVAL(L, 2); - unit->SetFacingTo(o); - return 0; - } - - /** - * Sets the [Unit] to face the given [WorldObject]'s direction. - * - * @param [WorldObject] target - */ - int SetFacingToObject(lua_State* L, Unit* unit) - { - WorldObject* obj = ALE::CHECKOBJ(L, 2); - unit->SetFacingToObject(obj); - return 0; - } - - /** - * Sets creator GUID - * - * @param ObjectGuid guid - */ - int SetCreatorGUID(lua_State* L, Unit* unit) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - unit->SetCreatorGUID(guid); - return 0; - } - - /** - * Sets pet GUID - * - * @param ObjectGuid guid - */ - int SetPetGUID(lua_State* L, Unit* unit) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - unit->SetPetGUID(guid); - return 0; - } - - /** - * Toggles (Sets) [Unit]'s water walking - * - * @param bool enable = true - */ - int SetWaterWalk(lua_State* L, Unit* unit) - { - bool enable = ALE::CHECKVAL(L, 2, true); - unit->SetWaterWalking(enable); - return 0; - } - - /** - * Sets the [Unit]'s stand state - * - * @param uint8 state : stand state - */ - int SetStandState(lua_State* L, Unit* unit) - { - uint8 state = ALE::CHECKVAL(L, 2); - unit->SetStandState(state); - return 0; - } - - /** - * Sets the [Unit] in combat with the `enemy` [Unit]. - * - * @param [Unit] enemy : the [Unit] to start combat with - */ - int SetInCombatWith(lua_State* L, Unit* unit) - { - Unit* enemy = ALE::CHECKOBJ(L, 2); - unit->SetInCombatWith(enemy); - return 0; - } - - /** - * Sets the [Unit]'s FFA flag on or off. - * - * @param bool apply = true - */ - int SetFFA(lua_State* L, Unit* unit) - { - bool apply = ALE::CHECKVAL(L, 2, true); - - if (apply) - { - unit->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); - for (Unit::ControlSet::iterator itr = unit->m_Controlled.begin(); itr != unit->m_Controlled.end(); ++itr) - (*itr)->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); - } - else - { - unit->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); - for (Unit::ControlSet::iterator itr = unit->m_Controlled.begin(); itr != unit->m_Controlled.end(); ++itr) - (*itr)->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); - } - return 0; - } - - /** - * Sets the [Unit]'s sanctuary flag on or off. - * - * @param bool apply = true - */ - int SetSanctuary(lua_State* L, Unit* unit) - { - bool apply = ALE::CHECKVAL(L, 2, true); - - if (apply) - { - unit->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY); - unit->CombatStop(); - unit->CombatStopWithPets(); - } - else - unit->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY); - - return 0; - } - - /** - * Sets the [Unit]'s critter companion by GUID. - * - * This method assigns the specified [ObjectGuid] as the critter (non-combat pet) companion of the [Unit]. - * - * @param [ObjectGuid] guid : The GUID of the critter to set - */ - int SetCritterGUID(lua_State* L, Unit* unit) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - unit->SetCritterGUID(guid); - return 0; - } - - /*int SetStunned(lua_State* L, Unit* unit) - { - bool apply = ALE::CHECKVAL(L, 2, true); - unit->SetControlled(apply, UNIT_STATE_STUNNED); - return 0; - }*/ - - /** - * Roots the [Unit] to the ground, if 'false' specified, unroots the [Unit]. - * - * @param bool apply = true - */ - int SetRooted(lua_State* L, Unit* unit) - { - bool apply = ALE::CHECKVAL(L, 2, true); - unit->SetControlled(apply, UNIT_STATE_ROOT); - return 0; - } - - /** - * Confuses the [Unit], if 'false' specified, the [Unit] is no longer confused. - * - * @param bool apply = true - */ - int SetConfused(lua_State* L, Unit* unit) - { - bool apply = ALE::CHECKVAL(L, 2, true); - unit->SetControlled(apply, UNIT_STATE_CONFUSED); - return 0; - } - - /** - * Fears the [Unit], if 'false' specified, the [Unit] is no longer feared. - * - * @param bool apply = true - */ - int SetFeared(lua_State* L, Unit* unit) - { - bool apply = ALE::CHECKVAL(L, 2, true); - unit->SetControlled(apply, UNIT_STATE_FLEEING); - return 0; - } - - /*int SetCanFly(lua_State* L, Unit* unit) - { - bool apply = ALE::CHECKVAL(L, 2, true); - unit->SetCanFly(apply); - return 0; - }*/ - - /*int SetVisible(lua_State* L, Unit* unit) - { - bool x = ALE::CHECKVAL(L, 2, true); - unit->SetVisible(x); - return 0; - }*/ - - /** - * Clears the [Unit]'s threat list. - */ - int ClearThreatList(lua_State* /*L*/, Unit* unit) - { - unit->GetThreatMgr().ClearAllThreat(); - return 0; - } - - /** - * Returns the [Unit]'s threat list. - * - * @return table threatList : table of [Unit]s in the threat list - */ - int GetThreatList(lua_State* L, Unit* unit) - { - if (!unit->CanHaveThreatList()) - { - ALE::Push(L); - return 1; - } - - ThreatContainer::StorageType const& list = unit->GetThreatMgr().GetThreatList(); - - lua_newtable(L); - int table = lua_gettop(L); - uint32 i = 1; - for (ThreatReference* item : list) - { - if (!item) - { - continue; - } - Unit* victim = item->GetVictim(); - if (!victim) - { - continue; - } - - ALE::Push(L, victim); - lua_rawseti(L, table, i); - ++i; - } - - lua_settop(L, table); // push table to top of stack - return 1; - } - - /** - * Mounts the [Unit] on the given displayID/modelID. - * - * @param uint32 displayId - */ - int Mount(lua_State* L, Unit* unit) - { - uint32 displayId = ALE::CHECKVAL(L, 2); - - unit->Mount(displayId); - return 0; - } - - /** - * Dismounts the [Unit]. - */ - int Dismount(lua_State* /*L*/, Unit* unit) - { - if (unit->IsMounted()) - { - unit->Dismount(); - unit->RemoveAurasByType(SPELL_AURA_MOUNTED); - } - - return 0; - } - - /** - * Makes the [Unit] perform the given emote. - * - * @param uint32 emoteId - */ - int PerformEmote(lua_State* L, Unit* unit) - { - unit->HandleEmoteCommand(ALE::CHECKVAL(L, 2)); - return 0; - } - - /** - * Makes the [Unit] perform the given emote continuously. - * - * @param uint32 emoteId - */ - int EmoteState(lua_State* L, Unit* unit) - { - uint32 emoteId = ALE::CHECKVAL(L, 2); - - unit->SetUInt32Value(UNIT_NPC_EMOTESTATE, emoteId); - return 0; - } - - /** - * Returns calculated percentage from Health - * - * @return int32 percentage - */ - int CountPctFromCurHealth(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->CountPctFromCurHealth(ALE::CHECKVAL(L, 2))); - return 1; - } - - /** - * Returns calculated percentage from Max Health - * - * @return int32 percentage - */ - int CountPctFromMaxHealth(lua_State* L, Unit* unit) - { - ALE::Push(L, unit->CountPctFromMaxHealth(ALE::CHECKVAL(L, 2))); - return 1; - } - - /** - * Sends chat message to [Player] - * - * @param uint8 type : chat, whisper, etc - * @param uint32 lang : language to speak - * @param string msg - * @param [Player] target - */ - int SendChatMessageToPlayer(lua_State* L, Unit* unit) - { - uint8 type = ALE::CHECKVAL(L, 2); - uint32 lang = ALE::CHECKVAL(L, 3); - std::string msg = ALE::CHECKVAL(L, 4); - Player* target = ALE::CHECKOBJ(L, 5); - - if (type >= MAX_CHAT_MSG_TYPE) - return luaL_argerror(L, 2, "valid ChatMsg expected"); - if (lang >= LANGUAGES_COUNT) - return luaL_argerror(L, 3, "valid Language expected"); - - WorldPacket data; - ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), unit, target, msg); - target->GetSession()->SendPacket(&data); - return 0; - } - - /*static void PrepareMove(Unit* unit) - { - unit->GetMotionMaster()->MovementExpired(); // Chase - unit->StopMoving(); // Some - unit->GetMotionMaster()->Clear(); // all - }*/ - - /** - * Stops the [Unit]'s movement - */ - int MoveStop(lua_State* /*L*/, Unit* unit) - { - unit->StopMoving(); - return 0; - } - - /** - * The [Unit]'s movement expires and clears movement - * - * @param bool reset = true : cleans movement - */ - int MoveExpire(lua_State* L, Unit* unit) - { - bool reset = ALE::CHECKVAL(L, 2, true); - unit->GetMotionMaster()->MovementExpired(reset); - return 0; - } - - /** - * Clears the [Unit]'s movement - * - * @param bool reset = true : clean movement - */ - int MoveClear(lua_State* L, Unit* unit) - { - bool reset = ALE::CHECKVAL(L, 2, true); - unit->GetMotionMaster()->Clear(reset); - return 0; - } - - /** - * The [Unit] will be idle - */ - int MoveIdle(lua_State* /*L*/, Unit* unit) - { - unit->GetMotionMaster()->MoveIdle(); - return 0; - } - - /** - * The [Unit] will move at random - * - * @param float radius : limit on how far the [Unit] will move at random - */ - int MoveRandom(lua_State* L, Unit* unit) - { - float radius = ALE::CHECKVAL(L, 2); - float x, y, z; - unit->GetPosition(x, y, z); - unit->GetMotionMaster()->MoveRandom(radius); - return 0; - } - - /** - * The [Unit] will move to its set home location - */ - int MoveHome(lua_State* /*L*/, Unit* unit) - { - unit->GetMotionMaster()->MoveTargetedHome(); - return 0; - } - - /** - * The [Unit] will follow the target - * - * @param [Unit] target : target to follow - * @param float dist = 0 : distance to start following - * @param float angle = 0 - */ - int MoveFollow(lua_State* L, Unit* unit) - { - Unit* target = ALE::CHECKOBJ(L, 2); - float dist = ALE::CHECKVAL(L, 3, 0.0f); - float angle = ALE::CHECKVAL(L, 4, 0.0f); - unit->GetMotionMaster()->MoveFollow(target, dist, angle); - return 0; - } - - /** - * The [Unit] will chase the target - * - * @param [Unit] target : target to chase - * @param float dist = 0 : distance start chasing - * @param float angle = 0 - */ - int MoveChase(lua_State* L, Unit* unit) - { - Unit* target = ALE::CHECKOBJ(L, 2); - float dist = ALE::CHECKVAL(L, 3, 0.0f); - float angle = ALE::CHECKVAL(L, 4, 0.0f); - unit->GetMotionMaster()->MoveChase(target, dist, angle); - return 0; - } - - /** - * The [Unit] will move confused - */ - int MoveConfused(lua_State* /*L*/, Unit* unit) - { - unit->GetMotionMaster()->MoveConfused(); - return 0; - } - - /** - * The [Unit] will flee - * - * @param [Unit] target - * @param uint32 time = 0 : flee delay - */ - int MoveFleeing(lua_State* L, Unit* unit) - { - Unit* target = ALE::CHECKOBJ(L, 2); - uint32 time = ALE::CHECKVAL(L, 3, 0); - unit->GetMotionMaster()->MoveFleeing(target, time); - return 0; - } - - /** - * The [Unit] will move to the coordinates - * - * @param uint32 id : unique waypoint Id - * @param float x - * @param float y - * @param float z - * @param bool genPath = true : if true, generates path - */ - int MoveTo(lua_State* L, Unit* unit) - { - uint32 id = ALE::CHECKVAL(L, 2); - float x = ALE::CHECKVAL(L, 3); - float y = ALE::CHECKVAL(L, 4); - float z = ALE::CHECKVAL(L, 5); - bool genPath = ALE::CHECKVAL(L, 6, true); - unit->GetMotionMaster()->MovePoint(id, x, y, z, FORCED_MOVEMENT_NONE, 0.f, 0.f, genPath); - return 0; - } - - /** - * Makes the [Unit] jump to the coordinates - * - * @param float x - * @param float y - * @param float z - * @param float zSpeed : start velocity - * @param float maxHeight : maximum height - * @param uint32 id = 0 : unique movement Id - */ - int MoveJump(lua_State* L, Unit* unit) - { - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 3); - float z = ALE::CHECKVAL(L, 4); - float zSpeed = ALE::CHECKVAL(L, 5); - float maxHeight = ALE::CHECKVAL(L, 6); - uint32 id = ALE::CHECKVAL(L, 7, 0); - Position pos(x, y, z); - unit->GetMotionMaster()->MoveJump(pos, zSpeed, maxHeight, id); - return 0; - } - - /** - * The [Unit] will whisper the message to a [Player] - * - * @param string msg : message for the [Unit] to emote - * @param uint32 lang : language for the [Unit] to speak - * @param [Player] receiver : specific [Unit] to receive the message - * @param bool bossWhisper = false : is a boss whisper - */ - int SendUnitWhisper(lua_State* L, Unit* unit) - { - const char* msg = ALE::CHECKVAL(L, 2); - uint32 lang = ALE::CHECKVAL(L, 3); - (void)lang; // ensure that the variable is referenced in order to pass compiler checks - Player* receiver = ALE::CHECKOBJ(L, 4); - bool bossWhisper = ALE::CHECKVAL(L, 5, false); - if (std::string(msg).length() > 0) - unit->Whisper(msg, (Language)lang, receiver, bossWhisper); - return 0; - } - - /** - * The [Unit] will emote the message - * - * @param string msg : message for the [Unit] to emote - * @param [Unit] receiver = nil : specific [Unit] to receive the message - * @param bool bossEmote = false : is a boss emote - */ - int SendUnitEmote(lua_State* L, Unit* unit) - { - const char* msg = ALE::CHECKVAL(L, 2); - Unit* receiver = ALE::CHECKOBJ(L, 3, false); - bool bossEmote = ALE::CHECKVAL(L, 4, false); - if (std::string(msg).length() > 0) - unit->TextEmote(msg, receiver, bossEmote); - return 0; - } - - /** - * The [Unit] will say the message - * - * @param string msg : message for the [Unit] to say - * @param uint32 language : language for the [Unit] to speak - */ - int SendUnitSay(lua_State* L, Unit* unit) - { - const char* msg = ALE::CHECKVAL(L, 2); - uint32 language = ALE::CHECKVAL(L, 3); - if (std::string(msg).length() > 0) - unit->Say(msg, (Language)language, unit); - return 0; - } - - /** - * The [Unit] will yell the message - * - * @param string msg : message for the [Unit] to yell - * @param uint32 language : language for the [Unit] to speak - */ - int SendUnitYell(lua_State* L, Unit* unit) - { - const char* msg = ALE::CHECKVAL(L, 2); - uint32 language = ALE::CHECKVAL(L, 3); - if (std::string(msg).length() > 0) - unit->Yell(msg, (Language)language, unit); - return 0; - } - - /** - * Unmorphs the [Unit] setting it's display ID back to the native display ID. - */ - int DeMorph(lua_State* /*L*/, Unit* unit) - { - unit->DeMorph(); - return 0; - } - - /** - * Makes the [Unit] cast the spell on the target. - * - * @param [Unit] target = nil : can be self or another unit - * @param uint32 spell : entry of a spell - * @param bool triggered = false : if true the spell is instant and has no cost - */ - int CastSpell(lua_State* L, Unit* unit) - { - Unit* target = ALE::CHECKOBJ(L, 2, false); - uint32 spell = ALE::CHECKVAL(L, 3); - bool triggered = ALE::CHECKVAL(L, 4, false); - SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(spell); - if (!spellEntry) - return 0; - - unit->CastSpell(target, spell, triggered); - return 0; - } - - /** - * Casts the [Spell] at target [Unit] with custom basepoints or casters. - * See also [Unit:CastSpell]. - * - * @param [Unit] target = nil - * @param uint32 spell - * @param bool triggered = false - * @param int32 bp0 = nil : custom basepoints for [Spell] effect 1. If nil, no change is made - * @param int32 bp1 = nil : custom basepoints for [Spell] effect 2. If nil, no change is made - * @param int32 bp2 = nil : custom basepoints for [Spell] effect 3. If nil, no change is made - * @param [Item] castItem = nil - * @param ObjectGuid originalCaster = ObjectGuid() - */ - int CastCustomSpell(lua_State* L, Unit* unit) - { - Unit* target = ALE::CHECKOBJ(L, 2, false); - uint32 spell = ALE::CHECKVAL(L, 3); - bool triggered = ALE::CHECKVAL(L, 4, false); - bool has_bp0 = !lua_isnoneornil(L, 5); - int32 bp0 = ALE::CHECKVAL(L, 5, 0); - bool has_bp1 = !lua_isnoneornil(L, 6); - int32 bp1 = ALE::CHECKVAL(L, 6, 0); - bool has_bp2 = !lua_isnoneornil(L, 7); - int32 bp2 = ALE::CHECKVAL(L, 7, 0); - Item* castItem = ALE::CHECKOBJ(L, 8, false); - ObjectGuid originalCaster = ALE::CHECKVAL(L, 9, ObjectGuid()); - - unit->CastCustomSpell(target, spell, has_bp0 ? &bp0 : NULL, has_bp1 ? &bp1 : NULL, has_bp2 ? &bp2 : NULL, triggered, castItem, NULL, ObjectGuid(originalCaster)); - return 0; - } - - /** - * Makes the [Unit] cast the spell to the given coordinates, used for area effect spells. - * - * @param float x - * @param float y - * @param float z - * @param uint32 spell : entry of a spell - * @param bool triggered = false : if true the spell is instant and has no cost - */ - int CastSpellAoF(lua_State* L, Unit* unit) - { - float _x = ALE::CHECKVAL(L, 2); - float _y = ALE::CHECKVAL(L, 3); - float _z = ALE::CHECKVAL(L, 4); - uint32 spell = ALE::CHECKVAL(L, 5); - bool triggered = ALE::CHECKVAL(L, 6, true); - unit->CastSpell(_x, _y, _z, spell, triggered); - return 0; - } - - /** - * Clears the [Unit]'s combat - */ - int ClearInCombat(lua_State* /*L*/, Unit* unit) - { - unit->ClearInCombat(); - return 0; - } - - /** - * Stops the [Unit]'s current spell cast - * - * @param uint32 spell = 0 : entry of a spell - */ - int StopSpellCast(lua_State* L, Unit* unit) - { - uint32 spellId = ALE::CHECKVAL(L, 2, 0); - unit->CastStop(spellId); - return 0; - } - - /** - * Interrupts [Unit]'s spell state, casting, etc. - * - * if spell is not interruptible, it will return - * - * @param int32 spellType : type of spell to interrupt - * @param bool delayed = true : skips if the spell is delayed - */ - int InterruptSpell(lua_State* L, Unit* unit) - { - int spellType = ALE::CHECKVAL(L, 2); - bool delayed = ALE::CHECKVAL(L, 3, true); - switch (spellType) - { - case 0: - spellType = CURRENT_MELEE_SPELL; - break; - case 1: - spellType = CURRENT_GENERIC_SPELL; - break; - case 2: - spellType = CURRENT_CHANNELED_SPELL; - break; - case 3: - spellType = CURRENT_AUTOREPEAT_SPELL; - break; - default: - return luaL_argerror(L, 2, "valid CurrentSpellTypes expected"); - } - - unit->InterruptSpell((CurrentSpellTypes)spellType, delayed); - return 0; - } - - /** - * Adds the [Aura] of the given spell entry on the given target from the [Unit]. - * - * @param uint32 spell : entry of a spell - * @param [Unit] target : aura will be applied on the target - * @return [Aura] aura - */ - int AddAura(lua_State* L, Unit* unit) - { - uint32 spell = ALE::CHECKVAL(L, 2); - Unit* target = ALE::CHECKOBJ(L, 3); - SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(spell); - if (!spellEntry) - return 1; - - ALE::Push(L, unit->AddAura(spell, target)); - return 1; - } - - /** - * Removes [Aura] of the given spell entry from the [Unit]. - * - * @param uint32 spell : entry of a spell - */ - int RemoveAura(lua_State* L, Unit* unit) - { - uint32 spellId = ALE::CHECKVAL(L, 2); - unit->RemoveAurasDueToSpell(spellId); - return 0; - } - - /** - * Removes all [Aura]'s from the [Unit]. - * - * Note: talents and racials are also auras, use with caution - */ - int RemoveAllAuras(lua_State* /*L*/, Unit* unit) - { - unit->RemoveAllAuras(); - return 0; - } - - /** - * Removes all positive visible [Aura]'s from the [Unit]. - */ - int RemoveArenaAuras(lua_State* /*L*/, Unit* unit) - { - unit->RemoveArenaAuras(); - return 0; - } - - /** - * Adds the given unit state for the [Unit]. - * - * @param [UnitState] state - */ - int AddUnitState(lua_State* L, Unit* unit) - { - uint32 state = ALE::CHECKVAL(L, 2); - - unit->AddUnitState(state); - return 0; - } - - /** - * Removes the given unit state from the [Unit]. - * - * @param [UnitState] state - */ - int ClearUnitState(lua_State* L, Unit* unit) - { - uint32 state = ALE::CHECKVAL(L, 2); - - unit->ClearUnitState(state); - return 0; - } - - /** - * Makes the [Unit] teleport to given coordinates within same map. - * - * @param float x - * @param float y - * @param float z - * @param float o : orientation - */ - int NearTeleport(lua_State* L, Unit* unit) - { - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 3); - float z = ALE::CHECKVAL(L, 4); - float o = ALE::CHECKVAL(L, 5); - - unit->NearTeleportTo(x, y, z, o); - return 0; - } - - /** - * Makes the [Unit] damage the target [Unit] - * - *
-     * enum SpellSchools
-     * {
-     *     SPELL_SCHOOL_NORMAL  = 0,
-     *     SPELL_SCHOOL_HOLY    = 1,
-     *     SPELL_SCHOOL_FIRE    = 2,
-     *     SPELL_SCHOOL_NATURE  = 3,
-     *     SPELL_SCHOOL_FROST   = 4,
-     *     SPELL_SCHOOL_SHADOW  = 5,
-     *     SPELL_SCHOOL_ARCANE  = 6,
-     *     MAX_SPELL_SCHOOL     = 7
-     * };
-     * 
- * - * @param [Unit] target : [Unit] to damage - * @param uint32 damage : amount to damage - * @param bool durabilityloss = true : if false, the damage does not do durability damage - * @param [SpellSchools] school = MAX_SPELL_SCHOOL : school the damage is done in or MAX_SPELL_SCHOOL for direct damage - * @param uint32 spell = 0 : spell that inflicts the damage - */ - int DealDamage(lua_State* L, Unit* unit) - { - Unit* target = ALE::CHECKOBJ(L, 2); - uint32 damage = ALE::CHECKVAL(L, 3); - bool durabilityloss = ALE::CHECKVAL(L, 4, true); - uint32 school = ALE::CHECKVAL(L, 5, MAX_SPELL_SCHOOL); - uint32 spell = ALE::CHECKVAL(L, 6, 0); - if (school > MAX_SPELL_SCHOOL) - return luaL_argerror(L, 6, "valid SpellSchool expected"); - - // flat melee damage without resistence/etc reduction - if (school == MAX_SPELL_SCHOOL) - { - Unit::DealDamage(unit, target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, durabilityloss); - unit->SendAttackStateUpdate(HITINFO_AFFECTS_VICTIM, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_HIT, 0); - return 0; - } - - SpellSchoolMask schoolmask = SpellSchoolMask(1 << school); - - if (Unit::IsDamageReducedByArmor(schoolmask)) - damage = Unit::CalcArmorReducedDamage(unit, target, damage, NULL, BASE_ATTACK); - - if (!spell) - { - DamageInfo dmgInfo(unit, target, damage, nullptr, schoolmask, SPELL_DIRECT_DAMAGE); - unit->CalcAbsorbResist(dmgInfo); - - if (!dmgInfo.GetDamage()) - damage = 0; - else - damage = dmgInfo.GetDamage(); - - uint32 absorb = dmgInfo.GetAbsorb(); - uint32 resist = dmgInfo.GetResist(); - unit->DealDamageMods(target, damage, &absorb); - Unit::DealDamage(unit, target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false); - unit->SendAttackStateUpdate(HITINFO_AFFECTS_VICTIM, target, 0, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0); - return 0; - } - - if (!spell) - return 0; - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell); - if (!spellInfo) - return 0; - - SpellNonMeleeDamage dmgInfo(unit, target, spellInfo, spellInfo->GetSchoolMask()); - Unit::DealDamageMods(dmgInfo.target, dmgInfo.damage, &dmgInfo.absorb); - unit->SendSpellNonMeleeDamageLog(&dmgInfo); - unit->DealSpellDamage(&dmgInfo, true); - return 0; - } - - /** - * Makes the [Unit] heal the target [Unit] with given spell - * - * @param [Unit] target : [Unit] to heal - * @param uint32 spell : spell that causes the healing - * @param uint32 amount : amount to heal - * @param bool critical = false : if true, heal is logged as critical - */ - int DealHeal(lua_State* L, Unit* unit) - { - Unit* target = ALE::CHECKOBJ(L, 2); - uint32 spell = ALE::CHECKVAL(L, 3); - uint32 amount = ALE::CHECKVAL(L, 4); - bool critical = ALE::CHECKVAL(L, 5, false); - - if (const SpellInfo* info = sSpellMgr->GetSpellInfo(spell)) - { - HealInfo healInfo(unit, target, amount, info, info->GetSchoolMask()); - unit->HealBySpell(healInfo, critical); - } - return 0; - } - - /** - * Makes the [Unit] kill the target [Unit] - * - * @param [Unit] target : [Unit] to kill - * @param bool durLoss = true : when true, the target's items suffer durability loss - */ - int Kill(lua_State* L, Unit* unit) - { - Unit* target = ALE::CHECKOBJ(L, 2); - bool durLoss = ALE::CHECKVAL(L, 3, true); - - Unit::Kill(unit, target, durLoss); - return 0; - } - - /** - * Adds threat to the [Unit] from the victim. - * - *
-     * enum SpellSchoolMask
-     * {
-     *     SPELL_SCHOOL_MASK_NONE    = 0,
-     *     SPELL_SCHOOL_MASK_NORMAL  = 1,
-     *     SPELL_SCHOOL_MASK_HOLY    = 2,
-     *     SPELL_SCHOOL_MASK_FIRE    = 4,
-     *     SPELL_SCHOOL_MASK_NATURE  = 8,
-     *     SPELL_SCHOOL_MASK_FROST   = 16,
-     *     SPELL_SCHOOL_MASK_SHADOW  = 32,
-     *     SPELL_SCHOOL_MASK_ARCANE  = 64,
-     * }
-     * 
- * - * @param [Unit] victim : [Unit] that caused the threat - * @param float threat : threat amount - * @param [SpellSchoolMask] schoolMask = 0 : [SpellSchoolMask] of the threat causer - * @param uint32 spell = 0 : spell entry used for threat - */ - int AddThreat(lua_State* L, Unit* unit) - { - Unit* victim = ALE::CHECKOBJ(L, 2); - float threat = ALE::CHECKVAL(L, 3, true); - uint32 spell = ALE::CHECKVAL(L, 4, 0); - - uint32 schoolMask = ALE::CHECKVAL(L, 5, 0); - if (schoolMask > SPELL_SCHOOL_MASK_ALL) - { - return luaL_argerror(L, 4, "valid SpellSchoolMask expected"); - } - unit->AddThreat(victim, threat, (SpellSchoolMask)schoolMask, spell ? sSpellMgr->GetSpellInfo(spell) : NULL); - return 0; - } - - /** - * Modifies threat in pct to the [Unit] from the victim - * - * @param [Unit] victim : [Unit] that caused the threat - * @param int32 percent : threat amount in pct - */ - int ModifyThreatPct(lua_State* L, Unit* unit) - { - Unit* victim = ALE::CHECKOBJ(L, 2); - int32 threatPct = ALE::CHECKVAL(L, 3, true); - - unit->GetThreatMgr().ModifyThreatByPercent(victim, threatPct); - return 0; - } - - /*int RestoreDisplayId(lua_State* L, Unit* unit) - { - unit->RestoreDisplayId(); - return 0; - }*/ - - /*int RestoreFaction(lua_State* L, Unit* unit) - { - unit->RestoreFaction(); - return 0; - }*/ - - /*int RemoveBindSightAuras(lua_State* L, Unit* unit) - { - unit->RemoveBindSightAuras(); - return 0; - }*/ - - /*int RemoveCharmAuras(lua_State* L, Unit* unit) - { - unit->RemoveCharmAuras(); - return 0; - }*/ - - /*int DisableMelee(lua_State* L, Unit* unit) - { - bool apply = ALE::CHECKVAL(L, 2, true); - - if (apply) - unit->AddUnitState(UNIT_STATE_CANNOT_AUTOATTACK); - else - unit->ClearUnitState(UNIT_STATE_CANNOT_AUTOATTACK); - return 0; - }*/ - - /*int SummonGuardian(lua_State* L, Unit* unit) - { - uint32 entry = ALE::CHECKVAL(L, 2); - float x = ALE::CHECKVAL(L, 3); - float y = ALE::CHECKVAL(L, 4); - float z = ALE::CHECKVAL(L, 5); - float o = ALE::CHECKVAL(L, 6); - uint32 desp = ALE::CHECKVAL(L, 7, 0); - - SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(61); - if (!properties) - return 1; - Position pos; - pos.Relocate(x,y,z,o); - TempSummon* summon = unit->GetMap()->SummonCreature(entry, pos, properties, desp, unit); - - if (!summon) - return 1; - - if (summon->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) - ((Guardian*)summon)->InitStatsForLevel(unit->getLevel()); - - if (properties && properties->Category == SUMMON_CATEGORY_ALLY) - summon->setFaction(unit->getFaction()); - if (summon->GetEntry() == 27893) - { - if (uint32 weapon = unit->GetUInt32Value(PLAYER_VISIBLE_ITEM_16_ENTRYID)) - { - summon->SetDisplayId(11686); - summon->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, weapon); - } - else - summon->SetDisplayId(1126); - } - summon->AI()->EnterEvadeMode(); - - ALE::Push(L, summon); - return 1; - }*/ - - /** - * Clear the threat of a [Unit] in the threat list. - * - * @param [Unit] target - */ - int ClearThreat(lua_State* L, Unit* unit) - { - Unit* target = ALE::CHECKOBJ(L, 2); - - unit->GetThreatMgr().ClearThreat(target); - return 0; - } - - /** - * Resets the [Unit]'s threat list, setting all threat targets' threat to 0. - */ - int ResetAllThreat(lua_State* /*L*/, Unit* unit) - { - unit->GetThreatMgr().ResetAllThreat(); - return 0; - } - - /** - * Returns the threat of a [Unit]. - * - * @param [Unit] target - * @return float threat - */ - int GetThreat(lua_State* L, Unit* unit) - { - Unit* target = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, unit->GetThreatMgr().GetThreat(target)); - return 1; - } -}; -#endif diff --git a/src/LuaEngine/methods/VehicleMethods.h b/src/LuaEngine/methods/VehicleMethods.h deleted file mode 100644 index bb0a40c558..0000000000 --- a/src/LuaEngine/methods/VehicleMethods.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef VEHICLEMETHODS_H -#define VEHICLEMETHODS_H - -/*** - * Represents a vehicle in the game, which can carry passengers and provide special abilities or movement. - * - * Inherits all methods from: none - */ -namespace LuaVehicle -{ - /** - * Returns true if the [Unit] passenger is on board - * - * @param [Unit] passenger - * @return bool isOnBoard - */ - int IsOnBoard(lua_State* L, Vehicle* vehicle) - { - Unit* passenger = ALE::CHECKOBJ(L, 2); - ALE::Push(L, passenger->IsOnVehicle(vehicle->GetBase())); - return 1; - } - - /** - * Returns the [Vehicle]'s owner - * - * @return [Unit] owner - */ - int GetOwner(lua_State* L, Vehicle* vehicle) - { - ALE::Push(L, vehicle->GetBase()); - return 1; - } - - /** - * Returns the [Vehicle]'s entry - * - * @return uint32 entry - */ - int GetEntry(lua_State* L, Vehicle* vehicle) - { - ALE::Push(L, vehicle->GetVehicleInfo()->m_ID); - return 1; - } - - /** - * Returns the [Vehicle]'s passenger in the specified seat - * - * @param int8 seat - * @return [Unit] passenger - */ - int GetPassenger(lua_State* L, Vehicle* vehicle) - { - int8 seatId = ALE::CHECKVAL(L, 2); - ALE::Push(L, vehicle->GetPassenger(seatId)); - return 1; - } - - /** - * Adds [Unit] passenger to a specified seat in the [Vehicle] - * - * @param [Unit] passenger - * @param int8 seat - */ - int AddPassenger(lua_State* L, Vehicle* vehicle) - { - Unit* passenger = ALE::CHECKOBJ(L, 2); - int8 seatId = ALE::CHECKVAL(L, 3); - - vehicle->AddPassenger(passenger, seatId); - return 0; - } - - /** - * Removes [Unit] passenger from the [Vehicle] - * - * @param [Unit] passenger - */ - int RemovePassenger(lua_State* L, Vehicle* vehicle) - { - Unit* passenger = ALE::CHECKOBJ(L, 2); - vehicle->RemovePassenger(passenger); - return 0; - } -} - -#endif // VEHICLEMETHODS_H diff --git a/src/LuaEngine/methods/WorldObjectMethods.h b/src/LuaEngine/methods/WorldObjectMethods.h deleted file mode 100644 index 1fd0377d59..0000000000 --- a/src/LuaEngine/methods/WorldObjectMethods.h +++ /dev/null @@ -1,1098 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef WORLDOBJECTMETHODS_H -#define WORLDOBJECTMETHODS_H - -/*** - * Represents a [WorldObject] in the game world. - * - * Inherits all methods from: [Object] - */ -namespace LuaWorldObject -{ - /** - * Returns the name of the [WorldObject] - * - * @return string name - */ - int GetName(lua_State* L, WorldObject* obj) - { - ALE::Push(L, obj->GetName()); - return 1; - } - - /** - * Returns the current [Map] object of the [WorldObject] - * - * @return [Map] mapObject - */ - int GetMap(lua_State* L, WorldObject* obj) - { - ALE::Push(L, obj->GetMap()); - return 1; - } - - /** - * Returns the current phase of the [WorldObject] - * - * @return uint32 phase - */ - int GetPhaseMask(lua_State* L, WorldObject* obj) - { - ALE::Push(L, obj->GetPhaseMask()); - return 1; - } - - /** - * Sets the [WorldObject]'s phase mask. - * - * @param uint32 phaseMask - * @param bool update = true : update visibility to nearby objects - */ - int SetPhaseMask(lua_State* L, WorldObject* obj) - { - uint32 phaseMask = ALE::CHECKVAL(L, 2); - bool update = ALE::CHECKVAL(L, 3, true); - obj->SetPhaseMask(phaseMask, update); - return 0; - } - - /** - * Returns the current instance ID of the [WorldObject] - * - * @return uint32 instanceId - */ - int GetInstanceId(lua_State* L, WorldObject* obj) - { - ALE::Push(L, obj->GetInstanceId()); - return 1; - } - - /** - * Returns the current area ID of the [WorldObject] - * - * @return uint32 areaId - */ - int GetAreaId(lua_State* L, WorldObject* obj) - { - ALE::Push(L, obj->GetAreaId()); - return 1; - } - - /** - * Returns the current zone ID of the [WorldObject] - * - * @return uint32 zoneId - */ - int GetZoneId(lua_State* L, WorldObject* obj) - { - ALE::Push(L, obj->GetZoneId()); - return 1; - } - - /** - * Returns the current map ID of the [WorldObject] - * - * @return uint32 mapId - */ - int GetMapId(lua_State* L, WorldObject* obj) - { - ALE::Push(L, obj->GetMapId()); - return 1; - } - - /** - * Returns the current X coordinate of the [WorldObject] - * - * @return float x - */ - int GetX(lua_State* L, WorldObject* obj) - { - ALE::Push(L, obj->GetPositionX()); - return 1; - } - - /** - * Returns the current Y coordinate of the [WorldObject] - * - * @return float y - */ - int GetY(lua_State* L, WorldObject* obj) - { - ALE::Push(L, obj->GetPositionY()); - return 1; - } - - /** - * Returns the current Z coordinate of the [WorldObject] - * - * @return float z - */ - int GetZ(lua_State* L, WorldObject* obj) - { - ALE::Push(L, obj->GetPositionZ()); - return 1; - } - - /** - * Returns the current orientation of the [WorldObject] - * - * @return float orientation / facing - */ - int GetO(lua_State* L, WorldObject* obj) - { - ALE::Push(L, obj->GetOrientation()); - return 1; - } - - /** - * Returns the coordinates and orientation of the [WorldObject] - * - * @return float x : x coordinate of the [WorldObject] - * @return float y : y coordinate of the [WorldObject] - * @return float z : z coordinate (height) of the [WorldObject] - * @return float o : facing / orientation of the [WorldObject] - */ - int GetLocation(lua_State* L, WorldObject* obj) - { - ALE::Push(L, obj->GetPositionX()); - ALE::Push(L, obj->GetPositionY()); - ALE::Push(L, obj->GetPositionZ()); - ALE::Push(L, obj->GetOrientation()); - return 4; - } - - /** - * Returns the nearest [Player] object in sight of the [WorldObject] or within the given range - * - * @param float range = 533.33333 : optionally set range. Default range is grid size - * @param uint32 hostile = 0 : 0 both, 1 hostile, 2 friendly - * @param uint32 dead = 1 : 0 both, 1 alive, 2 dead - * - * @return [Player] nearestPlayer - */ - int GetNearestPlayer(lua_State* L, WorldObject* obj) - { - float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS); - uint32 hostile = ALE::CHECKVAL(L, 3, 0); - uint32 dead = ALE::CHECKVAL(L, 4, 1); - - Unit* target = NULL; - ALEUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_PLAYER, 0, hostile, dead); - - Acore::UnitLastSearcher searcher(obj, target, checker); - Cell::VisitObjects(obj, searcher, range); - - ALE::Push(L, target); - return 1; - } - - /** - * Returns the nearest [GameObject] object in sight of the [WorldObject] or within the given range and/or with a specific entry ID - * - * @param float range = 533.33333 : optionally set range. Default range is grid size - * @param uint32 entryId = 0 : optionally set entry ID of game object to find - * @param uint32 hostile = 0 : 0 both, 1 hostile, 2 friendly - * - * @return [GameObject] nearestGameObject - */ - int GetNearestGameObject(lua_State* L, WorldObject* obj) - { - float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS); - uint32 entry = ALE::CHECKVAL(L, 3, 0); - uint32 hostile = ALE::CHECKVAL(L, 4, 0); - - GameObject* target = NULL; - ALEUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_GAMEOBJECT, entry, hostile); - - Acore::GameObjectLastSearcher searcher(obj, target, checker); - Cell::VisitObjects(obj, searcher, range); - - ALE::Push(L, target); - return 1; - } - - /** - * Returns the nearest [Creature] object in sight of the [WorldObject] or within the given range and/or with a specific entry ID - * - * @param float range = 533.33333 : optionally set range. Default range is grid size - * @param uint32 entryId = 0 : optionally set entry ID of creature to find - * @param uint32 hostile = 0 : 0 both, 1 hostile, 2 friendly - * @param uint32 dead = 1 : 0 both, 1 alive, 2 dead - * - * @return [Creature] nearestCreature - */ - int GetNearestCreature(lua_State* L, WorldObject* obj) - { - float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS); - uint32 entry = ALE::CHECKVAL(L, 3, 0); - uint32 hostile = ALE::CHECKVAL(L, 4, 0); - uint32 dead = ALE::CHECKVAL(L, 5, 1); - - Creature* target = NULL; - ALEUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_UNIT, entry, hostile, dead); - - Acore::CreatureLastSearcher searcher(obj, target, checker); - Cell::VisitObjects(obj, searcher, range); - - ALE::Push(L, target); - return 1; - } - - /** - * Returns a table of [Player] objects in sight of the [WorldObject] or within the given range - * - * @param float range = 533.33333 : optionally set range. Default range is grid size - * @param uint32 hostile = 0 : 0 both, 1 hostile, 2 friendly - * @param uint32 dead = 1 : 0 both, 1 alive, 2 dead - * - * @return table playersInRange : table of [Player]s - */ - int GetPlayersInRange(lua_State* L, WorldObject* obj) - { - float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS); - uint32 hostile = ALE::CHECKVAL(L, 3, 0); - uint32 dead = ALE::CHECKVAL(L, 4, 1); - - std::list list; - ALEUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_PLAYER, 0, hostile, dead); - - Acore::PlayerListSearcher searcher(obj, list, checker); - Cell::VisitObjects(obj, searcher, range); - - lua_createtable(L, list.size(), 0); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) - { - ALE::Push(L, *it); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); - return 1; - } - - /** - * Returns a table of [Creature] objects in sight of the [WorldObject] or within the given range and/or with a specific entry ID - * - * @param float range = 533.33333 : optionally set range. Default range is grid size - * @param uint32 entryId = 0 : optionally set entry ID of creatures to find - * @param uint32 hostile = 0 : 0 both, 1 hostile, 2 friendly - * @param uint32 dead = 1 : 0 both, 1 alive, 2 dead - * - * @return table creaturesInRange : table of [Creature]s - */ - int GetCreaturesInRange(lua_State* L, WorldObject* obj) - { - float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS); - uint32 entry = ALE::CHECKVAL(L, 3, 0); - uint32 hostile = ALE::CHECKVAL(L, 4, 0); - uint32 dead = ALE::CHECKVAL(L, 5, 1); - - std::list list; - ALEUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_UNIT, entry, hostile, dead); - - Acore::CreatureListSearcher searcher(obj, list, checker); - Cell::VisitObjects(obj, searcher, range); - - lua_createtable(L, list.size(), 0); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) - { - ALE::Push(L, *it); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); - return 1; - } - - /** - * Returns a table of [GameObject] objects in sight of the [WorldObject] or within the given range and/or with a specific entry ID - * - * @param float range = 533.33333 : optionally set range. Default range is grid size - * @param uint32 entryId = 0 : optionally set entry ID of game objects to find - * @param uint32 hostile = 0 : 0 both, 1 hostile, 2 friendly - * - * @return table gameObjectsInRange : table of [GameObject]s - */ - int GetGameObjectsInRange(lua_State* L, WorldObject* obj) - { - float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS); - uint32 entry = ALE::CHECKVAL(L, 3, 0); - uint32 hostile = ALE::CHECKVAL(L, 4, 0); - - std::list list; - ALEUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_GAMEOBJECT, entry, hostile); - - Acore::GameObjectListSearcher searcher(obj, list, checker); - Cell::VisitObjects(obj, searcher, range); - - lua_createtable(L, list.size(), 0); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) - { - ALE::Push(L, *it); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); - return 1; - } - - /** - * Returns nearest [WorldObject] in sight of the [WorldObject]. - * The distance, type, entry and hostility requirements the [WorldObject] must match can be passed. - * - * @param float range = 533.33333 : optionally set range. Default range is grid size - * @param [TypeMask] type = 0 : the [TypeMask] that the [WorldObject] must be. This can contain multiple types. 0 will be ingored - * @param uint32 entry = 0 : the entry of the [WorldObject], 0 will be ingored - * @param uint32 hostile = 0 : specifies whether the [WorldObject] needs to be 1 hostile, 2 friendly or 0 either - * @param uint32 dead = 1 : 0 both, 1 alive, 2 dead - * - * @return [WorldObject] worldObject - */ - int GetNearObject(lua_State* L, WorldObject* obj) - { - float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS); - uint16 type = ALE::CHECKVAL(L, 3, 0); // TypeMask - uint32 entry = ALE::CHECKVAL(L, 4, 0); - uint32 hostile = ALE::CHECKVAL(L, 5, 0); // 0 none, 1 hostile, 2 friendly - uint32 dead = ALE::CHECKVAL(L, 6, 1); // 0 both, 1 alive, 2 dead - - float x, y, z; - obj->GetPosition(x, y, z); - ALEUtil::WorldObjectInRangeCheck checker(true, obj, range, type, entry, hostile, dead); - - WorldObject* target = NULL; - - Acore::WorldObjectLastSearcher searcher(obj, target, checker); - Cell::VisitObjects(obj, searcher, range); - - ALE::Push(L, target); - return 1; - } - - /** - * Returns a table of [WorldObject]s in sight of the [WorldObject]. - * The distance, type, entry and hostility requirements the [WorldObject] must match can be passed. - * - * @param float range = 533.33333 : optionally set range. Default range is grid size - * @param [TypeMask] type = 0 : the [TypeMask] that the [WorldObject] must be. This can contain multiple types. 0 will be ingored - * @param uint32 entry = 0 : the entry of the [WorldObject], 0 will be ingored - * @param uint32 hostile = 0 : specifies whether the [WorldObject] needs to be 1 hostile, 2 friendly or 0 either - * @param uint32 dead = 1 : 0 both, 1 alive, 2 dead - * - * @return table worldObjectList : table of [WorldObject]s - */ - int GetNearObjects(lua_State* L, WorldObject* obj) - { - float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS); - uint16 type = ALE::CHECKVAL(L, 3, 0); // TypeMask - uint32 entry = ALE::CHECKVAL(L, 4, 0); - uint32 hostile = ALE::CHECKVAL(L, 5, 0); // 0 none, 1 hostile, 2 friendly - uint32 dead = ALE::CHECKVAL(L, 6, 1); // 0 both, 1 alive, 2 dead - - float x, y, z; - obj->GetPosition(x, y, z); - ALEUtil::WorldObjectInRangeCheck checker(false, obj, range, type, entry, hostile, dead); - - std::list list; - - Acore::WorldObjectListSearcher searcher(obj, list, checker); - Cell::VisitObjects(obj, searcher, range); - - lua_createtable(L, list.size(), 0); - int tbl = lua_gettop(L); - uint32 i = 0; - - for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) - { - ALE::Push(L, *it); - lua_rawseti(L, tbl, ++i); - } - - lua_settop(L, tbl); - return 1; - } - - /** - * Returns the distance from this [WorldObject] to another [WorldObject], or from this [WorldObject] to a point in 3d space. - * - * The function takes into account the given object sizes. See also [WorldObject:GetExactDistance], [WorldObject:GetDistance2d] - * - * @proto dist = (obj) - * @proto dist = (x, y, z) - * - * @param [WorldObject] obj - * @param float x : the X-coordinate of the point - * @param float y : the Y-coordinate of the point - * @param float z : the Z-coordinate of the point - * - * @return float dist : the distance in yards - */ - int GetDistance(lua_State* L, WorldObject* obj) - { - WorldObject* target = ALE::CHECKOBJ(L, 2, false); - if (target) - ALE::Push(L, obj->GetDistance(target)); - else - { - float X = ALE::CHECKVAL(L, 2); - float Y = ALE::CHECKVAL(L, 3); - float Z = ALE::CHECKVAL(L, 4); - ALE::Push(L, obj->GetDistance(X, Y, Z)); - } - return 1; - } - - /** - * Returns the distance from this [WorldObject] to another [WorldObject], or from this [WorldObject] to a point in 3d space. - * - * The function does not take into account the given object sizes, which means only the object coordinates are compared. See also [WorldObject:GetDistance], [WorldObject:GetDistance2d] - * - * @proto dist = (obj) - * @proto dist = (x, y, z) - * - * @param [WorldObject] obj - * @param float x : the X-coordinate of the point - * @param float y : the Y-coordinate of the point - * @param float z : the Z-coordinate of the point - * - * @return float dist : the distance in yards - */ - int GetExactDistance(lua_State* L, WorldObject* obj) - { - float x, y, z; - obj->GetPosition(x, y, z); - WorldObject* target = ALE::CHECKOBJ(L, 2, false); - if (target) - { - float x2, y2, z2; - target->GetPosition(x2, y2, z2); - x -= x2; - y -= y2; - z -= z2; - } - else - { - x -= ALE::CHECKVAL(L, 2); - y -= ALE::CHECKVAL(L, 3); - z -= ALE::CHECKVAL(L, 4); - } - - ALE::Push(L, std::sqrt(x*x + y*y + z*z)); - return 1; - } - - /** - * Returns the distance from this [WorldObject] to another [WorldObject], or from this [WorldObject] to a point in 2d space. - * - * The function takes into account the given object sizes. See also [WorldObject:GetDistance], [WorldObject:GetExactDistance2d] - * - * @proto dist = (obj) - * @proto dist = (x, y) - * - * @param [WorldObject] obj - * @param float x : the X-coordinate of the point - * @param float y : the Y-coordinate of the point - * - * @return float dist : the distance in yards - */ - int GetDistance2d(lua_State* L, WorldObject* obj) - { - WorldObject* target = ALE::CHECKOBJ(L, 2, false); - if (target) - ALE::Push(L, obj->GetDistance2d(target)); - else - { - float X = ALE::CHECKVAL(L, 2); - float Y = ALE::CHECKVAL(L, 3); - ALE::Push(L, obj->GetDistance2d(X, Y)); - } - return 1; - } - - /** - * Returns the distance from this [WorldObject] to another [WorldObject], or from this [WorldObject] to a point in 2d space. - * - * The function does not take into account the given object sizes, which means only the object coordinates are compared. See also [WorldObject:GetDistance], [WorldObject:GetDistance2d] - * - * @proto dist = (obj) - * @proto dist = (x, y) - * - * @param [WorldObject] obj - * @param float x : the X-coordinate of the point - * @param float y : the Y-coordinate of the point - * - * @return float dist : the distance in yards - */ - int GetExactDistance2d(lua_State* L, WorldObject* obj) - { - float x, y, z; - obj->GetPosition(x, y, z); - WorldObject* target = ALE::CHECKOBJ(L, 2, false); - if (target) - { - float x2, y2, z2; - target->GetPosition(x2, y2, z2); - x -= x2; - y -= y2; - } - else - { - x -= ALE::CHECKVAL(L, 2); - y -= ALE::CHECKVAL(L, 3); - } - - ALE::Push(L, std::sqrt(x*x + y*y)); - return 1; - } - - /** - * Returns the x, y and z of a point dist away from the [WorldObject]. - * - * @param float distance : specifies the distance of the point from the [WorldObject] in yards - * @param float angle : specifies the angle of the point relative to the orientation / facing of the [WorldObject] in radians - * - * @return float x - * @return float y - * @return float z - */ - int GetRelativePoint(lua_State* L, WorldObject* obj) - { - float dist = ALE::CHECKVAL(L, 2); - float rad = ALE::CHECKVAL(L, 3); - - float x, y, z; - obj->GetClosePoint(x, y, z, 0.0f, dist, rad); - - ALE::Push(L, x); - ALE::Push(L, y); - ALE::Push(L, z); - return 3; - } - - /** - * Returns the angle between this [WorldObject] and another [WorldObject] or a point. - * - * The angle is the angle between two points and orientation will be ignored. - * - * @proto dist = (obj) - * @proto dist = (x, y) - * - * @param [WorldObject] object - * @param float x - * @param float y - * - * @return float angle : angle in radians in range 0..2*pi - */ - int GetAngle(lua_State* L, WorldObject* obj) - { - WorldObject* target = ALE::CHECKOBJ(L, 2, false); - if (target) - ALE::Push(L, obj->GetAbsoluteAngle(target)); - else - { - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 3); - ALE::Push(L, obj->GetAbsoluteAngle(x, y)); - } - - return 1; - } - - /** - * Sends a [WorldPacket] to [Player]s in sight of the [WorldObject]. - * - * @param [WorldPacket] packet - */ - int SendPacket(lua_State* L, WorldObject* obj) - { - WorldPacket* data = ALE::CHECKOBJ(L, 2); - obj->SendMessageToSet(data, true); - return 0; - } - - /** - * Spawns a [GameObject] at specified location. - * - * @param uint32 entry : [GameObject] entry ID - * @param float x - * @param float y - * @param float z - * @param float o - * @param uint32 respawnDelay = 30 : respawn time in seconds - * @return [GameObject] gameObject - */ - int SummonGameObject(lua_State* L, WorldObject* obj) - { - uint32 entry = ALE::CHECKVAL(L, 2); - float x = ALE::CHECKVAL(L, 3); - float y = ALE::CHECKVAL(L, 4); - float z = ALE::CHECKVAL(L, 5); - float o = ALE::CHECKVAL(L, 6); - uint32 respawnDelay = ALE::CHECKVAL(L, 7, 30); - - ALE::Push(L, obj->SummonGameObject(entry, x, y, z, o, 0, 0, 0, 0, respawnDelay)); - return 1; - } - - /** - * Spawns the creature at specified location. - * - * enum TempSummonType - * { - * TEMPSUMMON_TIMED_OR_DEAD_DESPAWN = 1, // despawns after a specified time OR when the creature disappears - * TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN = 2, // despawns after a specified time OR when the creature dies - * TEMPSUMMON_TIMED_DESPAWN = 3, // despawns after a specified time - * TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT = 4, // despawns after a specified time after the creature is out of combat - * TEMPSUMMON_CORPSE_DESPAWN = 5, // despawns instantly after death - * TEMPSUMMON_CORPSE_TIMED_DESPAWN = 6, // despawns after a specified time after death - * TEMPSUMMON_DEAD_DESPAWN = 7, // despawns when the creature disappears - * TEMPSUMMON_MANUAL_DESPAWN = 8, // despawns when UnSummon() is called - * TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN = 9, // despawns after a specified time (OOC) OR when the creature dies - * TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN = 10 // despawns after a specified time (OOC) OR when the creature disappears - * }; - * - * @param uint32 entry : [Creature]'s entry ID - * @param float x - * @param float y - * @param float z - * @param float o - * @param [TempSummonType] spawnType = MANUAL_DESPAWN : defines how and when the creature despawns - * @param uint32 despawnTimer = 0 : despawn time in milliseconds - * @return [Creature] spawnedCreature - */ - int SpawnCreature(lua_State* L, WorldObject* obj) - { - uint32 entry = ALE::CHECKVAL(L, 2); - float x = ALE::CHECKVAL(L, 3); - float y = ALE::CHECKVAL(L, 4); - float z = ALE::CHECKVAL(L, 5); - float o = ALE::CHECKVAL(L, 6); - uint32 spawnType = ALE::CHECKVAL(L, 7, 8); - uint32 despawnTimer = ALE::CHECKVAL(L, 8, 0); - - TempSummonType type; - switch (spawnType) - { - case 1: - type = TEMPSUMMON_TIMED_OR_DEAD_DESPAWN; - break; - case 2: - type = TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN; - break; - case 3: - type = TEMPSUMMON_TIMED_DESPAWN; - break; - case 4: - type = TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT; - break; - case 5: - type = TEMPSUMMON_CORPSE_DESPAWN; - break; - case 6: - type = TEMPSUMMON_CORPSE_TIMED_DESPAWN; - break; - case 7: - type = TEMPSUMMON_DEAD_DESPAWN; - break; - case 8: - type = TEMPSUMMON_MANUAL_DESPAWN; - break; - default: - return luaL_argerror(L, 7, "valid SpawnType expected"); - } - - ALE::Push(L, obj->SummonCreature(entry, x, y, z, o, type, despawnTimer)); - return 1; - } - - /** - * Registers a timed event to the [WorldObject] - * When the passed function is called, the parameters `(eventId, delay, repeats, worldobject)` are passed to it. - * Repeats will decrease on each call if the event does not repeat indefinitely - * - * Note that for [Creature] and [GameObject] the timed event timer ticks only if the creature is in sight of someone - * For all [WorldObject]s the timed events are removed when the object is destoryed. This means that for example a [Player]'s events are removed on logout. - * - * local function Timed(eventid, delay, repeats, worldobject) - * print(worldobject:GetName()) - * end - * worldobject:RegisterEvent(Timed, 1000, 5) -- do it after 1 second 5 times - * worldobject:RegisterEvent(Timed, {1000, 10000}, 0) -- do it after 1 to 10 seconds forever - * - * @proto eventId = (function, delay) - * @proto eventId = (function, delaytable) - * @proto eventId = (function, delay, repeats) - * @proto eventId = (function, delaytable, repeats) - * - * @param function function : function to trigger when the time has passed - * @param uint32 delay : set time in milliseconds for the event to trigger - * @param table delaytable : a table `{min, max}` containing the minimum and maximum delay time - * @param uint32 repeats = 1 : how many times for the event to repeat, 0 is infinite - * @return int eventId : unique ID for the timed event used to cancel it or nil - */ - int RegisterEvent(lua_State* L, WorldObject* obj) - { - luaL_checktype(L, 2, LUA_TFUNCTION); - uint32 min, max; - if (lua_istable(L, 3)) - { - ALE::Push(L, 1); - lua_gettable(L, 3); - min = ALE::CHECKVAL(L, -1); - ALE::Push(L, 2); - lua_gettable(L, 3); - max = ALE::CHECKVAL(L, -1); - lua_pop(L, 2); - } - else - min = max = ALE::CHECKVAL(L, 3); - uint32 repeats = ALE::CHECKVAL(L, 4, 1); - - if (min > max) - return luaL_argerror(L, 3, "min is bigger than max delay"); - - lua_pushvalue(L, 2); - int functionRef = luaL_ref(L, LUA_REGISTRYINDEX); - if (functionRef != LUA_REFNIL && functionRef != LUA_NOREF) - { - obj->ALEEvents->AddEvent(functionRef, min, max, repeats); - ALE::Push(L, functionRef); - } - return 1; - } - - /** - * Removes the timed event from a [WorldObject] by the specified event ID - * - * @param int eventId : event Id to remove - */ - int RemoveEventById(lua_State* L, WorldObject* obj) - { - int eventId = ALE::CHECKVAL(L, 2); - obj->ALEEvents->SetState(eventId, LUAEVENT_STATE_ABORT); - return 0; - } - - /** - * Removes all timed events from a [WorldObject] - * - */ - int RemoveEvents(lua_State* /*L*/, WorldObject* obj) - { - obj->ALEEvents->SetStates(LUAEVENT_STATE_ABORT); - return 0; - } - - /** - * Returns true if the given [WorldObject] or coordinates are in the [WorldObject]'s line of sight - * - * @proto isInLoS = (worldobject) - * @proto isInLoS = (x, y, z) - * - * @param [WorldObject] worldobject - * @param float x - * @param float y - * @param float z - * @return bool isInLoS - */ - int IsWithinLoS(lua_State* L, WorldObject* obj) - { - WorldObject* target = ALE::CHECKOBJ(L, 2, false); - - if (target) - ALE::Push(L, obj->IsWithinLOSInMap(target)); - else - { - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 3); - float z = ALE::CHECKVAL(L, 4); - ALE::Push(L, obj->IsWithinLOS(x, y, z)); - } - - return 1; - } - - /** - * Returns true if the [WorldObject]s are on the same map - * - * @param [WorldObject] worldobject - * @return bool isInMap - */ - int IsInMap(lua_State* L, WorldObject* obj) - { - WorldObject* target = ALE::CHECKOBJ(L, 2, true); - ALE::Push(L, obj->IsInMap(target)); - return 1; - } - - /** - * Returns true if the point is in the given distance of the [WorldObject] - * - * Notice that the distance is measured from the edge of the [WorldObject]. - * - * @param float x - * @param float y - * @param float z - * @param float distance - * @return bool isInDistance - */ - int IsWithinDist3d(lua_State* L, WorldObject* obj) - { - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 3); - float z = ALE::CHECKVAL(L, 4); - float dist = ALE::CHECKVAL(L, 5); - ALE::Push(L, obj->IsWithinDist3d(x, y, z, dist)); - return 1; - } - - /** - * Returns true if the point is in the given distance of the [WorldObject] - * - * The distance is measured only in x,y coordinates. - * Notice that the distance is measured from the edge of the [WorldObject]. - * - * @param float x - * @param float y - * @param float distance - * @return bool isInDistance - */ - int IsWithinDist2d(lua_State* L, WorldObject* obj) - { - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 3); - float dist = ALE::CHECKVAL(L, 4); - ALE::Push(L, obj->IsWithinDist2d(x, y, dist)); - return 1; - } - - /** - * Returns true if the target is in the given distance of the [WorldObject] - * - * Notice that the distance is measured from the edge of the [WorldObject]s. - * - * @param [WorldObject] target - * @param float distance - * @param bool is3D = true : if false, only x,y coordinates used for checking - * @return bool isInDistance - */ - int IsWithinDist(lua_State* L, WorldObject* obj) - { - WorldObject* target = ALE::CHECKOBJ(L, 2, true); - float distance = ALE::CHECKVAL(L, 3); - bool is3D = ALE::CHECKVAL(L, 4, true); - ALE::Push(L, obj->IsWithinDist(target, distance, is3D)); - return 1; - } - - /** - * Returns true if the [WorldObject] is on the same map and within given distance - * - * Notice that the distance is measured from the edge of the [WorldObject]s. - * - * @param [WorldObject] target - * @param float distance - * @param bool is3D = true : if false, only x,y coordinates used for checking - * @return bool isInDistance - */ - int IsWithinDistInMap(lua_State* L, WorldObject* obj) - { - WorldObject* target = ALE::CHECKOBJ(L, 2); - float distance = ALE::CHECKVAL(L, 3); - bool is3D = ALE::CHECKVAL(L, 4, true); - - ALE::Push(L, obj->IsWithinDistInMap(target, distance, is3D)); - return 1; - } - - /** - * Returns true if the target is within given range - * - * Notice that the distance is measured from the edge of the [WorldObject]s. - * - * @param [WorldObject] target - * @param float minrange - * @param float maxrange - * @param bool is3D = true : if false, only x,y coordinates used for checking - * @return bool isInDistance - */ - int IsInRange(lua_State* L, WorldObject* obj) - { - WorldObject* target = ALE::CHECKOBJ(L, 2); - float minrange = ALE::CHECKVAL(L, 3); - float maxrange = ALE::CHECKVAL(L, 4); - bool is3D = ALE::CHECKVAL(L, 5, true); - - ALE::Push(L, obj->IsInRange(target, minrange, maxrange, is3D)); - return 1; - } - - /** - * Returns true if the point is within given range - * - * Notice that the distance is measured from the edge of the [WorldObject]. - * - * @param float x - * @param float y - * @param float minrange - * @param float maxrange - * @return bool isInDistance - */ - int IsInRange2d(lua_State* L, WorldObject* obj) - { - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 3); - float minrange = ALE::CHECKVAL(L, 4); - float maxrange = ALE::CHECKVAL(L, 5); - - ALE::Push(L, obj->IsInRange2d(x, y, minrange, maxrange)); - return 1; - } - - /** - * Returns true if the point is within given range - * - * Notice that the distance is measured from the edge of the [WorldObject]. - * - * @param float x - * @param float y - * @param float z - * @param float minrange - * @param float maxrange - * @return bool isInDistance - */ - int IsInRange3d(lua_State* L, WorldObject* obj) - { - float x = ALE::CHECKVAL(L, 2); - float y = ALE::CHECKVAL(L, 3); - float z = ALE::CHECKVAL(L, 4); - float minrange = ALE::CHECKVAL(L, 5); - float maxrange = ALE::CHECKVAL(L, 6); - - ALE::Push(L, obj->IsInRange3d(x, y, z, minrange, maxrange)); - return 1; - } - - /** - * Returns true if the target is in the given arc in front of the [WorldObject] - * - * @param [WorldObject] target - * @param float arc = pi - * @return bool isInFront - */ - int IsInFront(lua_State* L, WorldObject* obj) - { - WorldObject* target = ALE::CHECKOBJ(L, 2); - float arc = ALE::CHECKVAL(L, 3, static_cast(M_PI)); - - ALE::Push(L, obj->isInFront(target, arc)); - return 1; - } - - /** - * Returns true if the target is in the given arc behind the [WorldObject] - * - * @param [WorldObject] target - * @param float arc = pi - * @return bool isInBack - */ - int IsInBack(lua_State* L, WorldObject* obj) - { - WorldObject* target = ALE::CHECKOBJ(L, 2); - float arc = ALE::CHECKVAL(L, 3, static_cast(M_PI)); - - ALE::Push(L, obj->isInBack(target, arc)); - return 1; - } - - /** - * The [WorldObject] plays music to a [Player] - * - * If no [Player] provided it will play the music to everyone near. - * This method does not interrupt previously played music. - * - * See also [WorldObject:PlayDistanceSound], [WorldObject:PlayDirectSound] - * - * @param uint32 music : entry of a music - * @param [Player] player = nil : [Player] to play the music to - */ - int PlayMusic(lua_State* L, WorldObject* obj) - { - uint32 musicid = ALE::CHECKVAL(L, 2); - Player* player = ALE::CHECKOBJ(L, 3, false); - - WorldPacket data(SMSG_PLAY_MUSIC, 4); - data << uint32(musicid); - if (player) - player->SendDirectMessage(&data); - else - obj->SendMessageToSet(&data, true); - return 0; - } - - /** - * The [WorldObject] plays a sound to a [Player] - * - * If no [Player] provided it will play the sound to everyone near. - * This method will play sound and does not interrupt prvious sound. - * - * See also [WorldObject:PlayDistanceSound], [WorldObject:PlayMusic] - * - * @param uint32 sound : entry of a sound - * @param [Player] player = nil : [Player] to play the sound to - */ - int PlayDirectSound(lua_State* L, WorldObject* obj) - { - uint32 soundId = ALE::CHECKVAL(L, 2); - Player* player = ALE::CHECKOBJ(L, 3, false); - if (!sSoundEntriesStore.LookupEntry(soundId)) - return 0; - - if (player) - obj->PlayDirectSound(soundId, player); - else - obj->PlayDirectSound(soundId); - return 0; - } - - /** - * The [WorldObject] plays a sound to a [Player] - * - * If no [Player] it will play the sound to everyone near. - * Sound will fade the further you are from the [WorldObject]. - * This method interrupts previously playing sound. - * - * See also [WorldObject:PlayDirectSound], [WorldObject:PlayMusic] - * - * @param uint32 sound : entry of a sound - * @param [Player] player = nil : [Player] to play the sound to - */ - int PlayDistanceSound(lua_State* L, WorldObject* obj) - { - uint32 soundId = ALE::CHECKVAL(L, 2); - Player* player = ALE::CHECKOBJ(L, 3, false); - if (!sSoundEntriesStore.LookupEntry(soundId)) - return 0; - - if (player) - obj->PlayDistanceSound(soundId, player); - else - obj->PlayDistanceSound(soundId); - return 0; - } -}; -#endif diff --git a/src/LuaEngine/methods/WorldPacketMethods.h b/src/LuaEngine/methods/WorldPacketMethods.h deleted file mode 100644 index 3972eee316..0000000000 --- a/src/LuaEngine/methods/WorldPacketMethods.h +++ /dev/null @@ -1,337 +0,0 @@ -/* -* Copyright (C) 2010 - 2025 Eluna Lua Engine -* This program is free software licensed under GPL version 3 -* Please see the included DOCS/LICENSE.md for more information -*/ - -#ifndef WORLDPACKETMETHODS_H -#define WORLDPACKETMETHODS_H - -/*** - * A packet used to pass messages between the server and a client. - * - * Each packet has an opcode that determines the type of message being sent, - * e.g. if a CMSG_LOGOUT_REQUEST packet is sent to the server, - * the client has sent a message that its [Player] wants to logout. - * - * The packet can contain further data, the format of which depends on the opcode. - * - * Inherits all methods from: none - */ -namespace LuaPacket -{ - /** - * Returns the opcode of the [WorldPacket]. - * - * @return uint16 opcode - */ - int GetOpcode(lua_State* L, WorldPacket* packet) - { - ALE::Push(L, packet->GetOpcode()); - return 1; - } - - /** - * Returns the size of the [WorldPacket]. - * - * @return uint32 size - */ - int GetSize(lua_State* L, WorldPacket* packet) - { - ALE::Push(L, packet->size()); - return 1; - } - - /** - * Sets the opcode of the [WorldPacket] to the specified opcode. - * - * @param [Opcodes] opcode : see Opcodes.h for all known opcodes - */ - int SetOpcode(lua_State* L, WorldPacket* packet) - { - uint32 opcode = ALE::CHECKVAL(L, 2); - if (opcode >= NUM_MSG_TYPES) - return luaL_argerror(L, 2, "valid opcode expected"); - packet->SetOpcode((OpcodesList)opcode); - return 0; - } - - /** - * Reads and returns a signed 8-bit integer value from the [WorldPacket]. - * - * @return int8 value - */ - int ReadByte(lua_State* L, WorldPacket* packet) - { - int8 _byte; - (*packet) >> _byte; - ALE::Push(L, _byte); - return 1; - } - - /** - * Reads and returns an unsigned 8-bit integer value from the [WorldPacket]. - * - * @return uint8 value - */ - int ReadUByte(lua_State* L, WorldPacket* packet) - { - uint8 _ubyte; - (*packet) >> _ubyte; - ALE::Push(L, _ubyte); - return 1; - } - - /** - * Reads and returns a signed 16-bit integer value from the [WorldPacket]. - * - * @return int16 value - */ - int ReadShort(lua_State* L, WorldPacket* packet) - { - int16 _short; - (*packet) >> _short; - ALE::Push(L, _short); - return 1; - } - - /** - * Reads and returns an unsigned 16-bit integer value from the [WorldPacket]. - * - * @return uint16 value - */ - int ReadUShort(lua_State* L, WorldPacket* packet) - { - uint16 _ushort; - (*packet) >> _ushort; - ALE::Push(L, _ushort); - return 1; - } - - /** - * Reads and returns a signed 32-bit integer value from the [WorldPacket]. - * - * @return int32 value - */ - int ReadLong(lua_State* L, WorldPacket* packet) - { - int32 _long; - (*packet) >> _long; - ALE::Push(L, _long); - return 1; - } - - /** - * Reads and returns an unsigned 32-bit integer value from the [WorldPacket]. - * - * @return uint32 value - */ - int ReadULong(lua_State* L, WorldPacket* packet) - { - uint32 _ulong; - (*packet) >> _ulong; - ALE::Push(L, _ulong); - return 1; - } - - /** - * Reads and returns a single-precision floating-point value from the [WorldPacket]. - * - * @return float value - */ - int ReadFloat(lua_State* L, WorldPacket* packet) - { - float _val; - (*packet) >> _val; - ALE::Push(L, _val); - return 1; - } - - /** - * Reads and returns a double-precision floating-point value from the [WorldPacket]. - * - * @return double value - */ - int ReadDouble(lua_State* L, WorldPacket* packet) - { - double _val; - (*packet) >> _val; - ALE::Push(L, _val); - return 1; - } - - /** - * Reads and returns an unsigned 64-bit integer value from the [WorldPacket]. - * - * @return ObjectGuid value : value returned as string - */ - int ReadGUID(lua_State* L, WorldPacket* packet) - { - ObjectGuid guid; - (*packet) >> guid; - ALE::Push(L, guid); - return 1; - } - - /** - * Reads a packed GUID from the [WorldPacket] and returns it as a full 64-bit integer. - * The packed data size varies (2-9 bytes), but always unpacks to a complete 64-bit GUID. - * - * @return uint64 value : value returned as string - */ - int ReadPackedGUID(lua_State* L, WorldPacket* packet) - { - uint64 guid; - packet->readPackGUID(guid); - ALE::Push(L, guid); - return 1; - } - - /** - * Reads and returns a string value from the [WorldPacket]. - * - * @return string value - */ - int ReadString(lua_State* L, WorldPacket* packet) - { - std::string _val; - (*packet) >> _val; - ALE::Push(L, _val); - return 1; - } - - /** - * Writes an unsigned 64-bit integer value to the [WorldPacket]. - * - * @param ObjectGuid value : the value to be written to the [WorldPacket] - */ - int WriteGUID(lua_State* L, WorldPacket* packet) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - (*packet) << guid; - return 0; - } - - /** - * Writes an ObjectGuid as packed GUID format to the [WorldPacket]. - * - * @param ObjectGuid value : the ObjectGuid to be packed to the [WorldPacket] - */ - int WritePackedGUID(lua_State* L, WorldPacket* packet) - { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - PackedGuid packedGuid(guid); - (*packet) << packedGuid; - return 0; - } - - /** - * Writes a string to the [WorldPacket]. - * - * @param string value : the string to be written to the [WorldPacket] - */ - int WriteString(lua_State* L, WorldPacket* packet) - { - std::string _val = ALE::CHECKVAL(L, 2); - (*packet) << _val; - return 0; - } - - /** - * Writes a signed 8-bit integer value to the [WorldPacket]. - * - * @param int8 value : the int8 value to be written to the [WorldPacket] - */ - int WriteByte(lua_State* L, WorldPacket* packet) - { - int8 byte = ALE::CHECKVAL(L, 2); - (*packet) << byte; - return 0; - } - - /** - * Writes an unsigned 8-bit integer value to the [WorldPacket]. - * - * @param uint8 value : the uint8 value to be written to the [WorldPacket] - */ - int WriteUByte(lua_State* L, WorldPacket* packet) - { - uint8 byte = ALE::CHECKVAL(L, 2); - (*packet) << byte; - return 0; - } - - /** - * Writes a signed 16-bit integer value to the [WorldPacket]. - * - * @param int16 value : the int16 value to be written to the [WorldPacket] - */ - int WriteShort(lua_State* L, WorldPacket* packet) - { - int16 _short = ALE::CHECKVAL(L, 2); - (*packet) << _short; - return 0; - } - - /** - * Writes an unsigned 16-bit integer value to the [WorldPacket]. - * - * @param uint16 value : the uint16 value to be written to the [WorldPacket] - */ - int WriteUShort(lua_State* L, WorldPacket* packet) - { - uint16 _ushort = ALE::CHECKVAL(L, 2); - (*packet) << _ushort; - return 0; - } - - /** - * Writes a signed 32-bit integer value to the [WorldPacket]. - * - * @param int32 value : the int32 value to be written to the [WorldPacket] - */ - int WriteLong(lua_State* L, WorldPacket* packet) - { - int32 _long = ALE::CHECKVAL(L, 2); - (*packet) << _long; - return 0; - } - - /** - * Writes an unsigned 32-bit integer value to the [WorldPacket]. - * - * @param uint32 value : the uint32 value to be written to the [WorldPacket] - */ - int WriteULong(lua_State* L, WorldPacket* packet) - { - uint32 _ulong = ALE::CHECKVAL(L, 2); - (*packet) << _ulong; - return 0; - } - - /** - * Writes a 32-bit floating-point value to the [WorldPacket]. - * - * @param float value : the float value to be written to the [WorldPacket] - */ - int WriteFloat(lua_State* L, WorldPacket* packet) - { - float _val = ALE::CHECKVAL(L, 2); - (*packet) << _val; - return 0; - } - - /** - * Writes a 64-bit floating-point value to the [WorldPacket]. - * - * @param double value : the double value to be written to the [WorldPacket] - */ - int WriteDouble(lua_State* L, WorldPacket* packet) - { - double _val = ALE::CHECKVAL(L, 2); - (*packet) << _val; - return 0; - } -}; - -#endif diff --git a/src/lualib/lua/CMakeLists.txt b/src/lualib/lua/CMakeLists.txt index 3f36675640..a7169134c0 100644 --- a/src/lualib/lua/CMakeLists.txt +++ b/src/lualib/lua/CMakeLists.txt @@ -115,8 +115,18 @@ elseif (UNIX) set_target_properties(lualib PROPERTIES OUTPUT_NAME ${LUA_VERSION}) endif() -add_executable(lua_interpreter ${LUA_SOURCE_FOLDER}/lua.c) -target_link_libraries(lua_interpreter lualib) +if (LUA_STATIC) + add_executable(lua_interpreter ${LUA_SOURCE_FOLDER}/lua.c) + target_link_libraries(lua_interpreter lualib) +else() + add_executable(lua_interpreter ${LUA_SOURCE_FOLDER}/lua.c ${LOCAL_SOURCES_C}) + target_include_directories(lua_interpreter PRIVATE "${LUA_SOURCE_FOLDER}") + if(APPLE) + target_link_libraries(lua_interpreter readline) + else() + target_link_libraries(lua_interpreter m ${CMAKE_DL_LIBS}) + endif() +endif() target_compile_definitions(lua_interpreter PRIVATE _CRT_SECURE_NO_WARNINGS) if (NOT WIN32) target_compile_options(lua_interpreter PRIVATE -Wno-empty-body -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -Wno-string-plus-int) @@ -129,8 +139,18 @@ else() install(TARGETS lua_interpreter DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") endif() -add_executable(lua_compiler ${LUA_SOURCE_FOLDER}/luac.c) -target_link_libraries(lua_compiler lualib) +if (LUA_STATIC) + add_executable(lua_compiler ${LUA_SOURCE_FOLDER}/luac.c) + target_link_libraries(lua_compiler lualib) +else() + add_executable(lua_compiler ${LUA_SOURCE_FOLDER}/luac.c ${LOCAL_SOURCES_C}) + target_include_directories(lua_compiler PRIVATE "${LUA_SOURCE_FOLDER}") + if(APPLE) + target_link_libraries(lua_compiler readline) + else() + target_link_libraries(lua_compiler m ${CMAKE_DL_LIBS}) + endif() +endif() target_compile_definitions(lua_compiler PRIVATE _CRT_SECURE_NO_WARNINGS) if (NOT WIN32) target_compile_options(lua_compiler PRIVATE -Wno-empty-body -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -Wno-string-plus-int) diff --git a/src/lualib/luajit/CMakeLists.txt b/src/lualib/luajit/CMakeLists.txt index 64c0cf4791..0e58b6e686 100644 --- a/src/lualib/luajit/CMakeLists.txt +++ b/src/lualib/luajit/CMakeLists.txt @@ -66,7 +66,7 @@ if (WIN32) set_target_properties(lualib PROPERTIES IMPORTED_LOCATION ${LUA_BIN_FOLDER}/src/lua51.lib - INTERFACE_INCLUDE_DIRECTORIES "${LUA_SRC_FOLDER}/src" + INTERFACE_INCLUDE_DIRECTORIES "${LUA_BIN_FOLDER}/src" INTERFACE_COMPILE_DEFINITIONS "LUAJIT_VERSION=1" ) @@ -155,7 +155,7 @@ if (UNIX OR APPLE) set_target_properties(lualib PROPERTIES # IMPORTED_LOCATION ${LUAJIT_LIB_PATH} # cmake bullshit. spent days figuring this and turns out set_target_properties does squat shit while set_property works fine. - INTERFACE_INCLUDE_DIRECTORIES "${LUA_SRC_FOLDER}/src" + INTERFACE_INCLUDE_DIRECTORIES "${LUA_BIN_FOLDER}/src" INTERFACE_COMPILE_DEFINITIONS "LUAJIT_VERSION=1" ) set_property(TARGET lualib PROPERTY IMPORTED_LOCATION ${LUAJIT_LIB_PATH}) @@ -163,5 +163,3 @@ if (UNIX OR APPLE) # install generated files install(DIRECTORY ${LUA_INSTALL_PATH}/ DESTINATION ${CMAKE_INSTALL_PREFIX}) endif() - - diff --git a/src/sol/config.hpp b/src/sol/config.hpp new file mode 100644 index 0000000000..cf1fdbb793 --- /dev/null +++ b/src/sol/config.hpp @@ -0,0 +1,137 @@ +// The MIT License (MIT) + +// Copyright (c) 2013-2020 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// This file was generated with a script. +// Generated 2022-06-25 08:14:19.336233 UTC +// This header was generated with sol v3.3.0 (revision eba86625) +// https://github.com/ThePhD/sol2 + +#ifndef SOL_SINGLE_CONFIG_HPP +#define SOL_SINGLE_CONFIG_HPP + +// beginning of sol/config.hpp + +/* AzerothCore mod-ale sol2 configuration + * + * This file configures sol2 for use with mod-ale (AzerothCore Lua Engine). + * + */ + +// ============================================================================ +// Lua Compatibility Flags +// ============================================================================ +#define LUA_COMPAT_ALL 1 +#define LUA_COMPAT_APIINTCASTS 1 + +// ============================================================================ +// Lua Headers +// ============================================================================ + +extern "C" { + #include + #include + #include +} + +// ============================================================================ +// Lua Version Detection +// ============================================================================ + +// Detect LuaJIT +#if defined(LUAJIT_VERSION) + #define SOL_LUAJIT 1 + #define SOL_USING_CXX_LUAJIT 1 + #define SOL_LUAJIT_VERSION 20100 + #define SOL_LUA_VERSION 501 +#else + #define SOL_LUAJIT 0 + #define SOL_USING_CXX_LUAJIT 0 + + // Detect Lua 5.1 + #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501 + #define SOL_LUA_VERSION 501 + + // Detect Lua 5.2 + #elif defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 502 + #define SOL_LUA_VERSION 502 + + // Detect Lua 5.3 + #elif defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 503 + #define SOL_LUA_VERSION 503 + + // Detect Lua 5.4 + #elif defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 504 + #define SOL_LUA_VERSION 504 + #endif +#endif + +// ============================================================================ +// Sol2 Safety Settings +// ============================================================================ + +// Enable safe function calls (catches errors instead of crashing) +#define SOL_SAFE_FUNCTION_CALLS 1 + +// Enable exception handling trampoline +#define SOL_FUNCTION_CALL_TRAMPOLINE 1 + +// ============================================================================ +// Sol2 Performance Optimizations +// ============================================================================ + +// Optimize for single return values (most common case) +#define SOL_OPTIMIZE_FOR_SINGLE_RETURN 1 + +// Don't check number precision (faster, but less safe) +#define SOL_NO_CHECK_NUMBER_PRECISION 1 + +// Optimize stack string operations (2KB buffer) +#define SOL_STACK_STRING_OPTIMIZATION_SIZE 2048 + +// Enable fast type checking +#define SOL_FAST_TYPE_CHECKING 1 + +// Minimize usertype size for better memory usage +#define SOL_MINIMIZE_USERTYPE_SIZE 1 + +// ============================================================================ +// Sol2 Container Support +// ============================================================================ + +// Enable container traits (support for std::vector, etc.) +#define SOL_CONTAINER_TRAITS 1 + +// Enable container start (required for container support) +#define SOL_CONTAINERS_START 1 + +// ============================================================================ +// Sol2 Compatibility Settings +// ============================================================================ + +// Use compatibility layer for different Lua versions +#define SOL_USE_COMPATIBILITY_LAYER 1 + +// Don't disable compatibility features +#define SOL_NO_COMPAT 0 + +// end of sol/config.hpp + +#endif // SOL_SINGLE_CONFIG_HPP diff --git a/src/sol/sol.hpp b/src/sol/sol.hpp new file mode 100644 index 0000000000..db9119fb7b --- /dev/null +++ b/src/sol/sol.hpp @@ -0,0 +1,28908 @@ +// The MIT License (MIT) + +// Copyright (c) 2013-2020 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// This file was generated with a script. +// Generated 2022-06-25 08:14:19.151876 UTC +// This header was generated with sol v3.3.0 (revision eba86625) +// https://github.com/ThePhD/sol2 + +#ifndef SOL_SINGLE_INCLUDE_HPP +#define SOL_SINGLE_INCLUDE_HPP + +// beginning of sol/sol.hpp + +#ifndef SOL_HPP +#define SOL_HPP + +// beginning of sol/version.hpp + +#include + +#define SOL_VERSION_MAJOR 3 +#define SOL_VERSION_MINOR 2 +#define SOL_VERSION_PATCH 3 +#define SOL_VERSION_STRING "3.2.3" +#define SOL_VERSION ((SOL_VERSION_MAJOR * 100000) + (SOL_VERSION_MINOR * 100) + (SOL_VERSION_PATCH)) + +#define SOL_TOKEN_TO_STRING_POST_EXPANSION_I_(_TOKEN) #_TOKEN +#define SOL_TOKEN_TO_STRING_I_(_TOKEN) SOL_TOKEN_TO_STRING_POST_EXPANSION_I_(_TOKEN) + +#define SOL_CONCAT_TOKENS_POST_EXPANSION_I_(_LEFT, _RIGHT) _LEFT##_RIGHT +#define SOL_CONCAT_TOKENS_I_(_LEFT, _RIGHT) SOL_CONCAT_TOKENS_POST_EXPANSION_I_(_LEFT, _RIGHT) + +#define SOL_RAW_IS_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) != 0) +#define SOL_RAW_IS_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3) == 0) +#define SOL_RAW_IS_DEFAULT_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) > 3) +#define SOL_RAW_IS_DEFAULT_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3 OP_SYMBOL 3) < 0) + +#define SOL_IS_ON(OP_SYMBOL) SOL_RAW_IS_ON(OP_SYMBOL ## _I_) +#define SOL_IS_OFF(OP_SYMBOL) SOL_RAW_IS_OFF(OP_SYMBOL ## _I_) +#define SOL_IS_DEFAULT_ON(OP_SYMBOL) SOL_RAW_IS_DEFAULT_ON(OP_SYMBOL ## _I_) +#define SOL_IS_DEFAULT_OFF(OP_SYMBOL) SOL_RAW_IS_DEFAULT_OFF(OP_SYMBOL ## _I_) + +#define SOL_ON | +#define SOL_OFF ^ +#define SOL_DEFAULT_ON + +#define SOL_DEFAULT_OFF - + +#if defined(SOL_BUILD_CXX_MODE) + #if (SOL_BUILD_CXX_MODE != 0) + #define SOL_BUILD_CXX_MODE_I_ SOL_ON + #else + #define SOL_BUILD_CXX_MODE_I_ SOL_OFF + #endif +#elif defined(__cplusplus) + #define SOL_BUILD_CXX_MODE_I_ SOL_DEFAULT_ON +#else + #define SOL_BUILD_CXX_MODE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_BUILD_C_MODE) + #if (SOL_BUILD_C_MODE != 0) + #define SOL_BUILD_C_MODE_I_ SOL_ON + #else + #define SOL_BUILD_C_MODE_I_ SOL_OFF + #endif +#elif defined(__STDC__) + #define SOL_BUILD_C_MODE_I_ SOL_DEFAULT_ON +#else + #define SOL_BUILD_C_MODE_I_ SOL_DEFAULT_OFF +#endif + +#if SOL_IS_ON(SOL_BUILD_C_MODE) + #include + #include + #include +#else + #include + #include + #include +#endif + +#if defined(SOL_COMPILER_VCXX) + #if defined(SOL_COMPILER_VCXX != 0) + #define SOL_COMPILER_VCXX_I_ SOL_ON + #else + #define SOL_COMPILER_VCXX_I_ SOL_OFF + #endif +#elif defined(_MSC_VER) + #define SOL_COMPILER_VCXX_I_ SOL_DEFAULT_ON +#else + #define SOL_COMPILER_VCXX_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_COMPILER_GCC) + #if defined(SOL_COMPILER_GCC != 0) + #define SOL_COMPILER_GCC_I_ SOL_ON + #else + #define SOL_COMPILER_GCC_I_ SOL_OFF + #endif +#elif defined(__GNUC__) + #define SOL_COMPILER_GCC_I_ SOL_DEFAULT_ON +#else + #define SOL_COMPILER_GCC_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_COMPILER_CLANG) + #if defined(SOL_COMPILER_CLANG != 0) + #define SOL_COMPILER_CLANG_I_ SOL_ON + #else + #define SOL_COMPILER_CLANG_I_ SOL_OFF + #endif +#elif defined(__clang__) + #define SOL_COMPILER_CLANG_I_ SOL_DEFAULT_ON +#else + #define SOL_COMPILER_CLANG_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_COMPILER_EDG) + #if defined(SOL_COMPILER_EDG != 0) + #define SOL_COMPILER_EDG_I_ SOL_ON + #else + #define SOL_COMPILER_EDG_I_ SOL_OFF + #endif +#else + #define SOL_COMPILER_EDG_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_COMPILER_MINGW) + #if (SOL_COMPILER_MINGW != 0) + #define SOL_COMPILER_MINGW_I_ SOL_ON + #else + #define SOL_COMPILER_MINGW_I_ SOL_OFF + #endif +#elif defined(__MINGW32__) + #define SOL_COMPILER_MINGW_I_ SOL_DEFAULT_ON +#else + #define SOL_COMPILER_MINGW_I_ SOL_DEFAULT_OFF +#endif + +#if SIZE_MAX <= 0xFFFFULL + #define SOL_PLATFORM_X16_I_ SOL_ON + #define SOL_PLATFORM_X86_I_ SOL_OFF + #define SOL_PLATFORM_X64_I_ SOL_OFF +#elif SIZE_MAX <= 0xFFFFFFFFULL + #define SOL_PLATFORM_X16_I_ SOL_OFF + #define SOL_PLATFORM_X86_I_ SOL_ON + #define SOL_PLATFORM_X64_I_ SOL_OFF +#else + #define SOL_PLATFORM_X16_I_ SOL_OFF + #define SOL_PLATFORM_X86_I_ SOL_OFF + #define SOL_PLATFORM_X64_I_ SOL_ON +#endif + +#define SOL_PLATFORM_ARM32_I_ SOL_OFF +#define SOL_PLATFORM_ARM64_I_ SOL_OFF + +#if defined(SOL_PLATFORM_WINDOWS) + #if (SOL_PLATFORM_WINDOWS != 0) + #define SOL_PLATFORM_WINDOWS_I_ SOL_ON + #else + #define SOL_PLATFORM_WINDOWS_I_ SOL_OFF + #endif +#elif defined(_WIN32) + #define SOL_PLATFORM_WINDOWS_I_ SOL_DEFAULT_ON +#else + #define SOL_PLATFORM_WINDOWS_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_PLATFORM_CYGWIN) + #if (SOL_PLATFORM_CYGWIN != 0) + #define SOL_PLATFORM_CYGWIN_I_ SOL_ON + #else + #define SOL_PLATFORM_CYGWIN_I_ SOL_ON + #endif +#elif defined(__CYGWIN__) + #define SOL_PLATFORM_CYGWIN_I_ SOL_DEFAULT_ON +#else + #define SOL_PLATFORM_CYGWIN_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_PLATFORM_APPLE) + #if (SOL_PLATFORM_APPLE != 0) + #define SOL_PLATFORM_APPLE_I_ SOL_ON + #else + #define SOL_PLATFORM_APPLE_I_ SOL_OFF + #endif +#elif defined(__APPLE__) + #define SOL_PLATFORM_APPLE_I_ SOL_DEFAULT_ON +#else + #define SOL_PLATFORM_APPLE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_PLATFORM_UNIX) + #if (SOL_PLATFORM_UNIX != 0) + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_ON + #else + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_OFF + #endif +#elif defined(__unix__) + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_DEFAUKT_ON +#else + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_PLATFORM_LINUX) + #if (SOL_PLATFORM_LINUX != 0) + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_ON + #else + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_OFF + #endif +#elif defined(__LINUX__) + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_DEFAUKT_ON +#else + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_DEFAULT_OFF +#endif + +#define SOL_PLATFORM_APPLE_IPHONE_I_ SOL_OFF +#define SOL_PLATFORM_BSDLIKE_I_ SOL_OFF + +#if defined(SOL_IN_DEBUG_DETECTED) + #if SOL_IN_DEBUG_DETECTED != 0 + #define SOL_DEBUG_BUILD_I_ SOL_ON + #else + #define SOL_DEBUG_BUILD_I_ SOL_OFF + #endif +#elif !defined(NDEBUG) + #if SOL_IS_ON(SOL_COMPILER_VCXX) && defined(_DEBUG) + #define SOL_DEBUG_BUILD_I_ SOL_ON + #elif (SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC)) && !defined(__OPTIMIZE__) + #define SOL_DEBUG_BUILD_I_ SOL_ON + #else + #define SOL_DEBUG_BUILD_I_ SOL_OFF + #endif +#else + #define SOL_DEBUG_BUILD_I_ SOL_DEFAULT_OFF +#endif // We are in a debug mode of some sort + +#if defined(SOL_NO_EXCEPTIONS) + #if (SOL_NO_EXCEPTIONS != 0) + #define SOL_EXCEPTIONS_I_ SOL_OFF + #else + #define SOL_EXCEPTIONS_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX) + #if !defined(_CPPUNWIND) + #define SOL_EXCEPTIONS_I_ SOL_OFF + #else + #define SOL_EXCEPTIONS_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC) + #if !defined(__EXCEPTIONS) + #define SOL_EXCEPTIONS_I_ SOL_OFF + #else + #define SOL_EXCEPTIONS_I_ SOL_ON + #endif +#else + #define SOL_EXCEPTIONS_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_NO_RTTI) + #if (SOL_NO_RTTI != 0) + #define SOL_RTTI_I_ SOL_OFF + #else + #define SOL_RTTI_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX) + #if !defined(_CPPRTTI) + #define SOL_RTTI_I_ SOL_OFF + #else + #define SOL_RTTI_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC) + #if !defined(__GXX_RTTI) + #define SOL_RTTI_I_ SOL_OFF + #else + #define SOL_RTTI_I_ SOL_ON + #endif +#else + #define SOL_RTTI_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_NO_THREAD_LOCAL) + #if SOL_NO_THREAD_LOCAL != 0 + #define SOL_USE_THREAD_LOCAL_I_ SOL_OFF + #else + #define SOL_USE_THREAD_LOCAL_I_ SOL_ON + #endif +#else + #define SOL_USE_THREAD_LOCAL_I_ SOL_DEFAULT_ON +#endif // thread_local keyword is bjorked on some platforms + +#if defined(SOL_ALL_SAFETIES_ON) + #if SOL_ALL_SAFETIES_ON != 0 + #define SOL_ALL_SAFETIES_ON_I_ SOL_ON + #else + #define SOL_ALL_SAFETIES_ON_I_ SOL_OFF + #endif +#else + #define SOL_ALL_SAFETIES_ON_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_SAFE_GETTER) + #if SOL_SAFE_GETTER != 0 + #define SOL_SAFE_GETTER_I_ SOL_ON + #else + #define SOL_SAFE_GETTER_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_GETTER_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_USERTYPE) + #if SOL_SAFE_USERTYPE != 0 + #define SOL_SAFE_USERTYPE_I_ SOL_ON + #else + #define SOL_SAFE_USERTYPE_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_USERTYPE_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_REFERENCES) + #if SOL_SAFE_REFERENCES != 0 + #define SOL_SAFE_REFERENCES_I_ SOL_ON + #else + #define SOL_SAFE_REFERENCES_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_REFERENCES_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_FUNCTIONS) + #if SOL_SAFE_FUNCTIONS != 0 + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON + #else + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_OFF + #endif +#elif defined (SOL_SAFE_FUNCTION_OBJECTS) + #if SOL_SAFE_FUNCTION_OBJECTS != 0 + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON + #else + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_FUNCTION_CALLS) + #if SOL_SAFE_FUNCTION_CALLS != 0 + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON + #else + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_PROXIES) + #if SOL_SAFE_PROXIES != 0 + #define SOL_SAFE_PROXIES_I_ SOL_ON + #else + #define SOL_SAFE_PROXIES_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_PROXIES_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_NUMERICS) + #if SOL_SAFE_NUMERICS != 0 + #define SOL_SAFE_NUMERICS_I_ SOL_ON + #else + #define SOL_SAFE_NUMERICS_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_NUMERICS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_ALL_INTEGER_VALUES_FIT) + #if (SOL_ALL_INTEGER_VALUES_FIT != 0) + #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_ON + #else + #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_OFF + #endif +#elif !SOL_IS_DEFAULT_OFF(SOL_SAFE_NUMERICS) && SOL_IS_OFF(SOL_SAFE_NUMERICS) + // if numerics is intentionally turned off, flip this on + #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_DEFAULT_ON +#else + // default to off + #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_SAFE_STACK_CHECK) + #if SOL_SAFE_STACK_CHECK != 0 + #define SOL_SAFE_STACK_CHECK_I_ SOL_ON + #else + #define SOL_SAFE_STACK_CHECK_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_STACK_CHECK_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_NO_CHECK_NUMBER_PRECISION) + #if SOL_NO_CHECK_NUMBER_PRECISION != 0 + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF + #else + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #endif +#elif defined(SOL_NO_CHECKING_NUMBER_PRECISION) + #if SOL_NO_CHECKING_NUMBER_PRECISION != 0 + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF + #else + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #elif SOL_IS_ON(SOL_SAFE_NUMERICS) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_ON + #else + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_STRINGS_ARE_NUMBERS) + #if (SOL_STRINGS_ARE_NUMBERS != 0) + #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_ON + #else + #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_OFF + #endif +#else + #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_ENABLE_INTEROP) + #if SOL_ENABLE_INTEROP != 0 + #define SOL_USE_INTEROP_I_ SOL_ON + #else + #define SOL_USE_INTEROP_I_ SOL_OFF + #endif +#elif defined(SOL_USE_INTEROP) + #if SOL_USE_INTEROP != 0 + #define SOL_USE_INTEROP_I_ SOL_ON + #else + #define SOL_USE_INTEROP_I_ SOL_OFF + #endif +#else + #define SOL_USE_INTEROP_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_NO_NIL) + #if (SOL_NO_NIL != 0) + #define SOL_NIL_I_ SOL_OFF + #else + #define SOL_NIL_I_ SOL_ON + #endif +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) || defined(__OBJC__) || defined(nil) + #define SOL_NIL_I_ SOL_DEFAULT_OFF +#else + #define SOL_NIL_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_USERTYPE_TYPE_BINDING_INFO) + #if (SOL_USERTYPE_TYPE_BINDING_INFO != 0) + #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_ON + #else + #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_OFF + #endif +#else + #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_DEFAULT_ON +#endif // We should generate a my_type.__type table with lots of class information for usertypes + +#if defined(SOL_AUTOMAGICAL_TYPES_BY_DEFAULT) + #if (SOL_AUTOMAGICAL_TYPES_BY_DEFAULT != 0) + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON + #else + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF + #endif +#elif defined(SOL_DEFAULT_AUTOMAGICAL_USERTYPES) + #if (SOL_DEFAULT_AUTOMAGICAL_USERTYPES != 0) + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON + #else + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF + #endif +#else + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_DEFAULT_ON +#endif // make is_automagical on/off by default + +#if defined(SOL_STD_VARIANT) + #if (SOL_STD_VARIANT != 0) + #define SOL_STD_VARIANT_I_ SOL_ON + #else + #define SOL_STD_VARIANT_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_COMPILER_CLANG) && SOL_IS_ON(SOL_PLATFORM_APPLE) + #if defined(__has_include) + #if __has_include() + #define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON + #else + #define SOL_STD_VARIANT_I_ SOL_DEFAULT_OFF + #endif + #else + #define SOL_STD_VARIANT_I_ SOL_DEFAULT_OFF + #endif + #else + #define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON + #endif +#endif // make is_automagical on/off by default + +#if defined(SOL_NOEXCEPT_FUNCTION_TYPE) + #if (SOL_NOEXCEPT_FUNCTION_TYPE != 0) + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON + #else + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF + #endif +#else + #if defined(__cpp_noexcept_function_type) + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON + #elif SOL_IS_ON(SOL_COMPILER_VCXX) && (defined(_MSVC_LANG) && (_MSVC_LANG < 201403L)) + // There is a bug in the VC++ compiler?? + // on /std:c++latest under x86 conditions (VS 15.5.2), + // compiler errors are tossed for noexcept markings being on function types + // that are identical in every other way to their non-noexcept marked types function types... + // VS 2019: There is absolutely a bug. + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF + #else + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_DEFAULT_ON + #endif +#endif // noexcept is part of a function's type + +#if defined(SOL_STACK_STRING_OPTIMIZATION_SIZE) && SOL_STACK_STRING_OPTIMIZATION_SIZE > 0 + #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ SOL_STACK_STRING_OPTIMIZATION_SIZE +#else + #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ 1024 +#endif + +#if defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0 + #define SOL_ID_SIZE_I_ SOL_ID_SIZE +#else + #define SOL_ID_SIZE_I_ 512 +#endif + +#if defined(LUA_IDSIZE) && LUA_IDSIZE > 0 + #define SOL_FILE_ID_SIZE_I_ LUA_IDSIZE +#elif defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0 + #define SOL_FILE_ID_SIZE_I_ SOL_FILE_ID_SIZE +#else + #define SOL_FILE_ID_SIZE_I_ 2048 +#endif + +#if defined(SOL_PRINT_ERRORS) + #if (SOL_PRINT_ERRORS != 0) + #define SOL_PRINT_ERRORS_I_ SOL_ON + #else + #define SOL_PRINT_ERRORS_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_PRINT_ERRORS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_PRINT_ERRORS_I_ SOL_DEFAULT_ON + #else + #define SOL_PRINT_ERRORS_I_ SOL_OFF + #endif +#endif + +#if defined(SOL_DEFAULT_PASS_ON_ERROR) + #if (SOL_DEFAULT_PASS_ON_ERROR != 0) + #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON + #else + #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_OFF + #endif +#else + #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_USING_CXX_LUA) + #if (SOL_USING_CXX_LUA != 0) + #define SOL_USE_CXX_LUA_I_ SOL_ON + #else + #define SOL_USE_CXX_LUA_I_ SOL_OFF + #endif +#elif defined(SOL_USE_CXX_LUA) + #if (SOL_USE_CXX_LUA != 0) + #define SOL_USE_CXX_LUA_I_ SOL_ON + #else + #define SOL_USE_CXX_LUA_I_ SOL_OFF + #endif +#else + #define SOL_USE_CXX_LUA_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_USING_CXX_LUAJIT) + #if (SOL_USING_CXX_LUA != 0) + #define SOL_USE_CXX_LUAJIT_I_ SOL_ON + #else + #define SOL_USE_CXX_LUAJIT_I_ SOL_OFF + #endif +#elif defined(SOL_USE_CXX_LUAJIT) + #if (SOL_USE_CXX_LUA != 0) + #define SOL_USE_CXX_LUAJIT_I_ SOL_ON + #else + #define SOL_USE_CXX_LUAJIT_I_ SOL_OFF + #endif +#else + #define SOL_USE_CXX_LUAJIT_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_NO_LUA_HPP) + #if (SOL_NO_LUA_HPP != 0) + #define SOL_USE_LUA_HPP_I_ SOL_OFF + #else + #define SOL_USE_LUA_HPP_I_ SOL_ON + #endif +#elif defined(SOL_USING_CXX_LUA) + #define SOL_USE_LUA_HPP_I_ SOL_OFF +#elif defined(__has_include) + #if __has_include() + #define SOL_USE_LUA_HPP_I_ SOL_ON + #else + #define SOL_USE_LUA_HPP_I_ SOL_OFF + #endif +#else + #define SOL_USE_LUA_HPP_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_CONTAINERS_START) + #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START +#elif defined(SOL_CONTAINERS_START_INDEX) + #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START_INDEX +#elif defined(SOL_CONTAINER_START_INDEX) + #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINER_START_INDEX +#else + #define SOL_CONTAINER_START_INDEX_I_ 1 +#endif + +#if defined (SOL_NO_MEMORY_ALIGNMENT) + #if (SOL_NO_MEMORY_ALIGNMENT != 0) + #define SOL_ALIGN_MEMORY_I_ SOL_OFF + #else + #define SOL_ALIGN_MEMORY_I_ SOL_ON + #endif +#else + #define SOL_ALIGN_MEMORY_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_USE_BOOST) + #if (SOL_USE_BOOST != 0) + #define SOL_USE_BOOST_I_ SOL_ON + #else + #define SOL_USE_BOOST_I_ SOL_OFF + #endif +#else + #define SOL_USE_BOOST_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_USE_UNSAFE_BASE_LOOKUP) + #if (SOL_USE_UNSAFE_BASE_LOOKUP != 0) + #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_ON + #else + #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF + #endif +#else + #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_INSIDE_UNREAL) + #if (SOL_INSIDE_UNREAL != 0) + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON + #else + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_OFF + #endif +#else + #if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT) || defined(UE_BUILD_TEST) || defined(UE_BUILD_SHIPPING) || defined(UE_SERVER) + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_ON + #else + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_NO_COMPAT) + #if (SOL_NO_COMPAT != 0) + #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_OFF + #else + #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_ON + #endif +#else + #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_GET_FUNCTION_POINTER_UNSAFE) + #if (SOL_GET_FUNCTION_POINTER_UNSAFE != 0) + #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_ON + #else + #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_OFF + #endif +#else + #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_FUNCTION_CALL_VALUE_SEMANTICS) + #if (SOL_FUNCTION_CALL_VALUE_SEMANTICS != 0) + #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_ON + #else + #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_OFF + #endif +#else + #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_MINGW_CCTYPE_IS_POISONED) + #if (SOL_MINGW_CCTYPE_IS_POISONED != 0) + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_ON + #else + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_OFF + #endif +#elif SOL_IS_ON(SOL_COMPILER_MINGW) && defined(__GNUC__) && (__GNUC__ < 6) + // MinGW is off its rocker in some places... + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_ON +#else + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_CHAR8_T) + #if (SOL_CHAR8_T != 0) + #define SOL_CHAR8_T_I_ SOL_ON + #else + #define SOL_CHAR8_T_I_ SOL_OFF + #endif +#else + #if defined(__cpp_char8_t) + #define SOL_CHAR8_T_I_ SOL_DEFAULT_ON + #else + #define SOL_CHAR8_T_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if SOL_IS_ON(SOL_USE_BOOST) + #include + + #if BOOST_VERSION >= 107500 // Since Boost 1.75.0 boost::none is constexpr + #define SOL_BOOST_NONE_CONSTEXPR_I_ constexpr + #else + #define SOL_BOOST_NONE_CONSTEXPR_I_ const + #endif // BOOST_VERSION +#else + // assume boost isn't using a garbage version + #define SOL_BOOST_NONE_CONSTEXPR_I_ constexpr +#endif + +#if defined(SOL2_CI) + #if (SOL2_CI != 0) + #define SOL2_CI_I_ SOL_ON + #else + #define SOL2_CI_I_ SOL_OFF + #endif +#else + #define SOL2_CI_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_C_ASSERT) + #define SOL_USER_C_ASSERT_I_ SOL_ON +#else + #define SOL_USER_C_ASSERT_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_M_ASSERT) + #define SOL_USER_M_ASSERT_I_ SOL_ON +#else + #define SOL_USER_M_ASSERT_I_ SOL_DEFAULT_OFF +#endif + +// beginning of sol/prologue.hpp + +#if defined(SOL_PROLOGUE_I_) + #error "[sol2] Library Prologue was already included in translation unit and not properly ended with an epilogue." +#endif + +#define SOL_PROLOGUE_I_ 1 + +#if SOL_IS_ON(SOL_BUILD_CXX_MODE) + #define _FWD(...) static_cast( __VA_ARGS__ ) + + #if SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define _MOVE(...) static_cast<__typeof( __VA_ARGS__ )&&>( __VA_ARGS__ ) + #else + #include + + #define _MOVE(...) static_cast<::std::remove_reference_t<( __VA_ARGS__ )>&&>( __VA_OPT__(,) ) + #endif +#endif + +// end of sol/prologue.hpp + +// beginning of sol/epilogue.hpp + +#if !defined(SOL_PROLOGUE_I_) + #error "[sol2] Library Prologue is missing from this translation unit." +#else + #undef SOL_PROLOGUE_I_ +#endif + +#if SOL_IS_ON(SOL_BUILD_CXX_MODE) + #undef _FWD + #undef _MOVE +#endif + +// end of sol/epilogue.hpp + +// beginning of sol/detail/build_version.hpp + +#if defined(SOL_DLL) + #if (SOL_DLL != 0) + #define SOL_DLL_I_ SOL_ON + #else + #define SOL_DLL_I_ SOL_OFF + #endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX) && (defined(DLL_) || defined(_DLL)) + #define SOL_DLL_I_ SOL_DEFAULT_ON +#else + #define SOL_DLL_I_ SOL_DEFAULT_OFF +#endif // DLL definition + +#if defined(SOL_HEADER_ONLY) + #if (SOL_HEADER_ONLY != 0) + #define SOL_HEADER_ONLY_I_ SOL_ON + #else + #define SOL_HEADER_ONLY_I_ SOL_OFF + #endif +#else + #define SOL_HEADER_ONLY_I_ SOL_DEFAULT_OFF +#endif // Header only library + +#if defined(SOL_BUILD) + #if (SOL_BUILD != 0) + #define SOL_BUILD_I_ SOL_ON + #else + #define SOL_BUILD_I_ SOL_OFF + #endif +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_BUILD_I_ SOL_DEFAULT_OFF +#else + #define SOL_BUILD_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_UNITY_BUILD) + #if (SOL_UNITY_BUILD != 0) + #define SOL_UNITY_BUILD_I_ SOL_ON + #else + #define SOL_UNITY_BUILD_I_ SOL_OFF + #endif +#else + #define SOL_UNITY_BUILD_I_ SOL_DEFAULT_OFF +#endif // Header only library + +#if defined(SOL_C_FUNCTION_LINKAGE) + #define SOL_C_FUNCTION_LINKAGE_I_ SOL_C_FUNCTION_LINKAGE +#else + #if SOL_IS_ON(SOL_BUILD_CXX_MODE) + // C++ + #define SOL_C_FUNCTION_LINKAGE_I_ extern "C" + #else + // normal + #define SOL_C_FUNCTION_LINKAGE_I_ + #endif // C++ or not +#endif // Linkage specification for C functions + +#if defined(SOL_API_LINKAGE) + #define SOL_API_LINKAGE_I_ SOL_API_LINKAGE +#else + #if SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) || SOL_IS_ON(SOL_PLATFORM_WINDOWS) || SOL_IS_ON(SOL_PLATFORM_CYGWIN) + // MSVC Compiler; or, Windows, or Cygwin platforms + #if SOL_IS_ON(SOL_BUILD) + // Building the library + #if SOL_IS_ON(SOL_COMPILER_GCC) + // Using GCC + #define SOL_API_LINKAGE_I_ __attribute__((dllexport)) + #else + // Using Clang, MSVC, etc... + #define SOL_API_LINKAGE_I_ __declspec(dllexport) + #endif + #else + #if SOL_IS_ON(SOL_COMPILER_GCC) + #define SOL_API_LINKAGE_I_ __attribute__((dllimport)) + #else + #define SOL_API_LINKAGE_I_ __declspec(dllimport) + #endif + #endif + #else + // extern if building normally on non-MSVC + #define SOL_API_LINKAGE_I_ extern + #endif + #elif SOL_IS_ON(SOL_UNITY_BUILD) + // Built-in library, like how stb typical works + #if SOL_IS_ON(SOL_HEADER_ONLY) + // Header only, so functions are defined "inline" + #define SOL_API_LINKAGE_I_ inline + #else + // Not header only, so seperately compiled files + #define SOL_API_LINKAGE_I_ extern + #endif + #else + // Normal static library + #if SOL_IS_ON(SOL_BUILD_CXX_MODE) + #define SOL_API_LINKAGE_I_ + #else + #define SOL_API_LINKAGE_I_ extern + #endif + #endif // DLL or not +#endif // Build definitions + +#if defined(SOL_PUBLIC_FUNC_DECL) + #define SOL_PUBLIC_FUNC_DECL_I_ SOL_PUBLIC_FUNC_DECL +#else + #define SOL_PUBLIC_FUNC_DECL_I_ SOL_API_LINKAGE_I_ +#endif + +#if defined(SOL_INTERNAL_FUNC_DECL_) + #define SOL_INTERNAL_FUNC_DECL_I_ SOL_INTERNAL_FUNC_DECL_ +#else + #define SOL_INTERNAL_FUNC_DECL_I_ SOL_API_LINKAGE_I_ +#endif + +#if defined(SOL_PUBLIC_FUNC_DEF) + #define SOL_PUBLIC_FUNC_DEF_I_ SOL_PUBLIC_FUNC_DEF +#else + #define SOL_PUBLIC_FUNC_DEF_I_ SOL_API_LINKAGE_I_ +#endif + +#if defined(SOL_INTERNAL_FUNC_DEF) + #define SOL_INTERNAL_FUNC_DEF_I_ SOL_INTERNAL_FUNC_DEF +#else + #define SOL_INTERNAL_FUNC_DEF_I_ SOL_API_LINKAGE_I_ +#endif + +#if defined(SOL_FUNC_DECL) + #define SOL_FUNC_DECL_I_ SOL_FUNC_DECL +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_FUNC_DECL_I_ +#elif SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) + #if SOL_IS_ON(SOL_BUILD) + #define SOL_FUNC_DECL_I_ extern __declspec(dllexport) + #else + #define SOL_FUNC_DECL_I_ extern __declspec(dllimport) + #endif + #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define SOL_FUNC_DECL_I_ extern __attribute__((visibility("default"))) + #else + #define SOL_FUNC_DECL_I_ extern + #endif +#endif + +#if defined(SOL_FUNC_DEFN) + #define SOL_FUNC_DEFN_I_ SOL_FUNC_DEFN +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_FUNC_DEFN_I_ inline +#elif SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) + #if SOL_IS_ON(SOL_BUILD) + #define SOL_FUNC_DEFN_I_ __declspec(dllexport) + #else + #define SOL_FUNC_DEFN_I_ __declspec(dllimport) + #endif + #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define SOL_FUNC_DEFN_I_ __attribute__((visibility("default"))) + #else + #define SOL_FUNC_DEFN_I_ + #endif +#endif + +#if defined(SOL_HIDDEN_FUNC_DECL) + #define SOL_HIDDEN_FUNC_DECL_I_ SOL_HIDDEN_FUNC_DECL +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_HIDDEN_FUNC_DECL_I_ +#elif SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) + #if SOL_IS_ON(SOL_BUILD) + #define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllexport) + #else + #define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllimport) + #endif + #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define SOL_HIDDEN_FUNC_DECL_I_ extern __attribute__((visibility("default"))) + #else + #define SOL_HIDDEN_FUNC_DECL_I_ extern + #endif +#endif + +#if defined(SOL_HIDDEN_FUNC_DEFN) + #define SOL_HIDDEN_FUNC_DEFN_I_ SOL_HIDDEN_FUNC_DEFN +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_HIDDEN_FUNC_DEFN_I_ inline +#elif SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) + #if SOL_IS_ON(SOL_BUILD) + #define SOL_HIDDEN_FUNC_DEFN_I_ + #else + #define SOL_HIDDEN_FUNC_DEFN_I_ + #endif + #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define SOL_HIDDEN_FUNC_DEFN_I_ __attribute__((visibility("hidden"))) + #else + #define SOL_HIDDEN_FUNC_DEFN_I_ + #endif +#endif + +// end of sol/detail/build_version.hpp + +// end of sol/version.hpp + +#if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE) +#ifdef check +#pragma push_macro("check") +#undef check +#endif +#endif // Unreal Engine 4 Bullshit + +#if SOL_IS_ON(SOL_COMPILER_GCC) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wconversion" +#if __GNUC__ > 6 +#pragma GCC diagnostic ignored "-Wnoexcept-type" +#endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG) +#elif SOL_IS_ON(SOL_COMPILER_VCXX) +#pragma warning(push) +#pragma warning(disable : 4505) // unreferenced local function has been removed GEE THANKS +#endif // clang++ vs. g++ vs. VC++ + +// beginning of sol/forward.hpp + +#ifndef SOL_FORWARD_HPP +#define SOL_FORWARD_HPP + +#include +#include +#include + +#if SOL_IS_ON(SOL_USE_CXX_LUA) || SOL_IS_ON(SOL_USE_CXX_LUAJIT) +struct lua_State; +#else +extern "C" { +struct lua_State; +} +#endif // C++ Mangling for Lua vs. Not + +namespace sol { + + enum class type; + + class stateless_reference; + template + class basic_reference; + using reference = basic_reference; + using main_reference = basic_reference; + class stateless_stack_reference; + class stack_reference; + + template + class basic_bytecode; + + struct lua_value; + + struct proxy_base_tag; + template + struct proxy_base; + template + struct table_proxy; + + template + class basic_table_core; + template + using table_core = basic_table_core; + template + using main_table_core = basic_table_core; + template + using stack_table_core = basic_table_core; + template + using basic_table = basic_table_core; + using table = table_core; + using global_table = table_core; + using main_table = main_table_core; + using main_global_table = main_table_core; + using stack_table = stack_table_core; + using stack_global_table = stack_table_core; + + template + struct basic_lua_table; + using lua_table = basic_lua_table; + using stack_lua_table = basic_lua_table; + + template + class basic_usertype; + template + using usertype = basic_usertype; + template + using stack_usertype = basic_usertype; + + template + class basic_metatable; + using metatable = basic_metatable; + using stack_metatable = basic_metatable; + + template + struct basic_environment; + using environment = basic_environment; + using main_environment = basic_environment; + using stack_environment = basic_environment; + + template + class basic_function; + template + class basic_protected_function; + using unsafe_function = basic_function; + using safe_function = basic_protected_function; + using main_unsafe_function = basic_function; + using main_safe_function = basic_protected_function; + using stack_unsafe_function = basic_function; + using stack_safe_function = basic_protected_function; + using stack_aligned_unsafe_function = basic_function; + using stack_aligned_safe_function = basic_protected_function; + using protected_function = safe_function; + using main_protected_function = main_safe_function; + using stack_protected_function = stack_safe_function; + using stack_aligned_protected_function = stack_aligned_safe_function; +#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS) + using function = protected_function; + using main_function = main_protected_function; + using stack_function = stack_protected_function; + using stack_aligned_function = stack_aligned_safe_function; +#else + using function = unsafe_function; + using main_function = main_unsafe_function; + using stack_function = stack_unsafe_function; + using stack_aligned_function = stack_aligned_unsafe_function; +#endif + using stack_aligned_stack_handler_function = basic_protected_function; + + struct unsafe_function_result; + struct protected_function_result; + using safe_function_result = protected_function_result; +#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS) + using function_result = safe_function_result; +#else + using function_result = unsafe_function_result; +#endif + + template + class basic_object_base; + template + class basic_object; + template + class basic_userdata; + template + class basic_lightuserdata; + template + class basic_coroutine; + template + class basic_packaged_coroutine; + template + class basic_thread; + + using object = basic_object; + using userdata = basic_userdata; + using lightuserdata = basic_lightuserdata; + using thread = basic_thread; + using coroutine = basic_coroutine; + using packaged_coroutine = basic_packaged_coroutine; + using main_object = basic_object; + using main_userdata = basic_userdata; + using main_lightuserdata = basic_lightuserdata; + using main_coroutine = basic_coroutine; + using stack_object = basic_object; + using stack_userdata = basic_userdata; + using stack_lightuserdata = basic_lightuserdata; + using stack_thread = basic_thread; + using stack_coroutine = basic_coroutine; + + struct stack_proxy_base; + struct stack_proxy; + struct variadic_args; + struct variadic_results; + struct stack_count; + struct this_state; + struct this_main_state; + struct this_environment; + + class state_view; + class state; + + template + struct as_table_t; + template + struct as_container_t; + template + struct nested; + template + struct light; + template + struct user; + template + struct as_args_t; + template + struct protect_t; + template + struct policy_wrapper; + + template + struct usertype_traits; + template + struct unique_usertype_traits; + + template + struct types { + typedef std::make_index_sequence indices; + static constexpr std::size_t size() { + return sizeof...(Args); + } + }; + + template + struct derive : std::false_type { + typedef types<> type; + }; + + template + struct base : std::false_type { + typedef types<> type; + }; + + template + struct weak_derive { + static bool value; + }; + + template + bool weak_derive::value = false; + + namespace stack { + struct record; + } + +#if SOL_IS_OFF(SOL_USE_BOOST) + template + class optional; + + template + class optional; +#endif + + using check_handler_type = int(lua_State*, int, type, type, const char*); + +} // namespace sol + +#define SOL_BASE_CLASSES(T, ...) \ + namespace sol { \ + template <> \ + struct base : std::true_type { \ + typedef ::sol::types<__VA_ARGS__> type; \ + }; \ + } \ + void a_sol3_detail_function_decl_please_no_collide() +#define SOL_DERIVED_CLASSES(T, ...) \ + namespace sol { \ + template <> \ + struct derive : std::true_type { \ + typedef ::sol::types<__VA_ARGS__> type; \ + }; \ + } \ + void a_sol3_detail_function_decl_please_no_collide() + +#endif // SOL_FORWARD_HPP +// end of sol/forward.hpp + +// beginning of sol/forward_detail.hpp + +#ifndef SOL_FORWARD_DETAIL_HPP +#define SOL_FORWARD_DETAIL_HPP + +// beginning of sol/traits.hpp + +// beginning of sol/tuple.hpp + +// beginning of sol/base_traits.hpp + +#include + +namespace sol { + namespace detail { + struct unchecked_t { }; + const unchecked_t unchecked = unchecked_t {}; + } // namespace detail + + namespace meta { + using sfinae_yes_t = std::true_type; + using sfinae_no_t = std::false_type; + + template + using void_t = void; + + template + using unqualified = std::remove_cv>; + + template + using unqualified_t = typename unqualified::type; + + namespace meta_detail { + template + struct unqualified_non_alias : unqualified { }; + + template