diff --git a/CMakeLists.txt b/CMakeLists.txt index 41b59b0f1c..4618349e36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,3 +19,17 @@ if (LUA_VERSION MATCHES "luajit") else() add_subdirectory(src/lualib/lua) endif() + +# sol (C++ <-> Lua binding library, header-only) is bundled in src/lualib/sol. +# Attaching it to lualib as INTERFACE propagates and its compile +# definitions to every consumer of lualib, whichever Lua backend is selected. +# SYSTEM keeps the vendored header out of our warning surface: sol carries +# GCC-only pragmas that clang would otherwise reject under -Werror. +target_include_directories(lualib SYSTEM INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/src/lualib") + +# Keep sol runtime safety checks enabled in every build type: script errors must +# surface as catchable Lua errors, never as undefined behaviour in the server. +# SOL_EXCEPTIONS_SAFE_PROPAGATION=0 makes sol catch C++ exceptions at the +# binding boundary and convert them into regular Lua errors carrying their +# message; without it LuaJIT swallows them into a generic "C++ exception". +target_compile_definitions(lualib INTERFACE SOL_ALL_SAFETIES_ON=1 SOL_EXCEPTIONS_SAFE_PROPAGATION=0) diff --git a/src/LuaEngine/ALEBind.cpp b/src/LuaEngine/ALEBind.cpp new file mode 100644 index 0000000000..34287840e3 --- /dev/null +++ b/src/LuaEngine/ALEBind.cpp @@ -0,0 +1,61 @@ +/* +* 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 "ALEBind.h" + +#include "Corpse.h" +#include "GameObject.h" +#include "Item.h" +#include "Object.h" +#include "Pet.h" +#include "Player.h" +#include "Transport.h" + +namespace ALEBind +{ + sol::object ToLuaDynamic(sol::state_view lua, Object const* obj) + { + if (!obj) + return sol::make_object(lua, sol::nil); + + if (Player const* player = obj->ToPlayer()) + return sol::make_object(lua, PlayerRef(player)); + + if (Creature* creature = const_cast(obj)->ToCreature()) + { + if (Pet const* pet = creature->ToPet()) + return sol::make_object(lua, PetRef(pet)); + + return sol::make_object(lua, CreatureRef(creature)); + } + + if (GameObject* go = const_cast(obj)->ToGameObject()) + { + if (Transport const* transport = go->ToTransport()) + return sol::make_object(lua, TransportRef(transport)); + + return sol::make_object(lua, GameObjectRef(go)); + } + + if (Corpse const* corpse = obj->ToCorpse()) + return sol::make_object(lua, CorpseRef(corpse)); + + if (obj->IsItem()) + return sol::make_object(lua, ItemRef(static_cast(obj))); + + return sol::make_object(lua, sol::nil); + } + + sol::object ToLuaDynamic(sol::state_view lua, WorldObject const* obj) + { + return ToLuaDynamic(lua, static_cast(obj)); + } + + sol::object ToLuaDynamic(sol::state_view lua, Unit const* unit) + { + return ToLuaDynamic(lua, static_cast(unit)); + } +} diff --git a/src/LuaEngine/ALEBind.h b/src/LuaEngine/ALEBind.h new file mode 100644 index 0000000000..bee88b35db --- /dev/null +++ b/src/LuaEngine/ALEBind.h @@ -0,0 +1,368 @@ +/* +* 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_BIND_H +#define _ALE_BIND_H + +#include "ALEHandles.h" + +#include + +#include +#include + +struct AuctionEntry; +class AuctionHouseObject; +class Aura; +class Battleground; +class ChatHandler; +class GmTicket; +struct Loot; +class Roll; +class Spell; +class Vehicle; +class Weather; + +/* + * Adapters that turn plain C++ functions into Lua-callable methods. + * + * Binding files should never touch the Lua stack or the handle machinery: they + * declare methods and this layer does the rest. The two entry points are: + * + * ALEBind::Method - binds a method on a game object usertype: + * + * player["GetName"] = ALEBind::Method(&Player::GetName); + * player["Emote"] = ALEBind::Method([](Player* self, uint32 emoteId) + * { + * self->HandleEmoteCommand(emoteId); + * }); + * + * ALEBind::Function - same conversions for free functions (no self): + * + * lua["GetPlayerByName"] = ALEBind::Function([](std::string const& name) + * { + * return ObjectAccessor::FindPlayerByName(name); + * }); + * + * What the adapters do for you: + * + * - `self` arrives as a safe handle (see ALEHandles.h) and is resolved before + * your code runs; if the object is gone, the script gets a Lua error + * instead of the server dereferencing freed memory. + * - every parameter typed as a game object pointer (Player*, Unit*, ...) is + * received as a handle from Lua and resolved the same way; + * - every game object pointer you return is wrapped back into a handle, and + * nullptr becomes nil. Pointers to Unit, WorldObject or Object are wrapped + * into the most-derived handle, so Lua always sees the concrete type; + * - all other types (numbers, strings, bools, enums, ...) pass through with + * sol's usual conversions. + * + * Patterns for less common signatures: + * + * - optional parameter: take sol::optional and use value_or: + * [](Player* self, sol::optional locale) { uint8 l = locale.value_or(DEFAULT_LOCALE); ... } + * - nullable object parameter: take sol::optional; + * - multiple return values: return std::tuple<...>; + * - C++ out-parameters (uint32&) have no Lua equivalent: wrap the call in a + * lambda and return the new value instead. + */ +namespace ALEBind +{ + // --------------------------------------------------------------------- + // Native type -> handle type mapping + // --------------------------------------------------------------------- + + template + struct HandleFor + { + }; + + // Object hierarchy: guid-resolved handles + template<> struct HandleFor { using type = ObjectRef; }; + template<> struct HandleFor { using type = WorldObjectRef; }; + template<> struct HandleFor { using type = UnitRef; }; + template<> struct HandleFor { using type = PlayerRef; }; + template<> struct HandleFor { using type = CreatureRef; }; + template<> struct HandleFor { using type = PetRef; }; + template<> struct HandleFor { using type = GameObjectRef; }; + template<> struct HandleFor { using type = TransportRef; }; + template<> struct HandleFor { using type = CorpseRef; }; + template<> struct HandleFor { using type = ItemRef; }; + + // Manager-resolved handles + template<> struct HandleFor { using type = MapRef; }; + template<> struct HandleFor { using type = GroupRef; }; + template<> struct HandleFor { using type = GuildRef; }; + + // Transient objects: only valid during the event that provided them + template<> struct HandleFor { using type = ScopedRef; }; + template<> struct HandleFor { using type = ScopedRef; }; + template<> struct HandleFor { using type = ScopedRef; }; + template<> struct HandleFor { using type = ScopedRef; }; + template<> struct HandleFor { using type = ScopedRef; }; + template<> struct HandleFor { using type = ScopedRef; }; + template<> struct HandleFor { using type = ScopedRef; }; + template<> struct HandleFor { using type = ScopedRef; }; + template<> struct HandleFor { using type = ScopedRef; }; + template<> struct HandleFor { using type = ScopedRef; }; + template<> struct HandleFor { using type = ScopedRef; }; + + template + using HandleForT = typename HandleFor>::type; + + // Whether T is a game class that Lua sees through a handle. + template + concept Handled = requires { typename HandleFor>::type; }; + + // Whether P is a (possibly const) pointer to a handled game class. + template + concept HandledPtr = std::is_pointer_v

&& Handled>; + + // Whether P points to a polymorphic base (Object, WorldObject, Unit): + // those are wrapped into the most-derived handle at runtime. + template + concept PolymorphicBasePtr = std::is_pointer_v

+ && (std::is_same_v>, Object> + || std::is_same_v>, WorldObject> + || std::is_same_v>, Unit>); + + // --------------------------------------------------------------------- + // Parameter and return value conversions + // --------------------------------------------------------------------- + + // Lua-side type of a native parameter: handles for game object pointers, + // the native type unchanged for everything else. + template + struct LuaParam + { + using type = P; + }; + + template + struct LuaParam

+ { + using type = HandleForT>; + }; + + template + using LuaParamT = typename LuaParam

::type; + + // Converts a Lua-side argument to what the native function expects. + // Handles resolve to live pointers or raise a Lua error if stale. + template + decltype(auto) FromLua(LuaParamT

& value) + { + if constexpr (HandledPtr

) + return value.Require(); + else + return static_cast

(value); + } + + // Wraps a pointer to a polymorphic base into the most-derived handle, so + // a Unit that is really a Player arrives in Lua as a Player. + // One exact overload per base class: binding files usually only see + // forward declarations, so no pointer conversion can happen there. + sol::object ToLuaDynamic(sol::state_view lua, Object const* obj); + sol::object ToLuaDynamic(sol::state_view lua, WorldObject const* obj); + sol::object ToLuaDynamic(sol::state_view lua, Unit const* unit); + + // Converts a native return value to what Lua receives. + // Game object pointers become handles, nullptr becomes nil. + // Always returns by value: the native value is a temporary that dies + // before sol converts the result, so a reference here would dangle. + template + auto ToLua(sol::state_view lua, R&& value) + { + using Bare = std::remove_cvref_t; + + if constexpr (PolymorphicBasePtr) + return ToLuaDynamic(lua, value); + else if constexpr (HandledPtr) + { + using Ref = HandleForT>; + return value ? sol::optional(Ref(value)) : sol::optional(sol::nullopt); + } + else + return Bare(std::forward(value)); + } + + // --------------------------------------------------------------------- + // Binding factories + // --------------------------------------------------------------------- + + // Builds the Lua-facing lambda for a callable invocable as R(T*, Args...). + template + auto MakeMethod(F&& fn) + { + return [fn = std::forward(fn)](sol::this_state state, HandleForT const& self, LuaParamT... args) + { + T* obj = self.Require(); + + if constexpr (std::is_void_v) + fn(obj, FromLua(args)...); + else + return ToLua(sol::state_view(state), fn(obj, FromLua(args)...)); + }; + } + + // Builds the Lua-facing lambda for a callable invocable as R(Args...). + template + auto MakeFunction(F&& fn) + { + return [fn = std::forward(fn)](sol::this_state state, LuaParamT... args) + { + if constexpr (std::is_void_v) + fn(FromLua(args)...); + else + return ToLua(sol::state_view(state), fn(FromLua(args)...)); + }; + } + + // Signature extraction for lambdas and other callables, via operator(). + template + struct CallableTraits : CallableTraits + { + }; + + template + struct CallableTraits + { + template + static auto Method(F&& fn) + { + // The first parameter of the callable is `self`. + return MethodImpl(std::forward(fn)); + } + + template + static auto Function(F&& fn) + { + return MakeFunction(std::forward(fn)); + } + + private: + template + static auto MethodImpl(F&& fn) + { + static_assert(std::is_pointer_v && Handled>, + "the first parameter of a method callable must be a pointer to a game class (Player*, Unit*, ...)"); + return MakeMethod>, Rest...>(std::forward(fn)); + } + }; + + // Binds a non-const member function: Method(&Player::HasSpell) + template + auto Method(R (T::*f)(Args...)) + { + return MakeMethod([f](T* self, Args... args) -> R + { + return (self->*f)(std::forward(args)...); + }); + } + + // Binds a const member function: Method(&Player::GetName) + template + auto Method(R (T::*f)(Args...) const) + { + return MakeMethod([f](T* self, Args... args) -> R + { + return (self->*f)(std::forward(args)...); + }); + } + + // Binds a free function whose first parameter is the self pointer: + // Method(&LuaCorpse::GetOwnerGUID) with ObjectGuid GetOwnerGUID(Corpse* corpse) + template + requires Handled> + auto Method(R (*f)(T*, Args...)) + { + return MakeMethod, Args...>([f](std::remove_const_t* self, Args... args) -> R + { + return f(self, std::forward(args)...); + }); + } + + // Binds a lambda whose first parameter is the self pointer: + // Method([](Player* self, uint32 id) { ... }) + template + requires (!std::is_member_function_pointer_v> + && !std::is_pointer_v>) + auto Method(F&& fn) + { + return CallableTraits>::Method(std::forward(fn)); + } + + // Binds a free function or lambda with no self parameter: + // Function([](std::string const& name) { ... }) + template + requires (!std::is_member_function_pointer_v> + && !std::is_pointer_v>) + auto Function(F&& fn) + { + return CallableTraits>::Function(std::forward(fn)); + } + + template + auto Function(R (*f)(Args...)) + { + return MakeFunction([f](Args... args) -> R + { + return f(std::forward(args)...); + }); + } + + // --------------------------------------------------------------------- + // Usertype creation + // --------------------------------------------------------------------- + + /* + * Creates the Lua usertype for a handle class: + * + * sol::usertype type = + * ALEBind::NewHandleType(lua, "Player"); + * + * `Bases` lists the handle's base classes so Lua can call, for example, + * Unit methods on a Player. Every handle type also receives: + * + * - IsValid() - whether the object is currently reachable; + * - GetObjectType() - the type name as a string ("Player", ...); + * - tostring() - "TypeName (guid)" for guid-based handles. + */ + template + sol::usertype NewHandleType(sol::state& lua, char const* name) + { + sol::usertype type = lua.new_usertype(name, + sol::no_constructor, + sol::base_classes, sol::bases()); + + type["IsValid"] = &Ref::IsValid; + type["GetObjectType"] = [name](Ref const&) { return name; }; + type[sol::meta_function::to_string] = [name](Ref const& ref) + { + if constexpr (requires { ref.GetGuid(); }) + return std::string(name) + " (" + ref.GetGuid().ToString() + ")"; + else + return std::string(name); + }; + + return type; + } +} + +// Lua-visible names of transient types, used in stale-handle error messages. +template<> struct ALETypeName { static constexpr char const* value = "Aura"; }; +template<> struct ALETypeName { static constexpr char const* value = "Spell"; }; +template<> struct ALETypeName { static constexpr char const* value = "Vehicle"; }; +template<> struct ALETypeName { static constexpr char const* value = "Ticket"; }; +template<> struct ALETypeName { static constexpr char const* value = "BattleGround"; }; +template<> struct ALETypeName { static constexpr char const* value = "Weather"; }; +template<> struct ALETypeName { static constexpr char const* value = "AuctionHouseObject"; }; +template<> struct ALETypeName { static constexpr char const* value = "AuctionEntry"; }; +template<> struct ALETypeName { static constexpr char const* value = "Roll"; }; +template<> struct ALETypeName { static constexpr char const* value = "Loot"; }; +template<> struct ALETypeName { static constexpr char const* value = "ChatHandler"; }; + +#endif // _ALE_BIND_H 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/ALECreatureAI.h b/src/LuaEngine/ALECreatureAI.h index cb9ccdae7c..1361783b3e 100644 --- a/src/LuaEngine/ALECreatureAI.h +++ b/src/LuaEngine/ALECreatureAI.h @@ -8,8 +8,7 @@ #define _ALE_CREATURE_AI_H #include "LuaEngine.h" - -struct ScriptedAI; +#include "ScriptedCreature.h" struct ALECreatureAI : ScriptedAI { @@ -45,7 +44,7 @@ struct ALECreatureAI : ScriptedAI if (!sALE->UpdateAI(me, diff)) { - if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC)) + if (!me->HasUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC)) ScriptedAI::UpdateAI(diff); } } diff --git a/src/LuaEngine/ALEDBCRegistry.h b/src/LuaEngine/ALEDBCRegistry.h index b525ce8e49..6026279312 100644 --- a/src/LuaEngine/ALEDBCRegistry.h +++ b/src/LuaEngine/ALEDBCRegistry.h @@ -1,38 +1,42 @@ #ifndef ALEDBCREGISTRY_H #define ALEDBCREGISTRY_H +#include "ALEBind.h" +#include "DBCStores.h" + +#include #include #include -#include -#include - -#include "DBCStores.h" -#include "LuaEngine.h" +/* + * Registry of DBC stores exposed to Lua through the global LookupEntry(name, id). + * + * Each entry knows how to look an id up in its store and how to wrap the found + * record into a Lua value of the matching usertype. DBC records live for the + * whole server uptime, so handing their address to Lua is safe. + */ struct DBCDefinition { std::string name; - void* storage; - const std::type_info& type; - std::function lookupFunction; - std::function pushFunction; + std::function lookupFunction; + std::function makeObject; }; 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); \ - } \ +#define REGISTER_DBC(dbcName, entryType, store) \ + { \ + #dbcName, \ + [](uint32 id) -> void const* \ + { \ + return store.LookupEntry(id); \ + }, \ + [](sol::state_view lua, void const* entry) -> sol::object \ + { \ + /* Setters exist on some DBC usertypes, so expose non-const. */ \ + return sol::make_object(lua, \ + const_cast(static_cast(entry))); \ + } \ } #endif // ALEDBCREGISTRY_H - diff --git a/src/LuaEngine/ALEEventMgr.cpp b/src/LuaEngine/ALEEventMgr.cpp index f90cee3167..8f123cd49f 100644 --- a/src/LuaEngine/ALEEventMgr.cpp +++ b/src/LuaEngine/ALEEventMgr.cpp @@ -8,13 +8,7 @@ #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) +ALEEventProcessor::ALEEventProcessor(ALE** _E, WorldObject* _obj) : obj(_obj), E(_E) { // can be called from multiple threads if (obj) @@ -48,7 +42,7 @@ void ALEEventProcessor::Update(uint32 diff) eventList.erase(it); if (luaEvent->state != LUAEVENT_STATE_ERASE) - eventMap.erase(luaEvent->funcRef); + eventMap.erase(luaEvent->id); if (luaEvent->state == LUAEVENT_STATE_RUN) { @@ -58,45 +52,41 @@ void ALEEventProcessor::Update(uint32 diff) AddEvent(luaEvent); // Reschedule before calling incase RemoveEvents used // Call the timed event - (*E)->OnTimedEvent(luaEvent->funcRef, delay, luaEvent->repeats ? luaEvent->repeats-- : luaEvent->repeats, obj); + (*E)->OnTimedEvent(luaEvent->callback, luaEvent->id, 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); + delete luaEvent; } } void ALEEventProcessor::SetStates(LuaEventState state) { - for (EventList::iterator it = eventList.begin(); it != eventList.end(); ++it) - it->second->SetState(state); + for (auto& [time, luaEvent] : eventList) + luaEvent->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); + for (auto& [time, luaEvent] : eventList) + delete luaEvent; eventList.clear(); eventMap.clear(); } -void ALEEventProcessor::SetState(int eventId, LuaEventState state) +void ALEEventProcessor::SetState(uint64 eventId, LuaEventState state) { - if (eventMap.find(eventId) != eventMap.end()) - eventMap[eventId]->SetState(state); + auto iter = eventMap.find(eventId); + if (iter != eventMap.end()) + iter->second->SetState(state); + if (state == LUAEVENT_STATE_ERASE) eventMap.erase(eventId); } @@ -104,27 +94,18 @@ void ALEEventProcessor::SetState(int eventId, LuaEventState state) void ALEEventProcessor::AddEvent(LuaEvent* luaEvent) { luaEvent->GenerateDelay(); - eventList.insert(std::pair(m_time + luaEvent->delay, luaEvent)); - eventMap[luaEvent->funcRef] = luaEvent; + eventList.insert({ m_time + luaEvent->delay, luaEvent }); + eventMap[luaEvent->id] = luaEvent; } -void ALEEventProcessor::AddEvent(int funcRef, uint32 min, uint32 max, uint32 repeats) +uint64 ALEEventProcessor::AddEvent(sol::protected_function callback, 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; + uint64 id = (*E)->eventMgr->NextEventId(); + AddEvent(new LuaEvent(id, std::move(callback), min, max, repeats)); + return id; } -EventMgr::EventMgr(ALE** _E) : globalProcessor(new ALEEventProcessor(_E, NULL)), E(_E) +EventMgr::EventMgr(ALE** _E) : globalProcessor(new ALEEventProcessor(_E, nullptr)), E(_E) { } @@ -132,29 +113,26 @@ EventMgr::~EventMgr() { { Guard guard(GetLock()); - if (!processors.empty()) - for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors - (*it)->RemoveEvents_internal(); + for (ALEEventProcessor* processor : processors) + processor->RemoveEvents_internal(); globalProcessor->RemoveEvents_internal(); } delete globalProcessor; - globalProcessor = NULL; + globalProcessor = nullptr; } 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); + for (ALEEventProcessor* processor : processors) + processor->SetStates(state); globalProcessor->SetStates(state); } -void EventMgr::SetState(int eventId, LuaEventState state) +void EventMgr::SetState(uint64 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); + for (ALEEventProcessor* processor : processors) + processor->SetState(eventId, state); globalProcessor->SetState(eventId, state); } diff --git a/src/LuaEngine/ALEEventMgr.h b/src/LuaEngine/ALEEventMgr.h index 5302ecead2..05a1505f24 100644 --- a/src/LuaEngine/ALEEventMgr.h +++ b/src/LuaEngine/ALEEventMgr.h @@ -10,9 +10,12 @@ #include "ALEUtility.h" #include "Common.h" #include "Util.h" -#include -#include "Define.h" +#include + +#include +#include +#include class ALE; class EventMgr; @@ -22,14 +25,19 @@ 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_ABORT, // On next call unregisters the callback and erases the data LUAEVENT_STATE_ERASE, // On next call just erases the data }; +/* + * A timed Lua callback registered with CreateLuaEvent or object:RegisterEvent. + * The callback keeps itself alive in the Lua registry for as long as the + * event exists. + */ 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) + LuaEvent(uint64 _id, sol::protected_function _callback, uint32 _min, uint32 _max, uint32 _repeats) : + min(_min), max(_max), delay(0), repeats(_repeats), id(_id), callback(std::move(_callback)), state(LUAEVENT_STATE_RUN) { } @@ -48,7 +56,8 @@ struct LuaEvent 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 + uint64 id; // Event ID, used to remove the event from Lua + sol::protected_function callback; LuaEventState state; // State for next call }; @@ -58,7 +67,7 @@ class ALEEventProcessor public: typedef std::multimap EventList; - typedef std::unordered_map EventMap; + typedef std::unordered_map EventMap; ALEEventProcessor(ALE** _E, WorldObject* _obj); ~ALEEventProcessor(); @@ -67,16 +76,16 @@ class ALEEventProcessor // 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); + void SetState(uint64 eventId, LuaEventState state); + // registers the callback and returns its event ID + uint64 AddEvent(sol::protected_function callback, 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; + uint64 m_time = 0; WorldObject* obj; ALE** E; }; @@ -92,13 +101,19 @@ class EventMgr : public ALEUtil::Lockable EventMgr(ALE** _E); ~EventMgr(); + // Returns a new unique id for a timed event. + uint64 NextEventId() { return ++maxEventId; } + // 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); + void SetState(uint64 eventId, LuaEventState state); + +private: + uint64 maxEventId = 0; }; -#endif +#endif // _ALE_EVENT_MGR_H diff --git a/src/LuaEngine/ALEHandles.cpp b/src/LuaEngine/ALEHandles.cpp new file mode 100644 index 0000000000..7c1b1382db --- /dev/null +++ b/src/LuaEngine/ALEHandles.cpp @@ -0,0 +1,357 @@ +/* +* 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 "ALEHandles.h" + +#include "Corpse.h" +#include "GameObject.h" +#include "Group.h" +#include "GroupMgr.h" +#include "Guild.h" +#include "GuildMgr.h" +#include "Item.h" +#include "Map.h" +#include "MapMgr.h" +#include "ObjectAccessor.h" +#include "Pet.h" +#include "Player.h" +#include "Transport.h" + +namespace ALEHandleEpoch +{ + namespace + { + // Starts above the default handle epoch (0) so a fresh handle never + // accidentally matches the current call stack before its first resolve. + uint64 currentEpoch = 1; + } + + uint64 GetEpoch() + { + return currentEpoch; + } + + void Bump() + { + ++currentEpoch; + } +} + +namespace +{ + // Captures where a world object lives so its handle can find the map again. + void CaptureMap(WorldObject const* obj, uint32& mapId, uint32& instanceId) + { + if (Map const* map = obj->FindMap()) + { + mapId = map->GetId(); + instanceId = map->GetInstanceId(); + } + } +} + +Object* ObjectRef::ResolveRaw() const +{ + if (!_guid) + return nullptr; + + // Reuse the pointer resolved earlier in this same Lua call stack. + if (_cached && _epoch == ALEHandleEpoch::GetEpoch()) + return _cached; + + Object* resolved = nullptr; + + // Players are reachable globally; items live in their owner's inventory; + // everything else is looked up on the map it was captured on. + if (_guid.IsPlayer()) + resolved = ObjectAccessor::FindPlayer(_guid); + else if (_guid.IsItem()) + { + if (Player* owner = ObjectAccessor::FindPlayer(_ownerGuid)) + resolved = owner->GetItemByGuid(_guid); + } + else if (Map* map = sMapMgr->FindMap(_mapId, _instanceId)) + { + if (_guid.IsCreatureOrVehicle()) + resolved = map->GetCreature(_guid); + else if (_guid.IsPet()) + resolved = map->GetPet(_guid); + else if (_guid.IsGameObject() || _guid.IsTransport()) + resolved = map->GetGameObject(_guid); + else if (_guid.IsMOTransport()) + resolved = map->GetTransport(_guid); + else if (_guid.IsCorpse()) + resolved = map->GetCorpse(_guid); + } + + if (resolved) + { + _cached = resolved; + _epoch = ALEHandleEpoch::GetEpoch(); + } + + return resolved; +} + +Object* ObjectRef::Resolve() const +{ + return ResolveRaw(); +} + +Object* ObjectRef::Require() const +{ + if (Object* obj = ResolveRaw()) + return obj; + + throw ALEStaleObjectError("Object"); +} + +WorldObjectRef::WorldObjectRef(WorldObject const* obj) : + ObjectRef(obj->GetGUID(), 0, 0) +{ + CaptureMap(obj, _mapId, _instanceId); +} + +WorldObject* WorldObjectRef::Resolve() const +{ + // Every guid type handled by ResolveRaw except items is a WorldObject. + if (_guid.IsItem()) + return nullptr; + + return static_cast(ResolveRaw()); +} + +WorldObject* WorldObjectRef::Require() const +{ + if (WorldObject* obj = Resolve()) + return obj; + + throw ALEStaleObjectError("WorldObject"); +} + +UnitRef::UnitRef(Unit const* unit) : + WorldObjectRef(unit) +{ +} + +Unit* UnitRef::Resolve() const +{ + if (Object* obj = ResolveRaw()) + return obj->ToUnit(); + + return nullptr; +} + +Unit* UnitRef::Require() const +{ + if (Unit* unit = Resolve()) + return unit; + + throw ALEStaleObjectError("Unit"); +} + +PlayerRef::PlayerRef(Player const* player) : + UnitRef(player) +{ +} + +Player* PlayerRef::Resolve() const +{ + if (Object* obj = ResolveRaw()) + return obj->ToPlayer(); + + return nullptr; +} + +Player* PlayerRef::Require() const +{ + if (Player* player = Resolve()) + return player; + + throw ALEStaleObjectError("Player"); +} + +CreatureRef::CreatureRef(Creature const* creature) : + UnitRef(creature) +{ +} + +Creature* CreatureRef::Resolve() const +{ + if (Object* obj = ResolveRaw()) + return obj->ToCreature(); + + return nullptr; +} + +Creature* CreatureRef::Require() const +{ + if (Creature* creature = Resolve()) + return creature; + + throw ALEStaleObjectError("Creature"); +} + +PetRef::PetRef(Pet const* pet) : + CreatureRef(pet) +{ +} + +Pet* PetRef::Resolve() const +{ + if (Object* obj = ResolveRaw()) + if (Unit* unit = obj->ToUnit()) + return unit->ToPet(); + + return nullptr; +} + +Pet* PetRef::Require() const +{ + if (Pet* pet = Resolve()) + return pet; + + throw ALEStaleObjectError("Pet"); +} + +GameObjectRef::GameObjectRef(GameObject const* go) : + WorldObjectRef(go) +{ +} + +GameObject* GameObjectRef::Resolve() const +{ + if (Object* obj = ResolveRaw()) + return obj->ToGameObject(); + + return nullptr; +} + +GameObject* GameObjectRef::Require() const +{ + if (GameObject* go = Resolve()) + return go; + + throw ALEStaleObjectError("GameObject"); +} + +TransportRef::TransportRef(Transport const* transport) : + GameObjectRef(transport) +{ +} + +Transport* TransportRef::Resolve() const +{ + if (GameObject* go = GameObjectRef::Resolve()) + return go->ToTransport(); + + return nullptr; +} + +Transport* TransportRef::Require() const +{ + if (Transport* transport = Resolve()) + return transport; + + throw ALEStaleObjectError("Transport"); +} + +CorpseRef::CorpseRef(Corpse const* corpse) : + WorldObjectRef(corpse) +{ +} + +Corpse* CorpseRef::Resolve() const +{ + if (Object* obj = ResolveRaw()) + return obj->ToCorpse(); + + return nullptr; +} + +Corpse* CorpseRef::Require() const +{ + if (Corpse* corpse = Resolve()) + return corpse; + + throw ALEStaleObjectError("Corpse"); +} + +ItemRef::ItemRef(Item const* item) : + ObjectRef(item->GetGUID(), 0, 0, item->GetOwnerGUID()) +{ +} + +Item* ItemRef::Resolve() const +{ + if (!_guid.IsItem()) + return nullptr; + + // The item resolution path in ResolveRaw only ever returns Item pointers. + return static_cast(ResolveRaw()); +} + +Item* ItemRef::Require() const +{ + if (Item* item = Resolve()) + return item; + + throw ALEStaleObjectError("Item"); +} + +MapRef::MapRef(Map const* map) : + _mapId(map->GetId()), _instanceId(map->GetInstanceId()) +{ +} + +Map* MapRef::Resolve() const +{ + return sMapMgr->FindMap(_mapId, _instanceId); +} + +Map* MapRef::Require() const +{ + if (Map* map = Resolve()) + return map; + + throw ALEStaleObjectError("Map"); +} + +GroupRef::GroupRef(Group const* group) : + _guid(group->GetGUID()) +{ +} + +Group* GroupRef::Resolve() const +{ + return sGroupMgr->GetGroupByGUID(_guid.GetCounter()); +} + +Group* GroupRef::Require() const +{ + if (Group* group = Resolve()) + return group; + + throw ALEStaleObjectError("Group"); +} + +GuildRef::GuildRef(Guild const* guild) : + _guildId(guild->GetId()) +{ +} + +Guild* GuildRef::Resolve() const +{ + return sGuildMgr->GetGuildById(_guildId); +} + +Guild* GuildRef::Require() const +{ + if (Guild* guild = Resolve()) + return guild; + + throw ALEStaleObjectError("Guild"); +} diff --git a/src/LuaEngine/ALEHandles.h b/src/LuaEngine/ALEHandles.h new file mode 100644 index 0000000000..a1133f9975 --- /dev/null +++ b/src/LuaEngine/ALEHandles.h @@ -0,0 +1,319 @@ +/* +* 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_HANDLES_H +#define _ALE_HANDLES_H + +#include "ObjectGuid.h" + +#include +#include + +class Corpse; +class GameObject; +class Group; +class Guild; +class Item; +class Map; +class Object; +class Pet; +class Player; +class Transport; +class Unit; +class WorldObject; +class Creature; + +/* + * Safe references ("handles") to game objects exposed to Lua. + * + * Lua scripts can keep a value alive for as long as they want, but the game + * object behind it can despawn, log out or be unloaded at any moment. Handing + * raw pointers to Lua would therefore be a use-after-free waiting to happen. + * + * Instead, every world object crossing the C++/Lua boundary is wrapped in a + * handle that stores its ObjectGuid (plus enough context to find it again) and + * is re-resolved through the core accessors on every use: + * + * - resolving is cheap: the resolved pointer is cached for the duration of + * the current Lua call stack (see ALEHandleEpoch below), so repeated method + * calls inside one event handler cost a single lookup; + * - a handle kept across calls stays *safe*: if the object is gone, methods + * raise a regular Lua error ("object no longer exists") instead of + * dereferencing freed memory. + * + * The handle classes mirror the game class hierarchy (PlayerRef is a UnitRef + * is a WorldObjectRef is an ObjectRef) so that sol can pass a Player value to + * any function expecting a Unit or WorldObject. + */ + +namespace ALEHandleEpoch +{ + /* + * Identifier of the current Lua call stack. + * + * The engine bumps it whenever the outermost event handler returns to C++. + * Handles use it to know whether their cached pointer belongs to the + * current call stack (safe to reuse) or to a previous one (must re-resolve). + */ + uint64 GetEpoch(); + void Bump(); +} + +/* + * Error thrown by Require() when a handle no longer resolves to a live object. + * sol converts it into a regular Lua error, catchable with pcall. + */ +class ALEStaleObjectError : public std::runtime_error +{ +public: + explicit ALEStaleObjectError(char const* typeName) : + std::runtime_error(std::string(typeName) + " no longer exists (despawned, logged out or unloaded)") + { + } +}; + +/* + * Base handle: identity and resolution logic shared by every handle type. + * + * Resolution dispatches on the guid's HighGuid, so a UnitRef holding a player + * guid correctly resolves through ObjectAccessor while a creature guid goes + * through its owning map. + */ +class ObjectRef +{ +public: + ObjectRef() = default; + + ObjectGuid GetGuid() const { return _guid; } + + // Returns whether the referenced object is currently reachable. + bool IsValid() const { return ResolveRaw() != nullptr; } + + // Handles compare by identity: same guid means same game object. + bool operator==(ObjectRef const& other) const { return _guid == other._guid; } + + Object* Resolve() const; + Object* Require() const; + +protected: + ObjectRef(ObjectGuid guid, uint32 mapId, uint32 instanceId, ObjectGuid ownerGuid = ObjectGuid::Empty) : + _guid(guid), _ownerGuid(ownerGuid), _mapId(mapId), _instanceId(instanceId) + { + } + + // Looks the object up through the appropriate core accessor, + // reusing the pointer cached for the current Lua call stack when possible. + Object* ResolveRaw() const; + + ObjectGuid _guid; + // Owning player's guid, only used to resolve items (an item lives in its owner's inventory). + ObjectGuid _ownerGuid; + uint32 _mapId = 0; + uint32 _instanceId = 0; + +private: + // Pointer cache, only trusted while _epoch matches the current call stack. + mutable Object* _cached = nullptr; + mutable uint64 _epoch = 0; +}; + +class WorldObjectRef : public ObjectRef +{ +public: + WorldObjectRef() = default; + explicit WorldObjectRef(WorldObject const* obj); + + WorldObject* Resolve() const; + WorldObject* Require() const; + +protected: + using ObjectRef::ObjectRef; +}; + +class UnitRef : public WorldObjectRef +{ +public: + UnitRef() = default; + explicit UnitRef(Unit const* unit); + + Unit* Resolve() const; + Unit* Require() const; + +protected: + using WorldObjectRef::WorldObjectRef; +}; + +class PlayerRef : public UnitRef +{ +public: + PlayerRef() = default; + explicit PlayerRef(Player const* player); + + Player* Resolve() const; + Player* Require() const; +}; + +class CreatureRef : public UnitRef +{ +public: + CreatureRef() = default; + explicit CreatureRef(Creature const* creature); + + Creature* Resolve() const; + Creature* Require() const; +}; + +class PetRef : public CreatureRef +{ +public: + PetRef() = default; + explicit PetRef(Pet const* pet); + + Pet* Resolve() const; + Pet* Require() const; +}; + +class GameObjectRef : public WorldObjectRef +{ +public: + GameObjectRef() = default; + explicit GameObjectRef(GameObject const* go); + + GameObject* Resolve() const; + GameObject* Require() const; +}; + +class TransportRef : public GameObjectRef +{ +public: + TransportRef() = default; + explicit TransportRef(Transport const* transport); + + Transport* Resolve() const; + Transport* Require() const; +}; + +class CorpseRef : public WorldObjectRef +{ +public: + CorpseRef() = default; + explicit CorpseRef(Corpse const* corpse); + + Corpse* Resolve() const; + Corpse* Require() const; +}; + +class ItemRef : public ObjectRef +{ +public: + ItemRef() = default; + explicit ItemRef(Item const* item); + + Item* Resolve() const; + Item* Require() const; +}; + +/* + * Handles for game objects outside the Object hierarchy that still have a + * stable identity: they resolve through their manager on every use, with the + * same guarantees as the handles above. + */ + +class MapRef +{ +public: + MapRef() = default; + explicit MapRef(Map const* map); + + bool IsValid() const { return Resolve() != nullptr; } + bool operator==(MapRef const& other) const { return _mapId == other._mapId && _instanceId == other._instanceId; } + + Map* Resolve() const; + Map* Require() const; + +private: + uint32 _mapId = 0; + uint32 _instanceId = 0; +}; + +class GroupRef +{ +public: + GroupRef() = default; + explicit GroupRef(Group const* group); + + bool IsValid() const { return Resolve() != nullptr; } + bool operator==(GroupRef const& other) const { return _guid == other._guid; } + + Group* Resolve() const; + Group* Require() const; + +private: + ObjectGuid _guid; +}; + +class GuildRef +{ +public: + GuildRef() = default; + explicit GuildRef(Guild const* guild); + + bool IsValid() const { return Resolve() != nullptr; } + bool operator==(GuildRef const& other) const { return _guildId == other._guildId; } + + Guild* Resolve() const; + Guild* Require() const; + +private: + uint32 _guildId = 0; +}; + +// Lua-visible type name of a scoped type, used in error messages. +template +struct ALETypeName; + +/* + * Handle for transient game objects with no way to look them up again + * (Aura, Spell, Vehicle, ...). + * + * The wrapped pointer is only trusted during the Lua call stack that created + * it: exactly the window the core guarantees the object stays alive for. + * Using it later raises a Lua error instead of touching freed memory. + */ +template +class ScopedRef +{ +public: + ScopedRef() = default; + + explicit ScopedRef(T const* ptr) : + _ptr(const_cast(ptr)), _epoch(ALEHandleEpoch::GetEpoch()) + { + } + + bool IsValid() const { return Resolve() != nullptr; } + bool operator==(ScopedRef const& other) const { return Resolve() == other.Resolve(); } + + T* Resolve() const + { + return _epoch == ALEHandleEpoch::GetEpoch() ? _ptr : nullptr; + } + + T* Require() const + { + if (T* ptr = Resolve()) + return ptr; + + throw std::runtime_error(std::string(ALETypeName::value) + + " is only valid during the event that provided it; it cannot be stored and used later"); + } + +private: + T* _ptr = nullptr; + uint64 _epoch = 0; +}; + +#endif // _ALE_HANDLES_H diff --git a/src/LuaEngine/ALEIncludes.h b/src/LuaEngine/ALEIncludes.h deleted file mode 100644 index bc38f08200..0000000000 --- a/src/LuaEngine/ALEIncludes.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 _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 "Transport.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 index ea32f2feaa..1c59f0a8c7 100644 --- a/src/LuaEngine/ALEInstanceAI.cpp +++ b/src/LuaEngine/ALEInstanceAI.cpp @@ -6,8 +6,198 @@ #include "ALEInstanceAI.h" #include "ALEUtility.h" -#include "lmarshal.h" +#include +#include +#include + +namespace +{ + /* + * Minimal binary serializer for the instance data table. + * + * Instance data only ever holds plain data (booleans, numbers, strings and + * nested tables), so a small tagged format is enough: one tag byte per + * value, numbers as doubles, strings length-prefixed, tables as a pair + * count followed by the key/value pairs. Entries of any other type + * (function, userdata, ...) cannot survive a server restart anyway and are + * skipped with a warning instead of failing the whole save. + */ + enum class DataTag : uint8 + { + False = 0, + True = 1, + Number = 2, + String = 3, + Table = 4 + }; + + bool IsSerializable(sol::object const& value) + { + switch (value.get_type()) + { + case sol::type::boolean: + case sol::type::number: + case sol::type::string: + case sol::type::table: + return true; + default: + return false; + } + } + + void EncodeValue(sol::object const& value, std::string& out, std::unordered_set& openTables); + + void EncodeTable(sol::table const& table, std::string& out, std::unordered_set& openTables) + { + // A table reachable from itself would recurse forever; fail the save + // cleanly instead. + if (!openTables.insert(table.pointer()).second) + throw std::runtime_error("instance data contains a table that references itself (cycle)"); + + uint32 count = 0; + for (auto const& [key, value] : table.pairs()) + if (IsSerializable(key) && IsSerializable(value)) + ++count; + + out.push_back(static_cast(DataTag::Table)); + out.append(reinterpret_cast(&count), sizeof(count)); + + for (auto const& [key, value] : table.pairs()) + { + if (!IsSerializable(key) || !IsSerializable(value)) + { + ALE_LOG_ERROR("Instance data entry skipped while saving: keys and values must be booleans, numbers, strings or tables"); + continue; + } + + EncodeValue(key, out, openTables); + EncodeValue(value, out, openTables); + } + + openTables.erase(table.pointer()); + } + + void EncodeValue(sol::object const& value, std::string& out, std::unordered_set& openTables) + { + switch (value.get_type()) + { + case sol::type::boolean: + out.push_back(static_cast(value.as() ? DataTag::True : DataTag::False)); + break; + case sol::type::number: + { + double number = value.as(); + out.push_back(static_cast(DataTag::Number)); + out.append(reinterpret_cast(&number), sizeof(number)); + break; + } + case sol::type::string: + { + std::string str = value.as(); + uint32 length = static_cast(str.size()); + out.push_back(static_cast(DataTag::String)); + out.append(reinterpret_cast(&length), sizeof(length)); + out.append(str); + break; + } + case sol::type::table: + EncodeTable(value.as(), out, openTables); + break; + default: + // Filtered out by IsSerializable before we get here. + break; + } + } + + // Cursor over the decoded save data; every read is bounds-checked so a + // truncated or corrupted blob fails cleanly instead of reading past the end. + struct DataReader + { + unsigned char const* pos; + unsigned char const* end; + + size_t Remaining() const { return static_cast(end - pos); } + + bool Read(void* dest, size_t size) + { + if (Remaining() < size) + return false; + + std::memcpy(dest, pos, size); + pos += size; + return true; + } + }; + + // Reads one value; returns sol::lua_nil and clears `ok` on malformed data. + sol::object DecodeValue(sol::state& lua, DataReader& reader, bool& ok) + { + uint8 tag; + if (!reader.Read(&tag, sizeof(tag))) + { + ok = false; + return sol::make_object(lua, sol::lua_nil); + } + + switch (static_cast(tag)) + { + case DataTag::False: + return sol::make_object(lua, false); + case DataTag::True: + return sol::make_object(lua, true); + case DataTag::Number: + { + double number; + if (!reader.Read(&number, sizeof(number))) + break; + + return sol::make_object(lua, number); + } + case DataTag::String: + { + uint32 length; + if (!reader.Read(&length, sizeof(length))) + break; + + // The length comes from persisted data: validate it against the + // remaining bytes before allocating anything. + if (length > reader.Remaining()) + break; + + std::string str(length, '\0'); + if (!reader.Read(str.data(), length)) + break; + + return sol::make_object(lua, str); + } + case DataTag::Table: + { + uint32 count; + if (!reader.Read(&count, sizeof(count))) + break; + + sol::table table = lua.create_table(); + for (uint32 i = 0; i < count; ++i) + { + sol::object key = DecodeValue(lua, reader, ok); + sol::object value = DecodeValue(lua, reader, ok); + if (!ok) + return sol::make_object(lua, sol::lua_nil); + + table[key] = value; + } + + return table; + } + default: + break; + } + + ok = false; + return sol::make_object(lua, sol::lua_nil); + } +} void ALEInstanceAI::Initialize() { @@ -16,9 +206,7 @@ void ALEInstanceAI::Initialize() ASSERT(!sALE->HasInstanceData(instance)); // Create a new table for instance data. - lua_State* L = sALE->L; - lua_newtable(L); - sALE->CreateInstanceData(instance); + sALE->CreateInstanceData(instance, sALE->lua.create_table()); sALE->OnInitialize(this); } @@ -30,115 +218,72 @@ void ALEInstanceAI::Load(const char* data) // 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->CreateInstanceData(instance, sALE->lua.create_table()); sALE->OnLoad(this); - // Stack: (empty) return; } size_t decodedLength; - const unsigned char* decodedData = ALEUtil::DecodeData(data, &decodedLength); - lua_State* L = sALE->L; + std::unique_ptr decodedData(ALEUtil::DecodeData(data, &decodedLength)); - if (decodedData) + 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) + ALE_LOG_ERROR("Error while decoding instance data: Data is not valid base-64"); + Initialize(); + return; + } - Initialize(); - } + DataReader reader{ decodedData.get(), decodedData.get() + decodedLength }; + bool ok = true; + sol::object decoded = DecodeValue(sALE->lua, reader, ok); - delete[] decodedData; - } - else + if (!ok || !decoded.is()) { - ALE_LOG_ERROR("Error while decoding instance data: Data is not valid base-64"); - + ALE_LOG_ERROR("Error while loading instance data: save data is malformed"); Initialize(); + return; } + + sALE->CreateInstanceData(instance, decoded.as()); + // WARNING! lastSaveData might be different after `OnLoad` if the Lua code saved data. + sALE->OnLoad(this); } 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 + std::string encoded; + std::unordered_set openTables; - if (lua_pcall(L, 1, 1, 0) != 0) + try { - // Stack: error_message - ALE_LOG_ERROR("Error while saving: {}", lua_tostring(L, -1)); - lua_pop(L, 1); - return NULL; + EncodeTable(sALE->GetInstanceData(self), encoded, openTables); + } + catch (std::exception const& error) + { + ALE_LOG_ERROR("Error while saving instance data: {}", error.what()); + return nullptr; } - // 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) + // The serialized table is binary; store it base-64 encoded. + ALEUtil::EncodeData(reinterpret_cast(encoded.data()), encoded.size(), self->lastSaveData); return lastSaveData.c_str(); } @@ -146,83 +291,31 @@ const char* ALEInstanceAI::Save() const 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; + sol::table data = sALE->GetInstanceData(const_cast(this)); + return data.get_or(key, 0u); } 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) + sol::table data = sALE->GetInstanceData(this); + data[key] = value; } 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; + sol::table data = sALE->GetInstanceData(const_cast(this)); + return data.get_or(key, uint64(0)); } 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) + sol::table data = sALE->GetInstanceData(this); + data[key] = value; } diff --git a/src/LuaEngine/ALEInstanceAI.h b/src/LuaEngine/ALEInstanceAI.h index ebc5037db0..900f0f1192 100644 --- a/src/LuaEngine/ALEInstanceAI.h +++ b/src/LuaEngine/ALEInstanceAI.h @@ -70,7 +70,8 @@ class ALEInstanceAI : public InstanceData // Simply calls Save, since the functions are a bit different in name and data types on different cores std::string GetSaveData() override { - return Save(); + char const* data = Save(); + return data ? data : ""; } const char* Save() const; diff --git a/src/LuaEngine/ALEScriptCache.cpp b/src/LuaEngine/ALEScriptCache.cpp new file mode 100644 index 0000000000..238395272a --- /dev/null +++ b/src/LuaEngine/ALEScriptCache.cpp @@ -0,0 +1,209 @@ +/* +* 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 "ALEScriptCache.h" +#include "ALEConfig.h" +#include "ALEUtility.h" + +#include +#include +#include +#include +#include + +namespace +{ + /* + * Identity of a script file's content: sub-second modification time plus + * size. Second-level mtime alone would let a script edited twice within + * the same second serve stale bytecode. + */ + struct FileStamp + { + std::filesystem::file_time_type mtime{}; + uintmax_t size = 0; + + bool operator==(FileStamp const&) const = default; + bool IsValid() const { return *this != FileStamp{}; } + }; + + struct CacheEntry + { + std::vector bytecode; + FileStamp stamp; + }; + + std::unordered_map bytecodeCache; + std::unordered_map stampCache; + std::mutex cacheMutex; + + FileStamp GetFileStamp(std::string const& filepath) + { + std::error_code ec; + FileStamp stamp; + + stamp.mtime = std::filesystem::last_write_time(filepath, ec); + if (ec) + return {}; + + stamp.size = std::filesystem::file_size(filepath, ec); + if (ec) + return {}; + + return stamp; + } + + // Same, but remembers the answer until the next reload so a directory of + // scripts doesn't stat the same files twice. + FileStamp GetFileStampCached(std::string const& filepath) + { + auto iter = stampCache.find(filepath); + if (iter != stampCache.end()) + return iter->second; + + FileStamp stamp = GetFileStamp(filepath); + stampCache[filepath] = stamp; + return stamp; + } + + // Loads `filepath` as a chunk in `lua` without caching: + // plain compilation for Lua, the `moonscript` module for MoonScript. + sol::protected_function LoadUncached(sol::state& lua, std::string const& filepath, bool isMoonScript) + { + if (isMoonScript) + { + std::string loader = "return require('moonscript').loadfile([[" + filepath + "]])"; + sol::protected_function_result result = lua.safe_script(loader, sol::script_pass_on_error); + if (!result.valid()) + { + sol::error error = result; + ALE_LOG_ERROR("[ALE]: Error compiling MoonScript `{}`: {}", filepath, error.what()); + return sol::protected_function(); + } + + return result.get(); + } + + sol::load_result loaded = lua.load_file(filepath); + if (!loaded.valid()) + { + sol::error error = loaded; + ALE_LOG_ERROR("[ALE]: Error loading `{}`: {}", filepath, error.what()); + return sol::protected_function(); + } + + return loaded.get(); + } + + // Compiles `filepath` in a throwaway state and stores its bytecode. + // Returns false (leaving no cache entry) if compilation fails. + bool CompileToCache(std::string const& filepath, bool isMoonScript) + { + sol::state compiler; + compiler.open_libraries(); + + sol::protected_function chunk = LoadUncached(compiler, filepath, isMoonScript); + if (!chunk.valid()) + return false; + + sol::bytecode dumped = chunk.dump(); + if (dumped.as_string_view().empty()) + return false; + + std::lock_guard guard(cacheMutex); + CacheEntry& entry = bytecodeCache[filepath]; + entry.stamp = GetFileStamp(filepath); + entry.bytecode.assign(dumped.as_string_view().begin(), dumped.as_string_view().end()); + return true; + } + + // Loads the cached bytecode of `filepath` if it is still up to date. + sol::protected_function LoadFromCache(sol::state& lua, std::string const& filepath) + { + std::lock_guard guard(cacheMutex); + + auto iter = bytecodeCache.find(filepath); + if (iter == bytecodeCache.end() || iter->second.bytecode.empty()) + return sol::protected_function(); + + FileStamp stamp = GetFileStampCached(filepath); + if (!stamp.IsValid() || iter->second.stamp != stamp) + return sol::protected_function(); + + sol::load_result loaded = lua.load( + std::string_view(iter->second.bytecode.data(), iter->second.bytecode.size()), + filepath, sol::load_mode::binary); + if (!loaded.valid()) + return sol::protected_function(); + + return loaded.get(); + } +} + +namespace ALEScriptCache +{ + sol::protected_function Load(sol::state& lua, std::string const& filepath, bool isMoonScript, + uint32& compiledCount, uint32& cachedCount) + { + if (!ALEConfig::GetInstance().IsByteCodeCacheEnabled()) + return LoadUncached(lua, filepath, isMoonScript); + + if (sol::protected_function cached = LoadFromCache(lua, filepath); cached.valid()) + { + ++cachedCount; + return cached; + } + + if (CompileToCache(filepath, isMoonScript)) + { + if (sol::protected_function compiled = LoadFromCache(lua, filepath); compiled.valid()) + { + ++compiledCount; + return compiled; + } + } + + // The cache could not serve this file; fall back to a direct load. + return LoadUncached(lua, filepath, isMoonScript); + } + + sol::protected_function LoadCompiled(sol::state& lua, std::string const& filepath) + { + std::ifstream file(filepath, std::ios::binary); + if (!file.is_open()) + { + ALE_LOG_ERROR("[ALE]: Could not open compiled script `{}`", filepath); + return sol::protected_function(); + } + + std::vector buffer(std::istreambuf_iterator(file), {}); + + sol::load_result loaded = lua.load( + std::string_view(buffer.data(), buffer.size()), filepath, sol::load_mode::binary); + if (!loaded.valid()) + { + sol::error error = loaded; + ALE_LOG_ERROR("[ALE]: Error loading compiled script `{}`: {}", filepath, error.what()); + return sol::protected_function(); + } + + return loaded.get(); + } + + void ClearCache() + { + std::lock_guard guard(cacheMutex); + bytecodeCache.clear(); + stampCache.clear(); + ALE_LOG_INFO("[ALE]: Global bytecode cache cleared"); + } + + void ClearTimestamps() + { + std::lock_guard guard(cacheMutex); + stampCache.clear(); + } +} diff --git a/src/LuaEngine/ALEScriptCache.h b/src/LuaEngine/ALEScriptCache.h new file mode 100644 index 0000000000..c29df0057b --- /dev/null +++ b/src/LuaEngine/ALEScriptCache.h @@ -0,0 +1,52 @@ +/* +* 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_SCRIPT_CACHE_H +#define _ALE_SCRIPT_CACHE_H + +#include "Common.h" + +#include + +#include +#include + +/* + * Script loading with an optional global bytecode cache. + * + * Compiling a large script collection on every reload is slow, so when + * `ALE.BytecodeCache` is enabled, compiled bytecode is kept in a cache that + * survives Lua state reloads and is only invalidated when the file on disk + * changes. MoonScript sources are compiled through the `moonscript` Lua module + * and cached the same way. + */ +namespace ALEScriptCache +{ + /* + * Loads a Lua or MoonScript file as a callable chunk, going through the + * bytecode cache when it is enabled. + * + * Increments `compiledCount` / `cachedCount` for the reload statistics. + * Returns an invalid function on failure (the error is logged). + */ + sol::protected_function Load(sol::state& lua, std::string const& filepath, bool isMoonScript, + uint32& compiledCount, uint32& cachedCount); + + /* + * Loads a precompiled (.out, luac output) script file as a callable chunk. + * Returns an invalid function on failure (the error is logged). + */ + sol::protected_function LoadCompiled(sol::state& lua, std::string const& filepath); + + // Drops all cached bytecode (called on shutdown). + void ClearCache(); + + // Drops the cached file timestamps so the next load re-checks the disk + // (called at the start of every reload). + void ClearTimestamps(); +} + +#endif // _ALE_SCRIPT_CACHE_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 index 9817465efa..d1d8bb92d0 100644 --- a/src/LuaEngine/ALEUtility.cpp +++ b/src/LuaEngine/ALEUtility.cpp @@ -27,7 +27,7 @@ ALEUtil::ObjectGUIDCheck::ObjectGUIDCheck(ObjectGuid guid) : _guid(guid) bool ALEUtil::ObjectGUIDCheck::operator()(WorldObject* object) { - return object->GET_GUID() == _guid; + return object->GetGUID() == _guid; } ALEUtil::ObjectDistanceOrderPred::ObjectDistanceOrderPred(WorldObject const* pRefObj, bool ascending) : m_refObj(pRefObj), m_ascending(ascending) @@ -59,7 +59,7 @@ bool ALEUtil::WorldObjectInRangeCheck::operator()(WorldObject* u) return false; if (i_entry && u->GetEntry() != i_entry) return false; - if (i_obj->GET_GUID() == u->GET_GUID()) + if (i_obj->GetGUID() == u->GetGUID()) return false; if (!i_obj->IsWithinDistInMap(u, i_range)) return false; diff --git a/src/LuaEngine/ALEUtility.h b/src/LuaEngine/ALEUtility.h index 5af4ad8519..07d65c3573 100644 --- a/src/LuaEngine/ALEUtility.h +++ b/src/LuaEngine/ALEUtility.h @@ -18,38 +18,11 @@ #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; diff --git a/src/LuaEngine/BindingMap.h b/src/LuaEngine/BindingMap.h index 786de550fc..6bf19d1ce0 100644 --- a/src/LuaEngine/BindingMap.h +++ b/src/LuaEngine/BindingMap.h @@ -7,232 +7,179 @@ #ifndef _BINDING_MAP_H #define _BINDING_MAP_H -#include #include "Common.h" -#include "ALEUtility.h" -#include +#include "ObjectGuid.h" -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -}; +#include +#include +#include +#include /* - * A set of bindings from keys of type `K` to Lua references. + * A set of Lua event handlers registered against keys of type `K`. + * + * Scripts register handlers with RegisterPlayerEvent & co; hooks fetch them + * back by key when the matching game event fires. Handlers are stored as + * sol::protected_function, so their lifetime in the Lua registry is managed + * automatically. */ template -class BindingMap : public ALEUtil::Lockable +class BindingMap { private: - lua_State* L; - uint64 maxBindingID; - struct Binding { uint64 id; - lua_State* L; + // Number of times the handler still fires before expiring; 0 means never expires. 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); - } + sol::protected_function callback; }; - 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; + std::unordered_map> bindings; + // Maps a binding id back to its key, so Remove doesn't have to scan every list. + std::unordered_map keysById; + uint64 maxBindingID = 0; + std::mutex mutex; public: - BindingMap(lua_State* L) : - L(L), - maxBindingID(0) - { } - /* - * Insert a new binding from `key` to `ref`, which lasts for `shots`-many pushes. + * Inserts a new handler for `key` that fires `shots` times. * - * If `shots` is 0, it will never automatically expire, but can still be - * removed with `Clear` or `Remove`. + * If `shots` is 0 the handler never expires on its own, but can still be + * removed with `Clear` or `Remove`. Returns an id usable with `Remove`. */ - uint64 Insert(const K& key, int ref, uint32 shots) + uint64 Insert(K const& key, sol::protected_function callback, uint32 shots) { - Guard guard(GetLock()); + std::lock_guard guard(mutex); - uint64 id = (++maxBindingID); - BindingList& list = bindings[key]; - list.push_back(std::unique_ptr(new Binding(L, id, ref, shots))); - id_lookup_table[id] = &list; + uint64 id = ++maxBindingID; + bindings[key].push_back({ id, shots, std::move(callback) }); + keysById.emplace(id, key); return id; } - /* - * Clear all bindings for `key`. - */ - void Clear(const K& key) + // Removes all handlers for `key`. + void Clear(K const& key) { - Guard guard(GetLock()); - - if (bindings.empty()) - return; + std::lock_guard guard(mutex); auto iter = bindings.find(key); if (iter == bindings.end()) return; - BindingList& list = iter->second; + for (Binding const& binding : iter->second) + keysById.erase(binding.id); - // 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); + bindings.erase(iter); } - /* - * Clear all bindings for all keys. - */ + // Removes all handlers for all keys. void Clear() { - Guard guard(GetLock()); + std::lock_guard guard(mutex); - if (bindings.empty()) - return; - - id_lookup_table.clear(); + keysById.clear(); bindings.clear(); } - /* - * Remove a specific binding identified by `id`. - * - * If `id` in invalid, nothing is removed. - */ + // Removes the single handler identified by `id`, if it still exists. void Remove(uint64 id) { - Guard guard(GetLock()); + std::lock_guard guard(mutex); - auto iter = id_lookup_table.find(id); - if (iter == id_lookup_table.end()) + auto keyIter = keysById.find(id); + if (keyIter == keysById.end()) return; - BindingList* list = iter->second; - auto i = list->begin(); - - for (; i != list->end(); ++i) + auto listIter = bindings.find(keyIter->second); + if (listIter != bindings.end()) { - std::unique_ptr& binding = *i; - if (binding->id == id) - break; + std::vector& list = listIter->second; + std::erase_if(list, [id](Binding const& binding) { return binding.id == id; }); + if (list.empty()) + bindings.erase(listIter); } - 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); + keysById.erase(keyIter); } - /* - * Check whether `key` has any bindings. - */ - bool HasBindingsFor(const K& key) + // Returns whether `key` has any handlers. + bool HasBindingsFor(K const& key) { - Guard guard(GetLock()); - - if (bindings.empty()) - return false; - - auto result = bindings.find(key); - if (result == bindings.end()) - return false; + std::lock_guard guard(mutex); - BindingList& list = result->second; - return !list.empty(); + auto iter = bindings.find(key); + return iter != bindings.end() && !iter->second.empty(); } /* - * Push all Lua references for `key` onto the stack. + * Returns a snapshot of the handlers registered for `key`, consuming one + * shot from each. + * + * Dispatch iterates the snapshot, so a handler that registers or removes + * handlers while running cannot corrupt the iteration. */ - void PushRefsFor(const K& key) + std::vector GetCallbacksFor(K const& key) { - Guard guard(GetLock()); + std::lock_guard guard(mutex); - if (bindings.empty()) - return; + std::vector callbacks; - auto result = bindings.find(key); - if (result == bindings.end()) - return; + auto iter = bindings.find(key); + if (iter == bindings.end()) + return callbacks; - BindingList& list = result->second; - luaL_checkstack(L, static_cast(list.size()), "not enough stack space to push function bindings"); - for (auto i = list.begin(); i != list.end();) + std::vector& list = iter->second; + callbacks.reserve(list.size()); + + for (Binding& binding : list) + callbacks.push_back(binding.callback); + + // Expire handlers that just used up their last shot. + std::erase_if(list, [this](Binding& binding) { - std::unique_ptr& binding = (*i); - auto i_prev = (i++); + if (binding.remainingShots == 0) + return false; - lua_rawgeti(L, LUA_REGISTRYINDEX, binding->functionReference); + --binding.remainingShots; + if (binding.remainingShots > 0) + return false; - if (binding->remainingShots > 0) - { - binding->remainingShots -= 1; + keysById.erase(binding.id); + return true; + }); - if (binding->remainingShots == 0) - { - id_lookup_table.erase(binding->id); - list.erase(i_prev); - } - } - } + if (list.empty()) + bindings.erase(iter); + + return callbacks; } }; - /* - * A `BindingMap` key type for simple event ID bindings - * (ServerEvents, GuildEvents, etc.). + * A `BindingMap` key for global event bindings (ServerEvents, GuildEvents, ...). */ -template +template struct EventKey { T event_id; EventKey(T event_id) : event_id(event_id) - { } + { + } + + bool operator==(EventKey const& other) const + { + return event_id == other.event_id; + } }; /* - * A `BindingMap` key type for event ID/Object entry ID bindings - * (CreatureEvents, GameObjectEvents, etc.). + * A `BindingMap` key for event ID + entry bindings (CreatureEvents, GameObjectEvents, ...). */ -template +template struct EntryKey { T event_id; @@ -241,14 +188,20 @@ struct EntryKey EntryKey(T event_id, uint32 entry) : event_id(event_id), entry(entry) - { } + { + } + + bool operator==(EntryKey const& other) const + { + return event_id == other.event_id && entry == other.entry; + } }; /* - * A `BindingMap` key type for event ID/unique Object bindings - * (currently just CreatureEvents). + * A `BindingMap` key for event ID + specific object bindings + * (currently just CreatureEvents on one spawned creature). */ -template +template struct UniqueObjectKey { T event_id; @@ -259,116 +212,64 @@ struct UniqueObjectKey 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) + bool operator==(UniqueObjectKey const& other) const { - return std::hash()(t); + return event_id == other.event_id && guid == other.guid && instance_id == other.instance_id; } +}; -private: - template - static inline void _hash_combine(result_type& seed, T const & v) +namespace ALEKeyHash +{ + inline void Combine(std::size_t& seed, std::size_t value) { - // from http://www.boost.org/doc/libs/1_40_0/boost/functional/hash/hash.hpp - seed ^= hash(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + // from boost::hash_combine + seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2); } - template - static inline void _hash_combine(result_type& seed, H const & h, T1 const & t1, T const &... t) + template + std::size_t HashEnum(T value) { - _hash_combine(seed, h); - _hash_combine(seed, t1, t...); + return std::hash>()(static_cast>(value)); } -}; +} /* - * Implementations of various std functions on the above key types, - * so that they can be used within an unordered_map. + * std::hash implementations so the key types can be used in 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 > + struct hash> { - bool operator()(UniqueObjectKey const& lhs, UniqueObjectKey const& rhs) const + std::size_t operator()(EventKey const& key) const { - return lhs.event_id == rhs.event_id - && lhs.guid == rhs.guid - && lhs.instance_id == rhs.instance_id; + return ALEKeyHash::HashEnum(key.event_id); } }; template - struct hash < EventKey > + struct hash> { - typedef EventKey argument_type; - - hash_helper::result_type operator()(argument_type const& k) const + std::size_t operator()(EntryKey const& key) const { - return hash_helper::hash(k.event_id); + std::size_t seed = ALEKeyHash::HashEnum(key.event_id); + ALEKeyHash::Combine(seed, std::hash()(key.entry)); + return seed; } }; template - struct hash < EntryKey > + struct hash> { - 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 + std::size_t operator()(UniqueObjectKey const& key) const { - return hash_helper::hash(k.event_id, k.instance_id, k.guid.GetRawValue()); + std::size_t seed = ALEKeyHash::HashEnum(key.event_id); + ALEKeyHash::Combine(seed, std::hash()(key.instance_id)); + ALEKeyHash::Combine(seed, std::hash()(key.guid.GetRawValue())); + return seed; } }; } 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/HttpManager.cpp b/src/LuaEngine/HttpManager.cpp index f7079cf3c9..0955ce2439 100644 --- a/src/LuaEngine/HttpManager.cpp +++ b/src/LuaEngine/HttpManager.cpp @@ -1,9 +1,10 @@ +/* +* 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 -extern "C" -{ -#include "lua.h" -#include "lauxlib.h" -}; #define CPPHTTPLIB_OPENSSL_SUPPORT @@ -11,8 +12,9 @@ extern "C" #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), +HttpWorkItem::HttpWorkItem(sol::protected_function callback, const std::string& httpVerb, const std::string& url, + const std::string& body, const std::string& contentType, const httplib::Headers& headers) + : callback(std::move(callback)), httpVerb(httpVerb), url(url), body(body), @@ -20,8 +22,8 @@ HttpWorkItem::HttpWorkItem(int funcRef, const std::string& httpVerb, const std:: headers(headers) { } -HttpResponse::HttpResponse(int funcRef, int statusCode, const std::string& body, const httplib::Headers& headers) - : funcRef(funcRef), +HttpResponse::HttpResponse(sol::protected_function callback, int statusCode, const std::string& body, const httplib::Headers& headers) + : callback(std::move(callback)), statusCode(statusCode), body(body), headers(headers) @@ -68,20 +70,14 @@ void HttpManager::ClearQueues() while (workQueue.front()) { HttpWorkItem* item = *workQueue.front(); - if (item != nullptr) - { - delete item; - } + delete item; workQueue.pop(); } while (responseQueue.front()) { HttpResponse* item = *responseQueue.front(); - if (item != nullptr) - { - delete item; - } + delete item; responseQueue.pop(); } } @@ -89,9 +85,7 @@ void HttpManager::ClearQueues() void HttpManager::StopHttpWorker() { if (!startedWorkerThread) - { return; - } cancelationToken.store(true); condVar.notify_one(); @@ -100,6 +94,13 @@ void HttpManager::StopHttpWorker() startedWorkerThread = false; } +void HttpManager::FinishRequest(HttpWorkItem* req, int statusCode, std::string body, httplib::Headers headers) +{ + // The callback must always come back to the world thread, even on + // failure, so its Lua reference is released there and never here. + responseQueue.push(new HttpResponse(std::move(req->callback), statusCode, std::move(body), std::move(headers))); +} + void HttpManager::HttpWorkerThread() { while (true) @@ -110,28 +111,26 @@ void HttpManager::HttpWorkerThread() } 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)) { + if (!ParseUrl(req->url, host, path)) + { ALE_LOG_ERROR("[ALE]: Could not parse URL {}", req->url); + FinishRequest(req, -1, "", {}); + delete req; continue; } @@ -145,32 +144,45 @@ void HttpManager::HttpWorkerThread() if (err != httplib::Error::Success) { ALE_LOG_ERROR("[ALE]: HTTP request error: {}", httplib::to_string(err)); + FinishRequest(req, -1, "", {}); + delete req; continue; } if (res->status == 301) { std::string location = res->get_header_value("Location"); - std::string host; - std::string path; + std::string redirectHost; + std::string redirectPath; - if (!ParseUrl(location, host, path)) + if (!ParseUrl(location, redirectHost, redirectPath)) { ALE_LOG_ERROR("[ALE]: Could not parse URL after redirect: {}", location); + FinishRequest(req, -1, "", {}); + delete req; continue; } - httplib::Client cli2(host); + httplib::Client cli2(redirectHost); 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); + res = DoRequest(cli2, req, redirectPath); + + if (res.error() != httplib::Error::Success) + { + ALE_LOG_ERROR("[ALE]: HTTP request error after redirect: {}", httplib::to_string(res.error())); + FinishRequest(req, -1, "", {}); + delete req; + continue; + } } - responseQueue.push(new HttpResponse(req->funcRef, res->status, res->body, res->headers)); + FinishRequest(req, res->status, res->body, res->headers); } catch (const std::exception& ex) { ALE_LOG_ERROR("[ALE]: HTTP request error: {}", ex.what()); + FinishRequest(req, -1, "", {}); } delete req; @@ -181,33 +193,19 @@ httplib::Result HttpManager::DoRequest(httplib::Client& client, HttpWorkItem* re { 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); @@ -218,9 +216,7 @@ bool HttpManager::ParseUrl(const std::string& url, std::string& host, std::strin std::smatch matches; if (!std::regex_search(url, matches, parseUrlRegex)) - { return false; - } std::string scheme = matches[2]; std::string authority = matches[4]; @@ -228,9 +224,8 @@ bool HttpManager::ParseUrl(const std::string& url, std::string& host, std::strin host = scheme + "://" + authority; path = matches[5]; if (path.empty()) - { path = "/"; - } + path += (query.empty() ? "" : "?") + query; return true; @@ -243,33 +238,23 @@ void HttpManager::HandleHttpResponses() HttpResponse* res = *responseQueue.front(); responseQueue.pop(); - if (res == nullptr) - { + if (!res) continue; - } LOCK_ALE; - lua_State* L = ALE::GALE->L; - - // Get function - lua_rawgeti(L, LUA_REGISTRYINDEX, res->funcRef); + // Failures are delivered too (statusCode -1, empty body), so Lua + // callers can tell their request never completed. + if (sALE->HasLuaState()) + { + // The handler receives the headers as a table. + sol::table headerTable = sALE->lua.create_table(); + for (auto const& [name, value] : res->headers) + headerTable[name] = value; - // 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); + sALE->CallFunction(res->callback, res->statusCode, res->body, headerTable); } - // 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 index cab17a4466..d089b4c8de 100644 --- a/src/LuaEngine/HttpManager.h +++ b/src/LuaEngine/HttpManager.h @@ -1,17 +1,31 @@ +/* +* 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_HTTP_MANAGER_H #define ALE_HTTP_MANAGER_H +#include + #include #include "libs/httplib.h" #include "libs/rigtorp/SPSCQueue.h" +/* + * Threading note: the Lua callback travels through the worker thread as a + * moved sol reference. Moving never touches the Lua state, so the worker + * stays Lua-free; the callback is only invoked - and released - from the + * world thread in HandleHttpResponses(). + */ 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); + HttpWorkItem(sol::protected_function callback, const std::string& httpVerb, const std::string& url, + const std::string& body, const std::string& contentType, const httplib::Headers& headers); - int funcRef; + sol::protected_function callback; std::string httpVerb; std::string url; std::string body; @@ -21,16 +35,15 @@ struct HttpWorkItem struct HttpResponse { -public: - HttpResponse(int funcRef, int statusCode, const std::string& body, const httplib::Headers& headers); + HttpResponse(sol::protected_function callback, int statusCode, const std::string& body, const httplib::Headers& headers); - int funcRef; + sol::protected_function callback; + // -1 when the request failed: the callback is not invoked, only released. int statusCode; std::string body; httplib::Headers headers; }; - class HttpManager { public: @@ -45,6 +58,8 @@ class HttpManager private: void ClearQueues(); void HttpWorkerThread(); + // Hands the callback back to the world thread, with the request's result. + void FinishRequest(HttpWorkItem* req, int statusCode, std::string body, httplib::Headers headers); bool ParseUrl(const std::string& url, std::string& host, std::string& path); httplib::Result DoRequest(httplib::Client& client, HttpWorkItem* req, const std::string& path); @@ -58,4 +73,4 @@ class HttpManager std::regex parseUrlRegex; }; -#endif // #ifndef ALE_HTTP_MANAGER_H +#endif // ALE_HTTP_MANAGER_H diff --git a/src/LuaEngine/LuaEngine.cpp b/src/LuaEngine/LuaEngine.cpp index c647d689a5..eeec89fff9 100644 --- a/src/LuaEngine/LuaEngine.cpp +++ b/src/LuaEngine/LuaEngine.cpp @@ -4,61 +4,41 @@ * 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 "ALEEventMgr.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 "ALEScriptCache.h" +#include "Chat.h" +#include "GameEventMgr.h" +#include "GuildMgr.h" +#include "Log.h" +#include "MapMgr.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Opcodes.h" +#include "Player.h" +#include "SpellMgr.h" +#include "StringFormat.h" +#include "WorldSessionMgr.h" #include -#include -#include -#include -#include -#include -extern "C" -{ -// Base lua libraries -#include "lua.h" -#include "lualib.h" -#include "lauxlib.h" +// Registers all usertypes and global functions into the state (LuaFunctions.cpp). +extern void RegisterFunctions(ALE* E); -// Additional lua libraries -}; +ALE* ALE::GALE = nullptr; 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; @@ -80,7 +60,7 @@ void ALE::Initialize() // Start file watcher if enabled if (ALEConfig::GetInstance().IsAutoReloadEnabled()) { - uint32 watchInterval = eConfigMgr->GetOption("ALE.AutoReloadInterval", 1); + uint32 watchInterval = sConfigMgr->GetOption("ALE.AutoReloadInterval", 1); fileWatcher = std::make_unique(); fileWatcher->StartWatching(lua_folderpath, watchInterval); } @@ -99,13 +79,12 @@ void ALE::Uninitialize() } delete GALE; - GALE = NULL; + GALE = nullptr; lua_scripts.clear(); lua_extensions.clear(); - // Clear global cache on shutdown - ClearGlobalCache(); + ALEScriptCache::ClearCache(); initialized = false; } @@ -118,23 +97,22 @@ void ALE::LoadScriptPaths() 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()); + std::string lua_path_extra(ALEConfig::GetInstance().GetRequirePath()); + std::string lua_cpath_extra(ALEConfig::GetInstance().GetRequireCPath()); #ifndef ALE_WINDOWS - if (lua_folderpath[0] == '~') - if (const char* home = getenv("HOME")) + if (!lua_folderpath.empty() && lua_folderpath[0] == '~') + if (char const* 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 + // append custom require paths and cpaths if the config variables are not empty if (!lua_path_extra.empty()) lua_requirepath += lua_path_extra; @@ -156,69 +134,32 @@ void ALE::_ReloadALE() LOCK_ALE; ASSERT(IsInitialized()); - if (eConfigMgr->GetOption("ALE.PlayerAnnounceReload", false)) - eWorldSessionMgr->SendServerMessage(SERVER_MSG_STRING, "Reloading ALE..."); + if (sConfigMgr->GetOption("ALE.PlayerAnnounceReload", false)) + sWorldSessionMgr->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) + eventMgr(nullptr) { 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 + // Must be after OpenLua() eventMgr = new EventMgr(&ALE::GALE); } @@ -229,22 +170,24 @@ ALE::~ALE() CloseLua(); delete eventMgr; - eventMgr = NULL; + eventMgr = nullptr; } void ALE::CloseLua() { + if (!stateOpened) + return; + OnLuaStateClose(); + // Everything referencing the Lua state must be released before it is + // replaced: handlers, instance data tables, ... DestroyBindStores(); - - // Must close lua state after deleting stores and mgr - if (L) - lua_close(L); - L = NULL; - instanceDataRefs.clear(); continentDataRefs.clear(); + + lua = sol::state(); + stateOpened = false; } void ALE::OpenLua() @@ -255,112 +198,76 @@ void ALE::OpenLua() return; } - L = luaL_newstate(); + lua = sol::state(); + lua.open_libraries(); + stateOpened = true; - lua_pushlightuserdata(L, this); - lua_setfield(L, LUA_REGISTRYINDEX, ALE_STATE_PTR); + // Append a Lua stack trace to every handler error when enabled + if (ALEConfig::GetInstance().IsTraceBackEnabled()) + sol::protected_function::set_default_handler(lua["debug"]["traceback"]); CreateBindStores(); - // open base lua libraries - luaL_openlibs(L); - - // open additional lua libraries - - // Register methods and functions + // Register usertypes and global 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); + lua["package"]["path"] = GetRequirePath(); + lua["package"]["cpath"] = GetRequireCPath(); } 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); + ServerEventBindings = std::make_unique>>(); + PlayerEventBindings = std::make_unique>>(); + GuildEventBindings = std::make_unique>>(); + GroupEventBindings = std::make_unique>>(); + VehicleEventBindings = std::make_unique>>(); + BGEventBindings = std::make_unique>>(); + TicketEventBindings = std::make_unique>>(); + AllCreatureEventBindings = std::make_unique>>(); + + PacketEventBindings = std::make_unique>>(); + CreatureEventBindings = std::make_unique>>(); + CreatureGossipBindings = std::make_unique>>(); + GameObjectEventBindings = std::make_unique>>(); + GameObjectGossipBindings = std::make_unique>>(); + ItemEventBindings = std::make_unique>>(); + ItemGossipBindings = std::make_unique>>(); + PlayerGossipBindings = std::make_unique>>(); + MapEventBindings = std::make_unique>>(); + InstanceEventBindings = std::make_unique>>(); + SpellEventBindings = std::make_unique>>(); + + CreatureUniqueBindings = std::make_unique>>(); } 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; + ServerEventBindings.reset(); + PlayerEventBindings.reset(); + GuildEventBindings.reset(); + GroupEventBindings.reset(); + VehicleEventBindings.reset(); + BGEventBindings.reset(); + TicketEventBindings.reset(); + AllCreatureEventBindings.reset(); + + PacketEventBindings.reset(); + CreatureEventBindings.reset(); + CreatureGossipBindings.reset(); + GameObjectEventBindings.reset(); + GameObjectGossipBindings.reset(); + ItemEventBindings.reset(); + ItemGossipBindings.reset(); + PlayerGossipBindings.reset(); + MapEventBindings.reset(); + InstanceEventBindings.reset(); + SpellEventBindings.reset(); + + CreatureUniqueBindings.reset(); } void ALE::AddScriptPath(std::string filename, const std::string& fullpath) @@ -375,7 +282,7 @@ void ALE::AddScriptPath(std::string filename, const std::string& fullpath) 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") + if (ext != ".lua" && ext != ".dll" && ext != ".so" && ext != ".ext" && ext != ".moon" && ext != ".out") return; bool extension = ext == ".ext"; @@ -391,228 +298,6 @@ void ALE::AddScriptPath(std::string filename, const std::string& fullpath) 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) { @@ -621,45 +306,45 @@ void ALE::GetScripts(std::string path) boost::filesystem::path someDir(path); boost::filesystem::directory_iterator end_iter; - if (boost::filesystem::exists(someDir) && boost::filesystem::is_directory(someDir)) + if (!boost::filesystem::exists(someDir) || !boost::filesystem::is_directory(someDir)) + return; + + 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) { - 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(); + std::string fullpath = dir_iter->path().generic_string(); - // Check if file is hidden + // Check if file is hidden #ifdef ALE_WINDOWS - DWORD dwAttrib = GetFileAttributes(fullpath.c_str()); - if (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_HIDDEN)) - continue; + 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; + std::string name = dir_iter->path().filename().generic_string(); + if (name[0] == '.') + continue; #endif - // load subfolder - if (boost::filesystem::is_directory(dir_iter->status())) - { - GetScripts(fullpath); - continue; - } + // 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); - } + 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); } } } @@ -672,7 +357,7 @@ static bool ScriptPathComparator(const LuaScript& first, const LuaScript& second void ALE::RunScripts() { LOCK_ALE; - if (!ALEConfig::GetInstance().IsALEEnabled()) + if (!stateOpened) return; uint32 oldMSTime = ALEUtil::GetCurrTime(); @@ -680,10 +365,10 @@ void ALE::RunScripts() uint32 compiledCount = 0; uint32 cachedCount = 0; uint32 precompiledCount = 0; - bool cacheEnabled = eConfigMgr->GetOption("ALE.BytecodeCache", true); - + bool cacheEnabled = ALEConfig::GetInstance().IsByteCodeCacheEnabled(); + if (cacheEnabled) - ClearTimestampCache(); + ALEScriptCache::ClearTimestamps(); ScriptList scripts; lua_extensions.sort(ScriptPathComparator); @@ -693,668 +378,128 @@ void ALE::RunScripts() 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) + sol::table packageLoaded = lua["package"]["loaded"]; + + for (LuaScript const& script : scripts) { // Check that no duplicate names exist - if (loaded.find(it->filename) != loaded.end()) + if (loaded.find(script.filename) != loaded.end()) { - ALE_LOG_ERROR("[ALE]: Error loading `{}`. File with same name already loaded from `{}`, rename either file", it->filepath, loaded[it->filename]); + ALE_LOG_ERROR("[ALE]: Error loading `{}`. File with same name already loaded from `{}`, rename either file", script.filepath, loaded[script.filename]); continue; } - loaded[it->filename] = it->filepath; + loaded[script.filename] = script.filepath; - lua_getfield(L, modules, it->filename.c_str()); - // Stack: package, modules, module - if (!lua_isnoneornil(L, -1)) + // Skip anything require() already pulled in + if (packageLoaded[script.filename].valid() && packageLoaded[script.filename] != sol::nil) { - lua_pop(L, 1); - ALE_LOG_DEBUG("[ALE]: `{}` was already loaded or required", it->filepath); + ALE_LOG_DEBUG("[ALE]: `{}` was already loaded or required", script.filepath); continue; } - lua_pop(L, 1); - // Stack: package, modules - if (it->fileext == ".moon") + // Load the file as a callable chunk + sol::protected_function chunk; + if (script.fileext == ".out") { - 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; - } + chunk = ALEScriptCache::LoadCompiled(lua, script.filepath); + if (chunk.valid()) + ++precompiledCount; } 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; - } - } + chunk = ALEScriptCache::Load(lua, script.filepath, script.fileext == ".moon", compiledCount, cachedCount); - // 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; + if (!chunk.valid()) 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] - } + // Run it and remember its result the way require() would + // (the guard covers the rest of the iteration, which is harmless). + DispatchGuard guard(this); + sol::protected_function_result result = chunk(); - // 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)) + if (!result.valid()) { - 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 ""; + Report(sol::error(result)); + continue; } - 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(); - } + sol::object value = result.get(0); + if (!value.valid() || value == sol::nil || (value.is() && !value.as())) + value = sol::make_object(lua, true); + packageLoaded[script.filename] = value; - 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); + ALE_LOG_DEBUG("[ALE]: Successfully loaded `{}`", script.filepath); + ++count; } - 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); -} + std::string details; + if (cacheEnabled && (compiledCount > 0 || cachedCount > 0 || precompiledCount > 0)) + details = fmt::format("({} compiled, {} cached, {} pre-compiled)", compiledCount, cachedCount, precompiledCount); -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)))); -} + ALE_LOG_INFO("[ALE]: Executed {} Lua scripts in {} ms {}", count, ALEUtil::GetTimeDiff(oldMSTime), details); -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; + OnLuaStateOpen(); } -template<> ALEObject* ALE::CHECKOBJ(lua_State* luastate, int narg, bool error) +void ALE::Report(sol::error const& error) { - return CHECKTYPE(luastate, narg, NULL, error); + ALE_LOG_ERROR("{}", error.what()); + OnError(std::string(error.what())); } -ALEObject* ALE::CHECKTYPE(lua_State* luastate, int narg, const char* tname, bool error) +/* + * Saves the handler to the register type's store for the given entry/guid + * under the given event. Returns a callable that cancels the registration. + */ +sol::object ALE::Register(uint8 regtype, uint32 entry, ObjectGuid guid, uint32 instanceId, + uint32 event_id, sol::protected_function callback, uint32 shots) { - if (lua_islightuserdata(luastate, narg)) + // Inserts the handler and builds the Lua-side cancel callable. + auto bind = [&](auto& bindings, auto key) -> sol::object { - 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; + uint64 bindingID = bindings->Insert(key, std::move(callback), shots); + auto* store = bindings.get(); + return sol::make_object(lua, [store, bindingID]() { store->Remove(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 - } + return bind(ServerEventBindings, EventKey((Hooks::ServerEvents)event_id)); 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 - } + return bind(PlayerEventBindings, EventKey((Hooks::PlayerEvents)event_id)); 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 - } + return bind(GuildEventBindings, EventKey((Hooks::GuildEvents)event_id)); 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 - } + return bind(GroupEventBindings, EventKey((Hooks::GroupEvents)event_id)); 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 - } + return bind(VehicleEventBindings, EventKey((Hooks::VehicleEvents)event_id)); 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 - } + return bind(BGEventBindings, EventKey((Hooks::BGEvents)event_id)); 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) - } + throw std::invalid_argument(Acore::StringFormat("Couldn't find an opcode with (ID: {})!", entry)); - auto key = EntryKey((Hooks::PacketEvents)event_id, entry); - bindingID = PacketEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, PacketEventBindings); - return 1; // Stack: callback + return bind(PacketEventBindings, EntryKey((Hooks::PacketEvents)event_id, entry)); } break; @@ -1363,261 +508,134 @@ int ALE::Register(lua_State* L, uint8 regtype, uint32 entry, ObjectGuid guid, ui { 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); + if (!sObjectMgr->GetCreatureTemplate(entry)) + throw std::invalid_argument(Acore::StringFormat("Couldn't find a creature with (ID: {})!", entry)); + + return bind(CreatureEventBindings, EntryKey((Hooks::CreatureEvents)event_id, entry)); } - return 1; // Stack: callback + + if (guid.IsEmpty()) + throw std::invalid_argument("guid was 0!"); + + return bind(CreatureUniqueBindings, UniqueObjectKey((Hooks::CreatureEvents)event_id, guid, instanceId)); } 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) - } + if (!sObjectMgr->GetCreatureTemplate(entry)) + throw std::invalid_argument(Acore::StringFormat("Couldn't find a creature with (ID: {})!", entry)); - auto key = EntryKey((Hooks::GossipEvents)event_id, entry); - bindingID = CreatureGossipBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, CreatureGossipBindings); - return 1; // Stack: callback + return bind(CreatureGossipBindings, EntryKey((Hooks::GossipEvents)event_id, entry)); } 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) - } + if (!sObjectMgr->GetGameObjectTemplate(entry)) + throw std::invalid_argument(Acore::StringFormat("Couldn't find a gameobject with (ID: {})!", entry)); - auto key = EntryKey((Hooks::GameObjectEvents)event_id, entry); - bindingID = GameObjectEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, GameObjectEventBindings); - return 1; // Stack: callback + return bind(GameObjectEventBindings, EntryKey((Hooks::GameObjectEvents)event_id, entry)); } 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) - } + if (!sObjectMgr->GetGameObjectTemplate(entry)) + throw std::invalid_argument(Acore::StringFormat("Couldn't find a gameobject with (ID: {})!", entry)); - auto key = EntryKey((Hooks::GossipEvents)event_id, entry); - bindingID = GameObjectGossipBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, GameObjectGossipBindings); - return 1; // Stack: callback + return bind(GameObjectGossipBindings, EntryKey((Hooks::GossipEvents)event_id, entry)); } 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) - } + if (!sObjectMgr->GetItemTemplate(entry)) + throw std::invalid_argument(Acore::StringFormat("Couldn't find an item with (ID: {})!", entry)); - auto key = EntryKey((Hooks::ItemEvents)event_id, entry); - bindingID = ItemEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, ItemEventBindings); - return 1; // Stack: callback + return bind(ItemEventBindings, EntryKey((Hooks::ItemEvents)event_id, entry)); } 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) - } + if (!sObjectMgr->GetItemTemplate(entry)) + throw std::invalid_argument(Acore::StringFormat("Couldn't find an item with (ID: {})!", entry)); - auto key = EntryKey((Hooks::GossipEvents)event_id, entry); - bindingID = ItemGossipBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, ItemGossipBindings); - return 1; // Stack: callback + return bind(ItemGossipBindings, EntryKey((Hooks::GossipEvents)event_id, entry)); } 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 - } + return bind(PlayerGossipBindings, EntryKey((Hooks::GossipEvents)event_id, entry)); 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 - } + return bind(MapEventBindings, EntryKey((Hooks::InstanceEvents)event_id, entry)); 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 - } + return bind(InstanceEventBindings, EntryKey((Hooks::InstanceEvents)event_id, entry)); break; - case Hooks::REGTYPE_TICKET: + 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 - } + return bind(TicketEventBindings, EventKey((Hooks::TicketEvents)event_id)); 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) - } + throw std::invalid_argument(Acore::StringFormat("Couldn't find a spell with (ID: {})!", entry)); - auto key = EntryKey((Hooks::SpellEvents)event_id, entry); - bindingID = SpellEventBindings->Insert(key, functionRef, shots); - createCancelCallback(L, bindingID, SpellEventBindings); - return 1; // Stack: callback + return bind(SpellEventBindings, EntryKey((Hooks::SpellEvents)event_id, entry)); } 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 - } + return bind(AllCreatureEventBindings, EventKey((Hooks::AllCreatureEvents)event_id)); 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). + throw std::invalid_argument(Acore::StringFormat( + "Unknown event type (regtype {}, event {}, entry {}, guid {}, instance {})", + regtype, event_id, entry, guid.GetRawValue(), instanceId)); } CreatureAI* ALE::GetAI(Creature* creature) { if (!ALEConfig::GetInstance().IsALEEnabled()) - return NULL; + return nullptr; 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()); + auto uniqueKey = UniqueObjectKey(event_id, creature->GetGUID(), creature->GetInstanceId()); if (CreatureEventBindings->HasBindingsFor(entryKey) || CreatureUniqueBindings->HasBindingsFor(uniqueKey)) return new ALECreatureAI(creature); } - return NULL; + return nullptr; } InstanceData* ALE::GetInstanceData(Map* map) { if (!ALEConfig::GetInstance().IsALEEnabled()) - return NULL; + return nullptr; for (int i = 1; i < Hooks::INSTANCE_EVENT_COUNT; ++i) { @@ -1630,52 +648,40 @@ InstanceData* ALE::GetInstanceData(Map* map) return new ALEInstanceAI(map); } - return NULL; + return nullptr; } bool ALE::HasInstanceData(Map const* map) { if (!map->Instanceable()) return continentDataRefs.find(map->GetId()) != continentDataRefs.end(); - else - return instanceDataRefs.find(map->GetInstanceId()) != instanceDataRefs.end(); + + return instanceDataRefs.find(map->GetInstanceId()) != instanceDataRefs.end(); } -void ALE::CreateInstanceData(Map const* map) +void ALE::CreateInstanceData(Map const* map, sol::table data) { - ASSERT(lua_istable(L, -1)); - int ref = luaL_ref(L, LUA_REGISTRYINDEX); - + // Overwriting an existing entry releases the previous table automatically. 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; - } + continentDataRefs[map->GetId()] = std::move(data); else - { - uint32 instanceId = map->GetInstanceId(); + instanceDataRefs[map->GetInstanceId()] = std::move(data); +} - // 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); - } +sol::table ALE::GetInstanceData(ALEInstanceAI* ai) +{ + // Check if the instance data is missing (i.e. someone reloaded ALE). + if (!HasInstanceData(ai->instance)) + ai->Reload(); - instanceDataRefs[instanceId] = ref; - } + if (!ai->instance->Instanceable()) + return continentDataRefs[ai->instance->GetId()]; + + return instanceDataRefs[ai->instance->GetInstanceId()]; } /* - * Unrefs the instanceId related events and data + * Releases the instanceId related events and data. * Does all required actions for when an instance is freed. */ void ALE::FreeInstanceId(uint32 instanceId) @@ -1689,34 +695,9 @@ void ALE::FreeInstanceId(uint32 instanceId) { 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); - } + MapEventBindings->Clear(key); + InstanceEventBindings->Clear(key); } -} - -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; + instanceDataRefs.erase(instanceId); } diff --git a/src/LuaEngine/LuaEngine.h b/src/LuaEngine/LuaEngine.h index a21640d0e4..74c6fef4a5 100644 --- a/src/LuaEngine/LuaEngine.h +++ b/src/LuaEngine/LuaEngine.h @@ -18,24 +18,24 @@ #include "Weather.h" #include "World.h" #include "Hooks.h" -#include "LFG.h" +#include "ALEBind.h" +#include "ALEConfig.h" +#include "ALEFileWatcher.h" +#include "ALEHandles.h" #include "ALEUtility.h" -#include "HttpManager.h" +#include "BindingMap.h" #include "EventEmitter.h" -#include "TicketMgr.h" +#include "HttpManager.h" +#include "LFG.h" #include "LootMgr.h" -#include "ALEFileWatcher.h" -#include "ALEConfig.h" -#include +#include "TicketMgr.h" + +#include + #include -#include -#include +#include #include - -extern "C" -{ -#include -}; +#include struct ItemTemplate; typedef BattlegroundTypeId BattleGroundTypeId; @@ -49,7 +49,6 @@ class Corpse; class Creature; class CreatureAI; class GameObject; -class GameObjectAI; class Guild; class Group; class InstanceScript; @@ -62,36 +61,12 @@ 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 { @@ -99,12 +74,9 @@ struct LuaScript 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 @@ -130,27 +102,23 @@ class ALE_GAME_API ALE // Lua script folder path static std::string lua_folderpath; - // lua path variable for require() function + // lua path variables for the 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; + // Depth of nested event dispatches. When it drops back to 0 the engine + // returns to C++ and the handle pointer caches are retired + // (see ALEHandleEpoch in ALEHandles.h). + uint32 event_level = 0; + + // Whether OpenLua() ran: a sol::state member always exists, but scripts + // and bindings are only loaded into it while the engine is enabled. + bool stateOpened = false; + + // Per-map instance data tables, kept alive by sol references. + std::unordered_map instanceDataRefs; + // Per-continent data tables (map id -> table). + std::unordered_map continentDataRefs; ALE(); ~ALE(); @@ -163,7 +131,6 @@ class ALE_GAME_API ALE void CloseLua(); void DestroyBindStores(); void CreateBindStores(); - void InvalidateObjects(); // Use ReloadALE() to make ALE reload // This is called on world update to reload ALE @@ -171,96 +138,61 @@ class ALE_GAME_API ALE 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) + + // RAII marker of one nested dispatch level; retires handle caches when the + // outermost handler returns, even if argument conversion or the call throws. + struct DispatchGuard { - return CallAllFunctionsBool(bindings, NULL, key, key, default_value); - } + explicit DispatchGuard(ALE* engine) : _engine(engine) { ++_engine->event_level; } + ~DispatchGuard() + { + if (--_engine->event_level == 0) + ALEHandleEpoch::Bump(); + } + + DispatchGuard(DispatchGuard const&) = delete; + DispatchGuard& operator=(DispatchGuard const&) = delete; + + private: + ALE* _engine; + }; - // 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; } + // Reports a failed handler call to the log and the OnError emitter. + void Report(sol::error const& error); public: static ALE* GALE; - lua_State* L; + // The Lua state. Bindings and hooks go through sol, never the raw C API. + sol::state lua; + 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; + std::unique_ptr>> ServerEventBindings; + std::unique_ptr>> PlayerEventBindings; + std::unique_ptr>> GuildEventBindings; + std::unique_ptr>> GroupEventBindings; + std::unique_ptr>> VehicleEventBindings; + std::unique_ptr>> BGEventBindings; + std::unique_ptr>> TicketEventBindings; + std::unique_ptr>> AllCreatureEventBindings; + + std::unique_ptr>> PacketEventBindings; + std::unique_ptr>> CreatureEventBindings; + std::unique_ptr>> CreatureGossipBindings; + std::unique_ptr>> GameObjectEventBindings; + std::unique_ptr>> GameObjectGossipBindings; + std::unique_ptr>> ItemEventBindings; + std::unique_ptr>> ItemGossipBindings; + std::unique_ptr>> PlayerGossipBindings; + std::unique_ptr>> MapEventBindings; + std::unique_ptr>> InstanceEventBindings; + std::unique_ptr>> SpellEventBindings; + + std::unique_ptr>> CreatureUniqueBindings; static void Initialize(); static void Uninitialize(); @@ -268,98 +200,184 @@ class ALE_GAME_API ALE 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) + + void RunScripts(); + bool ShouldReload() const { return reload; } + bool HasLuaState() const { return stateOpened; } + + /* + * Registers a Lua handler for an event. Called from the Register* global + * functions exposed to scripts. Returns a callable that cancels the + * registration, or raises a Lua error on invalid arguments. + */ + sol::object Register(uint8 regtype, uint32 entry, ObjectGuid guid, uint32 instanceId, + uint32 event_id, sol::protected_function callback, uint32 shots); + + // ----------------------------------------------------------------- + // Event dispatch + // + // Every game object argument is automatically wrapped into its safe + // handle (see ALEBind.h); plain values pass through unchanged. + // ----------------------------------------------------------------- + + // Calls one handler with (event_id, args...); reports errors. + // Returns an invalid result when the handler raised an error. + template + sol::protected_function_result Call(sol::protected_function const& callback, E event_id, Args&&... args) { - 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; + DispatchGuard guard(this); + sol::protected_function_result result = callback(event_id, ALEBind::ToLua(lua, std::forward(args))...); + + if (!result.valid()) + Report(sol::error(result)); + + return result; } - // 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) + // Calls a plain Lua callback (no event id prepended); reports errors. + // Used for timed events, HTTP responses, async query results, ... + template + sol::protected_function_result CallFunction(sol::protected_function const& callback, Args&&... args) { - ALETemplate::Push(luastate, ptr); + DispatchGuard guard(this); + sol::protected_function_result result = callback(ALEBind::ToLua(lua, std::forward(args))...); + + if (!result.valid()) + Report(sol::error(result)); + + return result; } - static std::string FormatQuery(lua_State* L, const char* query); + // Calls every handler bound to `key`, ignoring their results. + template + void CallAll(BindingMap& bindings, K const& key, Args&&... args) + { + for (sol::protected_function const& callback : bindings.GetCallbacksFor(key)) + Call(callback, key.event_id, args...); + } - bool ExecuteCall(int params, int res); + // Same, for events bound in two maps (creature entry + unique creature). + template + void CallAll(BindingMap& bindings1, BindingMap& bindings2, K1 const& key1, K2 const& key2, Args&&... args) + { + CallAll(bindings1, key1, args...); + CallAll(bindings2, key2, args...); + } /* - * Returns `true` if ALE has instance data for `map`. + * Calls every handler bound to `key` and folds their first return value: + * returns `default_value` if every handler returned it (or nothing), + * the opposite as soon as one handler disagrees. + * + * With default_value = false this implements the usual "return true to + * override default behaviour" hook contract. */ - bool HasInstanceData(Map const* map); + template + bool CallAllBool(BindingMap& bindings, K const& key, bool default_value, Args&&... args) + { + bool result = default_value; - /* - * 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); + for (sol::protected_function const& callback : bindings.GetCallbacksFor(key)) + { + sol::protected_function_result callResult = Call(callback, key.event_id, args...); + if (!callResult.valid()) + continue; + + if (sol::optional value = callResult.get>(0)) + if (*value != default_value) + result = !default_value; + } + + return result; + } + + // Same, for events bound in two maps (creature entry + unique creature). + template + bool CallAllBool(BindingMap& bindings1, BindingMap& bindings2, K1 const& key1, K2 const& key2, + bool default_value, Args&&... args) + { + bool result1 = CallAllBool(bindings1, key1, default_value, args...); + bool result2 = CallAllBool(bindings2, key2, default_value, args...); + return (result1 != default_value || result2 != default_value) ? !default_value : default_value; + } /* - * Retrieve the instance data for the `Map` scripted by `ai` and push it - * onto the stack. + * Calls every handler bound to `key` and threads `value` through them: + * a handler that returns a value of type V replaces it for the handlers + * after it. Returns the final value. * - * An `ALEInstanceAI` is needed because the instance data might - * not exist (i.e. ALE has been reloaded). + * `invoke` receives (handler, current value) and performs the call, so + * the caller decides where the value sits among the arguments: * - * 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). + * damage = CallAllFold(*bindings, key, damage, [&](auto const& callback, uint32 current) + * { + * return Call(callback, key.event_id, me, target, current, spellInfo); + * }); */ - 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); + template + V CallAllFold(BindingMap& bindings, K const& key, V value, Invoker&& invoke) + { + return FoldCallbacks(bindings.GetCallbacksFor(key), value, std::forward(invoke)); + } - // Checks - template static T CHECKVAL(lua_State* luastate, int narg); - template static T CHECKVAL(lua_State* luastate, int narg, T def) + // Same fold over an explicit handler snapshot, for events bound in two + // maps (see GetCreatureCallbacks). + template + V FoldCallbacks(std::vector const& callbacks, V value, Invoker&& invoke) { - return lua_isnoneornil(luastate, narg) ? def : CHECKVAL(luastate, narg); + for (sol::protected_function const& callback : callbacks) + { + sol::protected_function_result result = invoke(callback, value); + if (!result.valid()) + continue; + + if (sol::optional newValue = result.get>(0)) + value = *newValue; + } + + return value; } - template static T* CHECKOBJ(lua_State* luastate, int narg, bool error = true) + + /* + * Returns the merged handler snapshot for a creature event bound by entry + * and/or by unique spawn, for hooks that need to inspect each handler's + * results themselves (modified damage, multiple return values, ...). + */ + std::vector GetCreatureCallbacks( + EntryKey const& entryKey, UniqueObjectKey const& uniqueKey) { - return ALETemplate::Check(luastate, narg, error); + std::vector callbacks = CreatureEventBindings->GetCallbacksFor(entryKey); + std::vector unique = CreatureUniqueBindings->GetCallbacksFor(uniqueKey); + callbacks.insert(callbacks.end(), unique.begin(), unique.end()); + return callbacks; } - static ALEObject* CHECKTYPE(lua_State* luastate, int narg, const char *tname, bool error = true); + + /* + * Returns `true` if ALE has instance data for `map`. + */ + bool HasInstanceData(Map const* map); + + /* + * Stores `data` as the instance data table for `map`. + */ + void CreateInstanceData(Map const* map, sol::table data); + + /* + * Retrieves the instance data table for the `Map` scripted by `ai`. + * + * An `ALEInstanceAI` is needed because the instance data might not exist + * (i.e. ALE has been reloaded). In that case the AI is "reloaded" (a new + * instance data table is created and loaded with the last known save + * state, and `Load`/`Initialize` hooks are called). + */ + sol::table GetInstanceData(ALEInstanceAI* ai); CreatureAI* GetAI(Creature* creature); InstanceData* GetInstanceData(Map* map); void FreeInstanceId(uint32 instanceId); /* Custom */ - void OnTimedEvent(int funcRef, uint32 delay, uint32 calls, WorldObject* obj); + void OnTimedEvent(sol::protected_function const& callback, uint64 eventId, 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); @@ -475,6 +493,8 @@ class ALE_GAME_API ALE 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); + bool DispatchChatEvent(EventKey const& key, Player* pPlayer, std::string& msg, + uint32 type, uint32 lang, sol::optional extra); void OnEmote(Player* pPlayer, uint32 emote); void OnTextEmote(Player* pPlayer, uint32 textEmote, uint32 emoteNum, ObjectGuid guid); void OnPlayerSpellCast(Player* pPlayer, Spell* pSpell, bool skipCheck); @@ -597,7 +617,7 @@ class ALE_GAME_API ALE 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); @@ -618,10 +638,7 @@ class ALE_GAME_API ALE 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 + +#endif // _LUA_ENGINE_H diff --git a/src/LuaEngine/LuaFunctions.cpp b/src/LuaEngine/LuaFunctions.cpp index c0acc013a4..49eff2fa58 100644 --- a/src/LuaEngine/LuaFunctions.cpp +++ b/src/LuaEngine/LuaFunctions.cpp @@ -4,1994 +4,173 @@ * 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" -#include "TransportMethods.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 }, - { "GetTransport", &LuaWorldObject::GetTransport }, - - // 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 - { "GetInventoryFreeSlots", &LuaPlayer::GetInventoryFreeSlots }, - { "GetBankFreeSlots", &LuaPlayer::GetBankFreeSlots }, - { "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 }, - { "GetTodayHonorPoints", &LuaPlayer::GetTodayHonorPoints }, - { "GetYesterdayHonorPoints", &LuaPlayer::GetYesterdayHonorPoints }, - { "GetLifetimeKills", &LuaPlayer::GetLifetimeKills }, - { "GetTodayKills", &LuaPlayer::GetTodayKills }, - { "GetYesterdayKills", &LuaPlayer::GetYesterdayKills }, - { "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 }, - { "GetTalentTreePoints", &LuaPlayer::GetTalentTreePoints }, - { "GetMostPointsTalentTree", &LuaPlayer::GetMostPointsTalentTree }, - - // 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 }, - { "HasKnownTaxiNode", &LuaPlayer::HasKnownTaxiNode }, - { "IsBot", &LuaPlayer::IsBot }, - // { "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 }, - { "AllLootRemovedFromCorpse", &LuaCreature::AllLootRemovedFromCorpse }, - { "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 }, - { "GetTransports", &LuaMap::GetTransports }, - - - // 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 }, +#include "ALERegistry.h" +#include "CreatureData.h" +#include "ObjectGuid.h" - // Boolean - { "HasItem", &LuaLoot::HasItem }, - { "HasQuestItems", &LuaLoot::HasQuestItems }, - { "HasItemForAll", &LuaLoot::HasItemForAll }, - { "HasOverThresholdItem", &LuaLoot::HasOverThresholdItem }, - { "IsLooted", &LuaLoot::IsLooted }, - { "IsEmpty", &LuaLoot::IsEmpty }, - - { NULL, NULL } -}; - -ALERegister TransportMethods[] = -{ - // Getters - { "GetPassengers", &LuaTransport::GetPassengers }, - - // Boolean - { "IsMotionTransport", &LuaTransport::IsMotionTransport }, - - // Other - { "AddPassenger", &LuaTransport::AddPassenger }, - { "RemovePassenger", &LuaTransport::RemovePassenger }, - { "EnableMovement", &LuaTransport::EnableMovement }, - - { 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; +/* + * Every game object crossing the C++/Lua boundary carries its ObjectGuid, and + * many methods return one (GetGUID, GetOwnerGUID, ...). Exposing it as a real + * usertype replaces the old boxed "long long"/"unsigned long long" userdata: + * guids compare with ==, print with tostring() and never lose precision the + * way Lua numbers would. + */ +namespace LuaObjectGuid +{ + /** + * Returns the low (counter) part of the guid, unique per object type. + * + * @return uint32 counter + */ + uint32 GetCounter(ObjectGuid guid) + { + return guid.GetCounter(); + } + + /** + * Returns the entry id encoded in the guid (creature/gameobject template entry), or 0. + * + * @return uint32 entry + */ + uint32 GetEntry(ObjectGuid guid) + { + return guid.GetEntry(); + } + + /** + * Returns 'true' if the guid is empty (references nothing). + * + * @return bool isEmpty + */ + bool IsEmpty(ObjectGuid guid) + { + return guid.IsEmpty(); + } + + /** + * Returns 'true' if the guid belongs to a player. + * + * @return bool isPlayer + */ + bool IsPlayer(ObjectGuid guid) + { + return guid.IsPlayer(); + } + + /** + * Returns 'true' if the guid belongs to a creature, pet or vehicle. + * + * @return bool isCreature + */ + bool IsCreature(ObjectGuid guid) + { + return guid.IsAnyTypeCreature(); + } + + /** + * Returns 'true' if the guid belongs to a gameobject. + * + * @return bool isGameObject + */ + bool IsGameObject(ObjectGuid guid) + { + return guid.IsGameObject(); + } + + /** + * Returns 'true' if the guid belongs to an item. + * + * @return bool isItem + */ + bool IsItem(ObjectGuid guid) + { + return guid.IsItem(); + } + + /** + * Returns a readable representation of the guid, e.g. "Creature/0/12345". + * + * @return string guidString + */ + std::string ToString(ObjectGuid guid) + { + return guid.ToString(); + } } -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; +namespace +{ + void RegisterObjectGuid(sol::state& lua) + { + sol::usertype type = lua.new_usertype("ObjectGuid", sol::no_constructor); + + type["GetCounter"] = &LuaObjectGuid::GetCounter; + type["GetEntry"] = &LuaObjectGuid::GetEntry; + type["IsEmpty"] = &LuaObjectGuid::IsEmpty; + type["IsPlayer"] = &LuaObjectGuid::IsPlayer; + type["IsCreature"] = &LuaObjectGuid::IsCreature; + type["IsGameObject"] = &LuaObjectGuid::IsGameObject; + type["IsItem"] = &LuaObjectGuid::IsItem; + type["ToString"] = &LuaObjectGuid::ToString; + + type[sol::meta_function::to_string] = &LuaObjectGuid::ToString; + } + + // Some methods return a CreatureTemplate pointer; the type is registered + // without methods (as it always was) so those returns are valid Lua values. + void RegisterCreatureTemplate(sol::state& lua) + { + lua.new_usertype("CreatureTemplate", sol::no_constructor); + } } 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, "Transport"); - ALETemplate::SetMethods(E, ObjectMethods); - ALETemplate::SetMethods(E, WorldObjectMethods); - ALETemplate::SetMethods(E, GameObjectMethods); - ALETemplate::SetMethods(E, TransportMethods); - - 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, "Loot"); - ALETemplate::SetMethods(E, LootMethods); - - ALETemplate::Register(E, "long long", true); - - ALETemplate::Register(E, "unsigned long long", true); + sol::state& lua = E->lua; + + RegisterGlobalMethods(lua); + + RegisterObjectGuid(lua); + RegisterCreatureTemplate(lua); + + // The handle hierarchy, most-derived types after their bases. + RegisterObjectMethods(lua); + RegisterWorldObjectMethods(lua); + RegisterUnitMethods(lua); + RegisterPlayerMethods(lua); + RegisterCreatureMethods(lua); + RegisterGameObjectMethods(lua); + RegisterTransportMethods(lua); + RegisterCorpseMethods(lua); + RegisterItemMethods(lua); + RegisterPetMethods(lua); + + // Manager-resolved handles. + RegisterMapMethods(lua); + RegisterGroupMethods(lua); + RegisterGuildMethods(lua); + + // Event-scoped types, only valid during the event that provided them. + RegisterAuraMethods(lua); + RegisterSpellMethods(lua); + RegisterVehicleMethods(lua); + RegisterBattleGroundMethods(lua); + RegisterChatHandlerMethods(lua); + RegisterTicketMethods(lua); + RegisterRollMethods(lua); + RegisterLootMethods(lua); + + // Static game data. + RegisterAchievementMethods(lua); + RegisterItemTemplateMethods(lua); + RegisterQuestMethods(lua); + RegisterSpellInfoMethods(lua); + RegisterSpellEntryMethods(lua); + RegisterGemPropertiesEntryMethods(lua); + + // Value types. + RegisterWorldPacketMethods(lua); + RegisterALEQueryMethods(lua); } diff --git a/src/LuaEngine/hooks/AllCreatureHooks.cpp b/src/LuaEngine/hooks/AllCreatureHooks.cpp index f32fe110e1..9ca140d940 100644 --- a/src/LuaEngine/hooks/AllCreatureHooks.cpp +++ b/src/LuaEngine/hooks/AllCreatureHooks.cpp @@ -5,11 +5,8 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALEIncludes.h" -#include "ALETemplate.h" using namespace Hooks; @@ -32,246 +29,101 @@ using namespace Hooks; void ALE::OnAllCreatureAddToWorld(Creature* creature) { START_HOOK(ALL_CREATURE_EVENT_ON_ADD); - Push(creature); - CallAllFunctions(AllCreatureEventBindings, key); + CallAll(*AllCreatureEventBindings, key, creature); } void ALE::OnAllCreatureRemoveFromWorld(Creature* creature) { START_HOOK(ALL_CREATURE_EVENT_ON_REMOVE); - Push(creature); - CallAllFunctions(AllCreatureEventBindings, key); + CallAll(*AllCreatureEventBindings, key, creature); } void ALE::OnAllCreatureSelectLevel(const CreatureTemplate* cinfo, Creature* creature) { START_HOOK(ALL_CREATURE_EVENT_ON_SELECT_LEVEL); - Push(cinfo); - Push(creature); - CallAllFunctions(AllCreatureEventBindings, key); + CallAll(*AllCreatureEventBindings, key, cinfo, creature); } 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) + level = CallAllFold(*AllCreatureEventBindings, key, level, [&](auto const& callback, uint8 current) { - 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); + return Call(callback, key.event_id, cinfo, creature, current); + }); } void ALE::OnAllCreatureAuraApply(Creature* me, Aura* aura) { START_HOOK(ALL_CREATURE_EVENT_ON_AURA_APPLY); - Push(me); - Push(aura); - CallAllFunctions(AllCreatureEventBindings, key); + CallAll(*AllCreatureEventBindings, key, me, aura); } 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); + CallAll(*AllCreatureEventBindings, key, me, aura, mode); } 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) + gain = CallAllFold(*AllCreatureEventBindings, key, gain, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, key.event_id, me, target, current); + }); } 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) + damage = CallAllFold(*AllCreatureEventBindings, key, damage, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, key.event_id, me, target, current); + }); } 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) + damage = CallAllFold(*AllCreatureEventBindings, key, damage, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, key.event_id, me, target, current, spellInfo); + }); } 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) + damage = CallAllFold(*AllCreatureEventBindings, key, damage, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, key.event_id, me, target, current); + }); } 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) + damage = CallAllFold(*AllCreatureEventBindings, key, damage, [&](auto const& callback, int32 current) { - 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); + return Call(callback, key.event_id, me, target, current, spellInfo); + }); } 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) + heal = CallAllFold(*AllCreatureEventBindings, key, heal, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, key.event_id, me, target, current, spellInfo); + }); } 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) + return CallAllFold(*AllCreatureEventBindings, key, damage, [&](auto const& callback, uint32 current) { - 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; + return Call(callback, key.event_id, me, target, current, damagetype); + }); } diff --git a/src/LuaEngine/hooks/BattleGroundHooks.cpp b/src/LuaEngine/hooks/BattleGroundHooks.cpp index ec70cf5a15..c9d131259b 100644 --- a/src/LuaEngine/hooks/BattleGroundHooks.cpp +++ b/src/LuaEngine/hooks/BattleGroundHooks.cpp @@ -5,10 +5,8 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALETemplate.h" using namespace Hooks; @@ -23,36 +21,23 @@ using namespace Hooks; void ALE::OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) { START_HOOK(BG_EVENT_ON_START); - Push(bg); - Push(bgId); - Push(instanceId); - CallAllFunctions(BGEventBindings, key); + CallAll(*BGEventBindings, key, bg, bgId, instanceId); } 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); + CallAll(*BGEventBindings, key, bg, bgId, instanceId, winner); } void ALE::OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) { START_HOOK(BG_EVENT_ON_CREATE); - Push(bg); - Push(bgId); - Push(instanceId); - CallAllFunctions(BGEventBindings, key); + CallAll(*BGEventBindings, key, bg, bgId, instanceId); } 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); + CallAll(*BGEventBindings, key, bg, bgId, instanceId); } diff --git a/src/LuaEngine/hooks/CreatureHooks.cpp b/src/LuaEngine/hooks/CreatureHooks.cpp index 9fca834e48..d1513cafc6 100644 --- a/src/LuaEngine/hooks/CreatureHooks.cpp +++ b/src/LuaEngine/hooks/CreatureHooks.cpp @@ -5,99 +5,77 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALEIncludes.h" -#include "ALETemplate.h" using namespace Hooks; +// Creature events can be bound to every creature of an entry and/or to one +// specific spawn (see RegisterCreatureEvent / RegisterUniqueCreatureEvent). #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;\ + auto unique_key = UniqueObjectKey(EVENT, CREATURE->GetGUID(), CREATURE->GetInstanceId());\ + if (!CreatureEventBindings->HasBindingsFor(entry_key) && !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;\ + auto unique_key = UniqueObjectKey(EVENT, CREATURE->GetGUID(), CREATURE->GetInstanceId());\ + if (!CreatureEventBindings->HasBindingsFor(entry_key) && !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); + CallAll(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, pCaster, spellId, effIndex, pTarget); } 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, pPlayer, pCreature, pQuest); } 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, pPlayer, pCreature, pQuest, opt); } 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); + CallAll(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, pPlayer, pCreature); } void ALE::OnAddToWorld(Creature* pCreature) { START_HOOK(CREATURE_EVENT_ON_ADD, pCreature); - Push(pCreature); - CallAllFunctions(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); + CallAll(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, pCreature); } void ALE::OnRemoveFromWorld(Creature* pCreature) { START_HOOK(CREATURE_EVENT_ON_REMOVE, pCreature); - Push(pCreature); - CallAllFunctions(CreatureEventBindings, CreatureUniqueBindings, entry_key, unique_key); + CallAll(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, pCreature); } 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, pCreature, pSummoner); } 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, diff); } //Called for reaction at enter to combat if not in combat yet (enemy can be NULL) @@ -105,9 +83,7 @@ bool ALE::UpdateAI(Creature* me, const uint32 diff) 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, target); } // Called at any Damage from any attacker (before damage apply) @@ -115,30 +91,22 @@ 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) + // Handlers return (override, newDamage): `override` stops the default + // behaviour, `newDamage` feeds the handlers after it and the damage apply. + for (sol::protected_function const& callback : GetCreatureCallbacks(entry_key, unique_key)) { - int r = CallOneFunction(n--, 3, 2); + sol::protected_function_result callResult = Call(callback, entry_key.event_id, me, attacker, damage); + if (!callResult.valid()) + continue; - if (lua_isboolean(L, r + 0) && lua_toboolean(L, r + 0)) + if (callResult.get>(0) == sol::optional(true)) 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); + if (sol::optional newDamage = callResult.get>(1)) + damage = *newDamage; } - CleanUpStack(3); return result; } @@ -147,55 +115,42 @@ 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, killer); } //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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, victim); } // 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, summon); } // 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, summon); } //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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, type, id); } // 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, target); } // Called for reaction at stopping attack at no attackers or targets @@ -203,8 +158,7 @@ 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me); } // Called when creature is spawned or respawned (for reseting variables) @@ -212,26 +166,21 @@ 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me); } // 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me); } // 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, player, emoteId); } // called when the corpse of this creature gets removed @@ -239,290 +188,142 @@ 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) + // Handlers return (override, newRespawnDelay). + for (sol::protected_function const& callback : GetCreatureCallbacks(entry_key, unique_key)) { - int r = CallOneFunction(n--, 2, 2); + sol::protected_function_result callResult = Call(callback, entry_key.event_id, me, respawnDelay); + if (!callResult.valid()) + continue; - if (lua_isboolean(L, r + 0) && lua_toboolean(L, r + 0)) + if (callResult.get>(0) == sol::optional(true)) 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); + if (sol::optional newDelay = callResult.get>(1)) + respawnDelay = *newDelay; } - 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, who); } // 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); + CallAll(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, me); } // 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, caster, spell->Id); } // 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, target, spell->Id); } 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, summon, killer); } // 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, attacker); } // 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); + return CallAllBool(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, false, me, target); } 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); + CallAll(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, me, aura); } 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); + CallAll(*CreatureEventBindings, *CreatureUniqueBindings, entry_key, unique_key, me, aura, mode); } 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) + gain = FoldCallbacks(GetCreatureCallbacks(entry_key, unique_key), gain, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, entry_key.event_id, me, target, current); + }); } 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) + damage = FoldCallbacks(GetCreatureCallbacks(entry_key, unique_key), damage, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, entry_key.event_id, me, target, current); + }); } 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) + damage = FoldCallbacks(GetCreatureCallbacks(entry_key, unique_key), damage, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, entry_key.event_id, me, target, current, spellInfo); + }); } 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) + damage = FoldCallbacks(GetCreatureCallbacks(entry_key, unique_key), damage, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, entry_key.event_id, me, target, current); + }); } 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) + damage = FoldCallbacks(GetCreatureCallbacks(entry_key, unique_key), damage, [&](auto const& callback, int32 current) { - 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); + return Call(callback, entry_key.event_id, me, target, current, spellInfo); + }); } 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) + heal = FoldCallbacks(GetCreatureCallbacks(entry_key, unique_key), heal, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, entry_key.event_id, me, target, current, spellInfo); + }); } 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) + return FoldCallbacks(GetCreatureCallbacks(entry_key, unique_key), damage, [&](auto const& callback, uint32 current) { - 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; + return Call(callback, entry_key.event_id, me, target, current, damagetype); + }); } diff --git a/src/LuaEngine/hooks/GameObjectHooks.cpp b/src/LuaEngine/hooks/GameObjectHooks.cpp index 7dd8508f4f..9d451b5f3d 100644 --- a/src/LuaEngine/hooks/GameObjectHooks.cpp +++ b/src/LuaEngine/hooks/GameObjectHooks.cpp @@ -5,12 +5,9 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALEIncludes.h" #include "ALEEventMgr.h" -#include "ALETemplate.h" using namespace Hooks; @@ -33,106 +30,78 @@ using namespace Hooks; 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); + CallAll(*GameObjectEventBindings, key, pCaster, spellId, effIndex, pTarget); } 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); + CallAll(*GameObjectEventBindings, key, pGameObject, diff); } 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); + return CallAllBool(*GameObjectEventBindings, key, false, pPlayer, pGameObject, pQuest); } 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); + return CallAllBool(*GameObjectEventBindings, key, false, pPlayer, pGameObject, pQuest, opt); } 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); + CallAll(*GameObjectEventBindings, key, pPlayer, pGameObject); } void ALE::OnDestroyed(GameObject* pGameObject, WorldObject* attacker) { START_HOOK(GAMEOBJECT_EVENT_ON_DESTROYED, pGameObject->GetEntry()); - Push(pGameObject); - Push(attacker); - CallAllFunctions(GameObjectEventBindings, key); + CallAll(*GameObjectEventBindings, key, pGameObject, attacker); } void ALE::OnDamaged(GameObject* pGameObject, WorldObject* attacker) { START_HOOK(GAMEOBJECT_EVENT_ON_DAMAGED, pGameObject->GetEntry()); - Push(pGameObject); - Push(attacker); - CallAllFunctions(GameObjectEventBindings, key); + CallAll(*GameObjectEventBindings, key, pGameObject, attacker); } void ALE::OnLootStateChanged(GameObject* pGameObject, uint32 state) { START_HOOK(GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE, pGameObject->GetEntry()); - Push(pGameObject); - Push(state); - CallAllFunctions(GameObjectEventBindings, key); + CallAll(*GameObjectEventBindings, key, pGameObject, state); } void ALE::OnGameObjectStateChanged(GameObject* pGameObject, uint32 state) { START_HOOK(GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED, pGameObject->GetEntry()); - Push(pGameObject); - Push(state); - CallAllFunctions(GameObjectEventBindings, key); + CallAll(*GameObjectEventBindings, key, pGameObject, state); } void ALE::OnSpawn(GameObject* pGameObject) { START_HOOK(GAMEOBJECT_EVENT_ON_SPAWN, pGameObject->GetEntry()); - Push(pGameObject); - CallAllFunctions(GameObjectEventBindings, key); + CallAll(*GameObjectEventBindings, key, pGameObject); } void ALE::OnAddToWorld(GameObject* pGameObject) { START_HOOK(GAMEOBJECT_EVENT_ON_ADD, pGameObject->GetEntry()); - Push(pGameObject); - CallAllFunctions(GameObjectEventBindings, key); + CallAll(*GameObjectEventBindings, key, pGameObject); } void ALE::OnRemoveFromWorld(GameObject* pGameObject) { START_HOOK(GAMEOBJECT_EVENT_ON_REMOVE, pGameObject->GetEntry()); - Push(pGameObject); - CallAllFunctions(GameObjectEventBindings, key); + CallAll(*GameObjectEventBindings, key, pGameObject); } 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); + return CallAllBool(*GameObjectEventBindings, key, false, pGameObject, pPlayer); } diff --git a/src/LuaEngine/hooks/GossipHooks.cpp b/src/LuaEngine/hooks/GossipHooks.cpp index 5fa324516f..ddc8638ad4 100644 --- a/src/LuaEngine/hooks/GossipHooks.cpp +++ b/src/LuaEngine/hooks/GossipHooks.cpp @@ -5,11 +5,8 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALEIncludes.h" -#include "ALETemplate.h" using namespace Hooks; @@ -29,36 +26,37 @@ using namespace Hooks; return RETVAL;\ LOCK_ALE +namespace +{ + // Gossip codes are passed as nil when the option had no input box. + sol::object CodeOrNil(sol::state_view lua, std::string const& code) + { + if (code.empty()) + return sol::make_object(lua, sol::nil); + + return sol::make_object(lua, code); + } +} + 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); + return CallAllBool(*GameObjectGossipBindings, key, true, pPlayer, pGameObject); } 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); + return CallAllBool(*GameObjectGossipBindings, key, true, pPlayer, pGameObject, sender, action); } 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); + return CallAllBool(*GameObjectGossipBindings, key, true, pPlayer, pGameObject, sender, action, code); } void ALE::HandleGossipSelectOption(Player* pPlayer, uint32 menuId, uint32 sender, uint32 action, const std::string& code) @@ -66,82 +64,58 @@ void ALE::HandleGossipSelectOption(Player* pPlayer, uint32 menuId, uint32 sender 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); + // The player is passed twice: as the receiver and as the sender, + // to keep the same argument layout as the other gossip events. + CallAll(*PlayerGossipBindings, key, pPlayer, pPlayer, sender, action, CodeOrNil(lua, code)); } 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); + return CallAllBool(*ItemGossipBindings, key, true, pPlayer, pItem); } 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); + CallAll(*ItemGossipBindings, key, pPlayer, pItem, sender, action, CodeOrNil(lua, code)); } 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); + return CallAllBool(*CreatureGossipBindings, key, true, pPlayer, pCreature); } bool ALE::OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action) { START_HOOK_WITH_RETVAL(CreatureGossipBindings, GOSSIP_EVENT_ON_SELECT, pCreature->GetEntry(), false); + + // Restore the menu if no handler overrode the default behaviour. auto originalMenu = *pPlayer->PlayerTalkClass; pPlayer->PlayerTalkClass->ClearMenus(); - Push(pPlayer); - Push(pCreature); - Push(sender); - Push(action); - auto preventDefault = CallAllFunctionsBool(CreatureGossipBindings, key, true); - if (!preventDefault) { + + bool preventDefault = CallAllBool(*CreatureGossipBindings, key, true, pPlayer, pCreature, sender, action); + 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); + + // Restore the menu if no handler overrode the default behaviour. 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) { + + bool preventDefault = CallAllBool(*CreatureGossipBindings, key, true, pPlayer, pCreature, sender, action, code); + if (!preventDefault) *pPlayer->PlayerTalkClass = originalMenu; - } + return preventDefault; } diff --git a/src/LuaEngine/hooks/GroupHooks.cpp b/src/LuaEngine/hooks/GroupHooks.cpp index aac809d4aa..a8968a4083 100644 --- a/src/LuaEngine/hooks/GroupHooks.cpp +++ b/src/LuaEngine/hooks/GroupHooks.cpp @@ -5,10 +5,8 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALETemplate.h" using namespace Hooks; @@ -23,49 +21,35 @@ using namespace Hooks; void ALE::OnAddMember(Group* group, ObjectGuid guid) { START_HOOK(GROUP_EVENT_ON_MEMBER_ADD); - Push(group); - Push(guid); - CallAllFunctions(GroupEventBindings, key); + CallAll(*GroupEventBindings, key, group, guid); } void ALE::OnInviteMember(Group* group, ObjectGuid guid) { START_HOOK(GROUP_EVENT_ON_MEMBER_INVITE); - Push(group); - Push(guid); - CallAllFunctions(GroupEventBindings, key); + CallAll(*GroupEventBindings, key, group, guid); } 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); + CallAll(*GroupEventBindings, key, group, guid, method); } 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); + CallAll(*GroupEventBindings, key, group, newLeaderGuid, oldLeaderGuid); } void ALE::OnDisband(Group* group) { START_HOOK(GROUP_EVENT_ON_DISBAND); - Push(group); - CallAllFunctions(GroupEventBindings, key); + CallAll(*GroupEventBindings, key, group); } void ALE::OnCreate(Group* group, ObjectGuid leaderGuid, GroupType groupType) { START_HOOK(GROUP_EVENT_ON_CREATE); - Push(group); - Push(leaderGuid); - Push(groupType); - CallAllFunctions(GroupEventBindings, key); + CallAll(*GroupEventBindings, key, group, leaderGuid, groupType); } diff --git a/src/LuaEngine/hooks/GuildHooks.cpp b/src/LuaEngine/hooks/GuildHooks.cpp index 8b3adf9a69..6f53d7ebf3 100644 --- a/src/LuaEngine/hooks/GuildHooks.cpp +++ b/src/LuaEngine/hooks/GuildHooks.cpp @@ -5,10 +5,8 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALETemplate.h" using namespace Hooks; @@ -23,142 +21,78 @@ using namespace Hooks; 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); + CallAll(*GuildEventBindings, key, guild, player, plRank); } 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); + CallAll(*GuildEventBindings, key, guild, player, isDisbanding); } void ALE::OnMOTDChanged(Guild* guild, const std::string& newMotd) { START_HOOK(GUILD_EVENT_ON_MOTD_CHANGE); - Push(guild); - Push(newMotd); - CallAllFunctions(GuildEventBindings, key); + CallAll(*GuildEventBindings, key, guild, newMotd); } void ALE::OnInfoChanged(Guild* guild, const std::string& newInfo) { START_HOOK(GUILD_EVENT_ON_INFO_CHANGE); - Push(guild); - Push(newInfo); - CallAllFunctions(GuildEventBindings, key); + CallAll(*GuildEventBindings, key, guild, newInfo); } 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); + CallAll(*GuildEventBindings, key, guild, leader, name); } void ALE::OnDisband(Guild* guild) { START_HOOK(GUILD_EVENT_ON_DISBAND); - Push(guild); - CallAllFunctions(GuildEventBindings, key); + CallAll(*GuildEventBindings, key, guild); } 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); + // A handler that returns a number changes the amount, for the handlers + // after it and for the withdrawal itself. + amount = CallAllFold(*GuildEventBindings, key, amount, [&](auto const& callback, uint32 current) + { + return Call(callback, key.event_id, guild, player, current, isRepair); + }); } 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) + // A handler that returns a number changes the amount, for the handlers + // after it and for the deposit itself. + amount = CallAllFold(*GuildEventBindings, key, amount, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, key.event_id, guild, player, current); + }); } 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); + CallAll(*GuildEventBindings, key, guild, player, pItem, isSrcBank, srcContainer, srcSlotId, isDestBank, destContainer, destSlotId); } 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); + CallAll(*GuildEventBindings, key, guild, eventType, playerGuid1, playerGuid2, newRank); } 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); + CallAll(*GuildEventBindings, key, guild, eventType, tabId, playerGuid, itemOrMoney, itemStackCount, destTabId); } diff --git a/src/LuaEngine/hooks/InstanceHooks.cpp b/src/LuaEngine/hooks/InstanceHooks.cpp index 113ca2b348..254d40809f 100644 --- a/src/LuaEngine/hooks/InstanceHooks.cpp +++ b/src/LuaEngine/hooks/InstanceHooks.cpp @@ -5,15 +5,14 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALEIncludes.h" -#include "ALETemplate.h" #include "ALEInstanceAI.h" using namespace Hooks; +// Instance handlers receive (event, instance_data, map, ...) so they can keep +// their state in the instance data table. #define START_HOOK(EVENT, AI) \ if (!ALEConfig::GetInstance().IsALEEnabled())\ return;\ @@ -21,9 +20,7 @@ using namespace Hooks; auto instanceKey = EntryKey(EVENT, AI->instance->GetInstanceId());\ if (!MapEventBindings->HasBindingsFor(mapKey) && !InstanceEventBindings->HasBindingsFor(instanceKey))\ return;\ - LOCK_ALE;\ - PushInstanceData(L, AI);\ - Push(AI->instance) + LOCK_ALE #define START_HOOK_WITH_RETVAL(EVENT, AI, RETVAL) \ if (!ALEConfig::GetInstance().IsALEEnabled())\ @@ -32,52 +29,46 @@ using namespace Hooks; auto instanceKey = EntryKey(EVENT, AI->instance->GetInstanceId());\ if (!MapEventBindings->HasBindingsFor(mapKey) && !InstanceEventBindings->HasBindingsFor(instanceKey))\ return RETVAL;\ - LOCK_ALE;\ - PushInstanceData(L, AI);\ - Push(AI->instance) + LOCK_ALE void ALE::OnInitialize(ALEInstanceAI* ai) { START_HOOK(INSTANCE_EVENT_ON_INITIALIZE, ai); - CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); + CallAll(*MapEventBindings, *InstanceEventBindings, mapKey, instanceKey, GetInstanceData(ai), ai->instance); } void ALE::OnLoad(ALEInstanceAI* ai) { START_HOOK(INSTANCE_EVENT_ON_LOAD, ai); - CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); + CallAll(*MapEventBindings, *InstanceEventBindings, mapKey, instanceKey, GetInstanceData(ai), ai->instance); } void ALE::OnUpdateInstance(ALEInstanceAI* ai, uint32 diff) { START_HOOK(INSTANCE_EVENT_ON_UPDATE, ai); - Push(diff); - CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); + CallAll(*MapEventBindings, *InstanceEventBindings, mapKey, instanceKey, GetInstanceData(ai), ai->instance, diff); } void ALE::OnPlayerEnterInstance(ALEInstanceAI* ai, Player* player) { START_HOOK(INSTANCE_EVENT_ON_PLAYER_ENTER, ai); - Push(player); - CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); + CallAll(*MapEventBindings, *InstanceEventBindings, mapKey, instanceKey, GetInstanceData(ai), ai->instance, player); } void ALE::OnCreatureCreate(ALEInstanceAI* ai, Creature* creature) { START_HOOK(INSTANCE_EVENT_ON_CREATURE_CREATE, ai); - Push(creature); - CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); + CallAll(*MapEventBindings, *InstanceEventBindings, mapKey, instanceKey, GetInstanceData(ai), ai->instance, creature); } void ALE::OnGameObjectCreate(ALEInstanceAI* ai, GameObject* gameobject) { START_HOOK(INSTANCE_EVENT_ON_GAMEOBJECT_CREATE, ai); - Push(gameobject); - CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); + CallAll(*MapEventBindings, *InstanceEventBindings, mapKey, instanceKey, GetInstanceData(ai), ai->instance, gameobject); } bool ALE::OnCheckEncounterInProgress(ALEInstanceAI* ai) { START_HOOK_WITH_RETVAL(INSTANCE_EVENT_ON_CHECK_ENCOUNTER_IN_PROGRESS, ai, false); - return CallAllFunctionsBool(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); + return CallAllBool(*MapEventBindings, *InstanceEventBindings, mapKey, instanceKey, false, GetInstanceData(ai), ai->instance); } diff --git a/src/LuaEngine/hooks/ItemHooks.cpp b/src/LuaEngine/hooks/ItemHooks.cpp index 9bc347480c..ae60b84195 100644 --- a/src/LuaEngine/hooks/ItemHooks.cpp +++ b/src/LuaEngine/hooks/ItemHooks.cpp @@ -5,11 +5,9 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALEIncludes.h" -#include "ALETemplate.h" +#include "Spell.h" using namespace Hooks; @@ -32,25 +30,18 @@ using namespace Hooks; 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); + CallAll(*ItemEventBindings, key, pCaster, spellId, effIndex, pTarget); } 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); + return CallAllBool(*ItemEventBindings, key, false, pPlayer, pItem, pQuest); } bool ALE::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) { - ObjectGuid guid = pItem->GET_GUID(); + ObjectGuid guid = pItem->GetGUID(); bool castSpell = true; if (!OnItemUse(pPlayer, pItem, targets)) @@ -81,37 +72,31 @@ bool ALE::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) 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); + + // The handler receives whatever the item was used on, or nil. + sol::object target = sol::make_object(lua, sol::nil); + if (GameObject* goTarget = targets.GetGOTarget()) + target = sol::make_object(lua, GameObjectRef(goTarget)); + else if (Item* itemTarget = targets.GetItemTarget()) + target = sol::make_object(lua, ItemRef(itemTarget)); + else if (Corpse* corpseTarget = targets.GetCorpseTarget()) + target = sol::make_object(lua, CorpseRef(corpseTarget)); + else if (Unit* unitTarget = targets.GetUnitTarget()) + target = ALEBind::ToLuaDynamic(lua, unitTarget); + else if (WorldObject* objectTarget = targets.GetObjectTarget()) + target = ALEBind::ToLuaDynamic(lua, objectTarget); + + return CallAllBool(*ItemEventBindings, key, true, pPlayer, pItem, target); } 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); + return CallAllBool(*ItemEventBindings, key, false, pPlayer, pProto->ItemId); } 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); + return CallAllBool(*ItemEventBindings, key, false, pPlayer, pItem); } diff --git a/src/LuaEngine/hooks/PacketHooks.cpp b/src/LuaEngine/hooks/PacketHooks.cpp index e09cd941f4..02ca38bed2 100644 --- a/src/LuaEngine/hooks/PacketHooks.cpp +++ b/src/LuaEngine/hooks/PacketHooks.cpp @@ -5,11 +5,8 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALEIncludes.h" -#include "ALETemplate.h" using namespace Hooks; @@ -29,60 +26,53 @@ using namespace Hooks; return;\ LOCK_ALE +namespace +{ + // Handlers receive a copy of the packet; a handler returning false blocks it. + template + void DispatchPacketEvent(ALEType* engine, BindingsType& bindings, KeyType const& key, + WorldPacket const& packet, Player* player, bool& result) + { + for (sol::protected_function const& callback : bindings.GetCallbacksFor(key)) + { + sol::protected_function_result callResult = engine->Call(callback, key.event_id, WorldPacket(packet), player); + if (!callResult.valid()) + continue; + + if (sol::optional value = callResult.template get>(0)) + if (!*value) + result = false; + } + } +} + bool ALE::OnPacketSend(WorldSession* session, const WorldPacket& packet) { bool result = true; - Player* player = NULL; + Player* player = nullptr; 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); + DispatchPacketEvent(this, *ServerEventBindings, key, packet, player, result); } 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); + DispatchPacketEvent(this, *PacketEventBindings, key, packet, player, result); } bool ALE::OnPacketReceive(WorldSession* session, WorldPacket const& packet) { bool result = true; - Player* player = NULL; + Player* player = nullptr; if (session) player = session->GetPlayer(); OnPacketReceiveAny(player, packet, result); @@ -93,39 +83,11 @@ bool ALE::OnPacketReceive(WorldSession* session, WorldPacket const& packet) void ALE::OnPacketReceiveAny(Player* player, WorldPacket const& 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, 1); - - if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) - result = false; - - lua_pop(L, 1); - } - - CleanUpStack(2); + DispatchPacketEvent(this, *ServerEventBindings, key, packet, player, result); } void ALE::OnPacketReceiveOne(Player* player, WorldPacket const& 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, 1); - - if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) - result = false; - - lua_pop(L, 1); - } - - CleanUpStack(2); + DispatchPacketEvent(this, *PacketEventBindings, key, packet, player, result); } diff --git a/src/LuaEngine/hooks/PlayerHooks.cpp b/src/LuaEngine/hooks/PlayerHooks.cpp index 7649274840..a507c4caa9 100644 --- a/src/LuaEngine/hooks/PlayerHooks.cpp +++ b/src/LuaEngine/hooks/PlayerHooks.cpp @@ -5,11 +5,11 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALEIncludes.h" -#include "ALETemplate.h" +#include "Channel.h" + +#include using namespace Hooks; @@ -32,11 +32,7 @@ using namespace Hooks; 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); + CallAll(*PlayerEventBindings, key, pPlayer, talentId, talentRank, spellid); } bool ALE::OnCommand(ChatHandler& handler, const char* text) @@ -55,922 +51,530 @@ bool ALE::OnCommand(ChatHandler& handler, const char* text) } START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_COMMAND, true); - Push(player); - Push(text); - Push(&handler); - return CallAllFunctionsBool(PlayerEventBindings, key, true); + return CallAllBool(*PlayerEventBindings, key, true, player, text, &handler); } 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); + CallAll(*PlayerEventBindings, key, pPlayer, pItem, count, guid); } void ALE::OnLootMoney(Player* pPlayer, uint32 amount) { START_HOOK(PLAYER_EVENT_ON_LOOT_MONEY); - Push(pPlayer); - Push(amount); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer, amount); } void ALE::OnFirstLogin(Player* pPlayer) { START_HOOK(PLAYER_EVENT_ON_FIRST_LOGIN); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer); } void ALE::OnRepop(Player* pPlayer) { START_HOOK(PLAYER_EVENT_ON_REPOP); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer); } void ALE::OnResurrect(Player* pPlayer) { START_HOOK(PLAYER_EVENT_ON_RESURRECT); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer); } void ALE::OnQuestAbandon(Player* pPlayer, uint32 questId) { START_HOOK(PLAYER_EVENT_ON_QUEST_ABANDON); - Push(pPlayer); - Push(questId); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer, questId); } 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); + CallAll(*PlayerEventBindings, key, pPlayer, pItem, bag, slot); } 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) + // A handler that returns a number overrides the equip result. + uint32 result = CallAllFold(*PlayerEventBindings, key, static_cast(EQUIP_ERR_OK), + [&](auto const& callback, uint32 /*current*/) { - int r = CallOneFunction(n--, 2, 1); - - if (lua_isnumber(L, r)) - result = (InventoryResult)CHECKVAL(L, r); - - lua_pop(L, 1); - } + return Call(callback, key.event_id, pPlayer, itemEntry); + }); - CleanUpStack(2); - return result; + return static_cast(result); } + void ALE::OnPlayerEnterCombat(Player* pPlayer, Unit* pEnemy) { START_HOOK(PLAYER_EVENT_ON_ENTER_COMBAT); - Push(pPlayer); - Push(pEnemy); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer, pEnemy); } void ALE::OnPlayerLeaveCombat(Player* pPlayer) { START_HOOK(PLAYER_EVENT_ON_LEAVE_COMBAT); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer); } void ALE::OnPVPKill(Player* pKiller, Player* pKilled) { START_HOOK(PLAYER_EVENT_ON_KILL_PLAYER); - Push(pKiller); - Push(pKilled); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pKiller, pKilled); } void ALE::OnCreatureKill(Player* pKiller, Creature* pKilled) { START_HOOK(PLAYER_EVENT_ON_KILL_CREATURE); - Push(pKiller); - Push(pKilled); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pKiller, pKilled); } void ALE::OnPlayerKilledByCreature(Creature* pKiller, Player* pKilled) { START_HOOK(PLAYER_EVENT_ON_KILLED_BY_CREATURE); - Push(pKiller); - Push(pKilled); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pKiller, pKilled); } void ALE::OnLevelChanged(Player* pPlayer, uint8 oldLevel) { START_HOOK(PLAYER_EVENT_ON_LEVEL_CHANGE); - Push(pPlayer); - Push(oldLevel); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer, oldLevel); } void ALE::OnFreeTalentPointsChanged(Player* pPlayer, uint32 newPoints) { START_HOOK(PLAYER_EVENT_ON_TALENTS_CHANGE); - Push(pPlayer); - Push(newPoints); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer, newPoints); } void ALE::OnTalentsReset(Player* pPlayer, bool noCost) { START_HOOK(PLAYER_EVENT_ON_TALENTS_RESET); - Push(pPlayer); - Push(noCost); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer, noCost); } 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) + amount = CallAllFold(*PlayerEventBindings, key, amount, [&](auto const& callback, int32 current) { - 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); + return Call(callback, key.event_id, pPlayer, current); + }); } 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) + amount = CallAllFold(*PlayerEventBindings, key, amount, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, key.event_id, pPlayer, current, pVictim, xpSource); + }); } 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) + + // A handler that returns a number changes the new standing; + // returning -1 blocks the change entirely. + for (sol::protected_function const& callback : PlayerEventBindings->GetCallbacksFor(key)) { - int r = CallOneFunction(n--, 4, 1); + sol::protected_function_result callResult = Call(callback, key.event_id, pPlayer, factionID, standing, incremental); + if (!callResult.valid()) + continue; - if (lua_isnumber(L, r)) + if (sol::optional newStanding = callResult.get>(0)) { - standing = CHECKVAL(L, r); + standing = *newStanding; 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); + CallAll(*PlayerEventBindings, key, pTarget, pChallenger); } void ALE::OnDuelStart(Player* pStarter, Player* pChallenger) { START_HOOK(PLAYER_EVENT_ON_DUEL_START); - Push(pStarter); - Push(pChallenger); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pStarter, pChallenger); } 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); + CallAll(*PlayerEventBindings, key, pWinner, pLoser, type); } void ALE::OnEmote(Player* pPlayer, uint32 emote) { START_HOOK(PLAYER_EVENT_ON_EMOTE); - Push(pPlayer); - Push(emote); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer, emote); } 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); + CallAll(*PlayerEventBindings, key, pPlayer, textEmote, emoteNum, guid); } 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); + CallAll(*PlayerEventBindings, key, pPlayer, pSpell, skipCheck); } void ALE::OnLogin(Player* pPlayer) { START_HOOK(PLAYER_EVENT_ON_LOGIN); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer); } void ALE::OnLogout(Player* pPlayer) { START_HOOK(PLAYER_EVENT_ON_LOGOUT); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer); } void ALE::OnCreate(Player* pPlayer) { START_HOOK(PLAYER_EVENT_ON_CHARACTER_CREATE); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer); } void ALE::OnDelete(uint32 guidlow) { START_HOOK(PLAYER_EVENT_ON_CHARACTER_DELETE); - Push(guidlow); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, guidlow); } void ALE::OnSave(Player* pPlayer) { START_HOOK(PLAYER_EVENT_ON_SAVE); - Push(pPlayer); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, pPlayer); } 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); + CallAll(*PlayerEventBindings, key, pPlayer, difficulty, mapid, permanent); } 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); + CallAll(*PlayerEventBindings, key, pPlayer, oldArea, newArea); } 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); + CallAll(*PlayerEventBindings, key, pPlayer, newZone, newArea); } void ALE::OnMapChanged(Player* player) { START_HOOK(PLAYER_EVENT_ON_MAP_CHANGE); - Push(player); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, player); } -bool ALE::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg) +/* + * Shared implementation of the chat events: handlers return + * (false to block the message, new message text to rewrite it). + * `extra` is the chat context (group, guild, channel id, receiver, ...). + */ +bool ALE::DispatchChatEvent(EventKey const& key, Player* pPlayer, std::string& msg, + uint32 type, uint32 lang, sol::optional extra) { - 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) + for (sol::protected_function const& callback : PlayerEventBindings->GetCallbacksFor(key)) { - int r = CallOneFunction(n--, 4, 2); + sol::protected_function_result callResult = extra + ? Call(callback, key.event_id, pPlayer, msg, type, lang, *extra) + : Call(callback, key.event_id, pPlayer, msg, type, lang); + if (!callResult.valid()) + continue; - if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) + if (callResult.get>(0) == sol::optional(false)) result = false; - if (lua_isstring(L, r + 1)) - msg = std::string(lua_tostring(L, r + 1)); - - lua_pop(L, 2); + if (sol::optional newMessage = callResult.get>(1)) + msg = *newMessage; } - CleanUpStack(4); return result; } -bool ALE::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Group* pGroup) +bool ALE::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg) { if (lang == LANG_ADDON) - return OnAddonMessage(pPlayer, type, msg, NULL, NULL, pGroup, NULL); + return OnAddonMessage(pPlayer, type, msg, nullptr, nullptr, nullptr, nullptr); - 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)); + START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CHAT, true); + return DispatchChatEvent(key, pPlayer, msg, type, lang, sol::nullopt); +} - lua_pop(L, 2); - } +bool ALE::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Group* pGroup) +{ + if (lang == LANG_ADDON) + return OnAddonMessage(pPlayer, type, msg, nullptr, nullptr, pGroup, nullptr); - CleanUpStack(5); - return result; + START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_GROUP_CHAT, true); + return DispatchChatEvent(key, pPlayer, msg, type, lang, sol::make_object(lua, GroupRef(pGroup))); } 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); + return OnAddonMessage(pPlayer, type, msg, nullptr, pGuild, nullptr, nullptr); 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; + return DispatchChatEvent(key, pPlayer, msg, type, lang, sol::make_object(lua, GuildRef(pGuild))); } 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); + return OnAddonMessage(pPlayer, type, msg, nullptr, nullptr, nullptr, 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; + // Built-in channels are passed by id, custom channels by negated DB id. + int32 channelId = pChannel->IsConstant() + ? static_cast(pChannel->GetChannelId()) + : -static_cast(pChannel->GetChannelDBId()); + return DispatchChatEvent(key, pPlayer, msg, type, lang, sol::make_object(lua, channelId)); } 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); + return OnAddonMessage(pPlayer, type, msg, pReceiver, nullptr, nullptr, nullptr); 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; + return DispatchChatEvent(key, pPlayer, msg, type, lang, sol::make_object(lua, PlayerRef(pReceiver))); } void ALE::OnPetAddedToWorld(Player* player, Creature* pet) { START_HOOK(PLAYER_EVENT_ON_PET_ADDED_TO_WORLD); - Push(player); - Push(pet); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, player, pet); } void ALE::OnLearnSpell(Player* player, uint32 spellId) { START_HOOK(PLAYER_EVENT_ON_LEARN_SPELL); - Push(player); - Push(spellId); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, player, spellId); } void ALE::OnAchiComplete(Player* player, AchievementEntry const* achievement) { START_HOOK(PLAYER_EVENT_ON_ACHIEVEMENT_COMPLETE); - Push(player); - Push(achievement); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, player, achievement); } void ALE::OnFfaPvpStateUpdate(Player* player, bool hasFfaPvp) { START_HOOK(PLAYER_EVENT_ON_FFAPVP_CHANGE); - Push(player); - Push(hasFfaPvp); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, player, hasFfaPvp); } 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); + return CallAllBool(*PlayerEventBindings, key, true, player, target); } 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); + return CallAllBool(*PlayerEventBindings, key, true, player, receiverGuid, mailbox, subject, body, money, cod, item); } 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); + // The dungeon set is passed as an array-like table. + sol::table dungeonTable = lua.create_table(); uint32 counter = 1; for (uint32 dungeon : dungeons) - { - ALE::Push(L, dungeon); - lua_rawseti(L, table, counter); - ++counter; - } - lua_settop(L, table); - ++push_counter; + dungeonTable[counter++] = dungeon; - Push(comment); - return CallAllFunctionsBool(PlayerEventBindings, key); + return CallAllBool(*PlayerEventBindings, key, true, player, roles, dungeonTable, comment); } 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); + CallAll(*PlayerEventBindings, key, player, item, count); } 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); + CallAll(*PlayerEventBindings, key, player, item, count); } 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); + CallAll(*PlayerEventBindings, key, player, item, count); } void ALE::OnPlayerCompleteQuest(Player* player, Quest const* quest) { START_HOOK(PLAYER_EVENT_ON_COMPLETE_QUEST); - Push(player); - Push(quest); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, player, quest); } 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); + return CallAllBool(*PlayerEventBindings, key, true, player, memberName); } 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); + CallAll(*PlayerEventBindings, key, player, item, count, voteType, roll); } void ALE::OnBattlegroundDesertion(Player* player, const BattlegroundDesertionType type) { START_HOOK(PLAYER_EVENT_ON_BG_DESERTION); - Push(player); - Push(type); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, player, type); } void ALE::OnCreatureKilledByPet(Player* player, Creature* killed) { START_HOOK(PLAYER_EVENT_ON_PET_KILL); - Push(player); - Push(killed); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, player, killed); } 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); + return CallAllBool(*PlayerEventBindings, key, true, player, skill_id); } 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) + value = CallAllFold(*PlayerEventBindings, key, value, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, key.event_id, player, skill_id, current, max, step); + }); } 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); + CallAll(*PlayerEventBindings, key, player, skill_id, value, max, step, new_value); } bool ALE::CanPlayerResurrect(Player* player) { START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CAN_RESURRECT, true); - Push(player); - return CallAllFunctionsBool(PlayerEventBindings, key); + return CallAllBool(*PlayerEventBindings, key, true, player); } void ALE::OnPlayerReleasedGhost(Player* player) { START_HOOK(PLAYER_EVENT_ON_RELEASED_GHOST); - Push(player); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, player); } void ALE::OnPlayerQuestAccept(Player* player, Quest const* quest) { START_HOOK(PLAYER_EVENT_ON_QUEST_ACCEPT); - Push(player); - Push(quest); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, player, quest); } void ALE::OnPlayerAuraApply(Player* player, Aura* aura) { START_HOOK(PLAYER_EVENT_ON_AURA_APPLY); - Push(player); - Push(aura); - CallAllFunctions(PlayerEventBindings, key); + CallAll(*PlayerEventBindings, key, player, aura); } 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) + gain = CallAllFold(*PlayerEventBindings, key, gain, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, key.event_id, player, target, current); + }); } 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) + damage = CallAllFold(*PlayerEventBindings, key, damage, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, key.event_id, player, target, current); + }); } 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); + CallAll(*PlayerEventBindings, key, player, aura, mode); } 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) + damage = CallAllFold(*PlayerEventBindings, key, damage, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, key.event_id, player, target, current, spellInfo); + }); } 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) + damage = CallAllFold(*PlayerEventBindings, key, damage, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, key.event_id, player, target, current); + }); } 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) + damage = CallAllFold(*PlayerEventBindings, key, damage, [&](auto const& callback, int32 current) { - 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); + return Call(callback, key.event_id, player, target, current, spellInfo); + }); } 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) + heal = CallAllFold(*PlayerEventBindings, key, heal, [&](auto const& callback, uint32 current) { - 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); + return Call(callback, key.event_id, player, target, current, spellInfo); + }); } 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) + return CallAllFold(*PlayerEventBindings, key, damage, [&](auto const& callback, uint32 current) { - 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; + return Call(callback, key.event_id, player, target, current, damagetype); + }); } diff --git a/src/LuaEngine/hooks/ServerHooks.cpp b/src/LuaEngine/hooks/ServerHooks.cpp index f305c97b7e..ca9118d8f5 100644 --- a/src/LuaEngine/hooks/ServerHooks.cpp +++ b/src/LuaEngine/hooks/ServerHooks.cpp @@ -5,12 +5,13 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" #include "ALEEventMgr.h" -#include "ALEIncludes.h" -#include "ALETemplate.h" +#include "AuctionHouseMgr.h" +#include "Channel.h" +#include "GameEventMgr.h" +#include "ObjectAccessor.h" using namespace Hooks; @@ -33,220 +34,153 @@ using namespace Hooks; 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 - } + // Addon messages are "prefix\tcontent"; the handler receives them split. + sol::object prefix; + sol::object content = sol::make_object(lua, sol::nil); + + auto delimiterPosition = msg.find('\t'); + if (delimiterPosition == std::string::npos) + prefix = sol::make_object(lua, 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); + prefix = sol::make_object(lua, msg.substr(0, delimiterPosition)); + content = sol::make_object(lua, msg.substr(delimiterPosition + 1)); } + // The last argument is whoever the message was sent to: + // a player, a guild, a group, a channel id, or nil. + sol::object target = sol::make_object(lua, sol::nil); if (receiver) - Push(receiver); + target = sol::make_object(lua, PlayerRef(receiver)); else if (guild) - Push(guild); + target = sol::make_object(lua, GuildRef(guild)); else if (group) - Push(group); + target = sol::make_object(lua, GroupRef(group)); else if (channel) - Push(channel->GetChannelId()); - else - Push(); + { + // Same contract as the channel chat hook: built-in channels by id, + // custom channels by negated DB id. + int32 channelId = channel->IsConstant() + ? static_cast(channel->GetChannelId()) + : -static_cast(channel->GetChannelDBId()); + target = sol::make_object(lua, channelId); + } - return CallAllFunctionsBool(ServerEventBindings, key, true); + return CallAllBool(*ServerEventBindings, key, true, sender, type, prefix, content, target); } -void ALE::OnTimedEvent(int funcRef, uint32 delay, uint32 calls, WorldObject* obj) +void ALE::OnTimedEvent(sol::protected_function const& callback, uint64 eventId, 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(); + CallFunction(callback, eventId, delay, calls, ALEBind::ToLuaDynamic(lua, obj)); } void ALE::OnGameEventStart(uint32 eventid) { START_HOOK(GAME_EVENT_START); - Push(eventid); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key, eventid); } void ALE::OnGameEventStop(uint32 eventid) { START_HOOK(GAME_EVENT_STOP); - Push(eventid); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key, eventid); } void ALE::OnLuaStateClose() { START_HOOK(ALE_EVENT_ON_LUA_STATE_CLOSE); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key); } void ALE::OnLuaStateOpen() { START_HOOK(ALE_EVENT_ON_LUA_STATE_OPEN); - CallAllFunctions(ServerEventBindings, key); + CallAll(*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); + return CallAllBool(*ServerEventBindings, key, false, pPlayer, pTrigger->entry); } // 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); + CallAll(*ServerEventBindings, key, zone, state, grade); } // 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; - + Player* owner = ObjectAccessor::FindPlayer(entry->owner); + Item* item = sAuctionMgr->GetAItem(entry->item_guid); 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); + CallAll(*ServerEventBindings, key, entry->Id, owner, item, entry->expire_time, entry->buyout, entry->startbid, entry->bid, entry->bidder); } 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; - + Player* owner = ObjectAccessor::FindPlayer(entry->owner); + Item* item = sAuctionMgr->GetAItem(entry->item_guid); 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); + CallAll(*ServerEventBindings, key, entry->Id, owner, item, entry->expire_time, entry->buyout, entry->startbid, entry->bid, entry->bidder); } 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; - + Player* owner = ObjectAccessor::FindPlayer(entry->owner); + Item* item = sAuctionMgr->GetAItem(entry->item_guid); 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); + CallAll(*ServerEventBindings, key, entry->Id, owner, item, entry->expire_time, entry->buyout, entry->startbid, entry->bid, entry->bidder); } 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; - + Player* owner = ObjectAccessor::FindPlayer(entry->owner); + Item* item = sAuctionMgr->GetAItem(entry->item_guid); 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); + CallAll(*ServerEventBindings, key, entry->Id, owner, item, entry->expire_time, entry->buyout, entry->startbid, entry->bid, entry->bidder); } void ALE::OnOpenStateChange(bool open) { START_HOOK(WORLD_EVENT_ON_OPEN_STATE_CHANGE); - Push(open); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key, open); } void ALE::OnConfigLoad(bool reload, bool isBefore) { START_HOOK(WORLD_EVENT_ON_CONFIG_LOAD); - Push(reload); - Push(isBefore); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key, reload, isBefore); } void ALE::OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask) { START_HOOK(WORLD_EVENT_ON_SHUTDOWN_INIT); - Push(code); - Push(mask); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key, code, mask); } void ALE::OnShutdownCancel() { START_HOOK(WORLD_EVENT_ON_SHUTDOWN_CANCEL); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key); } void ALE::OnWorldUpdate(uint32 diff) @@ -262,73 +196,60 @@ void ALE::OnWorldUpdate(uint32 diff) queryProcessor.ProcessReadyCallbacks(); START_HOOK(WORLD_EVENT_ON_UPDATE); - Push(diff); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key, diff); } void ALE::OnStartup() { START_HOOK(WORLD_EVENT_ON_STARTUP); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key); } void ALE::OnShutdown() { START_HOOK(WORLD_EVENT_ON_SHUTDOWN); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key); } /* Map */ void ALE::OnCreate(Map* map) { START_HOOK(MAP_EVENT_ON_CREATE); - Push(map); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key, map); } void ALE::OnDestroy(Map* map) { START_HOOK(MAP_EVENT_ON_DESTROY); - Push(map); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key, map); } void ALE::OnPlayerEnter(Map* map, Player* player) { START_HOOK(MAP_EVENT_ON_PLAYER_ENTER); - Push(map); - Push(player); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key, map, player); } void ALE::OnPlayerLeave(Map* map, Player* player) { START_HOOK(MAP_EVENT_ON_PLAYER_LEAVE); - Push(map); - Push(player); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key, map, player); } 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); + CallAll(*ServerEventBindings, key, map, diff); } void ALE::OnRemove(GameObject* gameobject) { START_HOOK(WORLD_EVENT_ON_DELETE_GAMEOBJECT); - Push(gameobject); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key, gameobject); } void ALE::OnRemove(Creature* creature) { START_HOOK(WORLD_EVENT_ON_DELETE_CREATURE); - Push(creature); - CallAllFunctions(ServerEventBindings, key); + CallAll(*ServerEventBindings, key, creature); } diff --git a/src/LuaEngine/hooks/SpellHooks.cpp b/src/LuaEngine/hooks/SpellHooks.cpp index 8c0801893e..3d7a2651a4 100644 --- a/src/LuaEngine/hooks/SpellHooks.cpp +++ b/src/LuaEngine/hooks/SpellHooks.cpp @@ -5,11 +5,8 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALEIncludes.h" -#include "ALETemplate.h" using namespace Hooks; @@ -21,40 +18,20 @@ using namespace Hooks; 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); + CallAll(*SpellEventBindings, key, caster, spell, bySelf); } 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); + CallAll(*SpellEventBindings, key, caster, spell, skipCheck); } 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); + CallAll(*SpellEventBindings, key, caster, spell); } - diff --git a/src/LuaEngine/hooks/TicketHooks.cpp b/src/LuaEngine/hooks/TicketHooks.cpp index 0aa538624d..499f0f2fb1 100644 --- a/src/LuaEngine/hooks/TicketHooks.cpp +++ b/src/LuaEngine/hooks/TicketHooks.cpp @@ -5,11 +5,8 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALEIncludes.h" -#include "ALETemplate.h" using namespace Hooks; @@ -24,28 +21,23 @@ using namespace Hooks; void ALE::OnTicketCreate(GmTicket* ticket) { START_HOOK(TICKET_EVENT_ON_CREATE); - Push(ticket); - CallAllFunctions(TicketEventBindings, key); + CallAll(*TicketEventBindings, key, ticket); } void ALE::OnTicketUpdateLastChange(GmTicket* ticket) { START_HOOK(TICKET_EVENT_UPDATE_LAST_CHANGE); - Push(ticket); - CallAllFunctions(TicketEventBindings, key); + CallAll(*TicketEventBindings, key, ticket); } void ALE::OnTicketClose(GmTicket* ticket) { START_HOOK(TICKET_EVENT_ON_CLOSE); - Push(ticket); - CallAllFunctions(TicketEventBindings, key); + CallAll(*TicketEventBindings, key, ticket); } void ALE::OnTicketResolve(GmTicket* ticket) { START_HOOK(TICKET_EVENT_ON_RESOLVE); - Push(ticket); - CallAllFunctions(TicketEventBindings, key); + CallAll(*TicketEventBindings, key, ticket); } - diff --git a/src/LuaEngine/hooks/VehicleHooks.cpp b/src/LuaEngine/hooks/VehicleHooks.cpp index f03a9657f9..694daca1b1 100644 --- a/src/LuaEngine/hooks/VehicleHooks.cpp +++ b/src/LuaEngine/hooks/VehicleHooks.cpp @@ -5,10 +5,8 @@ */ #include "Hooks.h" -#include "HookHelpers.h" #include "LuaEngine.h" #include "BindingMap.h" -#include "ALETemplate.h" using namespace Hooks; @@ -23,38 +21,29 @@ using namespace Hooks; void ALE::OnInstall(Vehicle* vehicle) { START_HOOK(VEHICLE_EVENT_ON_INSTALL); - Push(vehicle); - CallAllFunctions(VehicleEventBindings, key); + CallAll(*VehicleEventBindings, key, vehicle); } void ALE::OnUninstall(Vehicle* vehicle) { START_HOOK(VEHICLE_EVENT_ON_UNINSTALL); - Push(vehicle); - CallAllFunctions(VehicleEventBindings, key); + CallAll(*VehicleEventBindings, key, vehicle); } void ALE::OnInstallAccessory(Vehicle* vehicle, Creature* accessory) { START_HOOK(VEHICLE_EVENT_ON_INSTALL_ACCESSORY); - Push(vehicle); - Push(accessory); - CallAllFunctions(VehicleEventBindings, key); + CallAll(*VehicleEventBindings, key, vehicle, accessory); } 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); + CallAll(*VehicleEventBindings, key, vehicle, passenger, seatId); } void ALE::OnRemovePassenger(Vehicle* vehicle, Unit* passenger) { START_HOOK(VEHICLE_EVENT_ON_REMOVE_PASSENGER); - Push(vehicle); - Push(passenger); - CallAllFunctions(VehicleEventBindings, key); + CallAll(*VehicleEventBindings, key, vehicle, passenger); } 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.cpp similarity index 53% rename from src/LuaEngine/methods/ALEQueryMethods.h rename to src/LuaEngine/methods/ALEQueryMethods.cpp index 474c4ecddc..94ca595c81 100644 --- a/src/LuaEngine/methods/ALEQueryMethods.h +++ b/src/LuaEngine/methods/ALEQueryMethods.cpp @@ -4,10 +4,10 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef QUERYMETHODS_H -#define QUERYMETHODS_H +#include "ALEBind.h" -#define RESULT (*result) +#include "QueryResult.h" +#include "StringFormat.h" /*** * The result of a database query. @@ -16,18 +16,13 @@ * * Inherits all methods from: none */ -namespace LuaQuery +namespace LuaALEQuery { - static void CheckFields(lua_State* L, ALEQuery* result) + static void CheckFields(ResultSet* resultset, uint32 field) { - uint32 field = ALE::CHECKVAL(L, 2); - uint32 count = RESULT->GetFieldCount(); + uint32 count = resultset->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); - } + throw std::invalid_argument(Acore::StringFormat("trying to access invalid field index {}. There are {} fields available and the indexes start from 0", field, count)); } /** @@ -36,13 +31,11 @@ namespace LuaQuery * @param uint32 column * @return bool isNull */ - int IsNull(lua_State* L, ALEQuery* result) + bool IsNull(ResultSet* resultset, uint32 col) { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); + CheckFields(resultset, col); - ALE::Push(L, RESULT->Fetch()[col].IsNull()); - return 1; + return resultset->Fetch()[col].IsNull(); } /** @@ -50,10 +43,9 @@ namespace LuaQuery * * @return uint32 columnCount */ - int GetColumnCount(lua_State* L, ALEQuery* result) + uint32 GetColumnCount(ResultSet* resultset) { - ALE::Push(L, RESULT->GetFieldCount()); - return 1; + return resultset->GetFieldCount(); } /** @@ -61,13 +53,12 @@ namespace LuaQuery * * @return uint32 rowCount */ - int GetRowCount(lua_State* L, ALEQuery* result) + uint32 GetRowCount(ResultSet* resultset) { - if (RESULT->GetRowCount() > (uint32)-1) - ALE::Push(L, (uint32)-1); - else - ALE::Push(L, (uint32)(RESULT->GetRowCount())); - return 1; + if (resultset->GetRowCount() > (uint32)-1) + return (uint32)-1; + + return (uint32)(resultset->GetRowCount()); } /** @@ -76,12 +67,10 @@ namespace LuaQuery * @param uint32 column * @return bool data */ - int GetBool(lua_State* L, ALEQuery* result) + bool GetBool(ResultSet* resultset, uint32 col) { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; + CheckFields(resultset, col); + return resultset->Fetch()[col].Get(); } /** @@ -90,12 +79,10 @@ namespace LuaQuery * @param uint32 column * @return uint8 data */ - int GetUInt8(lua_State* L, ALEQuery* result) + uint8 GetUInt8(ResultSet* resultset, uint32 col) { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; + CheckFields(resultset, col); + return resultset->Fetch()[col].Get(); } /** @@ -104,12 +91,10 @@ namespace LuaQuery * @param uint32 column * @return uint16 data */ - int GetUInt16(lua_State* L, ALEQuery* result) + uint16 GetUInt16(ResultSet* resultset, uint32 col) { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; + CheckFields(resultset, col); + return resultset->Fetch()[col].Get(); } /** @@ -118,12 +103,10 @@ namespace LuaQuery * @param uint32 column * @return uint32 data */ - int GetUInt32(lua_State* L, ALEQuery* result) + uint32 GetUInt32(ResultSet* resultset, uint32 col) { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; + CheckFields(resultset, col); + return resultset->Fetch()[col].Get(); } /** @@ -132,12 +115,10 @@ namespace LuaQuery * @param uint32 column * @return uint64 data */ - int GetUInt64(lua_State* L, ALEQuery* result) + uint64 GetUInt64(ResultSet* resultset, uint32 col) { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; + CheckFields(resultset, col); + return resultset->Fetch()[col].Get(); } /** @@ -146,12 +127,10 @@ namespace LuaQuery * @param uint32 column * @return int8 data */ - int GetInt8(lua_State* L, ALEQuery* result) + int8 GetInt8(ResultSet* resultset, uint32 col) { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; + CheckFields(resultset, col); + return resultset->Fetch()[col].Get(); } /** @@ -160,12 +139,10 @@ namespace LuaQuery * @param uint32 column * @return int16 data */ - int GetInt16(lua_State* L, ALEQuery* result) + int16 GetInt16(ResultSet* resultset, uint32 col) { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; + CheckFields(resultset, col); + return resultset->Fetch()[col].Get(); } /** @@ -174,12 +151,10 @@ namespace LuaQuery * @param uint32 column * @return int32 data */ - int GetInt32(lua_State* L, ALEQuery* result) + int32 GetInt32(ResultSet* resultset, uint32 col) { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; + CheckFields(resultset, col); + return resultset->Fetch()[col].Get(); } /** @@ -188,12 +163,10 @@ namespace LuaQuery * @param uint32 column * @return int64 data */ - int GetInt64(lua_State* L, ALEQuery* result) + int64 GetInt64(ResultSet* resultset, uint32 col) { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; + CheckFields(resultset, col); + return resultset->Fetch()[col].Get(); } /** @@ -202,12 +175,10 @@ namespace LuaQuery * @param uint32 column * @return float data */ - int GetFloat(lua_State* L, ALEQuery* result) + float GetFloat(ResultSet* resultset, uint32 col) { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; + CheckFields(resultset, col); + return resultset->Fetch()[col].Get(); } /** @@ -216,12 +187,10 @@ namespace LuaQuery * @param uint32 column * @return double data */ - int GetDouble(lua_State* L, ALEQuery* result) + double GetDouble(ResultSet* resultset, uint32 col) { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; + CheckFields(resultset, col); + return resultset->Fetch()[col].Get(); } /** @@ -230,12 +199,10 @@ namespace LuaQuery * @param uint32 column * @return string data */ - int GetString(lua_State* L, ALEQuery* result) + std::string GetString(ResultSet* resultset, uint32 col) { - uint32 col = ALE::CHECKVAL(L, 2); - CheckFields(L, result); - ALE::Push(L, RESULT->Fetch()[col].Get()); - return 1; + CheckFields(resultset, col); + return resultset->Fetch()[col].Get(); } /** @@ -247,10 +214,9 @@ namespace LuaQuery * * @return bool hadNextRow */ - int NextRow(lua_State* L, ALEQuery* result) + bool NextRow(ResultSet* resultset) { - ALE::Push(L, RESULT->NextRow()); - return 1; + return resultset->NextRow(); } /** @@ -270,22 +236,21 @@ namespace LuaQuery * * @return table rowData : table filled with row columns and data where `T[column] = data` */ - int GetRow(lua_State* L, ALEQuery* result) + sol::table GetRow(ResultSet* resultset, sol::this_state s) { - uint32 col = RESULT->GetFieldCount(); - Field* row = RESULT->Fetch(); + uint32 col = resultset->GetFieldCount(); + Field* row = resultset->Fetch(); - lua_createtable(L, 0, col); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(0, col); for (uint32 i = 0; i < col; ++i) { - ALE::Push(L, RESULT->GetFieldName(i)); + std::string fieldName = resultset->GetFieldName(i); std::string _str = row[i].Get(); - const char* str = _str.c_str(); + char const* str = _str.c_str(); if (row[i].IsNull() || !str) - ALE::Push(L); + tbl[fieldName] = sol::lua_nil; else { // MYSQL_TYPE_LONGLONG Interpreted as string for lua @@ -297,20 +262,38 @@ namespace LuaQuery case DatabaseFieldTypes::Int64: case DatabaseFieldTypes::Float: case DatabaseFieldTypes::Double: - ALE::Push(L, strtod(str, NULL)); + tbl[fieldName] = strtod(str, NULL); break; default: - ALE::Push(L, str); + tbl[fieldName] = str; break; } } - lua_rawset(L, tbl); } - lua_settop(L, tbl); - return 1; + return tbl; } -}; -#undef RESULT +} + +void RegisterALEQueryMethods(sol::state& lua) +{ + sol::usertype type = lua.new_usertype("ALEQuery", sol::no_constructor); -#endif + type["IsNull"] = &LuaALEQuery::IsNull; + type["GetColumnCount"] = &LuaALEQuery::GetColumnCount; + type["GetRowCount"] = &LuaALEQuery::GetRowCount; + type["GetBool"] = &LuaALEQuery::GetBool; + type["GetUInt8"] = &LuaALEQuery::GetUInt8; + type["GetUInt16"] = &LuaALEQuery::GetUInt16; + type["GetUInt32"] = &LuaALEQuery::GetUInt32; + type["GetUInt64"] = &LuaALEQuery::GetUInt64; + type["GetInt8"] = &LuaALEQuery::GetInt8; + type["GetInt16"] = &LuaALEQuery::GetInt16; + type["GetInt32"] = &LuaALEQuery::GetInt32; + type["GetInt64"] = &LuaALEQuery::GetInt64; + type["GetFloat"] = &LuaALEQuery::GetFloat; + type["GetDouble"] = &LuaALEQuery::GetDouble; + type["GetString"] = &LuaALEQuery::GetString; + type["NextRow"] = &LuaALEQuery::NextRow; + type["GetRow"] = &LuaALEQuery::GetRow; +} diff --git a/src/LuaEngine/methods/ALERegistry.h b/src/LuaEngine/methods/ALERegistry.h new file mode 100644 index 0000000000..4b5fc89f7c --- /dev/null +++ b/src/LuaEngine/methods/ALERegistry.h @@ -0,0 +1,49 @@ +/* +* 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 ALEREGISTRY_H +#define ALEREGISTRY_H + +#include + +/* + * One registration function per Lua type, each defined at the bottom of its + * methods/Methods.cpp file. RegisterFunctions (LuaFunctions.cpp) calls + * them all on engine startup. + */ + +void RegisterAchievementMethods(sol::state& lua); +void RegisterALEQueryMethods(sol::state& lua); +void RegisterAuraMethods(sol::state& lua); +void RegisterBattleGroundMethods(sol::state& lua); +void RegisterChatHandlerMethods(sol::state& lua); +void RegisterCorpseMethods(sol::state& lua); +void RegisterCreatureMethods(sol::state& lua); +void RegisterGameObjectMethods(sol::state& lua); +void RegisterGemPropertiesEntryMethods(sol::state& lua); +void RegisterGlobalMethods(sol::state& lua); +void RegisterGroupMethods(sol::state& lua); +void RegisterGuildMethods(sol::state& lua); +void RegisterItemMethods(sol::state& lua); +void RegisterItemTemplateMethods(sol::state& lua); +void RegisterLootMethods(sol::state& lua); +void RegisterMapMethods(sol::state& lua); +void RegisterObjectMethods(sol::state& lua); +void RegisterPetMethods(sol::state& lua); +void RegisterPlayerMethods(sol::state& lua); +void RegisterQuestMethods(sol::state& lua); +void RegisterRollMethods(sol::state& lua); +void RegisterSpellEntryMethods(sol::state& lua); +void RegisterSpellInfoMethods(sol::state& lua); +void RegisterSpellMethods(sol::state& lua); +void RegisterTicketMethods(sol::state& lua); +void RegisterTransportMethods(sol::state& lua); +void RegisterUnitMethods(sol::state& lua); +void RegisterVehicleMethods(sol::state& lua); +void RegisterWorldObjectMethods(sol::state& lua); +void RegisterWorldPacketMethods(sol::state& lua); + +#endif // ALEREGISTRY_H diff --git a/src/LuaEngine/methods/AchievementMethods.h b/src/LuaEngine/methods/AchievementMethods.cpp similarity index 58% rename from src/LuaEngine/methods/AchievementMethods.h rename to src/LuaEngine/methods/AchievementMethods.cpp index e5d34e61fa..b21384dfad 100644 --- a/src/LuaEngine/methods/AchievementMethods.h +++ b/src/LuaEngine/methods/AchievementMethods.cpp @@ -4,8 +4,11 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef ACHIEVEMENTMETHODS_H -#define ACHIEVEMENTMETHODS_H +#include "ALEBind.h" + +#include "Common.h" +#include "DBCStructure.h" +#include "SharedDefines.h" /*** * Represents an entry from the game's achievement database (e.g., achievement earned for completing certain tasks). @@ -19,10 +22,9 @@ namespace LuaAchievement * * @return uint32 id */ - int GetId(lua_State* L, AchievementEntry* const achievement) + uint32 GetId(AchievementEntry const& achievement) { - ALE::Push(L, achievement->ID); - return 1; + return achievement.ID; } /** @@ -44,16 +46,20 @@ namespace LuaAchievement * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the [Achievement] name in * @return string name */ - int GetName(lua_State* L, AchievementEntry* const achievement) + char const* GetName(AchievementEntry const& achievement, sol::optional locale) { - uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE); - if (locale >= TOTAL_LOCALES) - { - return luaL_argerror(L, 2, "valid LocaleConstant expected"); - } + uint8 localeIndex = locale.value_or(DEFAULT_LOCALE); + if (localeIndex >= TOTAL_LOCALES) + throw std::invalid_argument("valid LocaleConstant expected"); - ALE::Push(L, achievement->name[locale]); - return 1; + return achievement.name[localeIndex]; } -}; -#endif +} + +void RegisterAchievementMethods(sol::state& lua) +{ + sol::usertype type = lua.new_usertype("Achievement", sol::no_constructor); + + type["GetId"] = &LuaAchievement::GetId; + type["GetName"] = &LuaAchievement::GetName; +} diff --git a/src/LuaEngine/methods/AuraMethods.h b/src/LuaEngine/methods/AuraMethods.cpp similarity index 62% rename from src/LuaEngine/methods/AuraMethods.h rename to src/LuaEngine/methods/AuraMethods.cpp index 3f63743d25..9bf61e0496 100644 --- a/src/LuaEngine/methods/AuraMethods.h +++ b/src/LuaEngine/methods/AuraMethods.cpp @@ -4,8 +4,10 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef AURAMETHODS_H -#define AURAMETHODS_H +#include "ALEBind.h" + +#include "SpellAuras.h" +#include "Unit.h" /*** * The persistent effect of a [Spell] that remains on a [Unit] after the [Spell] @@ -26,10 +28,9 @@ namespace LuaAura * * @return [Unit] caster */ - int GetCaster(lua_State* L, Aura* aura) + Unit* GetCaster(Aura* aura) { - ALE::Push(L, aura->GetCaster()); - return 1; + return aura->GetCaster(); } /** @@ -37,10 +38,9 @@ namespace LuaAura * * @return string caster_guid : the GUID of the Unit as a decimal string */ - int GetCasterGUID(lua_State* L, Aura* aura) + ObjectGuid GetCasterGUID(Aura* aura) { - ALE::Push(L, aura->GetCasterGUID()); - return 1; + return aura->GetCasterGUID(); } /** @@ -48,10 +48,12 @@ namespace LuaAura * * @return uint32 caster_level */ - int GetCasterLevel(lua_State* L, Aura* aura) + sol::optional GetCasterLevel(Aura* aura) { - ALE::Push(L, aura->GetCaster()->GetLevel()); - return 1; + if (Unit const* caster = aura->GetCaster()) + return caster->GetLevel(); + + return sol::nullopt; } /** @@ -59,10 +61,9 @@ namespace LuaAura * * @return int32 duration : amount of time left in milliseconds */ - int GetDuration(lua_State* L, Aura* aura) + int32 GetDuration(Aura* aura) { - ALE::Push(L, aura->GetDuration()); - return 1; + return aura->GetDuration(); } /** @@ -70,10 +71,9 @@ namespace LuaAura * * @return uint32 aura_id */ - int GetAuraId(lua_State* L, Aura* aura) + uint32 GetAuraId(Aura* aura) { - ALE::Push(L, aura->GetId()); - return 1; + return aura->GetId(); } /** @@ -84,10 +84,9 @@ namespace LuaAura * * @return int32 max_duration : the maximum duration of the Aura, in milliseconds */ - int GetMaxDuration(lua_State* L, Aura* aura) + int32 GetMaxDuration(Aura* aura) { - ALE::Push(L, aura->GetMaxDuration()); - return 1; + return aura->GetMaxDuration(); } /** @@ -97,10 +96,9 @@ namespace LuaAura * * @return uint32 stack_amount */ - int GetStackAmount(lua_State* L, Aura* aura) + uint8 GetStackAmount(Aura* aura) { - ALE::Push(L, aura->GetStackAmount()); - return 1; + return aura->GetStackAmount(); } /** @@ -108,10 +106,9 @@ namespace LuaAura * * @return [Unit] owner */ - int GetOwner(lua_State* L, Aura* aura) + WorldObject* GetOwner(Aura* aura) { - ALE::Push(L, aura->GetOwner()); - return 1; + return aura->GetOwner(); } /** @@ -119,11 +116,9 @@ namespace LuaAura * * @param int32 duration : the new duration of the Aura, in milliseconds */ - int SetDuration(lua_State* L, Aura* aura) + void SetDuration(Aura* aura, int32 duration) { - int32 duration = ALE::CHECKVAL(L, 2); aura->SetDuration(duration); - return 0; } /** @@ -134,11 +129,9 @@ namespace LuaAura * * @param int32 duration : the new maximum duration of the Aura, in milliseconds */ - int SetMaxDuration(lua_State* L, Aura* aura) + void SetMaxDuration(Aura* aura, int32 duration) { - int32 duration = ALE::CHECKVAL(L, 2); aura->SetMaxDuration(duration); - return 0; } /** @@ -149,21 +142,34 @@ namespace LuaAura * * @param uint32 amount */ - int SetStackAmount(lua_State* L, Aura* aura) + void SetStackAmount(Aura* aura, uint8 amount) { - 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) + void Remove(Aura* aura) { aura->Remove(); - ALE::CHECKOBJ(L, 1)->Invalidate(); - return 0; } -}; -#endif +} + +void RegisterAuraMethods(sol::state& lua) +{ + sol::usertype> type = ALEBind::NewHandleType>(lua, "Aura"); + + type["GetCaster"] = ALEBind::Method(&LuaAura::GetCaster); + type["GetCasterGUID"] = ALEBind::Method(&LuaAura::GetCasterGUID); + type["GetCasterLevel"] = ALEBind::Method(&LuaAura::GetCasterLevel); + type["GetDuration"] = ALEBind::Method(&LuaAura::GetDuration); + type["GetAuraId"] = ALEBind::Method(&LuaAura::GetAuraId); + type["GetMaxDuration"] = ALEBind::Method(&LuaAura::GetMaxDuration); + type["GetStackAmount"] = ALEBind::Method(&LuaAura::GetStackAmount); + type["GetOwner"] = ALEBind::Method(&LuaAura::GetOwner); + type["SetDuration"] = ALEBind::Method(&LuaAura::SetDuration); + type["SetMaxDuration"] = ALEBind::Method(&LuaAura::SetMaxDuration); + type["SetStackAmount"] = ALEBind::Method(&LuaAura::SetStackAmount); + type["Remove"] = ALEBind::Method(&LuaAura::Remove); +} diff --git a/src/LuaEngine/methods/BattleGroundMethods.cpp b/src/LuaEngine/methods/BattleGroundMethods.cpp new file mode 100644 index 0000000000..031a3c71a5 --- /dev/null +++ b/src/LuaEngine/methods/BattleGroundMethods.cpp @@ -0,0 +1,214 @@ +/* +* 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 "ALEBind.h" + +#include "Battleground.h" +#include "Map.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 + */ + std::string GetName(Battleground* bg) + { + return bg->GetName(); + } + + /** + * Returns the amount of alive players in the [BattleGround] by the team ID. + * + * @param [Team] team : team ID + * @return uint32 count + */ + uint32 GetAlivePlayersCountByTeam(Battleground* bg, uint32 team) + { + return bg->GetAlivePlayersCountByTeam((TeamId)team); + } + + /** + * Returns the [Map] of the [BattleGround]. + * + * @return [Map] map + */ + Map* GetMap(Battleground* bg) + { + return bg->GetBgMap(); + } + + /** + * Returns the bonus honor given by amount of kills in the specific [BattleGround]. + * + * @param uint32 kills : amount of kills + * @return uint32 bonusHonor + */ + uint32 GetBonusHonorFromKillCount(Battleground* bg, uint32 kills) + { + return bg->GetBonusHonorFromKill(kills); + } + + /** + * Returns the end time of the [BattleGround]. + * + * @return uint32 endTime + */ + uint32 GetEndTime(Battleground* bg) + { + return bg->GetEndTime(); + } + + /** + * Returns the amount of free slots for the selected team in the specific [BattleGround]. + * + * @param [Team] team : team ID + * @return uint32 freeSlots + */ + uint32 GetFreeSlotsForTeam(Battleground* bg, uint32 team) + { + return bg->GetFreeSlotsForTeam((TeamId)team); + } + + /** + * Returns the instance ID of the [BattleGround]. + * + * @return uint32 instanceId + */ + uint32 GetInstanceId(Battleground* bg) + { + return bg->GetInstanceID(); + } + + /** + * Returns the map ID of the [BattleGround]. + * + * @return uint32 mapId + */ + uint32 GetMapId(Battleground* bg) + { + return bg->GetMapId(); + } + + /** + * Returns the type ID of the [BattleGround]. + * + * @return [BattleGroundTypeId] typeId + */ + BattlegroundTypeId GetTypeId(Battleground* bg) + { + return bg->GetBgTypeID(); + } + + /** + * Returns the max allowed [Player] level of the specific [BattleGround]. + * + * @return uint32 maxLevel + */ + uint32 GetMaxLevel(Battleground* bg) + { + return bg->GetMaxLevel(); + } + + /** + * Returns the minimum allowed [Player] level of the specific [BattleGround]. + * + * @return uint32 minLevel + */ + uint32 GetMinLevel(Battleground* bg) + { + return bg->GetMinLevel(); + } + + /** + * Returns the maximum allowed [Player] count of the specific [BattleGround]. + * + * @return uint32 maxPlayerCount + */ + uint32 GetMaxPlayers(Battleground* bg) + { + return bg->GetMaxPlayersPerTeam() * 2; + } + + /** + * Returns the minimum allowed [Player] count of the specific [BattleGround]. + * + * @return uint32 minPlayerCount + */ + uint32 GetMinPlayers(Battleground* bg) + { + return bg->GetMinPlayersPerTeam() * 2; + } + + /** + * Returns the maximum allowed [Player] count per team of the specific [BattleGround]. + * + * @return uint32 maxTeamPlayerCount + */ + uint32 GetMaxPlayersPerTeam(Battleground* bg) + { + return bg->GetMaxPlayersPerTeam(); + } + + /** + * Returns the minimum allowed [Player] count per team of the specific [BattleGround]. + * + * @return uint32 minTeamPlayerCount + */ + uint32 GetMinPlayersPerTeam(Battleground* bg) + { + return bg->GetMinPlayersPerTeam(); + } + + /** + * Returns the winning team of the specific [BattleGround]. + * + * @return [Team] team + */ + PvPTeamId GetWinner(Battleground* bg) + { + return bg->GetWinner(); + } + + /** + * Returns the status of the specific [BattleGround]. + * + * @return [BattleGroundStatus] status + */ + BattlegroundStatus GetStatus(Battleground* bg) + { + return bg->GetStatus(); + } +} + +void RegisterBattleGroundMethods(sol::state& lua) +{ + sol::usertype> type = ALEBind::NewHandleType>(lua, "BattleGround"); + + type["GetName"] = ALEBind::Method(&LuaBattleGround::GetName); + type["GetAlivePlayersCountByTeam"] = ALEBind::Method(&LuaBattleGround::GetAlivePlayersCountByTeam); + type["GetMap"] = ALEBind::Method(&LuaBattleGround::GetMap); + type["GetBonusHonorFromKillCount"] = ALEBind::Method(&LuaBattleGround::GetBonusHonorFromKillCount); + type["GetEndTime"] = ALEBind::Method(&LuaBattleGround::GetEndTime); + type["GetFreeSlotsForTeam"] = ALEBind::Method(&LuaBattleGround::GetFreeSlotsForTeam); + type["GetInstanceId"] = ALEBind::Method(&LuaBattleGround::GetInstanceId); + type["GetMapId"] = ALEBind::Method(&LuaBattleGround::GetMapId); + type["GetTypeId"] = ALEBind::Method(&LuaBattleGround::GetTypeId); + type["GetMaxLevel"] = ALEBind::Method(&LuaBattleGround::GetMaxLevel); + type["GetMinLevel"] = ALEBind::Method(&LuaBattleGround::GetMinLevel); + type["GetMaxPlayers"] = ALEBind::Method(&LuaBattleGround::GetMaxPlayers); + type["GetMinPlayers"] = ALEBind::Method(&LuaBattleGround::GetMinPlayers); + type["GetMaxPlayersPerTeam"] = ALEBind::Method(&LuaBattleGround::GetMaxPlayersPerTeam); + type["GetMinPlayersPerTeam"] = ALEBind::Method(&LuaBattleGround::GetMinPlayersPerTeam); + type["GetWinner"] = ALEBind::Method(&LuaBattleGround::GetWinner); + type["GetStatus"] = ALEBind::Method(&LuaBattleGround::GetStatus); +} 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.cpp similarity index 53% rename from src/LuaEngine/methods/ChatHandlerMethods.h rename to src/LuaEngine/methods/ChatHandlerMethods.cpp index ac6f9a2900..8a417bede9 100644 --- a/src/LuaEngine/methods/ChatHandlerMethods.h +++ b/src/LuaEngine/methods/ChatHandlerMethods.cpp @@ -4,8 +4,7 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef CHATHANDLERMETHODS_H -#define CHATHANDLERMETHODS_H +#include "ALEBind.h" #include "Chat.h" @@ -26,19 +25,18 @@ namespace LuaChatHandler * @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) + void SendSysMessage(ChatHandler* handler, sol::object msg) { - if (lua_isnumber(L, 2)) + if (msg.get_type() == sol::type::number) { - uint32 entry = ALE::CHECKVAL(L, 2); + uint32 entry = msg.as(); handler->SendSysMessage(entry); } else { - std::string text = ALE::CHECKVAL(L, 2); + std::string text = msg.as(); handler->SendSysMessage(text); } - return 0; } /** @@ -46,10 +44,9 @@ namespace LuaChatHandler * * @return bool isConsole */ - int IsConsole(lua_State* L, ChatHandler* handler) + bool IsConsole(ChatHandler* handler) { - ALE::Push(L, handler->IsConsole()); - return 1; + return handler->IsConsole(); } /** @@ -57,10 +54,9 @@ namespace LuaChatHandler * * @return [Player] player */ - int GetPlayer(lua_State* L, ChatHandler* handler) + Player* GetPlayer(ChatHandler* handler) { - ALE::Push(L, handler->GetPlayer()); - return 1; + return handler->GetPlayer(); } /** @@ -68,11 +64,9 @@ namespace LuaChatHandler * * @param string text : text to send */ - int SendGlobalSysMessage(lua_State* L, ChatHandler* handler) + void SendGlobalSysMessage(ChatHandler* handler, std::string text) { - std::string text = ALE::CHECKVAL(L, 2); handler->SendGlobalSysMessage(text.c_str()); - return 0; } /** @@ -80,11 +74,9 @@ namespace LuaChatHandler * * @param string text : text to send */ - int SendGlobalGMSysMessage(lua_State* L, ChatHandler* handler) + void SendGlobalGMSysMessage(ChatHandler* handler, std::string text) { - std::string text = ALE::CHECKVAL(L, 2); handler->SendGlobalGMSysMessage(text.c_str()); - return 0; } /** @@ -94,12 +86,9 @@ namespace LuaChatHandler * @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) + bool HasLowerSecurity(ChatHandler* handler, Player* player, sol::optional strong) { - Player* player = ALE::CHECKOBJ(L, 2); - bool strong = ALE::CHECKVAL(L, 3); - ALE::Push(L, handler->HasLowerSecurity(player, ObjectGuid::Empty, strong)); - return 1; + return handler->HasLowerSecurity(player, ObjectGuid::Empty, strong.value_or(false)); } /** @@ -109,12 +98,9 @@ namespace LuaChatHandler * @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) + bool HasLowerSecurityAccount(ChatHandler* handler, uint32 account, sol::optional strong) { - uint32 account = ALE::CHECKVAL(L, 2); - bool strong = ALE::CHECKVAL(L, 3); - ALE::Push(L, handler->HasLowerSecurityAccount(nullptr, account, strong)); - return 1; + return handler->HasLowerSecurityAccount(nullptr, account, strong.value_or(false)); } /** @@ -122,10 +108,9 @@ namespace LuaChatHandler * * @return [Player] player */ - int GetSelectedPlayer(lua_State* L, ChatHandler* handler) + Player* GetSelectedPlayer(ChatHandler* handler) { - ALE::Push(L, handler->getSelectedPlayer()); - return 1; + return handler->getSelectedPlayer(); } /** @@ -133,10 +118,9 @@ namespace LuaChatHandler * * @return [Creature] creature */ - int GetSelectedCreature(lua_State* L, ChatHandler* handler) + Creature* GetSelectedCreature(ChatHandler* handler) { - ALE::Push(L, handler->getSelectedCreature()); - return 1; + return handler->getSelectedCreature(); } /** @@ -144,10 +128,9 @@ namespace LuaChatHandler * * @return [Unit] unit */ - int GetSelectedUnit(lua_State* L, ChatHandler* handler) + Unit* GetSelectedUnit(ChatHandler* handler) { - ALE::Push(L, handler->getSelectedUnit()); - return 1; + return handler->getSelectedUnit(); } /** @@ -155,10 +138,9 @@ namespace LuaChatHandler * * @return [WorldObject] object */ - int GetSelectedObject(lua_State* L, ChatHandler* handler) + WorldObject* GetSelectedObject(ChatHandler* handler) { - ALE::Push(L, handler->getSelectedObject()); - return 1; + return handler->getSelectedObject(); } /** @@ -166,10 +148,9 @@ namespace LuaChatHandler * * @return [Player] player */ - int GetSelectedPlayerOrSelf(lua_State* L, ChatHandler* handler) + Player* GetSelectedPlayerOrSelf(ChatHandler* handler) { - ALE::Push(L, handler->getSelectedPlayerOrSelf()); - return 1; + return handler->getSelectedPlayerOrSelf(); } /** @@ -178,11 +159,9 @@ namespace LuaChatHandler * @param [uint32] securityLevel * @return [bool] isAvailable */ - int IsAvailable(lua_State* L, ChatHandler* handler) + bool IsAvailable(ChatHandler* handler, uint32 securityLevel) { - uint32 securityLevel = ALE::CHECKVAL(L, 2); - ALE::Push(L, handler->IsAvailable(securityLevel)); - return 1; + return handler->IsAvailable(securityLevel); } /** @@ -190,10 +169,28 @@ namespace LuaChatHandler * * @return [bool] sentErrorMessage */ - int HasSentErrorMessage(lua_State* L, ChatHandler* handler) + bool HasSentErrorMessage(ChatHandler* handler) { - ALE::Push(L, handler->HasSentErrorMessage()); - return 1; + return handler->HasSentErrorMessage(); } } -#endif + +void RegisterChatHandlerMethods(sol::state& lua) +{ + sol::usertype> type = ALEBind::NewHandleType>(lua, "ChatHandler"); + + type["SendSysMessage"] = ALEBind::Method(&LuaChatHandler::SendSysMessage); + type["IsConsole"] = ALEBind::Method(&LuaChatHandler::IsConsole); + type["GetPlayer"] = ALEBind::Method(&LuaChatHandler::GetPlayer); + type["SendGlobalSysMessage"] = ALEBind::Method(&LuaChatHandler::SendGlobalSysMessage); + type["SendGlobalGMSysMessage"] = ALEBind::Method(&LuaChatHandler::SendGlobalGMSysMessage); + type["HasLowerSecurity"] = ALEBind::Method(&LuaChatHandler::HasLowerSecurity); + type["HasLowerSecurityAccount"] = ALEBind::Method(&LuaChatHandler::HasLowerSecurityAccount); + type["GetSelectedPlayer"] = ALEBind::Method(&LuaChatHandler::GetSelectedPlayer); + type["GetSelectedCreature"] = ALEBind::Method(&LuaChatHandler::GetSelectedCreature); + type["GetSelectedUnit"] = ALEBind::Method(&LuaChatHandler::GetSelectedUnit); + type["GetSelectedObject"] = ALEBind::Method(&LuaChatHandler::GetSelectedObject); + type["GetSelectedPlayerOrSelf"] = ALEBind::Method(&LuaChatHandler::GetSelectedPlayerOrSelf); + type["IsAvailable"] = ALEBind::Method(&LuaChatHandler::IsAvailable); + type["HasSentErrorMessage"] = ALEBind::Method(&LuaChatHandler::HasSentErrorMessage); +} diff --git a/src/LuaEngine/methods/CorpseMethods.h b/src/LuaEngine/methods/CorpseMethods.cpp similarity index 58% rename from src/LuaEngine/methods/CorpseMethods.h rename to src/LuaEngine/methods/CorpseMethods.cpp index cf8f6f71ed..54b91ce6a5 100644 --- a/src/LuaEngine/methods/CorpseMethods.h +++ b/src/LuaEngine/methods/CorpseMethods.cpp @@ -4,8 +4,9 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef CORPSEMETHODS_H -#define CORPSEMETHODS_H +#include "ALEBind.h" + +#include "Corpse.h" /*** * The remains of a [Player] that has died. @@ -19,10 +20,9 @@ namespace LuaCorpse * * @return ObjectGuid ownerGUID */ - int GetOwnerGUID(lua_State* L, Corpse* corpse) + ObjectGuid GetOwnerGUID(Corpse* corpse) { - ALE::Push(L, corpse->GetOwnerGUID()); - return 1; + return corpse->GetOwnerGUID(); } /** @@ -30,10 +30,9 @@ namespace LuaCorpse * * @return uint32 ghostTime */ - int GetGhostTime(lua_State* L, Corpse* corpse) + uint32 GetGhostTime(Corpse* corpse) { - ALE::Push(L, corpse->GetGhostTime()); - return 1; + return corpse->GetGhostTime(); } /** @@ -48,10 +47,9 @@ namespace LuaCorpse * * @return [CorpseType] corpseType */ - int GetType(lua_State* L, Corpse* corpse) + CorpseType GetType(Corpse* corpse) { - ALE::Push(L, corpse->GetType()); - return 1; + return corpse->GetType(); } /** @@ -59,19 +57,27 @@ namespace LuaCorpse * * See [Corpse:GetGhostTime]. */ - int ResetGhostTime(lua_State* /*L*/, Corpse* corpse) + void ResetGhostTime(Corpse* corpse) { corpse->ResetGhostTime(); - return 0; } /** * Saves the [Corpse] to the database. */ - int SaveToDB(lua_State* /*L*/, Corpse* corpse) + void SaveToDB(Corpse* corpse) { corpse->SaveToDB(); - return 0; } -}; -#endif +} + +void RegisterCorpseMethods(sol::state& lua) +{ + sol::usertype type = ALEBind::NewHandleType(lua, "Corpse"); + + type["GetOwnerGUID"] = ALEBind::Method(&LuaCorpse::GetOwnerGUID); + type["GetGhostTime"] = ALEBind::Method(&LuaCorpse::GetGhostTime); + type["GetType"] = ALEBind::Method(&LuaCorpse::GetType); + type["ResetGhostTime"] = ALEBind::Method(&LuaCorpse::ResetGhostTime); + type["SaveToDB"] = ALEBind::Method(&LuaCorpse::SaveToDB); +} diff --git a/src/LuaEngine/methods/CreatureMethods.h b/src/LuaEngine/methods/CreatureMethods.cpp similarity index 57% rename from src/LuaEngine/methods/CreatureMethods.h rename to src/LuaEngine/methods/CreatureMethods.cpp index fc8833d851..948a965e50 100644 --- a/src/LuaEngine/methods/CreatureMethods.h +++ b/src/LuaEngine/methods/CreatureMethods.cpp @@ -4,8 +4,16 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef CREATUREMETHODS_H -#define CREATUREMETHODS_H +#include "ALEBind.h" +#include "ALEUtility.h" + +#include "Creature.h" +#include "CreatureAI.h" +#include "MotionMaster.h" +#include "ObjectMgr.h" +#include "SpellInfo.h" +#include "SpellMgr.h" +#include "ThreatManager.h" /*** * Non-[Player] controlled [Unit]s (i.e. NPCs). @@ -20,10 +28,9 @@ namespace LuaCreature * * @return bool isRegenerating */ - int IsRegeneratingHealth(lua_State* L, Creature* creature) + bool IsRegeneratingHealth(Creature* creature) { - ALE::Push(L, creature->isRegeneratingHealth()); - return 1; + return creature->isRegeneratingHealth(); } /** @@ -31,12 +38,9 @@ namespace LuaCreature * * @param bool enable = true : `true` to enable health regeneration, `false` to disable it */ - int SetRegeneratingHealth(lua_State* L, Creature* creature) + void SetRegeneratingHealth(Creature* creature, sol::optional enable) { - bool enable = ALE::CHECKVAL(L, 2, true); - - creature->SetRegeneratingHealth(enable); - return 0; + creature->SetRegeneratingHealth(enable.value_or(true)); } /** @@ -45,10 +49,9 @@ namespace LuaCreature * * @return bool reputationDisabled */ - int IsReputationGainDisabled(lua_State* L, Creature* creature) + bool IsReputationGainDisabled(Creature* creature) { - ALE::Push(L, creature->IsReputationRewardDisabled()); - return 1; + return creature->IsReputationRewardDisabled(); } /** @@ -58,12 +61,9 @@ namespace LuaCreature * @param uint32 questID : the ID of a [Quest] * @return bool completesQuest */ - int CanCompleteQuest(lua_State* L, Creature* creature) + bool CanCompleteQuest(Creature* creature, uint32 quest_id) { - uint32 quest_id = ALE::CHECKVAL(L, 2); - - ALE::Push(L, creature->hasInvolvedQuest(quest_id)); - return 1; + return creature->hasInvolvedQuest(quest_id); } /** @@ -73,12 +73,9 @@ namespace LuaCreature * @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 IsTargetableForAttack(Creature* creature, sol::optional mustBeDead) { - bool mustBeDead = ALE::CHECKVAL(L, 2, false); - - ALE::Push(L, creature->isTargetableForAttack(mustBeDead)); - return 1; + return creature->isTargetableForAttack(mustBeDead.value_or(false)); } /** @@ -90,14 +87,9 @@ namespace LuaCreature * @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) + bool CanAssistTo(Creature* creature, Unit* u, Unit* enemy, sol::optional checkfaction) { - 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; + return creature->CanAssistTo(u, enemy, checkfaction.value_or(true)); } /** @@ -106,10 +98,9 @@ namespace LuaCreature * * @return bool searchedForAssistance */ - int HasSearchedAssistance(lua_State* L, Creature* creature) + bool HasSearchedAssistance(Creature* creature) { - ALE::Push(L, creature->HasSearchedAssistance()); - return 1; + return creature->HasSearchedAssistance(); } /** @@ -118,12 +109,9 @@ namespace LuaCreature * * @return bool tapped */ - int IsTappedBy(lua_State* L, Creature* creature) + bool IsTappedBy(Creature* creature, Player* player) { - Player* player = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, creature->isTappedBy(player)); - return 1; + return creature->isTappedBy(player); } /** @@ -132,10 +120,9 @@ namespace LuaCreature * * @return bool hasLootRecipient */ - int HasLootRecipient(lua_State* L, Creature* creature) + bool HasLootRecipient(Creature* creature) { - ALE::Push(L, creature->hasLootRecipient()); - return 1; + return creature->hasLootRecipient(); } /** @@ -144,10 +131,9 @@ namespace LuaCreature * * @return bool canAggro */ - int CanAggro(lua_State* L, Creature* creature) + bool CanAggro(Creature* creature) { - ALE::Push(L, !creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC)); - return 1; + return !creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC); } /** @@ -156,10 +142,9 @@ namespace LuaCreature * * @return bool canSwim */ - int CanSwim(lua_State* L, Creature* creature) + bool CanSwim(Creature* creature) { - ALE::Push(L, creature->CanSwim()); - return 1; + return creature->CanSwim(); } /** @@ -168,10 +153,9 @@ namespace LuaCreature * * @return bool canWalk */ - int CanWalk(lua_State* L, Creature* creature) + bool CanWalk(Creature* creature) { - ALE::Push(L, creature->CanWalk()); - return 1; + return creature->CanWalk(); } /** @@ -180,10 +164,9 @@ namespace LuaCreature * * @return bool inEvadeMode */ - int IsInEvadeMode(lua_State* L, Creature* creature) + bool IsInEvadeMode(Creature* creature) { - ALE::Push(L, creature->IsInEvadeMode()); - return 1; + return creature->IsInEvadeMode(); } /** @@ -192,10 +175,9 @@ namespace LuaCreature * * @return bool isElite */ - int IsElite(lua_State* L, Creature* creature) + bool IsElite(Creature* creature) { - ALE::Push(L, creature->isElite()); - return 1; + return creature->isElite(); } /** @@ -204,10 +186,9 @@ namespace LuaCreature * * @return bool isGuard */ - int IsGuard(lua_State* L, Creature* creature) + bool IsGuard(Creature* creature) { - ALE::Push(L, creature->IsGuard()); - return 1; + return creature->IsGuard(); } /** @@ -216,10 +197,9 @@ namespace LuaCreature * * @return bool isCivilian */ - int IsCivilian(lua_State* L, Creature* creature) + bool IsCivilian(Creature* creature) { - ALE::Push(L, creature->IsCivilian()); - return 1; + return creature->IsCivilian(); } /** @@ -228,10 +208,9 @@ namespace LuaCreature * * @return bool isLeader */ - int IsRacialLeader(lua_State* L, Creature* creature) + bool IsRacialLeader(Creature* creature) { - ALE::Push(L, creature->IsRacialLeader()); - return 1; + return creature->IsRacialLeader(); } /** @@ -240,10 +219,9 @@ namespace LuaCreature * * @return bool isDungeonBoss */ - int IsDungeonBoss(lua_State* L, Creature* creature) + bool IsDungeonBoss(Creature* creature) { - ALE::Push(L, creature->IsDungeonBoss()); - return 1; + return creature->IsDungeonBoss(); } /** @@ -252,10 +230,9 @@ namespace LuaCreature * * @return bool isWorldBoss */ - int IsWorldBoss(lua_State* L, Creature* creature) + bool IsWorldBoss(Creature* creature) { - ALE::Push(L, creature->isWorldBoss()); - return 1; + return creature->isWorldBoss(); } /** @@ -265,15 +242,12 @@ namespace LuaCreature * @param uint32 spellId : the ID of a [Spell] * @return bool hasCooldown */ - int HasCategoryCooldown(lua_State* L, Creature* creature) + bool HasCategoryCooldown(Creature* creature, uint32 spell) { - uint32 spell = ALE::CHECKVAL(L, 2); + if (SpellInfo const* info = sSpellMgr->GetSpellInfo(spell)) + return info->GetCategory() && creature->HasSpellCooldown(spell); - if (const SpellInfo* info = sSpellMgr->GetSpellInfo(spell)) - ALE::Push(L, info->GetCategory() && creature->HasSpellCooldown(spell)); - else - ALE::Push(L, false); - return 1; + return false; } /** @@ -283,12 +257,9 @@ namespace LuaCreature * @param uint32 spellId : the ID of a [Spell] * @return bool hasSpell */ - int HasSpell(lua_State* L, Creature* creature) + bool HasSpell(Creature* creature, uint32 id) { - uint32 id = ALE::CHECKVAL(L, 2); - - ALE::Push(L, creature->HasSpell(id)); - return 1; + return creature->HasSpell(id); } /** @@ -298,12 +269,9 @@ namespace LuaCreature * @param uint32 questId : the ID of a [Quest] * @return bool hasQuest */ - int HasQuest(lua_State* L, Creature* creature) + bool HasQuest(Creature* creature, uint32 questId) { - uint32 questId = ALE::CHECKVAL(L, 2); - - ALE::Push(L, creature->hasQuest(questId)); - return 1; + return creature->hasQuest(questId); } /** @@ -313,12 +281,9 @@ namespace LuaCreature * @param uint32 spellId : the ID of a [Spell] * @return bool hasCooldown */ - int HasSpellCooldown(lua_State* L, Creature* creature) + bool HasSpellCooldown(Creature* creature, uint32 spellId) { - uint32 spellId = ALE::CHECKVAL(L, 2); - - ALE::Push(L, creature->HasSpellCooldown(spellId)); - return 1; + return creature->HasSpellCooldown(spellId); } /** @@ -327,10 +292,9 @@ namespace LuaCreature * * @return bool canFly */ - int CanFly(lua_State* L, Creature* creature) + bool CanFly(Creature* creature) { - ALE::Push(L, creature->CanFly()); - return 1; + return creature->CanFly(); } /** @@ -339,10 +303,9 @@ namespace LuaCreature * * @return bool canFly */ - int IsTrigger(lua_State* L, Creature* creature) + bool IsTrigger(Creature* creature) { - ALE::Push(L, creature->IsTrigger()); - return 1; + return creature->IsTrigger(); } /** @@ -350,10 +313,9 @@ namespace LuaCreature * * @return bool isDamagedEnough */ - int IsDamageEnoughForLootingAndReward(lua_State* L, Creature* creature) + bool IsDamageEnoughForLootingAndReward(Creature* creature) { - ALE::Push(L, creature->IsDamageEnoughForLootingAndReward()); - return 1; + return creature->IsDamageEnoughForLootingAndReward(); } /** @@ -364,12 +326,9 @@ namespace LuaCreature * @param [Unit] target * @param bool force = true : force [Creature] to attack */ - int CanStartAttack(lua_State* L, Creature* creature) // TODO: Implement core side + bool CanStartAttack(Creature* creature, Unit* target) // TODO: Implement core side { - Unit* target = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, creature->CanStartAttack(target)); - return 1; + return creature->CanStartAttack(target); } /** @@ -378,12 +337,9 @@ namespace LuaCreature * @param uint16 lootMode * @return bool hasLootMode */ - int HasLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features + bool HasLootMode(Creature* creature, uint16 lootMode) // TODO: Implement LootMode features { - uint16 lootMode = ALE::CHECKVAL(L, 2); - - ALE::Push(L, creature->HasLootMode(lootMode)); - return 1; + return creature->HasLootMode(lootMode); } /** @@ -394,10 +350,9 @@ namespace LuaCreature * * @return uint32 respawnDelay : the respawn delay, in seconds */ - int GetRespawnDelay(lua_State* L, Creature* creature) + uint32 GetRespawnDelay(Creature* creature) { - ALE::Push(L, creature->GetRespawnDelay()); - return 1; + return creature->GetRespawnDelay(); } /** @@ -406,10 +361,9 @@ namespace LuaCreature * * @return float wanderRadius */ - int GetWanderRadius(lua_State* L, Creature* creature) + float GetWanderRadius(Creature* creature) { - ALE::Push(L, creature->GetWanderDistance()); - return 1; + return creature->GetWanderDistance(); } /** @@ -417,10 +371,9 @@ namespace LuaCreature * * @return uint32 pathId */ - int GetWaypointPath(lua_State* L, Creature* creature) + uint32 GetWaypointPath(Creature* creature) { - ALE::Push(L, creature->GetWaypointPath()); - return 1; + return creature->GetWaypointPath(); } /** @@ -428,10 +381,9 @@ namespace LuaCreature * * @return uint32 wpId */ - int GetCurrentWaypointId(lua_State* L, Creature* creature) + uint32 GetCurrentWaypointId(Creature* creature) { - ALE::Push(L, creature->GetCurrentWaypointID()); - return 1; + return creature->GetCurrentWaypointID(); } /** @@ -439,10 +391,9 @@ namespace LuaCreature * * @return uint32 spawnId */ - int GetSpawnId(lua_State* L, Creature* creature) + uint32 GetSpawnId(Creature* creature) { - ALE::Push(L, creature->GetSpawnId()); - return 1; + return creature->GetSpawnId(); } /** @@ -450,10 +401,9 @@ namespace LuaCreature * * @return [MovementGeneratorType] defaultMovementType */ - int GetDefaultMovementType(lua_State* L, Creature* creature) + MovementGeneratorType GetDefaultMovementType(Creature* creature) { - ALE::Push(L, creature->GetDefaultMovementType()); - return 1; + return creature->GetDefaultMovementType(); } /** @@ -462,12 +412,9 @@ namespace LuaCreature * @param [Unit] target * @return float aggroRange */ - int GetAggroRange(lua_State* L, Creature* creature) + float GetAggroRange(Creature* creature, Unit* target) { - Unit* target = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, creature->GetAggroRange(target)); - return 1; + return creature->GetAggroRange(target); } /** @@ -475,10 +422,9 @@ namespace LuaCreature * * @return [Group] lootRecipientGroup : the group or `nil` */ - int GetLootRecipientGroup(lua_State* L, Creature* creature) + Group* GetLootRecipientGroup(Creature* creature) { - ALE::Push(L, creature->GetLootRecipientGroup()); - return 1; + return creature->GetLootRecipientGroup(); } /** @@ -486,10 +432,9 @@ namespace LuaCreature * * @return [Player] lootRecipient : the player or `nil` */ - int GetLootRecipient(lua_State* L, Creature* creature) + Player* GetLootRecipient(Creature* creature) { - ALE::Push(L, creature->GetLootRecipient()); - return 1; + return creature->GetLootRecipient(); } /** @@ -501,10 +446,9 @@ namespace LuaCreature * * @return string scriptName */ - int GetScriptName(lua_State* L, Creature* creature) + std::string GetScriptName(Creature* creature) { - ALE::Push(L, creature->GetScriptName()); - return 1; + return creature->GetScriptName(); } /** @@ -516,10 +460,9 @@ namespace LuaCreature * * @return string AIName */ - int GetAIName(lua_State* L, Creature* creature) + std::string GetAIName(Creature* creature) { - ALE::Push(L, creature->GetAIName()); - return 1; + return creature->GetAIName(); } /** @@ -530,10 +473,9 @@ namespace LuaCreature * * @return uint32 scriptID */ - int GetScriptId(lua_State* L, Creature* creature) + uint32 GetScriptId(Creature* creature) { - ALE::Push(L, creature->GetScriptId()); - return 1; + return creature->GetScriptId(); } /** @@ -542,16 +484,12 @@ namespace LuaCreature * @param uint32 spellID * @return uint32 cooldown : the cooldown, in milliseconds */ - int GetCreatureSpellCooldownDelay(lua_State* L, Creature* creature) + uint32 GetCreatureSpellCooldownDelay(Creature* creature, uint32 spell) { - uint32 spell = ALE::CHECKVAL(L, 2); - if (sSpellMgr->GetSpellInfo(spell)) - ALE::Push(L, creature->GetSpellCooldown(spell)); - else - ALE::Push(L, 0); + return creature->GetSpellCooldown(spell); - return 1; + return 0; } /** @@ -559,10 +497,9 @@ namespace LuaCreature * * @return uint32 corpseDelay : the delay, in seconds */ - int GetCorpseDelay(lua_State* L, Creature* creature) + uint32 GetCorpseDelay(Creature* creature) { - ALE::Push(L, creature->GetCorpseDelay()); - return 1; + return creature->GetCorpseDelay(); } /** @@ -574,16 +511,12 @@ namespace LuaCreature * @return float z * @return float o */ - int GetHomePosition(lua_State* L, Creature* creature) + std::tuple GetHomePosition(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; + return std::tuple(x, y, z, o); } /** @@ -595,15 +528,9 @@ namespace LuaCreature * @param float z * @param float o */ - int SetHomePosition(lua_State* L, Creature* creature) + void SetHomePosition(Creature* creature, float x, float y, float z, float o) { - 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 @@ -641,20 +568,19 @@ namespace LuaCreature * @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) + Unit* GetAITarget(Creature* creature, uint32 targetType, sol::optional playerOnlyArg, sol::optional positionArg, sol::optional distArg, sol::optional auraArg) { - 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); + bool playerOnly = playerOnlyArg.value_or(false); + uint32 position = positionArg.value_or(0); + float dist = distArg.value_or(0.0f); + int32 aura = auraArg.value_or(0); ThreatManager const& threatMgr = creature->GetThreatMgr(); if (threatMgr.IsThreatListEmpty()) - return 1; + return nullptr; if (position >= threatMgr.GetThreatListSize()) - return 1; + return nullptr; std::list targetList; @@ -678,9 +604,9 @@ namespace LuaCreature } if (targetList.empty()) - return 1; + return nullptr; if (position >= targetList.size()) - return 1; + return nullptr; if (targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) targetList.sort(ALEUtil::ObjectDistanceOrderPred(creature)); @@ -693,18 +619,16 @@ namespace LuaCreature std::list::const_iterator itr = targetList.begin(); if (position) std::advance(itr, position); - ALE::Push(L, *itr); + return *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); + return *ritr; } - break; case SELECT_TARGET_RANDOM: { std::list::const_iterator itr = targetList.begin(); @@ -712,15 +636,13 @@ namespace LuaCreature std::advance(itr, urand(0, position)); else std::advance(itr, urand(0, targetList.size() - 1)); - ALE::Push(L, *itr); + return *itr; } - break; default: - luaL_argerror(L, 2, "SelectAggroTarget expected"); - break; + throw std::invalid_argument("SelectAggroTarget expected"); } - return 1; + return nullptr; } /** @@ -728,21 +650,18 @@ namespace LuaCreature * * @return table targets */ - int GetAITargets(lua_State* L, Creature* creature) + sol::table GetAITargets(Creature* creature, sol::this_state s) { ThreatManager const& threatMgr = creature->GetThreatMgr(); - lua_createtable(L, threatMgr.GetThreatListSize(), 0); - int tbl = lua_gettop(L); + sol::state_view lua(s); + sol::table tbl = lua.create_table(static_cast(threatMgr.GetThreatListSize()), 0); uint32 i = 0; + for (ThreatReference const* ref : threatMgr.GetSortedThreatList()) - { - ALE::Push(L, ref->GetVictim()); - lua_rawseti(L, tbl, ++i); - } + tbl[++i] = ALEBind::ToLuaDynamic(lua, ref->GetVictim()); - lua_settop(L, tbl); - return 1; + return tbl; } /** @@ -750,10 +669,9 @@ namespace LuaCreature * * @return int targetsCount */ - int GetAITargetsCount(lua_State* L, Creature* creature) + std::size_t GetAITargetsCount(Creature* creature) { - ALE::Push(L, creature->GetThreatMgr().GetThreatListSize()); - return 1; + return creature->GetThreatMgr().GetThreatListSize(); } /** @@ -764,10 +682,9 @@ namespace LuaCreature * * @return [NPCFlags] npcFlags */ - int GetNPCFlags(lua_State* L, Creature* creature) + uint32 GetNPCFlags(Creature* creature) { - ALE::Push(L, creature->GetUInt32Value(UNIT_NPC_FLAGS)); - return 1; + return creature->GetUInt32Value(UNIT_NPC_FLAGS); } /** @@ -777,10 +694,9 @@ namespace LuaCreature * * @return [UnitFlags] unitFlags */ - int GetUnitFlags(lua_State* L, Creature* creature) + uint32 GetUnitFlags(Creature* creature) { - ALE::Push(L, creature->GetUInt32Value(UNIT_FIELD_FLAGS)); - return 1; + return creature->GetUInt32Value(UNIT_FIELD_FLAGS); } /** @@ -788,10 +704,9 @@ namespace LuaCreature * * @return [UnitFlags2] unitFlags2 */ - int GetUnitFlagsTwo(lua_State* L, Creature* creature) + uint32 GetUnitFlagsTwo(Creature* creature) { - ALE::Push(L, creature->GetUInt32Value(UNIT_FIELD_FLAGS_2)); - return 1; + return creature->GetUInt32Value(UNIT_FIELD_FLAGS_2); } /** @@ -802,10 +717,9 @@ namespace LuaCreature * * @return [ExtraFlags] extraFlags */ - int GetExtraFlags(lua_State* L, Creature* creature) + uint32 GetExtraFlags(Creature* creature) { - ALE::Push(L, creature->GetCreatureTemplate()->flags_extra); - return 1; + return creature->GetCreatureTemplate()->flags_extra; } /** @@ -813,10 +727,9 @@ namespace LuaCreature * * @return [Rank] rank */ - int GetRank(lua_State* L, Creature* creature) + uint32 GetRank(Creature* creature) { - ALE::Push(L, creature->GetCreatureTemplate()->rank); - return 1; + return creature->GetCreatureTemplate()->rank; } /** @@ -824,10 +737,9 @@ namespace LuaCreature * * @return uint32 shieldBlockValue */ - int GetShieldBlockValue(lua_State* L, Creature* creature) + uint32 GetShieldBlockValue(Creature* creature) { - ALE::Push(L, creature->GetShieldBlockValue()); - return 1; + return creature->GetShieldBlockValue(); } /** @@ -836,10 +748,9 @@ namespace LuaCreature * @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 + uint16 GetLootMode(Creature* creature) // TODO: Implement LootMode features { - ALE::Push(L, creature->GetLootMode()); - return 1; + return creature->GetLootMode(); } /** @@ -847,10 +758,9 @@ namespace LuaCreature * * @return uint32 dbguid */ - int GetDBTableGUIDLow(lua_State* L, Creature* creature) + uint32 GetDBTableGUIDLow(Creature* creature) { - ALE::Push(L, creature->GetSpawnId()); - return 1; + return creature->GetSpawnId(); } /** @@ -867,11 +777,10 @@ namespace LuaCreature * * @return [ReactState] state */ - int GetReactState(lua_State* L, Creature* creature) + int32 GetReactState(Creature* creature) { ReactStates state = creature->GetReactState(); - lua_pushinteger(L, (int)state); - return 1; + return static_cast(state); } /** @@ -879,24 +788,19 @@ namespace LuaCreature * * @param [NPCFlags] flags */ - int SetNPCFlags(lua_State* L, Creature* creature) + void SetNPCFlags(Creature* creature, uint32 flags) { - 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) + void SetUnitFlags(Creature* creature, uint32 flags) { - uint32 flags = ALE::CHECKVAL(L, 2); creature->SetUInt32Value(UNIT_FIELD_FLAGS, flags); - return 0; } /** @@ -904,11 +808,9 @@ namespace LuaCreature * * @param [UnitFlags2] flags */ - int SetUnitFlagsTwo(lua_State* L, Creature* creature) + void SetUnitFlagsTwo(Creature* creature, uint32 flags) { - uint32 flags = ALE::CHECKVAL(L, 2); creature->SetUInt32Value(UNIT_FIELD_FLAGS_2, flags); - return 0; } /** @@ -916,12 +818,9 @@ namespace LuaCreature * * @param [ReactState] state */ - int SetReactState(lua_State* L, Creature* creature) + void SetReactState(Creature* creature, uint32 state) { - uint32 state = ALE::CHECKVAL(L, 2); - creature->SetReactState((ReactStates)state); - return 0; } /** @@ -929,12 +828,9 @@ namespace LuaCreature * * @param bool disable */ - int SetDisableGravity(lua_State* L, Creature* creature) + void SetDisableGravity(Creature* creature, bool disable) { - bool disable = ALE::CHECKVAL(L, 2); - creature->SetDisableGravity(disable); - return 0; } /** @@ -943,12 +839,9 @@ namespace LuaCreature * @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 + void SetLootMode(Creature* creature, uint16 lootMode) // TODO: Implement LootMode features { - uint16 lootMode = ALE::CHECKVAL(L, 2); - creature->SetLootMode(lootMode); - return 0; } /** @@ -956,12 +849,9 @@ namespace LuaCreature * * @param [DeathState] deathState */ - int SetDeathState(lua_State* L, Creature* creature) + void SetDeathState(Creature* creature, int32 state) { - int32 state = ALE::CHECKVAL(L, 2); - creature->setDeathState((DeathState)state); - return 0; } /** @@ -969,12 +859,9 @@ namespace LuaCreature * * @param bool enable = true : `true` to enable walking, `false` for running */ - int SetWalk(lua_State* L, Creature* creature) // TODO: Move same to Player ? + void SetWalk(Creature* creature, sol::optional enable) // TODO: Move same to Player ? { - bool enable = ALE::CHECKVAL(L, 2, true); - - creature->SetWalk(enable); - return 0; + creature->SetWalk(enable.value_or(true)); } /** @@ -984,17 +871,11 @@ namespace LuaCreature * @param uint32 off_hand : off hand [Item]'s entry * @param uint32 ranged : ranged [Item]'s entry */ - int SetEquipmentSlots(lua_State* L, Creature* creature) + void SetEquipmentSlots(Creature* creature, uint32 main_hand, uint32 off_hand, uint32 ranged) { - 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; } /** @@ -1002,16 +883,14 @@ namespace LuaCreature * * @param bool allow = true : `true` to allow aggro, `false` to disable aggro */ - int SetAggroEnabled(lua_State* L, Creature* creature) + void SetAggroEnabled(Creature* creature, sol::optional allowArg) { - bool allow = ALE::CHECKVAL(L, 2, true); + bool allow = allowArg.value_or(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; } /** @@ -1019,12 +898,9 @@ namespace LuaCreature * * @param bool disable = true : `true` to disable reputation, `false` to enable */ - int SetDisableReputationGain(lua_State* L, Creature* creature) + void SetDisableReputationGain(Creature* creature, sol::optional disable) { - bool disable = ALE::CHECKVAL(L, 2, true); - - creature->SetReputationRewardDisabled(disable); - return 0; + creature->SetReputationRewardDisabled(disable.value_or(true)); } /** @@ -1033,12 +909,10 @@ namespace LuaCreature * 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) + void SetInCombatWithZone(Creature* creature) { if (creature->IsAIEnabled) creature->AI()->DoZoneInCombat(); - - return 0; } /** @@ -1046,13 +920,9 @@ namespace LuaCreature * * @param float distance */ - int SetWanderRadius(lua_State* L, Creature* creature) + void SetWanderRadius(Creature* creature, float dist) { - float dist = ALE::CHECKVAL(L, 2); - creature->SetWanderDistance(dist); - - return 0; } /** @@ -1060,12 +930,9 @@ namespace LuaCreature * * @param uint32 delay : the delay, in seconds */ - int SetRespawnDelay(lua_State* L, Creature* creature) + void SetRespawnDelay(Creature* creature, uint32 delay) { - uint32 delay = ALE::CHECKVAL(L, 2); - creature->SetRespawnDelay(delay); - return 0; } /** @@ -1073,12 +940,9 @@ namespace LuaCreature * * @param [MovementGeneratorType] type */ - int SetDefaultMovementType(lua_State* L, Creature* creature) + void SetDefaultMovementType(Creature* creature, int32 type) { - int32 type = ALE::CHECKVAL(L, 2); - creature->SetDefaultMovementType((MovementGeneratorType)type); - return 0; } /** @@ -1086,12 +950,9 @@ namespace LuaCreature * * @param bool enable = true : `true` to disable searching, `false` to allow */ - int SetNoSearchAssistance(lua_State* L, Creature* creature) + void SetNoSearchAssistance(Creature* creature, sol::optional val) { - bool val = ALE::CHECKVAL(L, 2, true); - - creature->SetNoSearchAssistance(val); - return 0; + creature->SetNoSearchAssistance(val.value_or(true)); } /** @@ -1099,12 +960,9 @@ namespace LuaCreature * * @param bool enable = true : `true` to disable calling for help, `false` to enable */ - int SetNoCallAssistance(lua_State* L, Creature* creature) + void SetNoCallAssistance(Creature* creature, sol::optional val) { - bool val = ALE::CHECKVAL(L, 2, true); - - creature->SetNoCallAssistance(val); - return 0; + creature->SetNoCallAssistance(val.value_or(true)); } /** @@ -1112,13 +970,9 @@ namespace LuaCreature * * @param bool enable = true : `true` to enable hovering, `false` to disable */ - int SetHover(lua_State* L, Creature* creature) + void SetHover(Creature* creature, sol::optional enable) { - bool enable = ALE::CHECKVAL(L, 2, true); - - creature->SetHover(enable); - - return 0; + creature->SetHover(enable.value_or(true)); } /** @@ -1126,39 +980,33 @@ namespace LuaCreature * * @param uint32 delay = 0 : dely to despawn in milliseconds */ - int DespawnOrUnsummon(lua_State* L, Creature* creature) + void DespawnOrUnsummon(Creature* creature, sol::optional msTimeToDespawn) { - uint32 msTimeToDespawn = ALE::CHECKVAL(L, 2, 0); - creature->DespawnOrUnsummon(Milliseconds(msTimeToDespawn)); - - return 0; + creature->DespawnOrUnsummon(Milliseconds(msTimeToDespawn.value_or(0))); } /** * Respawn this [Creature]. */ - int Respawn(lua_State* /*L*/, Creature* creature) + void Respawn(Creature* creature) { creature->Respawn(); - return 0; } /** * Remove this [Creature]'s corpse. */ - int RemoveCorpse(lua_State* /*L*/, Creature* creature) + void RemoveCorpse(Creature* creature) { creature->RemoveCorpse(); - return 0; } /** * Handles this [Creature]'s corpse state after all loot is removed. */ - int AllLootRemovedFromCorpse(lua_State* /*L*/, Creature* creature) + void AllLootRemovedFromCorpse(Creature* creature) { creature->AllLootRemovedFromCorpse(); - return 0; } /** @@ -1166,30 +1014,25 @@ namespace LuaCreature * * @param uint32 delay : the delay, in seconds */ - int SetCorpseDelay(lua_State* L, Creature* creature) + void SetCorpseDelay(Creature* creature, uint32 delay) { - 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) + void MoveWaypoint(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) + void CallAssistance(Creature* creature) { creature->CallAssistance(); - return 0; } /** @@ -1197,21 +1040,17 @@ namespace LuaCreature * * @param float radius */ - int CallForHelp(lua_State* L, Creature* creature) + void CallForHelp(Creature* creature, float radius) { - 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) + void FleeToGetAssistance(Creature* creature) { creature->DoFleeToGetAssistance(); - return 0; } /** @@ -1219,21 +1058,18 @@ namespace LuaCreature * * @param [Unit] target */ - int AttackStart(lua_State* L, Creature* creature) + void AttackStart(Creature* creature, Unit* target) { - Unit* target = ALE::CHECKOBJ(L, 2); - - creature->AI()->AttackStart(target); - return 0; + if (creature->IsAIEnabled) + creature->AI()->AttackStart(target); } /** * Save the [Creature] in the database. */ - int SaveToDB(lua_State* /*L*/, Creature* creature) + void SaveToDB(Creature* creature) { creature->SaveToDB(); - return 0; } /** @@ -1241,10 +1077,9 @@ namespace LuaCreature * * This should be called every update cycle for the Creature's AI. */ - int SelectVictim(lua_State* L, Creature* creature) + Unit* SelectVictim(Creature* creature) { - ALE::Push(L, creature->SelectVictim()); - return 1; + return creature->SelectVictim(); } /** @@ -1253,22 +1088,19 @@ namespace LuaCreature * @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) + void UpdateEntry(Creature* creature, uint32 entry, sol::optional dataGuidLowArg) { - uint32 entry = ALE::CHECKVAL(L, 2); - uint32 dataGuidLow = ALE::CHECKVAL(L, 3, 0); + uint32 dataGuidLow = dataGuidLowArg.value_or(0); - creature->UpdateEntry(entry, dataGuidLow ? eObjectMgr->GetCreatureData(dataGuidLow) : NULL); - return 0; + creature->UpdateEntry(entry, dataGuidLow ? sObjectMgr->GetCreatureData(dataGuidLow) : nullptr); } /** * Resets [Creature]'s loot mode to default */ - int ResetLootMode(lua_State* /*L*/, Creature* creature) // TODO: Implement LootMode features + void ResetLootMode(Creature* creature) // TODO: Implement LootMode features { creature->ResetLootMode(); - return 0; } /** @@ -1276,12 +1108,9 @@ namespace LuaCreature * * @param uint16 lootMode */ - int RemoveLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features + void RemoveLootMode(Creature* creature, uint16 lootMode) // TODO: Implement LootMode features { - uint16 lootMode = ALE::CHECKVAL(L, 2); - creature->RemoveLootMode(lootMode); - return 0; } /** @@ -1289,12 +1118,9 @@ namespace LuaCreature * * @param uint16 lootMode */ - int AddLootMode(lua_State* L, Creature* creature) // TODO: Implement LootMode features + void AddLootMode(Creature* creature, uint16 lootMode) // TODO: Implement LootMode features { - uint16 lootMode = ALE::CHECKVAL(L, 2); - creature->AddLootMode(lootMode); - return 0; } /** @@ -1351,15 +1177,15 @@ namespace LuaCreature * * @return [CreatureFamily] creatureFamily */ - int GetCreatureFamily(lua_State* L, Creature* creature) + sol::optional GetCreatureFamily(Creature* creature) { uint32 entry = creature->GetEntry(); CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(entry); if (cInfo) - ALE::Push(L, cInfo->family); + return cInfo->family; - return 1; + return sol::nullopt; } /** @@ -1367,10 +1193,106 @@ namespace LuaCreature * * @return [Loot] loot : the loot object */ - int GetLoot(lua_State* L, Creature* creature) + Loot* GetLoot(Creature* creature) { - ALE::Push(L, &creature->loot); - return 1; + return &creature->loot; } -}; -#endif +} + +void RegisterCreatureMethods(sol::state& lua) +{ + sol::usertype type = ALEBind::NewHandleType(lua, "Creature"); + + type["IsRegeneratingHealth"] = ALEBind::Method(&LuaCreature::IsRegeneratingHealth); + type["SetRegeneratingHealth"] = ALEBind::Method(&LuaCreature::SetRegeneratingHealth); + type["IsReputationGainDisabled"] = ALEBind::Method(&LuaCreature::IsReputationGainDisabled); + type["CanCompleteQuest"] = ALEBind::Method(&LuaCreature::CanCompleteQuest); + type["IsTargetableForAttack"] = ALEBind::Method(&LuaCreature::IsTargetableForAttack); + type["CanAssistTo"] = ALEBind::Method(&LuaCreature::CanAssistTo); + type["HasSearchedAssistance"] = ALEBind::Method(&LuaCreature::HasSearchedAssistance); + type["IsTappedBy"] = ALEBind::Method(&LuaCreature::IsTappedBy); + type["HasLootRecipient"] = ALEBind::Method(&LuaCreature::HasLootRecipient); + type["CanAggro"] = ALEBind::Method(&LuaCreature::CanAggro); + type["CanSwim"] = ALEBind::Method(&LuaCreature::CanSwim); + type["CanWalk"] = ALEBind::Method(&LuaCreature::CanWalk); + type["IsInEvadeMode"] = ALEBind::Method(&LuaCreature::IsInEvadeMode); + type["IsElite"] = ALEBind::Method(&LuaCreature::IsElite); + type["IsGuard"] = ALEBind::Method(&LuaCreature::IsGuard); + type["IsCivilian"] = ALEBind::Method(&LuaCreature::IsCivilian); + type["IsRacialLeader"] = ALEBind::Method(&LuaCreature::IsRacialLeader); + type["IsDungeonBoss"] = ALEBind::Method(&LuaCreature::IsDungeonBoss); + type["IsWorldBoss"] = ALEBind::Method(&LuaCreature::IsWorldBoss); + type["HasCategoryCooldown"] = ALEBind::Method(&LuaCreature::HasCategoryCooldown); + type["HasSpell"] = ALEBind::Method(&LuaCreature::HasSpell); + type["HasQuest"] = ALEBind::Method(&LuaCreature::HasQuest); + type["HasSpellCooldown"] = ALEBind::Method(&LuaCreature::HasSpellCooldown); + type["CanFly"] = ALEBind::Method(&LuaCreature::CanFly); + type["IsTrigger"] = ALEBind::Method(&LuaCreature::IsTrigger); + type["IsDamageEnoughForLootingAndReward"] = ALEBind::Method(&LuaCreature::IsDamageEnoughForLootingAndReward); + type["CanStartAttack"] = ALEBind::Method(&LuaCreature::CanStartAttack); + type["HasLootMode"] = ALEBind::Method(&LuaCreature::HasLootMode); + type["GetRespawnDelay"] = ALEBind::Method(&LuaCreature::GetRespawnDelay); + type["GetWanderRadius"] = ALEBind::Method(&LuaCreature::GetWanderRadius); + type["GetWaypointPath"] = ALEBind::Method(&LuaCreature::GetWaypointPath); + type["GetCurrentWaypointId"] = ALEBind::Method(&LuaCreature::GetCurrentWaypointId); + type["GetSpawnId"] = ALEBind::Method(&LuaCreature::GetSpawnId); + type["GetDefaultMovementType"] = ALEBind::Method(&LuaCreature::GetDefaultMovementType); + type["GetAggroRange"] = ALEBind::Method(&LuaCreature::GetAggroRange); + type["GetLootRecipientGroup"] = ALEBind::Method(&LuaCreature::GetLootRecipientGroup); + type["GetLootRecipient"] = ALEBind::Method(&LuaCreature::GetLootRecipient); + type["GetScriptName"] = ALEBind::Method(&LuaCreature::GetScriptName); + type["GetAIName"] = ALEBind::Method(&LuaCreature::GetAIName); + type["GetScriptId"] = ALEBind::Method(&LuaCreature::GetScriptId); + type["GetCreatureSpellCooldownDelay"] = ALEBind::Method(&LuaCreature::GetCreatureSpellCooldownDelay); + type["GetCorpseDelay"] = ALEBind::Method(&LuaCreature::GetCorpseDelay); + type["GetHomePosition"] = ALEBind::Method(&LuaCreature::GetHomePosition); + type["SetHomePosition"] = ALEBind::Method(&LuaCreature::SetHomePosition); + type["GetAITarget"] = ALEBind::Method(&LuaCreature::GetAITarget); + type["GetAITargets"] = ALEBind::Method(&LuaCreature::GetAITargets); + type["GetAITargetsCount"] = ALEBind::Method(&LuaCreature::GetAITargetsCount); + type["GetNPCFlags"] = ALEBind::Method(&LuaCreature::GetNPCFlags); + type["GetUnitFlags"] = ALEBind::Method(&LuaCreature::GetUnitFlags); + type["GetUnitFlagsTwo"] = ALEBind::Method(&LuaCreature::GetUnitFlagsTwo); + type["GetExtraFlags"] = ALEBind::Method(&LuaCreature::GetExtraFlags); + type["GetRank"] = ALEBind::Method(&LuaCreature::GetRank); + type["GetShieldBlockValue"] = ALEBind::Method(&LuaCreature::GetShieldBlockValue); + type["GetLootMode"] = ALEBind::Method(&LuaCreature::GetLootMode); + type["GetDBTableGUIDLow"] = ALEBind::Method(&LuaCreature::GetDBTableGUIDLow); + type["GetReactState"] = ALEBind::Method(&LuaCreature::GetReactState); + type["SetNPCFlags"] = ALEBind::Method(&LuaCreature::SetNPCFlags); + type["SetUnitFlags"] = ALEBind::Method(&LuaCreature::SetUnitFlags); + type["SetUnitFlagsTwo"] = ALEBind::Method(&LuaCreature::SetUnitFlagsTwo); + type["SetReactState"] = ALEBind::Method(&LuaCreature::SetReactState); + type["SetDisableGravity"] = ALEBind::Method(&LuaCreature::SetDisableGravity); + type["SetLootMode"] = ALEBind::Method(&LuaCreature::SetLootMode); + type["SetDeathState"] = ALEBind::Method(&LuaCreature::SetDeathState); + type["SetWalk"] = ALEBind::Method(&LuaCreature::SetWalk); + type["SetEquipmentSlots"] = ALEBind::Method(&LuaCreature::SetEquipmentSlots); + type["SetAggroEnabled"] = ALEBind::Method(&LuaCreature::SetAggroEnabled); + type["SetDisableReputationGain"] = ALEBind::Method(&LuaCreature::SetDisableReputationGain); + type["SetInCombatWithZone"] = ALEBind::Method(&LuaCreature::SetInCombatWithZone); + type["SetWanderRadius"] = ALEBind::Method(&LuaCreature::SetWanderRadius); + type["SetRespawnDelay"] = ALEBind::Method(&LuaCreature::SetRespawnDelay); + type["SetDefaultMovementType"] = ALEBind::Method(&LuaCreature::SetDefaultMovementType); + type["SetNoSearchAssistance"] = ALEBind::Method(&LuaCreature::SetNoSearchAssistance); + type["SetNoCallAssistance"] = ALEBind::Method(&LuaCreature::SetNoCallAssistance); + type["SetHover"] = ALEBind::Method(&LuaCreature::SetHover); + type["DespawnOrUnsummon"] = ALEBind::Method(&LuaCreature::DespawnOrUnsummon); + type["Respawn"] = ALEBind::Method(&LuaCreature::Respawn); + type["RemoveCorpse"] = ALEBind::Method(&LuaCreature::RemoveCorpse); + type["AllLootRemovedFromCorpse"] = ALEBind::Method(&LuaCreature::AllLootRemovedFromCorpse); + type["SetCorpseDelay"] = ALEBind::Method(&LuaCreature::SetCorpseDelay); + type["MoveWaypoint"] = ALEBind::Method(&LuaCreature::MoveWaypoint); + type["CallAssistance"] = ALEBind::Method(&LuaCreature::CallAssistance); + type["CallForHelp"] = ALEBind::Method(&LuaCreature::CallForHelp); + type["FleeToGetAssistance"] = ALEBind::Method(&LuaCreature::FleeToGetAssistance); + type["AttackStart"] = ALEBind::Method(&LuaCreature::AttackStart); + type["SaveToDB"] = ALEBind::Method(&LuaCreature::SaveToDB); + type["SelectVictim"] = ALEBind::Method(&LuaCreature::SelectVictim); + type["UpdateEntry"] = ALEBind::Method(&LuaCreature::UpdateEntry); + type["ResetLootMode"] = ALEBind::Method(&LuaCreature::ResetLootMode); + type["RemoveLootMode"] = ALEBind::Method(&LuaCreature::RemoveLootMode); + type["AddLootMode"] = ALEBind::Method(&LuaCreature::AddLootMode); + type["GetCreatureFamily"] = ALEBind::Method(&LuaCreature::GetCreatureFamily); + type["GetLoot"] = ALEBind::Method(&LuaCreature::GetLoot); +} diff --git a/src/LuaEngine/methods/GameObjectMethods.h b/src/LuaEngine/methods/GameObjectMethods.cpp similarity index 59% rename from src/LuaEngine/methods/GameObjectMethods.h rename to src/LuaEngine/methods/GameObjectMethods.cpp index 43e8ffd33d..b03725e994 100644 --- a/src/LuaEngine/methods/GameObjectMethods.h +++ b/src/LuaEngine/methods/GameObjectMethods.cpp @@ -4,8 +4,17 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef GAMEOBJECTMETHODS_H -#define GAMEOBJECTMETHODS_H +#include "ALEBind.h" + +#include "DatabaseEnv.h" +#include "GameObject.h" +#include "Item.h" +#include "LootMgr.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "SharedDefines.h" +#include "StringFormat.h" +#include "Unit.h" /*** * Represents a game object in the world, such as doors, chests, and other interactive objects. @@ -20,12 +29,9 @@ namespace LuaGameObject * @param uint32 questId : quest entry Id to check * @return bool hasQuest */ - int HasQuest(lua_State* L, GameObject* go) + bool HasQuest(GameObject* go, uint32 questId) { - uint32 questId = ALE::CHECKVAL(L, 2); - - ALE::Push(L, go->hasQuest(questId)); - return 1; + return go->hasQuest(questId); } /** @@ -33,10 +39,9 @@ namespace LuaGameObject * * @return bool isSpawned */ - int IsSpawned(lua_State* L, GameObject* go) + bool IsSpawned(GameObject* go) { - ALE::Push(L, go->isSpawned()); - return 1; + return go->isSpawned(); } /** @@ -44,10 +49,9 @@ namespace LuaGameObject * * @return bool isTransport */ - int IsTransport(lua_State* L, GameObject* go) + bool IsTransport(GameObject* go) { - ALE::Push(L, go->IsTransport()); - return 1; + return go->IsTransport(); } /** @@ -55,16 +59,14 @@ namespace LuaGameObject * * @return bool isActive */ - int IsActive(lua_State* L, GameObject* go) + bool IsActive(GameObject* go) { - ALE::Push(L, go->isActiveObject()); - return 1; + return go->isActiveObject(); } - /*int IsDestructible(lua_State* L, GameObject* go) // TODO: Implementation core side + /*bool IsDestructible(GameObject* go) // TODO: Implementation core side { - ALE::Push(L, go->IsDestructibleBuilding()); - return 1; + return go->IsDestructibleBuilding(); }*/ /** @@ -72,10 +74,9 @@ namespace LuaGameObject * * @return uint32 displayId */ - int GetDisplayId(lua_State* L, GameObject* go) + uint32 GetDisplayId(GameObject* go) { - ALE::Push(L, go->GetDisplayId()); - return 1; + return go->GetDisplayId(); } /** @@ -93,10 +94,9 @@ namespace LuaGameObject * * @return [GOState] goState */ - int GetGoState(lua_State* L, GameObject* go) + GOState GetGoState(GameObject* go) { - ALE::Push(L, go->GetGoState()); - return 1; + return go->GetGoState(); } /** @@ -115,10 +115,9 @@ namespace LuaGameObject * * @return [LootState] lootState */ - int GetLootState(lua_State* L, GameObject* go) + LootState GetLootState(GameObject* go) { - ALE::Push(L, go->getLootState()); - return 1; + return go->getLootState(); } /** @@ -128,10 +127,9 @@ namespace LuaGameObject * * @return [Player] player */ - int GetLootRecipient(lua_State* L, GameObject* go) + Player* GetLootRecipient(GameObject* go) { - ALE::Push(L, go->GetLootRecipient()); - return 1; + return go->GetLootRecipient(); } /** @@ -141,10 +139,9 @@ namespace LuaGameObject * * @return [Group] group */ - int GetLootRecipientGroup(lua_State* L, GameObject* go) + Group* GetLootRecipientGroup(GameObject* go) { - ALE::Push(L, go->GetLootRecipientGroup()); - return 1; + return go->GetLootRecipientGroup(); } /** @@ -152,10 +149,9 @@ namespace LuaGameObject * * @return uint32 spawnId */ - int GetSpawnId(lua_State* L, GameObject* go) + uint32 GetSpawnId(GameObject* go) { - ALE::Push(L, go->GetSpawnId()); - return 1; + return go->GetSpawnId(); } /** @@ -172,9 +168,9 @@ namespace LuaGameObject * * @param [GOState] state : all available go states can be seen above */ - int SetGoState(lua_State* L, GameObject* go) + void SetGoState(GameObject* go, sol::optional stateArg) { - uint32 state = ALE::CHECKVAL(L, 2, 0); + uint32 state = stateArg.value_or(0); if (state == 0) go->SetGoState(GO_STATE_ACTIVE); @@ -182,8 +178,6 @@ namespace LuaGameObject go->SetGoState(GO_STATE_READY); else if (state == 2) go->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - - return 0; } /** @@ -202,9 +196,9 @@ namespace LuaGameObject * * @param [LootState] state : all available loot states can be seen above */ - int SetLootState(lua_State* L, GameObject* go) + void SetLootState(GameObject* go, sol::optional stateArg) { - uint32 state = ALE::CHECKVAL(L, 2, 0); + uint32 state = stateArg.value_or(0); if (state == 0) go->SetLootState(GO_NOT_READY); @@ -214,8 +208,6 @@ namespace LuaGameObject go->SetLootState(GO_ACTIVATED); else if (state == 3) go->SetLootState(GO_JUST_DEACTIVATED); - - return 0; } /** @@ -226,53 +218,55 @@ namespace LuaGameObject * @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) + sol::variadic_results AddLoot(GameObject* go, sol::variadic_args args, sol::this_state s) { - int i = 1; - int argAmount = lua_gettop(L); + sol::state_view lua(s); + sol::variadic_results results; - CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); - - uint8 addedItems = 0; - while (i + 2 <= argAmount) + // Validate every (entry, amount) pair before touching the DB or the + // loot, so an invalid pair cannot abort the call halfway through. + std::vector> lootItems; + for (std::size_t i = 0; i < args.size(); i += 2) { - uint32 entry = ALE::CHECKVAL(L, ++i); - uint32 amount = ALE::CHECKVAL(L, ++i); + uint32 entry = args[i].as(); + // A trailing entry without amount gets the documented default (1). + uint32 amount = i + 1 < args.size() ? args[i + 1].as() : 1; - ItemTemplate const* item_proto = eObjectMgr->GetItemTemplate(entry); + ItemTemplate const* item_proto = sObjectMgr->GetItemTemplate(entry); if (!item_proto) - { - luaL_error(L, "Item entry %d does not exist", entry); - continue; - } + throw std::runtime_error(Acore::StringFormat("Item entry {} does not exist", entry)); + 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; - } + throw std::runtime_error(Acore::StringFormat("Item entry {} has invalid amount {}", entry, amount)); + + lootItems.emplace_back(entry, amount); + } + + CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); + + for (auto const& [entry, amount] : lootItems) + { 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; + results.push_back(sol::make_object(lua, item->GetGUID().GetCounter())); } } CharacterDatabase.CommitTransaction(trans); - return addedItems; + return results; } /** * Saves [GameObject] to the database * */ - int SaveToDB(lua_State* /*L*/, GameObject* go) + void SaveToDB(GameObject* go) { go->SaveToDB(); - return 0; } /** @@ -282,17 +276,17 @@ namespace LuaGameObject * * @param bool deleteFromDB : if true, it will delete the [GameObject] from the database */ - int RemoveFromWorld(lua_State* L, GameObject* go) + void RemoveFromWorld(GameObject* go, sol::optional deleteFromDB) { - bool deldb = ALE::CHECKVAL(L, 2, false); + bool deldb = deleteFromDB.value_or(false); // cs_gobject.cpp copy paste ObjectGuid ownerGuid = go->GetOwnerGUID(); if (ownerGuid) { - Unit* owner = eObjectAccessor()GetUnit(*go, ownerGuid); + Unit* owner = ObjectAccessor::GetUnit(*go, ownerGuid); if (!owner || !ownerGuid.IsPlayer()) - return 0; + return; owner->RemoveGameObject(go, false); } @@ -302,9 +296,6 @@ namespace LuaGameObject go->SetRespawnTime(0); go->Delete(); - - ALE::CHECKOBJ(L, 1)->Invalidate(); - return 0; } /** @@ -312,12 +303,9 @@ namespace LuaGameObject * * @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) + void UseDoorOrButton(GameObject* go, sol::optional delay) { - uint32 delay = ALE::CHECKVAL(L, 2, 0); - - go->UseDoorOrButton(delay); - return 0; + go->UseDoorOrButton(delay.value_or(0)); } /** @@ -325,19 +313,17 @@ namespace LuaGameObject * * The gameobject may be automatically respawned by the core */ - int Despawn(lua_State* /*L*/, GameObject* go) + void Despawn(GameObject* go) { go->SetLootState(GO_JUST_DEACTIVATED); - return 0; } /** * Respawns a [GameObject] */ - int Respawn(lua_State* /*L*/, GameObject* go) + void Respawn(GameObject* go) { go->Respawn(); - return 0; } /** @@ -347,12 +333,9 @@ namespace LuaGameObject * * @param int32 delay = 0 : cooldown time in seconds to respawn or despawn the object. 0 means never */ - int SetRespawnTime(lua_State* L, GameObject* go) + void SetRespawnTime(GameObject* go, int32 respawn) { - int32 respawn = ALE::CHECKVAL(L, 2); - go->SetRespawnTime(respawn); - return 0; } /** @@ -362,12 +345,34 @@ namespace LuaGameObject * * @param int32 delay = 0 : cooldown time in seconds to respawn or despawn the object. 0 means never */ - int SetRespawnDelay(lua_State* L, GameObject* go) + void SetRespawnDelay(GameObject* go, int32 respawn) { - int32 respawn = ALE::CHECKVAL(L, 2); - go->SetRespawnDelay(respawn); - return 0; } -}; -#endif +} + +void RegisterGameObjectMethods(sol::state& lua) +{ + sol::usertype type = ALEBind::NewHandleType(lua, "GameObject"); + + type["HasQuest"] = ALEBind::Method(&LuaGameObject::HasQuest); + type["IsSpawned"] = ALEBind::Method(&LuaGameObject::IsSpawned); + type["IsTransport"] = ALEBind::Method(&LuaGameObject::IsTransport); + type["IsActive"] = ALEBind::Method(&LuaGameObject::IsActive); + type["GetDisplayId"] = ALEBind::Method(&LuaGameObject::GetDisplayId); + type["GetGoState"] = ALEBind::Method(&LuaGameObject::GetGoState); + type["GetLootState"] = ALEBind::Method(&LuaGameObject::GetLootState); + type["GetLootRecipient"] = ALEBind::Method(&LuaGameObject::GetLootRecipient); + type["GetLootRecipientGroup"] = ALEBind::Method(&LuaGameObject::GetLootRecipientGroup); + type["GetSpawnId"] = ALEBind::Method(&LuaGameObject::GetSpawnId); + type["SetGoState"] = ALEBind::Method(&LuaGameObject::SetGoState); + type["SetLootState"] = ALEBind::Method(&LuaGameObject::SetLootState); + type["AddLoot"] = ALEBind::Method(&LuaGameObject::AddLoot); + type["SaveToDB"] = ALEBind::Method(&LuaGameObject::SaveToDB); + type["RemoveFromWorld"] = ALEBind::Method(&LuaGameObject::RemoveFromWorld); + type["UseDoorOrButton"] = ALEBind::Method(&LuaGameObject::UseDoorOrButton); + type["Despawn"] = ALEBind::Method(&LuaGameObject::Despawn); + type["Respawn"] = ALEBind::Method(&LuaGameObject::Respawn); + type["SetRespawnTime"] = ALEBind::Method(&LuaGameObject::SetRespawnTime); + type["SetRespawnDelay"] = ALEBind::Method(&LuaGameObject::SetRespawnDelay); +} diff --git a/src/LuaEngine/methods/GemPropertiesEntryMethods.h b/src/LuaEngine/methods/GemPropertiesEntryMethods.cpp similarity index 59% rename from src/LuaEngine/methods/GemPropertiesEntryMethods.h rename to src/LuaEngine/methods/GemPropertiesEntryMethods.cpp index b76edae2b9..47201472de 100644 --- a/src/LuaEngine/methods/GemPropertiesEntryMethods.h +++ b/src/LuaEngine/methods/GemPropertiesEntryMethods.cpp @@ -4,8 +4,10 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef GEMPROPERTIESENTRYMETHODS_H -#define GEMPROPERTIESENTRYMETHODS_H +#include "ALEBind.h" + +#include "Common.h" +#include "DBCStructure.h" /*** * Represents static gem data used in item enhancement, including spell enchantments triggered by socketed gems. @@ -20,15 +22,11 @@ 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) + uint32 GetId(GemPropertiesEntry* gempropertiesentry) { - ALE::Push(L, gemProperties->ID); - return 1; + return gempropertiesentry->ID; } /** @@ -38,11 +36,16 @@ namespace LuaGemPropertiesEntry * * @return uint32 spellitemenchantement : The spell item enchantment ID. */ - int GetSpellItemEnchantement(lua_State* L, GemPropertiesEntry* entry) + uint32 GetSpellItemEnchantement(GemPropertiesEntry* gempropertiesentry) { - ALE::Push(L, entry->spellitemenchantement); - return 1; + return gempropertiesentry->spellitemenchantement; } } -#endif +void RegisterGemPropertiesEntryMethods(sol::state& lua) +{ + sol::usertype type = lua.new_usertype("GemPropertiesEntry", sol::no_constructor); + + type["GetId"] = &LuaGemPropertiesEntry::GetId; + type["GetSpellItemEnchantement"] = &LuaGemPropertiesEntry::GetSpellItemEnchantement; +} diff --git a/src/LuaEngine/methods/GlobalMethods.h b/src/LuaEngine/methods/GlobalMethods.cpp similarity index 71% rename from src/LuaEngine/methods/GlobalMethods.h rename to src/LuaEngine/methods/GlobalMethods.cpp index cebb7bc6d6..b4b21b262a 100644 --- a/src/LuaEngine/methods/GlobalMethods.h +++ b/src/LuaEngine/methods/GlobalMethods.cpp @@ -4,18 +4,45 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef GLOBALMETHODS_H -#define GLOBALMETHODS_H +#include "ALEBind.h" +#include "LuaEngine.h" -#include "BindingMap.h" #include "ALEDBCRegistry.h" +#include "ALEEventMgr.h" #include "BanMgr.h" +#include "Config.h" +#include "DatabaseEnv.h" +#include "GameEventMgr.h" +#include "GameObject.h" #include "GameTime.h" -#include "SharedDefines.h" +#include "GitRevision.h" +#include "GuildMgr.h" +#include "Mail.h" +#include "MapMgr.h" +#include "ObjectAccessor.h" +#include "ObjectDefines.h" +#include "ObjectMgr.h" +#include "Opcodes.h" #include "OutdoorPvPMgr.h" +#include "QueryCallback.h" +#include "SharedDefines.h" +#include "SpellMgr.h" +#include "StringConvert.h" +#include "StringFormat.h" +#include "TemporarySummon.h" +#include "Util.h" +#include "WorldPacket.h" +#include "WorldSessionMgr.h" #include "../../../../src/server/scripts/OutdoorPvP/OutdoorPvPNA.h" +#include +#include +#include +#include +#include +#include +#include enum BanMode { @@ -36,10 +63,9 @@ namespace LuaGlobalFunctions * * @return string engineName */ - int GetLuaEngine(lua_State* L) + char const* GetLuaEngine() { - ALE::Push(L, "ALEEngine"); - return 1; + return "ALEEngine"; } /** @@ -49,10 +75,9 @@ namespace LuaGlobalFunctions * * @return string coreName */ - int GetCoreName(lua_State* L) + char const* GetCoreName() { - ALE::Push(L, CORE_NAME); - return 1; + return "AzerothCore"; } /** @@ -61,41 +86,28 @@ namespace LuaGlobalFunctions * @param string name : name of the value * @return string value */ - int GetConfigValue(lua_State* L) + sol::object GetConfigValue(std::string key, sol::this_state s) { - const char* key = ALE::CHECKVAL(L, 1); - if (!key) return 0; - + sol::state_view lua(s); + std::string val = sConfigMgr->GetOption(key, "", false); if (val.empty()) - { - ALE::Push(L, val); - return 1; - } + return sol::make_object(lua, val); std::string lower = val; std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); - + if (lower == "true") - { - ALE::Push(L, true); - return 1; - } + return sol::make_object(lua, true); else if (lower == "false") - { - ALE::Push(L, false); - return 1; - } - + return sol::make_object(lua, false); + auto intVal = Acore::StringTo(val); - if (intVal) { - ALE::Push(L, *intVal); - return 1; - } - - ALE::Push(L, val); - return 1; + if (intVal) + return sol::make_object(lua, *intVal); + + return sol::make_object(lua, val); } /** @@ -105,10 +117,9 @@ namespace LuaGlobalFunctions * - for TrinityCore returns the realmID as it is in the conf file. * @return uint32 realm ID */ - int GetRealmID(lua_State* L) + uint32 GetRealmID() { - ALE::Push(L, sConfigMgr->GetOption("RealmID", 1)); - return 1; + return sConfigMgr->GetOption("RealmID", 1); } /** @@ -120,10 +131,9 @@ namespace LuaGlobalFunctions * * @return string version */ - int GetCoreVersion(lua_State* L) + char const* GetCoreVersion() { - ALE::Push(L, CORE_VERSION); - return 1; + return GitRevision::GetFullVersion(); } /** @@ -133,22 +143,20 @@ namespace LuaGlobalFunctions * * @return int32 expansion */ - int GetCoreExpansion(lua_State* L) + int32 GetCoreExpansion() { - ALE::Push(L, 2); - return 1; + return 2; } - + /** * Returns the [Map] pointer of the Lua state. Returns null for the "World" state. * * @return [Map] map */ - int GetStateMap(lua_State* L) + Map* GetStateMap() { // Until AC supports multistate, this will always return nil - ALE::Push(L); - return 1; + return nullptr; } /** @@ -156,11 +164,10 @@ namespace LuaGlobalFunctions * * @return int32 mapId */ - int GetStateMapId(lua_State* L) + int32 GetStateMapId() { // Until AC supports multistate, this will always return -1 - ALE::Push(L, -1); - return 1; + return -1; } /** @@ -168,11 +175,10 @@ namespace LuaGlobalFunctions * * @return uint32 instanceId */ - int GetStateInstanceId(lua_State* L) + uint32 GetStateInstanceId() { // Until AC supports multistate, this will always return 0 - ALE::Push(L, 0); - return 1; + return 0; } /** @@ -181,12 +187,9 @@ namespace LuaGlobalFunctions * @param uint32 questId : [Quest] entry ID * @return [Quest] quest */ - int GetQuest(lua_State* L) + Quest* GetQuest(uint32 questId) { - uint32 questId = ALE::CHECKVAL(L, 1); - - ALE::Push(L, eObjectMgr->GetQuestTemplate(questId)); - return 1; + return const_cast(sObjectMgr->GetQuestTemplate(questId)); } /** @@ -195,11 +198,9 @@ namespace LuaGlobalFunctions * @param ObjectGuid guid : guid of the [Player], you can get it with [Object:GetGUID] * @return [Player] player */ - int GetPlayerByGUID(lua_State* L) + Player* GetPlayerByGUID(ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - ALE::Push(L, eObjectAccessor()FindPlayer(guid)); - return 1; + return ObjectAccessor::FindPlayer(guid); } /** @@ -208,11 +209,9 @@ namespace LuaGlobalFunctions * @param string name : name of the [Player] * @return [Player] player */ - int GetPlayerByName(lua_State* L) + Player* GetPlayerByName(std::string name) { - const char* name = ALE::CHECKVAL(L, 1); - ALE::Push(L, eObjectAccessor()FindPlayerByName(name)); - return 1; + return ObjectAccessor::FindPlayerByName(name); } /** @@ -220,10 +219,9 @@ namespace LuaGlobalFunctions * * @return uint32 time */ - int GetGameTime(lua_State* L) + int64 GetGameTime() { - ALE::Push(L, GameTime::GetGameTime().count()); - return 1; + return GameTime::GetGameTime().count(); } /** @@ -242,18 +240,17 @@ namespace LuaGlobalFunctions * @param bool onlyGM = false : optional check if GM only * @return table worldPlayers */ - int GetPlayersInWorld(lua_State* L) + sol::table GetPlayersInWorld(sol::optional teamArg, sol::optional onlyGMArg, sol::this_state s) { - uint32 team = ALE::CHECKVAL(L, 1, TEAM_NEUTRAL); - bool onlyGM = ALE::CHECKVAL(L, 2, false); + uint32 team = teamArg.value_or(TEAM_NEUTRAL); + bool onlyGM = onlyGMArg.value_or(false); - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; { std::shared_lock lock(*HashMapHolder::GetLock()); - const HashMapHolder::MapType& m = eObjectAccessor()GetPlayers(); + const HashMapHolder::MapType& m = ObjectAccessor::GetPlayers(); for (HashMapHolder::MapType::const_iterator it = m.begin(); it != m.end(); ++it) { if (Player* player = it->second) @@ -262,16 +259,12 @@ namespace LuaGlobalFunctions continue; if ((team == TEAM_NEUTRAL || player->GetTeamId() == team) && (!onlyGM || player->IsGameMaster())) - { - ALE::Push(L, player); - lua_rawseti(L, tbl, ++i); - } + tbl[++i] = PlayerRef(player); } } } - lua_settop(L, tbl); // push table to top of stack - return 1; + return tbl; } /** @@ -280,11 +273,9 @@ namespace LuaGlobalFunctions * @param string name * @return [Guild] guild : the Guild, or `nil` if it doesn't exist */ - int GetGuildByName(lua_State* L) + Guild* GetGuildByName(std::string name) { - const char* name = ALE::CHECKVAL(L, 1); - ALE::Push(L, eGuildMgr->GetGuildByName(name)); - return 1; + return sGuildMgr->GetGuildByName(name); } /** @@ -294,13 +285,11 @@ namespace LuaGlobalFunctions * @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) + Map* GetMapById(uint32 mapid, sol::optional instanceArg) { - uint32 mapid = ALE::CHECKVAL(L, 1); - uint32 instance = ALE::CHECKVAL(L, 2, 0); + uint32 instance = instanceArg.value_or(0); - ALE::Push(L, eMapMgr->FindMap(mapid, instance)); - return 1; + return sMapMgr->FindMap(mapid, instance); } /** @@ -309,12 +298,9 @@ namespace LuaGlobalFunctions * @param ObjectGuid guid : the guid of a [Guild] leader * @return [Guild] guild, or `nil` if it doesn't exist */ - int GetGuildByLeaderGUID(lua_State* L) + Guild* GetGuildByLeaderGUID(ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - - ALE::Push(L, eGuildMgr->GetGuildByLeader(guid)); - return 1; + return sGuildMgr->GetGuildByLeader(guid); } /** @@ -322,10 +308,9 @@ namespace LuaGlobalFunctions * * @return uint32 count */ - int GetPlayerCount(lua_State* L) + uint32 GetPlayerCount() { - ALE::Push(L, eWorldSessionMgr->GetActiveSessionCount()); - return 1; + return sWorldSessionMgr->GetActiveSessionCount(); } /** @@ -338,11 +323,9 @@ namespace LuaGlobalFunctions * @param uint32 lowguid : low GUID of the [Player] * @return ObjectGuid guid */ - int GetPlayerGUID(lua_State* L) + ObjectGuid GetPlayerGUID(uint32 lowguid) { - uint32 lowguid = ALE::CHECKVAL(L, 1); - ALE::Push(L, MAKE_NEW_GUID(lowguid, 0, HIGHGUID_PLAYER)); - return 1; + return ObjectGuid(HighGuid::Player, 0, lowguid); } /** @@ -354,11 +337,9 @@ namespace LuaGlobalFunctions * @param uint32 lowguid : low GUID of the [Item] * @return ObjectGuid guid */ - int GetItemGUID(lua_State* L) + ObjectGuid GetItemGUID(uint32 lowguid) { - uint32 lowguid = ALE::CHECKVAL(L, 1); - ALE::Push(L, MAKE_NEW_GUID(lowguid, 0, HIGHGUID_ITEM)); - return 1; + return ObjectGuid(HighGuid::Item, 0, lowguid); } /** @@ -367,11 +348,9 @@ namespace LuaGlobalFunctions * @param uint32 itemID : the item entry ID from `item_template` to look up * @return [ItemTemplate] itemTemplate */ - int GetItemTemplate(lua_State* L) + ItemTemplate* GetItemTemplate(uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 1); - ALE::Push(L, eObjectMgr->GetItemTemplate(entry)); - return 1; + return const_cast(sObjectMgr->GetItemTemplate(entry)); } /** @@ -385,12 +364,9 @@ namespace LuaGlobalFunctions * @param uint32 entry : entry ID of the [GameObject] * @return ObjectGuid guid */ - int GetObjectGUID(lua_State* L) + ObjectGuid GetObjectGUID(uint32 lowguid, uint32 entry) { - uint32 lowguid = ALE::CHECKVAL(L, 1); - uint32 entry = ALE::CHECKVAL(L, 2); - ALE::Push(L, MAKE_NEW_GUID(lowguid, entry, HIGHGUID_GAMEOBJECT)); - return 1; + return ObjectGuid(HighGuid::GameObject, entry, lowguid); } /** @@ -404,12 +380,9 @@ namespace LuaGlobalFunctions * @param uint32 entry : entry ID of the [Creature] * @return ObjectGuid guid */ - int GetUnitGUID(lua_State* L) + ObjectGuid GetUnitGUID(uint32 lowguid, uint32 entry) { - uint32 lowguid = ALE::CHECKVAL(L, 1); - uint32 entry = ALE::CHECKVAL(L, 2); - ALE::Push(L, MAKE_NEW_GUID(lowguid, entry, HIGHGUID_UNIT)); - return 1; + return ObjectGuid(HighGuid::Unit, entry, lowguid); } /** @@ -431,12 +404,9 @@ namespace LuaGlobalFunctions * @param ObjectGuid guid : GUID of an [Object] * @return uint32 lowguid : low GUID of the [Object] */ - int GetGUIDLow(lua_State* L) + uint32 GetGUIDLow(ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - - ALE::Push(L, guid.GetCounter()); - return 1; + return guid.GetCounter(); } /** @@ -459,19 +429,18 @@ namespace LuaGlobalFunctions * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the [Item] name in * @return string itemLink */ - int GetItemLink(lua_State* L) + std::string GetItemLink(uint32 entry, sol::optional localeArg) { - uint32 entry = ALE::CHECKVAL(L, 1); - uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE); + uint8 locale = localeArg.value_or(DEFAULT_LOCALE); if (locale >= TOTAL_LOCALES) - return luaL_argerror(L, 2, "valid LocaleConstant expected"); + throw std::invalid_argument("valid LocaleConstant expected"); - const ItemTemplate* temp = eObjectMgr->GetItemTemplate(entry); + const ItemTemplate* temp = sObjectMgr->GetItemTemplate(entry); if (!temp) - return luaL_argerror(L, 1, "valid ItemEntry expected"); + throw std::invalid_argument("valid ItemEntry expected"); std::string name = temp->Name1; - if (ItemLocale const* il = eObjectMgr->GetItemLocale(entry)) + if (ItemLocale const* il = sObjectMgr->GetItemLocale(entry)) ObjectMgr::GetLocaleString(il->Name, static_cast(locale), name); std::ostringstream oss; @@ -480,8 +449,7 @@ namespace LuaGlobalFunctions "0:0:0:0:" << "0:0:0:0|h[" << name << "]|h|r"; - ALE::Push(L, oss.str()); - return 1; + return oss.str(); } /** @@ -494,11 +462,9 @@ namespace LuaGlobalFunctions * @param ObjectGuid guid : GUID of an [Object] * @return int32 typeId : type ID of the [Object] */ - int GetGUIDType(lua_State* L) + int32 GetGUIDType(ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - ALE::Push(L, static_cast(guid.GetHigh())); - return 1; + return static_cast(guid.GetHigh()); } /** @@ -509,11 +475,9 @@ namespace LuaGlobalFunctions * @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) + uint32 GetGUIDEntry(ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 1); - ALE::Push(L, guid.GetEntry()); - return 1; + return guid.GetEntry(); } /** @@ -522,12 +486,10 @@ namespace LuaGlobalFunctions * @param ObjectGuid guid : the ObjectGuid to get packed size for * @return number size */ - int GetPackedGUIDSize(lua_State* L) + int32 GetPackedGUIDSize(ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 1); PackedGuid packedGuid(guid); - ALE::Push(L, static_cast(packedGuid.size())); - return 1; + return static_cast(packedGuid.size()); } /** @@ -550,20 +512,18 @@ namespace LuaGlobalFunctions * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the name in * @return string areaOrZoneName */ - int GetAreaName(lua_State* L) + char const* GetAreaName(uint32 areaOrZoneId, sol::optional localeArg) { - uint32 areaOrZoneId = ALE::CHECKVAL(L, 1); - uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE); + uint8 locale = localeArg.value_or(DEFAULT_LOCALE); if (locale >= TOTAL_LOCALES) - return luaL_argerror(L, 2, "valid LocaleConstant expected"); + throw std::invalid_argument("valid LocaleConstant expected"); AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaOrZoneId); if (!areaEntry) - return luaL_argerror(L, 1, "valid Area or Zone ID expected"); + throw std::invalid_argument("valid Area or Zone ID expected"); - ALE::Push(L, areaEntry->area_name[locale]); - return 1; + return areaEntry->area_name[locale]; } /** @@ -571,71 +531,35 @@ namespace LuaGlobalFunctions * * @return table activeEvents */ - int GetActiveGameEvents(lua_State* L) + sol::table GetActiveGameEvents(sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 counter = 1; - GameEventMgr::ActiveEvents const& activeEvents = eGameEventMgr->GetActiveEventList(); + GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr->GetActiveEventList(); for (GameEventMgr::ActiveEvents::const_iterator i = activeEvents.begin(); i != activeEvents.end(); ++i) { - ALE::Push(L, *i); - lua_rawseti(L, tbl, counter); + tbl[counter] = *i; counter++; } - lua_settop(L, tbl); - return 1; + return tbl; } - static int RegisterEntryHelper(lua_State* L, int regtype) + static sol::object RegisterEntryHelper(uint8 regtype, uint32 id, uint32 ev, sol::protected_function callback, sol::optional shots) { - 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; + return sALE->Register(regtype, id, ObjectGuid::Empty, 0, ev, std::move(callback), shots.value_or(0)); } - static int RegisterEventHelper(lua_State* L, int regtype) + static sol::object RegisterEventHelper(uint8 regtype, uint32 ev, sol::protected_function callback, sol::optional shots) { - 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; + return sALE->Register(regtype, 0, ObjectGuid::Empty, 0, ev, std::move(callback), shots.value_or(0)); } - static int RegisterUniqueHelper(lua_State* L, int regtype) + static sol::object RegisterUniqueHelper(uint8 regtype, ObjectGuid guid, uint32 instanceId, uint32 ev, sol::protected_function callback, sol::optional shots) { - 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; + return sALE->Register(regtype, 0, guid, instanceId, ev, std::move(callback), shots.value_or(0)); } /** @@ -708,9 +632,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterServerEvent(lua_State* L) + sol::object RegisterServerEvent(uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEventHelper(L, Hooks::REGTYPE_SERVER); + return RegisterEventHelper(Hooks::REGTYPE_SERVER, event, std::move(callback), shots); } /** @@ -806,9 +730,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterPlayerEvent(lua_State* L) + sol::object RegisterPlayerEvent(uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEventHelper(L, Hooks::REGTYPE_PLAYER); + return RegisterEventHelper(Hooks::REGTYPE_PLAYER, event, std::move(callback), shots); } /** @@ -843,9 +767,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterGuildEvent(lua_State* L) + sol::object RegisterGuildEvent(uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEventHelper(L, Hooks::REGTYPE_GUILD); + return RegisterEventHelper(Hooks::REGTYPE_GUILD, event, std::move(callback), shots); } /** @@ -875,9 +799,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterGroupEvent(lua_State* L) + sol::object RegisterGroupEvent(uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEventHelper(L, Hooks::REGTYPE_GROUP); + return RegisterEventHelper(Hooks::REGTYPE_GROUP, event, std::move(callback), shots); } /** @@ -903,9 +827,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterBGEvent(lua_State* L) + sol::object RegisterBGEvent(uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEventHelper(L, Hooks::REGTYPE_BG); + return RegisterEventHelper(Hooks::REGTYPE_BG, event, std::move(callback), shots); } /** @@ -932,9 +856,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterPacketEvent(lua_State* L) + sol::object RegisterPacketEvent(uint32 entry, uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEntryHelper(L, Hooks::REGTYPE_PACKET); + return RegisterEntryHelper(Hooks::REGTYPE_PACKET, entry, event, std::move(callback), shots); } /** @@ -959,9 +883,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterCreatureGossipEvent(lua_State* L) + sol::object RegisterCreatureGossipEvent(uint32 entry, uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEntryHelper(L, Hooks::REGTYPE_CREATURE_GOSSIP); + return RegisterEntryHelper(Hooks::REGTYPE_CREATURE_GOSSIP, entry, event, std::move(callback), shots); } /** @@ -986,9 +910,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterGameObjectGossipEvent(lua_State* L) + sol::object RegisterGameObjectGossipEvent(uint32 entry, uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEntryHelper(L, Hooks::REGTYPE_GAMEOBJECT_GOSSIP); + return RegisterEntryHelper(Hooks::REGTYPE_GAMEOBJECT_GOSSIP, entry, event, std::move(callback), shots); } /** @@ -1016,9 +940,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterItemEvent(lua_State* L) + sol::object RegisterItemEvent(uint32 entry, uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEntryHelper(L, Hooks::REGTYPE_ITEM); + return RegisterEntryHelper(Hooks::REGTYPE_ITEM, entry, event, std::move(callback), shots); } /** @@ -1043,9 +967,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterItemGossipEvent(lua_State* L) + sol::object RegisterItemGossipEvent(uint32 entry, uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEntryHelper(L, Hooks::REGTYPE_ITEM_GOSSIP); + return RegisterEntryHelper(Hooks::REGTYPE_ITEM_GOSSIP, entry, event, std::move(callback), shots); } /** @@ -1070,9 +994,9 @@ namespace LuaGlobalFunctions * @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) + sol::object RegisterMapEvent(uint32 map_id, uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEntryHelper(L, Hooks::REGTYPE_MAP); + return RegisterEntryHelper(Hooks::REGTYPE_MAP, map_id, event, std::move(callback), shots); } /** @@ -1097,9 +1021,9 @@ namespace LuaGlobalFunctions * @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) + sol::object RegisterInstanceEvent(uint32 instance_id, uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEntryHelper(L, Hooks::REGTYPE_INSTANCE); + return RegisterEntryHelper(Hooks::REGTYPE_INSTANCE, instance_id, event, std::move(callback), shots); } /** @@ -1126,9 +1050,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterPlayerGossipEvent(lua_State* L) + sol::object RegisterPlayerGossipEvent(uint32 menu_id, uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEntryHelper(L, Hooks::REGTYPE_PLAYER_GOSSIP); + return RegisterEntryHelper(Hooks::REGTYPE_PLAYER_GOSSIP, menu_id, event, std::move(callback), shots); } /** @@ -1197,9 +1121,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterCreatureEvent(lua_State* L) + sol::object RegisterCreatureEvent(uint32 entry, uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEntryHelper(L, Hooks::REGTYPE_CREATURE); + return RegisterEntryHelper(Hooks::REGTYPE_CREATURE, entry, event, std::move(callback), shots); } /** @@ -1269,9 +1193,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterUniqueCreatureEvent(lua_State* L) + sol::object RegisterUniqueCreatureEvent(ObjectGuid guid, uint32 instance_id, uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterUniqueHelper(L, Hooks::REGTYPE_CREATURE); + return RegisterUniqueHelper(Hooks::REGTYPE_CREATURE, guid, instance_id, event, std::move(callback), shots); } /** @@ -1308,9 +1232,9 @@ namespace LuaGlobalFunctions * * @return function cancel : a function that cancels the binding when called */ - int RegisterGameObjectEvent(lua_State* L) + sol::object RegisterGameObjectEvent(uint32 entry, uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEntryHelper(L, Hooks::REGTYPE_GAMEOBJECT); + return RegisterEntryHelper(Hooks::REGTYPE_GAMEOBJECT, entry, event, std::move(callback), shots); } /** @@ -1332,9 +1256,9 @@ namespace LuaGlobalFunctions * @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) + sol::object RegisterTicketEvent(uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEventHelper(L, Hooks::REGTYPE_TICKET); + return RegisterEventHelper(Hooks::REGTYPE_TICKET, event, std::move(callback), shots); } /** @@ -1355,9 +1279,9 @@ namespace LuaGlobalFunctions * @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) + sol::object RegisterSpellEvent(uint32 entry, uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEntryHelper(L, Hooks::REGTYPE_SPELL); + return RegisterEntryHelper(Hooks::REGTYPE_SPELL, entry, event, std::move(callback), shots); } /** @@ -1387,18 +1311,26 @@ namespace LuaGlobalFunctions * @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) + sol::object RegisterAllCreatureEvent(uint32 event, sol::protected_function callback, sol::optional shots) { - return RegisterEventHelper(L, Hooks::REGTYPE_ALL_CREATURE); + return RegisterEventHelper(Hooks::REGTYPE_ALL_CREATURE, event, std::move(callback), shots); } /** * Reloads the Lua engine. */ - int ReloadALE(lua_State* /*L*/) + void ReloadALE() { ALE::ReloadALE(); - return 0; + } + + static void PrintRunCommandOutput(void* /*callbackArg*/, std::string_view view) + { + std::string str = { view.begin(), view.end() }; + // Remove trailing spaces and line breaks + while (!str.empty() && std::isspace(static_cast(str.back()))) + str.pop_back(); + ALE_LOG_INFO("{}", str); } /** @@ -1406,18 +1338,9 @@ namespace LuaGlobalFunctions * * @param string command : the command to run */ - int RunCommand(lua_State* L) + void RunCommand(std::string command) { - 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; + sWorld->QueueCliCommand(new CliCommandHolder(nullptr, command.c_str(), &PrintRunCommandOutput, nullptr)); } /** @@ -1425,45 +1348,23 @@ namespace LuaGlobalFunctions * * @param string message : message to send */ - int SendWorldMessage(lua_State* L) + void SendWorldMessage(std::string message) { - const char* message = ALE::CHECKVAL(L, 1); - eWorldSessionMgr->SendServerMessage(SERVER_MSG_STRING, message); - return 0; + sWorldSessionMgr->SendServerMessage(SERVER_MSG_STRING, message); } - template - static int DBQueryAsync(lua_State* L, DatabaseWorkerPool& db) + static void ForwardAsyncQueryResult(sol::protected_function callback, QueryResult result) { - 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); + LOCK_ALE; - // Push parameters - ALE::Push(L, eq); - - // Call function - ALE::GALE->ExecuteCall(1, 0); - - luaL_unref(L, LUA_REGISTRYINDEX, funcRef); - })); + sALE->CallFunction(callback, result); + } - return 0; + template + static void DBQueryAsync(DatabaseWorkerPool& db, std::string const& query, sol::protected_function callback) + { + sALE->queryProcessor.AddCallback(db.AsyncQuery(query.c_str()) + .WithCallback(std::bind(&ForwardAsyncQueryResult, std::move(callback), std::placeholders::_1))); } /** @@ -1484,20 +1385,9 @@ namespace LuaGlobalFunctions * @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) + QueryResult WorldDBQuery(std::string query) { - 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; + return WorldDatabase.Query(query.c_str()); } /** @@ -1519,9 +1409,9 @@ namespace LuaGlobalFunctions * @param string sql : query to execute * @param function callback : function that will be called when the results are available */ - int WorldDBQueryAsync(lua_State* L) + void WorldDBQueryAsync(std::string query, sol::protected_function callback) { - return DBQueryAsync(L, WorldDatabase); + DBQueryAsync(WorldDatabase, query, std::move(callback)); } /** @@ -1537,16 +1427,9 @@ namespace LuaGlobalFunctions * * @param string sql : query to execute */ - int WorldDBExecute(lua_State* L) + void WorldDBExecute(std::string query) { - 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; + WorldDatabase.Execute(query.c_str()); } /** @@ -1561,20 +1444,9 @@ namespace LuaGlobalFunctions * @param string sql : query to execute * @return [ALEQuery] results or nil if no rows found */ - int CharDBQuery(lua_State* L) + QueryResult CharDBQuery(std::string query) { - 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; + return CharacterDatabase.Query(query.c_str()); } /** @@ -1589,9 +1461,9 @@ namespace LuaGlobalFunctions * @param string sql : query to execute * @param function callback : function that will be called when the results are available */ - int CharDBQueryAsync(lua_State* L) + void CharDBQueryAsync(std::string query, sol::protected_function callback) { - return DBQueryAsync(L, CharacterDatabase); + DBQueryAsync(CharacterDatabase, query, std::move(callback)); } /** @@ -1607,16 +1479,9 @@ namespace LuaGlobalFunctions * * @param string sql : query to execute */ - int CharDBExecute(lua_State* L) + void CharDBExecute(std::string query) { - 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; + CharacterDatabase.Execute(query.c_str()); } /** @@ -1631,20 +1496,9 @@ namespace LuaGlobalFunctions * @param string sql : query to execute * @return [ALEQuery] results or nil if no rows found */ - int AuthDBQuery(lua_State* L) + QueryResult AuthDBQuery(std::string query) { - 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; + return LoginDatabase.Query(query.c_str()); } /** @@ -1659,9 +1513,9 @@ namespace LuaGlobalFunctions * @param string sql : query to execute * @param function callback : function that will be called when the results are available */ - int AuthDBQueryAsync(lua_State* L) + void AuthDBQueryAsync(std::string query, sol::protected_function callback) { - return DBQueryAsync(L, LoginDatabase); + DBQueryAsync(LoginDatabase, query, std::move(callback)); } /** @@ -1677,16 +1531,9 @@ namespace LuaGlobalFunctions * * @param string sql : query to execute */ - int AuthDBExecute(lua_State* L) + void AuthDBExecute(std::string query) { - 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; + LoginDatabase.Execute(query.c_str()); } /** @@ -1707,35 +1554,23 @@ namespace LuaGlobalFunctions * @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) + uint64 CreateLuaEvent(sol::protected_function callback, sol::object delay, sol::optional repeatsArg) { - luaL_checktype(L, 1, LUA_TFUNCTION); uint32 min, max; - if (lua_istable(L, 2)) + if (delay.is()) { - 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); + sol::table delayTable = delay.as(); + min = delayTable.get(1); + max = delayTable.get(2); } else - min = max = ALE::CHECKVAL(L, 2); - uint32 repeats = ALE::CHECKVAL(L, 3, 1); + min = max = delay.as(); + uint32 repeats = repeatsArg.value_or(1); if (min > max) - return luaL_argerror(L, 2, "min is bigger than max delay"); + throw std::invalid_argument("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; + return sALE->eventMgr->globalProcessor->AddEvent(std::move(callback), min, max, repeats); } /** @@ -1744,17 +1579,15 @@ namespace LuaGlobalFunctions * @param int eventId : event Id to remove * @param bool all_Events = false : remove from all events, not just global */ - int RemoveEventById(lua_State* L) + void RemoveEventById(uint64 eventId, sol::optional allEventsArg) { - int eventId = ALE::CHECKVAL(L, 1); - bool all_Events = ALE::CHECKVAL(L, 1, false); + bool all_Events = allEventsArg.value_or(false); // not thread safe if (all_Events) - ALE::GetALE(L)->eventMgr->SetState(eventId, LUAEVENT_STATE_ABORT); + sALE->eventMgr->SetState(eventId, LUAEVENT_STATE_ABORT); else - ALE::GetALE(L)->eventMgr->globalProcessor->SetState(eventId, LUAEVENT_STATE_ABORT); - return 0; + sALE->eventMgr->globalProcessor->SetState(eventId, LUAEVENT_STATE_ABORT); } /** @@ -1762,16 +1595,15 @@ namespace LuaGlobalFunctions * * @param bool all_Events = false : remove all events, not just global */ - int RemoveEvents(lua_State* L) + void RemoveEvents(sol::optional allEventsArg) { - bool all_Events = ALE::CHECKVAL(L, 1, false); + bool all_Events = allEventsArg.value_or(false); // not thread safe if (all_Events) - ALE::GetALE(L)->eventMgr->SetStates(LUAEVENT_STATE_ABORT); + sALE->eventMgr->SetStates(LUAEVENT_STATE_ABORT); else - ALE::GetALE(L)->eventMgr->globalProcessor->SetStates(LUAEVENT_STATE_ABORT); - return 0; + sALE->eventMgr->globalProcessor->SetStates(LUAEVENT_STATE_ABORT); } /** @@ -1790,33 +1622,20 @@ namespace LuaGlobalFunctions * @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); - + WorldObject* PerformIngameSpawn(int32 spawntype, uint32 entry, uint32 mapID, uint32 instanceID, + float x, float y, float z, float o, + sol::optional saveArg, sol::optional durorresptimeArg, sol::optional phaseArg) + { + bool save = saveArg.value_or(false); + uint32 durorresptime = durorresptimeArg.value_or(0); + uint32 phase = phaseArg.value_or(PHASEMASK_NORMAL); + if (!phase) - { - ALE::Push(L); - return 1; - } + return nullptr; - Map* map = eMapMgr->FindMap(mapID, instanceID); + Map* map = sMapMgr->FindMap(mapID, instanceID); if (!map) - { - ALE::Push(L); - return 1; - } + return nullptr; Position pos = { x, y, z, o }; @@ -1828,8 +1647,7 @@ namespace LuaGlobalFunctions if (!creature->Create(map->GenerateLowGuid(), map, phase, entry, 0, x, y, z, o)) { delete creature; - ALE::Push(L); - return 1; + return nullptr; } creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), phase); @@ -1845,47 +1663,35 @@ namespace LuaGlobalFunctions if (!creature->LoadCreatureFromDB(db_guid, map, true, true)) { delete creature; - ALE::Push(L); - return 1; + return nullptr; } - eObjectMgr->AddCreatureToGrid(db_guid, eObjectMgr->GetCreatureData(db_guid)); - ALE::Push(L, creature); + sObjectMgr->AddCreatureToGrid(db_guid, sObjectMgr->GetCreatureData(db_guid)); + return creature; } else { - TempSummon* creature = map->SummonCreature(entry, pos, NULL, durorresptime); + TempSummon* creature = map->SummonCreature(entry, pos, nullptr, durorresptime); if (!creature) - { - ALE::Push(L); - return 1; - } + return nullptr; if (durorresptime) creature->SetTempSummonType(TEMPSUMMON_TIMED_OR_DEAD_DESPAWN); else creature->SetTempSummonType(TEMPSUMMON_MANUAL_DESPAWN); - ALE::Push(L, creature); + return creature; } - - return 1; } if (spawntype == 2) // Spawn object { - const GameObjectTemplate* objectInfo = eObjectMgr->GetGameObjectTemplate(entry); + const GameObjectTemplate* objectInfo = sObjectMgr->GetGameObjectTemplate(entry); if (!objectInfo) - { - ALE::Push(L); - return 1; - } + return nullptr; if (objectInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(objectInfo->displayId)) - { - ALE::Push(L); - return 1; - } + return nullptr; GameObject* object = new GameObject; uint32 guidLow = map->GenerateLowGuid(); @@ -1893,8 +1699,7 @@ namespace LuaGlobalFunctions 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; + return nullptr; } if (durorresptime) @@ -1915,19 +1720,16 @@ namespace LuaGlobalFunctions if (!object->LoadGameObjectFromDB(guidLow, map, true)) { delete object; - ALE::Push(L); - return 1; + return nullptr; } - eObjectMgr->AddGameobjectToGrid(guidLow, eObjectMgr->GetGameObjectData(guidLow)); + sObjectMgr->AddGameobjectToGrid(guidLow, sObjectMgr->GetGameObjectData(guidLow)); } else map->AddToMap(object); - ALE::Push(L, object); - return 1; + return object; } - ALE::Push(L); - return 1; + return nullptr; } /** @@ -1937,15 +1739,12 @@ namespace LuaGlobalFunctions * @param uint32 size : the size of the packet * @return [WorldPacket] packet */ - int CreatePacket(lua_State* L) + WorldPacket CreatePacket(uint32 opcode, size_t size) { - 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"); + throw std::invalid_argument("valid opcode expected"); - ALE::Push(L, new WorldPacket((OpcodesList)opcode, size)); - return 1; + return WorldPacket(static_cast(opcode), size); } /** @@ -1957,19 +1756,11 @@ namespace LuaGlobalFunctions * @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) + void AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedcost) { - 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; + if (!sObjectMgr->IsVendorItemValid(entry, item, maxcount, incrtime, extendedcost)) + return; + sObjectMgr->AddVendorItem(entry, item, maxcount, incrtime, extendedcost); } /** @@ -1978,15 +1769,12 @@ namespace LuaGlobalFunctions * @param uint32 entry : [Creature] entry Id * @param uint32 item : [Item] entry Id */ - int VendorRemoveItem(lua_State* L) + void VendorRemoveItem(uint32 entry, uint32 item) { - uint32 entry = ALE::CHECKVAL(L, 1); - uint32 item = ALE::CHECKVAL(L, 2); - if (!eObjectMgr->GetCreatureTemplate(entry)) - return luaL_argerror(L, 1, "valid CreatureEntry expected"); + if (!sObjectMgr->GetCreatureTemplate(entry)) + throw std::invalid_argument("valid CreatureEntry expected"); - eObjectMgr->RemoveVendorItem(entry, item); - return 0; + sObjectMgr->RemoveVendorItem(entry, item); } /** @@ -1994,18 +1782,15 @@ namespace LuaGlobalFunctions * * @param uint32 entry : [Creature] entry Id */ - int VendorRemoveAllItems(lua_State* L) + void VendorRemoveAllItems(uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 1); - - VendorItemData const* items = eObjectMgr->GetNpcVendorItemList(entry); + VendorItemData const* items = sObjectMgr->GetNpcVendorItemList(entry); if (!items || items->Empty()) - return 0; + return; auto const& itemlist = items->m_items; for (auto itr = itemlist.rbegin(); itr != itemlist.rend(); ++itr) - eObjectMgr->RemoveVendorItem(entry, (*itr)->item); - return 0; + sObjectMgr->RemoveVendorItem(entry, (*itr)->item); } /** @@ -2013,11 +1798,9 @@ namespace LuaGlobalFunctions * * @param [Player] player : [Player] to kick */ - int Kick(lua_State* L) + void Kick(Player* player) { - Player* player = ALE::CHECKOBJ(L, 1); player->GetSession()->KickPlayer(); - return 0; } /** @@ -2037,13 +1820,10 @@ namespace LuaGlobalFunctions * @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) + sol::optional Ban(int32 banMode, std::string nameOrIP, uint32 duration, sol::optional reasonArg, sol::optional whoBannedArg) { - 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, ""); + std::string reason = reasonArg.value_or(""); + std::string whoBanned = whoBannedArg.value_or(""); const int BAN_ACCOUNT = 0; const int BAN_CHARACTER = 1; @@ -2053,18 +1833,18 @@ namespace LuaGlobalFunctions { case BAN_ACCOUNT: if (!Utf8ToUpperOnlyLatin(nameOrIP)) - return luaL_argerror(L, 2, "invalid account name"); + throw std::invalid_argument("invalid account name"); break; case BAN_CHARACTER: if (!normalizePlayerName(nameOrIP)) - return luaL_argerror(L, 2, "invalid character name"); + throw std::invalid_argument("invalid character name"); break; case BAN_IP: if (!IsIPAddress(nameOrIP.c_str())) - return luaL_argerror(L, 2, "invalid ip"); + throw std::invalid_argument("invalid ip"); break; default: - return luaL_argerror(L, 1, "unknown banmode"); + throw std::invalid_argument("unknown banmode"); } BanReturn result; @@ -2084,28 +1864,23 @@ namespace LuaGlobalFunctions switch (result) { case BanReturn::BAN_SUCCESS: - ALE::Push(L, 0); - break; + return 0; case BanReturn::BAN_SYNTAX_ERROR: - ALE::Push(L, 1); - break; + return 1; case BanReturn::BAN_NOTFOUND: - ALE::Push(L, 2); - break; + return 2; case BanReturn::BAN_LONGER_EXISTS: - ALE::Push(L, 3); - break; + return 3; } - return 1; + return sol::nullopt; } /** * Saves all [Player]s. */ - int SaveAllPlayers(lua_State* /*L*/) + void SaveAllPlayers() { - eObjectAccessor()SaveAllPlayers(); - return 0; + ObjectAccessor::SaveAllPlayers(); } /** @@ -2137,18 +1912,15 @@ namespace LuaGlobalFunctions * @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) + sol::variadic_results SendMail(std::string subject, std::string text, uint32 receiverGUIDLow, + sol::optional senderGUIDLowArg, sol::optional stationaryArg, sol::optional delayArg, + sol::optional moneyArg, sol::optional codArg, sol::this_state s, sol::variadic_args itemArgs) { - 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); + uint32 senderGUIDLow = senderGUIDLowArg.value_or(0); + uint32 stationary = stationaryArg.value_or(MAIL_STATIONERY_DEFAULT); + uint32 delay = delayArg.value_or(0); + uint32 money = moneyArg.value_or(0); + uint32 cod = codArg.value_or(0); MailSender sender(MAIL_NORMAL, senderGUIDLow, (MailStationery)stationary); MailDraft draft(subject, text); @@ -2159,36 +1931,32 @@ namespace LuaGlobalFunctions draft.AddMoney(money); CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); + sol::variadic_results results; uint8 addedItems = 0; - while (addedItems <= MAX_MAIL_ITEMS && i + 2 <= argAmount) + std::size_t argIndex = 0; + while (addedItems <= MAX_MAIL_ITEMS && argIndex + 2 <= itemArgs.size()) { - uint32 entry = ALE::CHECKVAL(L, ++i); - uint32 amount = ALE::CHECKVAL(L, ++i); + uint32 entry = itemArgs.get(argIndex++); + uint32 amount = itemArgs.get(argIndex++); - ItemTemplate const* item_proto = eObjectMgr->GetItemTemplate(entry); + ItemTemplate const* item_proto = sObjectMgr->GetItemTemplate(entry); if (!item_proto) - { - luaL_error(L, "Item entry %d does not exist", entry); - continue; - } + throw std::runtime_error(Acore::StringFormat("Item entry {} does not exist", entry)); 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; - } + throw std::runtime_error(Acore::StringFormat("Item entry {} has invalid amount {}", entry, amount)); if (Item* item = Item::CreateItem(entry, amount)) { item->SaveToDB(trans); draft.AddItem(item); - ALE::Push(L, item->GetGUID().GetCounter()); + results.push_back(sol::make_object(s, item->GetGUID().GetCounter())); ++addedItems; } } - Player* receiverPlayer = eObjectAccessor()FindPlayer(MAKE_NEW_GUID(receiverGUIDLow, 0, HIGHGUID_PLAYER)); + Player* receiverPlayer = ObjectAccessor::FindPlayer(ObjectGuid(HighGuid::Player, 0, receiverGUIDLow)); draft.SendMailTo(trans, MailReceiver(receiverPlayer, receiverGUIDLow), sender, MAIL_CHECK_MASK_NONE, delay); CharacterDatabase.CommitTransaction(trans); - return addedItems; + return results; } /** @@ -2198,12 +1966,9 @@ namespace LuaGlobalFunctions * @param uint32 b * @return uint32 result */ - int bit_and(lua_State* L) + uint32 bit_and(uint32 a, uint32 b) { - uint32 a = ALE::CHECKVAL(L, 1); - uint32 b = ALE::CHECKVAL(L, 2); - ALE::Push(L, a & b); - return 1; + return a & b; } /** @@ -2213,12 +1978,9 @@ namespace LuaGlobalFunctions * @param uint32 b * @return uint32 result */ - int bit_or(lua_State* L) + uint32 bit_or(uint32 a, uint32 b) { - uint32 a = ALE::CHECKVAL(L, 1); - uint32 b = ALE::CHECKVAL(L, 2); - ALE::Push(L, a | b); - return 1; + return a | b; } /** @@ -2228,12 +1990,9 @@ namespace LuaGlobalFunctions * @param uint32 b * @return uint32 result */ - int bit_lshift(lua_State* L) + uint32 bit_lshift(uint32 a, uint32 b) { - uint32 a = ALE::CHECKVAL(L, 1); - uint32 b = ALE::CHECKVAL(L, 2); - ALE::Push(L, a << b); - return 1; + return a << b; } /** @@ -2243,12 +2002,9 @@ namespace LuaGlobalFunctions * @param uint32 b * @return uint32 result */ - int bit_rshift(lua_State* L) + uint32 bit_rshift(uint32 a, uint32 b) { - uint32 a = ALE::CHECKVAL(L, 1); - uint32 b = ALE::CHECKVAL(L, 2); - ALE::Push(L, a >> b); - return 1; + return a >> b; } /** @@ -2258,12 +2014,9 @@ namespace LuaGlobalFunctions * @param uint32 b * @return uint32 result */ - int bit_xor(lua_State* L) + uint32 bit_xor(uint32 a, uint32 b) { - uint32 a = ALE::CHECKVAL(L, 1); - uint32 b = ALE::CHECKVAL(L, 2); - ALE::Push(L, a ^ b); - return 1; + return a ^ b; } /** @@ -2272,11 +2025,9 @@ namespace LuaGlobalFunctions * @param uint32 a * @return uint32 result */ - int bit_not(lua_State* L) + uint32 bit_not(uint32 a) { - uint32 a = ALE::CHECKVAL(L, 1); - ALE::Push(L, ~a); - return 1; + return ~a; } /** @@ -2301,73 +2052,38 @@ namespace LuaGlobalFunctions * @param uint32 pathId = 0 : path Id of the taxi path * @return uint32 actualPathId */ - int AddTaxiPath(lua_State* L) + uint32 AddTaxiPath(sol::table waypoints, uint32 mountA, uint32 mountH, sol::optional priceArg, sol::optional pathIdArg) { - 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} + uint32 price = priceArg.value_or(0); + uint32 pathId = pathIdArg.value_or(0); 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) + std::size_t nodeCount = waypoints.size(); + for (std::size_t i = 1; i <= nodeCount; ++i) { - // 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"); + sol::optional node = waypoints.get>(i); + if (!node) + throw std::invalid_argument("table expected as waypoint"); + + if (node->size() < 4) // no mandatory args, dont add + throw std::invalid_argument("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); + entry.mapid = node->get(1); + entry.x = node->get(2); + entry.y = node->get(3); + entry.z = node->get(4); // optional - entry.actionFlag = ALE::CHECKVAL(L, start + 4, 0); - entry.delay = ALE::CHECKVAL(L, start + 5, 0); + entry.actionFlag = node->get_or(5, 0); + entry.delay = node->get_or(6, 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; + return pathId; if (!pathId) pathId = sTaxiPathNodesByPath.size(); if (sTaxiPathNodesByPath.size() <= pathId) @@ -2396,7 +2112,7 @@ namespace LuaGlobalFunctions sTaxiPathNodesByPath[pathId][index++] = new TaxiPathNodeEntry(entry); } if (startNode >= nodeId) - return 1; + return pathId; TaxiPathEntry* pathEntry = new TaxiPathEntry(); pathEntry->from = startNode; @@ -2406,8 +2122,7 @@ namespace LuaGlobalFunctions sTaxiPathStore.SetEntry(pathId, pathEntry); sTaxiPathSetBySource[startNode][nodeId - 1] = pathEntry; - ALE::Push(L, pathId); - return 1; + return pathId; } /** @@ -2415,11 +2130,10 @@ namespace LuaGlobalFunctions * * @return bool isCompatibilityMode */ - int IsCompatibilityMode(lua_State* L) + bool IsCompatibilityMode() { // Until AC supports multistate, this will always return true - ALE::Push(L, true); - return 1; + return true; } /** @@ -2448,13 +2162,9 @@ namespace LuaGlobalFunctions * @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) + bool IsInventoryPos(uint8 bag, uint8 slot) { - uint8 bag = ALE::CHECKVAL(L, 1); - uint8 slot = ALE::CHECKVAL(L, 2); - - ALE::Push(L, Player::IsInventoryPos(bag, slot)); - return 1; + return Player::IsInventoryPos(bag, slot); } /** @@ -2466,13 +2176,9 @@ namespace LuaGlobalFunctions * @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) + bool IsEquipmentPos(uint8 bag, uint8 slot) { - uint8 bag = ALE::CHECKVAL(L, 1); - uint8 slot = ALE::CHECKVAL(L, 2); - - ALE::Push(L, Player::IsEquipmentPos(bag, slot)); - return 1; + return Player::IsEquipmentPos(bag, slot); } /** @@ -2484,13 +2190,9 @@ namespace LuaGlobalFunctions * @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) + bool IsBankPos(uint8 bag, uint8 slot) { - uint8 bag = ALE::CHECKVAL(L, 1); - uint8 slot = ALE::CHECKVAL(L, 2); - - ALE::Push(L, Player::IsBankPos(bag, slot)); - return 1; + return Player::IsBankPos(bag, slot); } /** @@ -2502,13 +2204,9 @@ namespace LuaGlobalFunctions * @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) + bool IsBagPos(uint8 bag, uint8 slot) { - uint8 bag = ALE::CHECKVAL(L, 1); - uint8 slot = ALE::CHECKVAL(L, 2); - - ALE::Push(L, Player::IsBagPos((bag << 8) + slot)); - return 1; + return Player::IsBagPos((bag << 8) + slot); } /** @@ -2517,12 +2215,9 @@ namespace LuaGlobalFunctions * @param uint16 eventId : the event id to check. * @return bool isActive */ - int IsGameEventActive(lua_State* L) + bool IsGameEventActive(uint16 eventId) { - uint16 eventId = ALE::CHECKVAL(L, 1); - - ALE::Push(L, eGameEventMgr->IsActiveEvent(eventId)); - return 1; + return sGameEventMgr->IsActiveEvent(eventId); } /** @@ -2530,10 +2225,9 @@ namespace LuaGlobalFunctions * * @return uint32 currTime : the current time, in milliseconds */ - int GetCurrTime(lua_State* L) + uint32 GetCurrTime() { - ALE::Push(L, ALEUtil::GetCurrTime()); - return 1; + return ALEUtil::GetCurrTime(); } /** @@ -2542,23 +2236,20 @@ namespace LuaGlobalFunctions * @param uint32 oldTime : an old timestamp, in milliseconds * @return uint32 timeDiff : the difference, in milliseconds */ - int GetTimeDiff(lua_State* L) + uint32 GetTimeDiff(uint32 oldtimems) { - uint32 oldtimems = ALE::CHECKVAL(L, 1); - - ALE::Push(L, ALEUtil::GetTimeDiff(oldtimems)); - return 1; + return ALEUtil::GetTimeDiff(oldtimems); } - static std::string GetStackAsString(lua_State* L) + static std::string BuildLogString(sol::variadic_args const& args) { + sol::state_view lua(args.lua_state()); + sol::protected_function tostring = lua["tostring"]; + 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); - } + for (sol::stack_proxy arg : args) + oss << tostring(arg).get(); + return oss.str(); } @@ -2567,10 +2258,9 @@ namespace LuaGlobalFunctions * * @param ... */ - int PrintInfo(lua_State* L) + void PrintInfo(sol::variadic_args args) { - ALE_LOG_INFO("{}", GetStackAsString(L)); - return 0; + ALE_LOG_INFO("{}", BuildLogString(args)); } /** @@ -2578,10 +2268,9 @@ namespace LuaGlobalFunctions * * @param ... */ - int PrintError(lua_State* L) + void PrintError(sol::variadic_args args) { - ALE_LOG_ERROR("{}", GetStackAsString(L)); - return 0; + ALE_LOG_ERROR("{}", BuildLogString(args)); } /** @@ -2589,10 +2278,9 @@ namespace LuaGlobalFunctions * * @param ... */ - int PrintDebug(lua_State* L) + void PrintDebug(sol::variadic_args args) { - ALE_LOG_DEBUG("{}", GetStackAsString(L)); - return 0; + ALE_LOG_DEBUG("{}", BuildLogString(args)); } /** @@ -2601,13 +2289,11 @@ namespace LuaGlobalFunctions * @param uint16 eventId : the event id to start. * @param bool force = false : set `true` to force start the event. */ - int StartGameEvent(lua_State* L) + void StartGameEvent(uint16 eventId, sol::optional forceArg) { - uint16 eventId = ALE::CHECKVAL(L, 1); - bool force = ALE::CHECKVAL(L, 2, false); + bool force = forceArg.value_or(false); - eGameEventMgr->StartEvent(eventId, force); - return 0; + sGameEventMgr->StartEvent(eventId, force); } /** @@ -2616,13 +2302,11 @@ namespace LuaGlobalFunctions * @param uint16 eventId : the event id to stop. * @param bool force = false : set `true` to force stop the event. */ - int StopGameEvent(lua_State* L) + void StopGameEvent(uint16 eventId, sol::optional forceArg) { - uint16 eventId = ALE::CHECKVAL(L, 1); - bool force = ALE::CHECKVAL(L, 2, false); + bool force = forceArg.value_or(false); - eGameEventMgr->StopEvent(eventId, force); - return 0; + sGameEventMgr->StopEvent(eventId, force); } /** @@ -2657,56 +2341,42 @@ namespace LuaGlobalFunctions * @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) + void HttpRequest(std::string httpVerb, std::string url, sol::object arg3, + sol::optional arg4, sol::optional arg5, sol::optional arg6) { - 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; + sol::object headersOrCallback = arg3; + sol::object callbackAfterHeaders = arg4.value_or(sol::object()); - if (!lua_istable(L, headersIdx) && lua_isstring(L, headersIdx) && lua_isstring(L, headersIdx + 1)) + if (arg3.get_type() == sol::type::string && arg4 && arg4->get_type() == sol::type::string) { - body = ALE::CHECKVAL(L, 3); - bodyContentType = ALE::CHECKVAL(L, 4); - headersIdx = 5; - callbackIdx = 5; + body = arg3.as(); + bodyContentType = arg4->as(); + headersOrCallback = arg5.value_or(sol::object()); + callbackAfterHeaders = arg6.value_or(sol::object()); } - if (lua_istable(L, headersIdx)) + sol::object callbackObject = headersOrCallback; + if (headersOrCallback.get_type() == sol::type::table) { - ++callbackIdx; - - lua_pushnil(L); // First key - while (lua_next(L, headersIdx) != 0) + sol::table headerTable = headersOrCallback.as(); + for (auto const& pair : headerTable) { - // 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); + if (pair.first.get_type() == sol::type::string + && (pair.second.get_type() == sol::type::string || pair.second.get_type() == sol::type::number)) + headers.insert(std::pair(pair.first.as(), pair.second.as())); } - } - 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"); + callbackObject = callbackAfterHeaders; } - return 0; + if (callbackObject.get_type() != sol::type::function) + throw std::invalid_argument("function expected for the HTTP request callback"); + + sALE->httpManager.PushRequest(new HttpWorkItem(callbackObject.as(), httpVerb, url, body, bodyContentType, headers)); } /** @@ -2723,22 +2393,21 @@ namespace LuaGlobalFunctions * @param string n_str * @return int64 value */ - int CreateLongLong(lua_State* L) + int64 CreateLongLong(sol::optional value) { long long init = 0; - if (lua_isstring(L, 1)) + if (value && value->get_type() == sol::type::string) { - std::string str = ALE::CHECKVAL(L, 1); + std::string str = value->as(); std::istringstream iss(str); iss >> init; if (iss.bad()) - return luaL_argerror(L, 1, "long long (as string) could not be converted"); + throw std::invalid_argument("long long (as string) could not be converted"); } - else if (!lua_isnoneornil(L, 1)) - init = ALE::CHECKVAL(L, 1); + else if (value && value->get_type() != sol::type::lua_nil) + init = value->as(); - ALE::Push(L, init); - return 1; + return init; } /** @@ -2755,22 +2424,21 @@ namespace LuaGlobalFunctions * @param string n_str * @return uint64 value */ - int CreateULongLong(lua_State* L) + uint64 CreateULongLong(sol::optional value) { unsigned long long init = 0; - if (lua_isstring(L, 1)) + if (value && value->get_type() == sol::type::string) { - std::string str = ALE::CHECKVAL(L, 1); + std::string str = value->as(); std::istringstream iss(str); iss >> init; if (iss.bad()) - return luaL_argerror(L, 1, "unsigned long long (as string) could not be converted"); + throw std::invalid_argument("unsigned long long (as string) could not be converted"); } - else if (!lua_isnoneornil(L, 1)) - init = ALE::CHECKVAL(L, 1); + else if (value && value->get_type() != sol::type::lua_nil) + init = value->as(); - ALE::Push(L, init); - return 1; + return init; } /** @@ -2784,20 +2452,19 @@ namespace LuaGlobalFunctions * @proto (event_type) * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterBGEvent] */ - int ClearBattleGroundEvents(lua_State* L) + void ClearBattleGroundEvents(sol::optional eventTypeArg) { typedef EventKey Key; - if (lua_isnoneornil(L, 1)) + if (!eventTypeArg) { - ALE::GetALE(L)->BGEventBindings->Clear(); + sALE->BGEventBindings->Clear(); } else { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->BGEventBindings->Clear(Key((Hooks::BGEvents)event_type)); + uint32 event_type = *eventTypeArg; + sALE->BGEventBindings->Clear(Key((Hooks::BGEvents)event_type)); } - return 0; } /** @@ -2815,25 +2482,20 @@ namespace LuaGlobalFunctions * @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) + void ClearCreatureEvents(uint32 entry, sol::optional eventTypeArg) { typedef EntryKey Key; - if (lua_isnoneornil(L, 2)) + if (!eventTypeArg) { - 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)); + sALE->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)); + uint32 event_type = *eventTypeArg; + sALE->CreatureEventBindings->Clear(Key((Hooks::CreatureEvents)event_type, entry)); } - return 0; } /** @@ -2852,27 +2514,20 @@ namespace LuaGlobalFunctions * @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) + void ClearUniqueCreatureEvents(ObjectGuid guid, uint32 instanceId, sol::optional eventTypeArg) { typedef UniqueObjectKey Key; - if (lua_isnoneornil(L, 3)) + if (!eventTypeArg) { - 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)); + sALE->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)); + uint32 event_type = *eventTypeArg; + sALE->CreatureUniqueBindings->Clear(Key((Hooks::CreatureEvents)event_type, guid, instanceId)); } - return 0; } /** @@ -2890,25 +2545,20 @@ namespace LuaGlobalFunctions * @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) + void ClearCreatureGossipEvents(uint32 entry, sol::optional eventTypeArg) { typedef EntryKey Key; - if (lua_isnoneornil(L, 2)) + if (!eventTypeArg) { - 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)); + sALE->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)); + uint32 event_type = *eventTypeArg; + sALE->CreatureGossipBindings->Clear(Key((Hooks::GossipEvents)event_type, entry)); } - return 0; } /** @@ -2926,25 +2576,20 @@ namespace LuaGlobalFunctions * @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) + void ClearGameObjectEvents(uint32 entry, sol::optional eventTypeArg) { typedef EntryKey Key; - if (lua_isnoneornil(L, 2)) + if (!eventTypeArg) { - 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)); + sALE->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)); + uint32 event_type = *eventTypeArg; + sALE->GameObjectEventBindings->Clear(Key((Hooks::GameObjectEvents)event_type, entry)); } - return 0; } /** @@ -2962,25 +2607,20 @@ namespace LuaGlobalFunctions * @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) + void ClearGameObjectGossipEvents(uint32 entry, sol::optional eventTypeArg) { typedef EntryKey Key; - if (lua_isnoneornil(L, 2)) + if (!eventTypeArg) { - 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)); + sALE->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)); + uint32 event_type = *eventTypeArg; + sALE->GameObjectGossipBindings->Clear(Key((Hooks::GossipEvents)event_type, entry)); } - return 0; } /** @@ -2994,20 +2634,19 @@ namespace LuaGlobalFunctions * @proto (event_type) * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterGroupEvent] */ - int ClearGroupEvents(lua_State* L) + void ClearGroupEvents(sol::optional eventTypeArg) { typedef EventKey Key; - if (lua_isnoneornil(L, 1)) + if (!eventTypeArg) { - ALE::GetALE(L)->GroupEventBindings->Clear(); + sALE->GroupEventBindings->Clear(); } else { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->GroupEventBindings->Clear(Key((Hooks::GroupEvents)event_type)); + uint32 event_type = *eventTypeArg; + sALE->GroupEventBindings->Clear(Key((Hooks::GroupEvents)event_type)); } - return 0; } /** @@ -3021,20 +2660,19 @@ namespace LuaGlobalFunctions * @proto (event_type) * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterGuildEvent] */ - int ClearGuildEvents(lua_State* L) + void ClearGuildEvents(sol::optional eventTypeArg) { typedef EventKey Key; - if (lua_isnoneornil(L, 1)) + if (!eventTypeArg) { - ALE::GetALE(L)->GuildEventBindings->Clear(); + sALE->GuildEventBindings->Clear(); } else { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->GuildEventBindings->Clear(Key((Hooks::GuildEvents)event_type)); + uint32 event_type = *eventTypeArg; + sALE->GuildEventBindings->Clear(Key((Hooks::GuildEvents)event_type)); } - return 0; } /** @@ -3052,25 +2690,20 @@ namespace LuaGlobalFunctions * @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) + void ClearItemEvents(uint32 entry, sol::optional eventTypeArg) { typedef EntryKey Key; - if (lua_isnoneornil(L, 2)) + if (!eventTypeArg) { - 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)); + sALE->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)); + uint32 event_type = *eventTypeArg; + sALE->ItemEventBindings->Clear(Key((Hooks::ItemEvents)event_type, entry)); } - return 0; } /** @@ -3088,25 +2721,20 @@ namespace LuaGlobalFunctions * @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) + void ClearItemGossipEvents(uint32 entry, sol::optional eventTypeArg) { typedef EntryKey Key; - if (lua_isnoneornil(L, 2)) + if (!eventTypeArg) { - 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)); + sALE->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)); + uint32 event_type = *eventTypeArg; + sALE->ItemGossipBindings->Clear(Key((Hooks::GossipEvents)event_type, entry)); } - return 0; } /** @@ -3121,25 +2749,20 @@ namespace LuaGlobalFunctions * @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) + void ClearPacketEvents(uint32 entry, sol::optional eventTypeArg) { typedef EntryKey Key; - if (lua_isnoneornil(L, 2)) + if (!eventTypeArg) { - 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)); + sALE->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)); + uint32 event_type = *eventTypeArg; + sALE->PacketEventBindings->Clear(Key((Hooks::PacketEvents)event_type, entry)); } - return 0; } /** @@ -3153,20 +2776,19 @@ namespace LuaGlobalFunctions * @proto (event_type) * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterPlayerEvent] */ - int ClearPlayerEvents(lua_State* L) + void ClearPlayerEvents(sol::optional eventTypeArg) { typedef EventKey Key; - if (lua_isnoneornil(L, 1)) + if (!eventTypeArg) { - ALE::GetALE(L)->PlayerEventBindings->Clear(); + sALE->PlayerEventBindings->Clear(); } else { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->PlayerEventBindings->Clear(Key((Hooks::PlayerEvents)event_type)); + uint32 event_type = *eventTypeArg; + sALE->PlayerEventBindings->Clear(Key((Hooks::PlayerEvents)event_type)); } - return 0; } /** @@ -3181,25 +2803,20 @@ namespace LuaGlobalFunctions * @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) + void ClearPlayerGossipEvents(uint32 entry, sol::optional eventTypeArg) { typedef EntryKey Key; - if (lua_isnoneornil(L, 2)) + if (!eventTypeArg) { - 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)); + sALE->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)); + uint32 event_type = *eventTypeArg; + sALE->PlayerGossipBindings->Clear(Key((Hooks::GossipEvents)event_type, entry)); } - return 0; } /** @@ -3213,20 +2830,19 @@ namespace LuaGlobalFunctions * @proto (event_type) * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterServerEvent] */ - int ClearServerEvents(lua_State* L) + void ClearServerEvents(sol::optional eventTypeArg) { typedef EventKey Key; - if (lua_isnoneornil(L, 1)) + if (!eventTypeArg) { - ALE::GetALE(L)->ServerEventBindings->Clear(); + sALE->ServerEventBindings->Clear(); } else { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->ServerEventBindings->Clear(Key((Hooks::ServerEvents)event_type)); + uint32 event_type = *eventTypeArg; + sALE->ServerEventBindings->Clear(Key((Hooks::ServerEvents)event_type)); } - return 0; } /** @@ -3241,26 +2857,20 @@ namespace LuaGlobalFunctions * @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) + void ClearMapEvents(uint32 entry, sol::optional eventTypeArg) { typedef EntryKey Key; - if (lua_isnoneornil(L, 2)) + if (!eventTypeArg) { - 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)); + sALE->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)); + uint32 event_type = *eventTypeArg; + sALE->MapEventBindings->Clear(Key((Hooks::InstanceEvents)event_type, entry)); } - - return 0; } /** @@ -3275,26 +2885,20 @@ namespace LuaGlobalFunctions * @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) + void ClearInstanceEvents(uint32 entry, sol::optional eventTypeArg) { typedef EntryKey Key; - if (lua_isnoneornil(L, 2)) + if (!eventTypeArg) { - 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)); + sALE->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)); + uint32 event_type = *eventTypeArg; + sALE->InstanceEventBindings->Clear(Key((Hooks::InstanceEvents)event_type, entry)); } - - return 0; } /** @@ -3308,20 +2912,19 @@ namespace LuaGlobalFunctions * @proto (event_type) * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterTicketEvent] */ - int ClearTicketEvents(lua_State* L) + void ClearTicketEvents(sol::optional eventTypeArg) { typedef EventKey Key; - if (lua_isnoneornil(L, 1)) + if (!eventTypeArg) { - ALE::GetALE(L)->TicketEventBindings->Clear(); + sALE->TicketEventBindings->Clear(); } else { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->TicketEventBindings->Clear(Key((Hooks::TicketEvents)event_type)); + uint32 event_type = *eventTypeArg; + sALE->TicketEventBindings->Clear(Key((Hooks::TicketEvents)event_type)); } - return 0; } /** @@ -3337,25 +2940,20 @@ namespace LuaGlobalFunctions * @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) + void ClearSpellEvents(uint32 entry, sol::optional eventTypeArg) { typedef EntryKey Key; - if (lua_isnoneornil(L, 2)) + if (!eventTypeArg) { - 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)); + sALE->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)); + uint32 event_type = *eventTypeArg; + sALE->SpellEventBindings->Clear(Key((Hooks::SpellEvents)event_type, entry)); } - return 0; } /** @@ -3369,20 +2967,19 @@ namespace LuaGlobalFunctions * @proto (event_type) * @param uint32 event_type : the event whose handlers will be cleared, see [Global:RegisterAllCreatureEvent] */ - int ClearAllCreatureEvents(lua_State* L) + void ClearAllCreatureEvents(sol::optional eventTypeArg) { typedef EventKey Key; - if (lua_isnoneornil(L, 1)) + if (!eventTypeArg) { - ALE::GetALE(L)->AllCreatureEventBindings->Clear(); + sALE->AllCreatureEventBindings->Clear(); } else { - uint32 event_type = ALE::CHECKVAL(L, 1); - ALE::GetALE(L)->AllCreatureEventBindings->Clear(Key((Hooks::AllCreatureEvents)event_type)); + uint32 event_type = *eventTypeArg; + sALE->AllCreatureEventBindings->Clear(Key((Hooks::AllCreatureEvents)event_type)); } - return 0; } /** @@ -3396,14 +2993,12 @@ namespace LuaGlobalFunctions * @return int16 the ID of the team to own Halaa * @return float the slider position. */ - int GetOwnerHalaa(lua_State* L) + std::tuple GetOwnerHalaa() { OutdoorPvPNA* nagrandPvp = (OutdoorPvPNA*)sOutdoorPvPMgr->GetOutdoorPvPToZoneId(3518); OPvPCapturePointNA* halaa = nagrandPvp->GetCapturePoint(); - ALE::Push(L, halaa->GetControllingFaction()); - ALE::Push(L, halaa->GetSlider()); - return 2; + return std::tuple(halaa->GetControllingFaction(), halaa->GetSlider()); } /** @@ -3413,10 +3008,8 @@ namespace LuaGlobalFunctions * * @param uint16 teamId : the ID of the team to own Halaa */ - int SetOwnerHalaa(lua_State* L) + void SetOwnerHalaa(uint16 teamId) { - uint16 teamId = ALE::CHECKVAL(L, 1); - OutdoorPvPNA* nagrandPvp = (OutdoorPvPNA*)sOutdoorPvPMgr->GetOutdoorPvPToZoneId(3518); OPvPCapturePointNA* halaa = nagrandPvp->GetCapturePoint(); @@ -3430,10 +3023,8 @@ namespace LuaGlobalFunctions } else { - return luaL_argerror(L, 1, "0 for Alliance or 1 for Horde expected"); + throw std::invalid_argument("0 for Alliance or 1 for Horde expected"); } - - return 0; } /** @@ -3446,12 +3037,8 @@ namespace LuaGlobalFunctions * * @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) + std::tuple GetGossipMenuOptionLocale(uint32 menuId, uint32 optionId, uint8 locale) { - uint32 menuId = ALE::CHECKVAL(L, 1); - uint32 optionId = ALE::CHECKVAL(L, 2); - uint8 locale = ALE::CHECKVAL(L, 3); - std::string strOptionText; std::string strBoxText; @@ -3480,9 +3067,7 @@ namespace LuaGlobalFunctions } } - ALE::Push(L, strOptionText); - ALE::Push(L, strBoxText); - return 2; + return std::tuple(strOptionText, strBoxText); } /** @@ -3495,39 +3080,27 @@ namespace LuaGlobalFunctions * @return uint32 pos_z * @return uint32 pos_o */ - int GetMapEntrance(lua_State* L) + sol::optional> GetMapEntrance(uint32 mapId) { - 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 sol::nullopt; - return 5; + return std::tuple(at->target_X, at->target_Y, at->target_Z, at->target_Orientation); } - - /** + + /** * Get the [SpellInfo] for the specified [Spell] id * * @param uint32 spellId : the ID of the spell * @return [SpellInfo] spellInfo */ - int GetSpellInfo(lua_State* L) + SpellInfo* GetSpellInfo(uint32 spellId) { - uint32 spellId = ALE::CHECKVAL(L, 1); - ALE::Push(L, sSpellMgr->GetSpellInfo(spellId)); - return 1; - + return const_cast(sSpellMgr->GetSpellInfo(spellId)); } - + /** * Returns an entry from the specified DBC (DatabaseClient) store. * @@ -3538,10 +3111,9 @@ namespace LuaGlobalFunctions * * @return [DBCStore] store : The requested DBC store instance */ - int LookupEntry(lua_State* L) + sol::object LookupEntry(std::string dbcName, uint32 id, sol::this_state s) { - const char* dbcName = ALE::CHECKVAL(L, 1); - uint32 id = ALE::CHECKVAL(L, 2); + sol::state_view lua(s); for (const auto& dbc : dbcRegistry) { @@ -3549,14 +3121,137 @@ namespace LuaGlobalFunctions { const void* entry = dbc.lookupFunction(id); if (!entry) - return 0; + return sol::make_object(lua, sol::lua_nil); - dbc.pushFunction(L, entry); - return 1; + return dbc.makeObject(lua, entry); } } - return luaL_error(L, "Invalid DBC name: %s", dbcName); + throw std::runtime_error(Acore::StringFormat("Invalid DBC name: {}", dbcName)); } } -#endif + +void RegisterGlobalMethods(sol::state& lua) +{ + lua["GetLuaEngine"] = ALEBind::Function(&LuaGlobalFunctions::GetLuaEngine); + lua["GetCoreName"] = ALEBind::Function(&LuaGlobalFunctions::GetCoreName); + lua["GetConfigValue"] = ALEBind::Function(&LuaGlobalFunctions::GetConfigValue); + lua["GetRealmID"] = ALEBind::Function(&LuaGlobalFunctions::GetRealmID); + lua["GetCoreVersion"] = ALEBind::Function(&LuaGlobalFunctions::GetCoreVersion); + lua["GetCoreExpansion"] = ALEBind::Function(&LuaGlobalFunctions::GetCoreExpansion); + lua["GetStateMap"] = ALEBind::Function(&LuaGlobalFunctions::GetStateMap); + lua["GetStateMapId"] = ALEBind::Function(&LuaGlobalFunctions::GetStateMapId); + lua["GetStateInstanceId"] = ALEBind::Function(&LuaGlobalFunctions::GetStateInstanceId); + lua["GetQuest"] = ALEBind::Function(&LuaGlobalFunctions::GetQuest); + lua["GetPlayerByGUID"] = ALEBind::Function(&LuaGlobalFunctions::GetPlayerByGUID); + lua["GetPlayerByName"] = ALEBind::Function(&LuaGlobalFunctions::GetPlayerByName); + lua["GetGameTime"] = ALEBind::Function(&LuaGlobalFunctions::GetGameTime); + lua["GetPlayersInWorld"] = ALEBind::Function(&LuaGlobalFunctions::GetPlayersInWorld); + lua["GetGuildByName"] = ALEBind::Function(&LuaGlobalFunctions::GetGuildByName); + lua["GetMapById"] = ALEBind::Function(&LuaGlobalFunctions::GetMapById); + lua["GetGuildByLeaderGUID"] = ALEBind::Function(&LuaGlobalFunctions::GetGuildByLeaderGUID); + lua["GetPlayerCount"] = ALEBind::Function(&LuaGlobalFunctions::GetPlayerCount); + lua["GetPlayerGUID"] = ALEBind::Function(&LuaGlobalFunctions::GetPlayerGUID); + lua["GetItemGUID"] = ALEBind::Function(&LuaGlobalFunctions::GetItemGUID); + lua["GetItemTemplate"] = ALEBind::Function(&LuaGlobalFunctions::GetItemTemplate); + lua["GetObjectGUID"] = ALEBind::Function(&LuaGlobalFunctions::GetObjectGUID); + lua["GetUnitGUID"] = ALEBind::Function(&LuaGlobalFunctions::GetUnitGUID); + lua["GetGUIDLow"] = ALEBind::Function(&LuaGlobalFunctions::GetGUIDLow); + lua["GetItemLink"] = ALEBind::Function(&LuaGlobalFunctions::GetItemLink); + lua["GetGUIDType"] = ALEBind::Function(&LuaGlobalFunctions::GetGUIDType); + lua["GetGUIDEntry"] = ALEBind::Function(&LuaGlobalFunctions::GetGUIDEntry); + lua["GetPackedGUIDSize"] = ALEBind::Function(&LuaGlobalFunctions::GetPackedGUIDSize); + lua["GetAreaName"] = ALEBind::Function(&LuaGlobalFunctions::GetAreaName); + lua["GetActiveGameEvents"] = ALEBind::Function(&LuaGlobalFunctions::GetActiveGameEvents); + lua["RegisterServerEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterServerEvent); + lua["RegisterPlayerEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterPlayerEvent); + lua["RegisterGuildEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterGuildEvent); + lua["RegisterGroupEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterGroupEvent); + lua["RegisterBGEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterBGEvent); + lua["RegisterPacketEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterPacketEvent); + lua["RegisterCreatureGossipEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterCreatureGossipEvent); + lua["RegisterGameObjectGossipEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterGameObjectGossipEvent); + lua["RegisterItemEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterItemEvent); + lua["RegisterItemGossipEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterItemGossipEvent); + lua["RegisterMapEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterMapEvent); + lua["RegisterInstanceEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterInstanceEvent); + lua["RegisterPlayerGossipEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterPlayerGossipEvent); + lua["RegisterCreatureEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterCreatureEvent); + lua["RegisterUniqueCreatureEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterUniqueCreatureEvent); + lua["RegisterGameObjectEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterGameObjectEvent); + lua["RegisterTicketEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterTicketEvent); + lua["RegisterSpellEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterSpellEvent); + lua["RegisterAllCreatureEvent"] = ALEBind::Function(&LuaGlobalFunctions::RegisterAllCreatureEvent); + lua["ReloadALE"] = ALEBind::Function(&LuaGlobalFunctions::ReloadALE); + lua["RunCommand"] = ALEBind::Function(&LuaGlobalFunctions::RunCommand); + lua["SendWorldMessage"] = ALEBind::Function(&LuaGlobalFunctions::SendWorldMessage); + lua["WorldDBQuery"] = ALEBind::Function(&LuaGlobalFunctions::WorldDBQuery); + lua["WorldDBQueryAsync"] = ALEBind::Function(&LuaGlobalFunctions::WorldDBQueryAsync); + lua["WorldDBExecute"] = ALEBind::Function(&LuaGlobalFunctions::WorldDBExecute); + lua["CharDBQuery"] = ALEBind::Function(&LuaGlobalFunctions::CharDBQuery); + lua["CharDBQueryAsync"] = ALEBind::Function(&LuaGlobalFunctions::CharDBQueryAsync); + lua["CharDBExecute"] = ALEBind::Function(&LuaGlobalFunctions::CharDBExecute); + lua["AuthDBQuery"] = ALEBind::Function(&LuaGlobalFunctions::AuthDBQuery); + lua["AuthDBQueryAsync"] = ALEBind::Function(&LuaGlobalFunctions::AuthDBQueryAsync); + lua["AuthDBExecute"] = ALEBind::Function(&LuaGlobalFunctions::AuthDBExecute); + lua["CreateLuaEvent"] = ALEBind::Function(&LuaGlobalFunctions::CreateLuaEvent); + lua["RemoveEventById"] = ALEBind::Function(&LuaGlobalFunctions::RemoveEventById); + lua["RemoveEvents"] = ALEBind::Function(&LuaGlobalFunctions::RemoveEvents); + lua["PerformIngameSpawn"] = ALEBind::Function(&LuaGlobalFunctions::PerformIngameSpawn); + lua["CreatePacket"] = ALEBind::Function(&LuaGlobalFunctions::CreatePacket); + lua["AddVendorItem"] = ALEBind::Function(&LuaGlobalFunctions::AddVendorItem); + lua["VendorRemoveItem"] = ALEBind::Function(&LuaGlobalFunctions::VendorRemoveItem); + lua["VendorRemoveAllItems"] = ALEBind::Function(&LuaGlobalFunctions::VendorRemoveAllItems); + lua["Kick"] = ALEBind::Function(&LuaGlobalFunctions::Kick); + lua["Ban"] = ALEBind::Function(&LuaGlobalFunctions::Ban); + lua["SaveAllPlayers"] = ALEBind::Function(&LuaGlobalFunctions::SaveAllPlayers); + lua["SendMail"] = ALEBind::Function(&LuaGlobalFunctions::SendMail); + lua["bit_and"] = ALEBind::Function(&LuaGlobalFunctions::bit_and); + lua["bit_or"] = ALEBind::Function(&LuaGlobalFunctions::bit_or); + lua["bit_lshift"] = ALEBind::Function(&LuaGlobalFunctions::bit_lshift); + lua["bit_rshift"] = ALEBind::Function(&LuaGlobalFunctions::bit_rshift); + lua["bit_xor"] = ALEBind::Function(&LuaGlobalFunctions::bit_xor); + lua["bit_not"] = ALEBind::Function(&LuaGlobalFunctions::bit_not); + lua["AddTaxiPath"] = ALEBind::Function(&LuaGlobalFunctions::AddTaxiPath); + lua["IsCompatibilityMode"] = ALEBind::Function(&LuaGlobalFunctions::IsCompatibilityMode); + lua["IsInventoryPos"] = ALEBind::Function(&LuaGlobalFunctions::IsInventoryPos); + lua["IsEquipmentPos"] = ALEBind::Function(&LuaGlobalFunctions::IsEquipmentPos); + lua["IsBankPos"] = ALEBind::Function(&LuaGlobalFunctions::IsBankPos); + lua["IsBagPos"] = ALEBind::Function(&LuaGlobalFunctions::IsBagPos); + lua["IsGameEventActive"] = ALEBind::Function(&LuaGlobalFunctions::IsGameEventActive); + lua["GetCurrTime"] = ALEBind::Function(&LuaGlobalFunctions::GetCurrTime); + lua["GetTimeDiff"] = ALEBind::Function(&LuaGlobalFunctions::GetTimeDiff); + lua["PrintInfo"] = ALEBind::Function(&LuaGlobalFunctions::PrintInfo); + lua["PrintError"] = ALEBind::Function(&LuaGlobalFunctions::PrintError); + lua["PrintDebug"] = ALEBind::Function(&LuaGlobalFunctions::PrintDebug); + lua["StartGameEvent"] = ALEBind::Function(&LuaGlobalFunctions::StartGameEvent); + lua["StopGameEvent"] = ALEBind::Function(&LuaGlobalFunctions::StopGameEvent); + lua["HttpRequest"] = ALEBind::Function(&LuaGlobalFunctions::HttpRequest); + lua["CreateLongLong"] = ALEBind::Function(&LuaGlobalFunctions::CreateLongLong); + lua["CreateULongLong"] = ALEBind::Function(&LuaGlobalFunctions::CreateULongLong); + lua["ClearBattleGroundEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearBattleGroundEvents); + lua["ClearCreatureEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearCreatureEvents); + lua["ClearUniqueCreatureEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearUniqueCreatureEvents); + lua["ClearCreatureGossipEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearCreatureGossipEvents); + lua["ClearGameObjectEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearGameObjectEvents); + lua["ClearGameObjectGossipEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearGameObjectGossipEvents); + lua["ClearGroupEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearGroupEvents); + lua["ClearGuildEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearGuildEvents); + lua["ClearItemEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearItemEvents); + lua["ClearItemGossipEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearItemGossipEvents); + lua["ClearPacketEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearPacketEvents); + lua["ClearPlayerEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearPlayerEvents); + lua["ClearPlayerGossipEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearPlayerGossipEvents); + lua["ClearServerEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearServerEvents); + lua["ClearMapEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearMapEvents); + lua["ClearInstanceEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearInstanceEvents); + lua["ClearTicketEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearTicketEvents); + lua["ClearSpellEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearSpellEvents); + lua["ClearAllCreatureEvents"] = ALEBind::Function(&LuaGlobalFunctions::ClearAllCreatureEvents); + lua["GetOwnerHalaa"] = ALEBind::Function(&LuaGlobalFunctions::GetOwnerHalaa); + lua["SetOwnerHalaa"] = ALEBind::Function(&LuaGlobalFunctions::SetOwnerHalaa); + lua["GetGossipMenuOptionLocale"] = ALEBind::Function(&LuaGlobalFunctions::GetGossipMenuOptionLocale); + lua["GetMapEntrance"] = ALEBind::Function(&LuaGlobalFunctions::GetMapEntrance); + lua["GetSpellInfo"] = ALEBind::Function(&LuaGlobalFunctions::GetSpellInfo); + lua["LookupEntry"] = ALEBind::Function(&LuaGlobalFunctions::LookupEntry); +} diff --git a/src/LuaEngine/methods/GroupMethods.h b/src/LuaEngine/methods/GroupMethods.cpp similarity index 56% rename from src/LuaEngine/methods/GroupMethods.h rename to src/LuaEngine/methods/GroupMethods.cpp index 5c0fc37b74..d1178e71fd 100644 --- a/src/LuaEngine/methods/GroupMethods.h +++ b/src/LuaEngine/methods/GroupMethods.cpp @@ -4,8 +4,11 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef GROUPMETHODS_H -#define GROUPMETHODS_H +#include "ALEBind.h" + +#include "Group.h" +#include "Player.h" +#include "WorldPacket.h" /*** * Represents a player group in the game, such as a party or raid. @@ -20,11 +23,9 @@ namespace LuaGroup * @param ObjectGuid guid : guid of a possible leader * @return bool isLeader */ - int IsLeader(lua_State* L, Group* group) + bool IsLeader(Group* group, ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - ALE::Push(L, group->IsLeader(guid)); - return 1; + return group->IsLeader(guid); } /** @@ -32,10 +33,9 @@ namespace LuaGroup * * @return bool isFull */ - int IsFull(lua_State* L, Group* group) + bool IsFull(Group* group) { - ALE::Push(L, group->IsFull()); - return 1; + return group->IsFull(); } /** @@ -43,10 +43,9 @@ namespace LuaGroup * * @return bool isLFGGroup */ - int IsLFGGroup(lua_State* L, Group* group) + bool IsLFGGroup(Group* group) { - ALE::Push(L, group->isLFGGroup()); - return 1; + return group->isLFGGroup(); } /** @@ -54,10 +53,9 @@ namespace LuaGroup * * @return bool isRaid */ - int IsRaidGroup(lua_State* L, Group* group) + bool IsRaidGroup(Group* group) { - ALE::Push(L, group->isRaidGroup()); - return 1; + return group->isRaidGroup(); } /** @@ -65,10 +63,9 @@ namespace LuaGroup * * @return bool isBG */ - int IsBGGroup(lua_State* L, Group* group) + bool IsBGGroup(Group* group) { - ALE::Push(L, group->isBGGroup()); - return 1; + return group->isBGGroup(); } /** @@ -77,11 +74,9 @@ namespace LuaGroup * @param ObjectGuid guid : guid of a player * @return bool isMember */ - int IsMember(lua_State* L, Group* group) + bool IsMember(Group* group, ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - ALE::Push(L, group->IsMember(guid)); - return 1; + return group->IsMember(guid); } /** @@ -90,11 +85,9 @@ namespace LuaGroup * @param ObjectGuid guid : guid of a player * @return bool isAssistant */ - int IsAssistant(lua_State* L, Group* group) + bool IsAssistant(Group* group, ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - ALE::Push(L, group->IsAssistant(guid)); - return 1; + return group->IsAssistant(guid); } /** @@ -104,12 +97,9 @@ namespace LuaGroup * @param [Player] player2 : second [Player] to check * @return bool sameSubGroup */ - int SameSubGroup(lua_State* L, Group* group) + bool SameSubGroup(Group* group, Player* player1, Player* player2) { - Player* player1 = ALE::CHECKOBJ(L, 2); - Player* player2 = ALE::CHECKOBJ(L, 3); - ALE::Push(L, group->SameSubGroup(player1, player2)); - return 1; + return group->SameSubGroup(player1, player2); } /** @@ -118,18 +108,12 @@ namespace LuaGroup * @param uint8 subGroup : subGroup ID to check * @return bool hasFreeSlot */ - int HasFreeSlotSubGroup(lua_State* L, Group* group) + bool HasFreeSlotSubGroup(Group* group, uint8 subGroup) { - uint8 subGroup = ALE::CHECKVAL(L, 2); - if (subGroup >= MAX_RAID_SUBGROUPS) - { - luaL_argerror(L, 2, "valid subGroup ID expected"); - return 0; - } + throw std::invalid_argument("valid subGroup ID expected"); - ALE::Push(L, group->HasFreeSlotSubGroup(subGroup)); - return 1; + return group->HasFreeSlotSubGroup(subGroup); } /** @@ -138,15 +122,10 @@ namespace LuaGroup * @param [Player] player : [Player] to add to the group * @return bool added : true if member was added */ - int AddMember(lua_State* L, Group* group) + bool AddMember(Group* group, Player* player) { - Player* player = ALE::CHECKOBJ(L, 2); - if (player->GetGroup() || !group->IsCreated() || group->IsFull()) - { - ALE::Push(L, false); - return 1; - } + return false; if (player->GetGroupInvite()) player->UninviteFromGroup(); @@ -155,20 +134,17 @@ namespace LuaGroup if (success) group->BroadcastGroupUpdate(); - ALE::Push(L, success); - return 1; + return success; } - /*int IsLFGGroup(lua_State* L, Group* group) // TODO: Implementation + /*bool IsLFGGroup(Group* group) // TODO: Implementation { - ALE::Push(L, group->isLFGGroup()); - return 1; + return group->isLFGGroup(); }*/ - /*int IsBFGroup(lua_State* L, Group* group) // TODO: Implementation + /*bool IsBFGroup(Group* group) // TODO: Implementation { - ALE::Push(L, group->isBFGroup()); - return 1; + return group->isBFGroup(); }*/ /** @@ -176,10 +152,9 @@ namespace LuaGroup * * @return table groupPlayers : table of [Player]s */ - int GetMembers(lua_State* L, Group* group) + sol::table GetMembers(Group* group, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (GroupReference* itr = group->GetFirstMember(); itr; itr = itr->next()) @@ -189,12 +164,10 @@ namespace LuaGroup if (!member || !member->GetSession()) continue; - ALE::Push(L, member); - lua_rawseti(L, tbl, ++i); + tbl[++i] = PlayerRef(member); } - lua_settop(L, tbl); // push table to top of stack - return 1; + return tbl; } /** @@ -202,10 +175,9 @@ namespace LuaGroup * * @return ObjectGuid leaderGUID */ - int GetLeaderGUID(lua_State* L, Group* group) + ObjectGuid GetLeaderGUID(Group* group) { - ALE::Push(L, group->GetLeaderGUID()); - return 1; + return group->GetLeaderGUID(); } /** @@ -213,10 +185,9 @@ namespace LuaGroup * * @return ObjectGuid groupGUID */ - int GetGUID(lua_State* L, Group* group) + ObjectGuid GetGUID(Group* group) { - ALE::Push(L, group->GET_GUID()); - return 1; + return group->GetGUID(); } /** @@ -225,12 +196,9 @@ namespace LuaGroup * @param string name : the [Player]'s name * @return ObjectGuid memberGUID */ - int GetMemberGUID(lua_State* L, Group* group) + ObjectGuid GetMemberGUID(Group* group, std::string const& name) { - const char* name = ALE::CHECKVAL(L, 2); - - ALE::Push(L, group->GetMemberGUID(name)); - return 1; + return group->GetMemberGUID(name); } /** @@ -238,10 +206,9 @@ namespace LuaGroup * * @return uint32 memberCount */ - int GetMembersCount(lua_State* L, Group* group) + uint32 GetMembersCount(Group* group) { - ALE::Push(L, group->GetMembersCount()); - return 1; + return group->GetMembersCount(); } /** @@ -260,10 +227,9 @@ namespace LuaGroup * * @return [GroupType] groupType */ - int GetGroupType(lua_State* L, Group* group) + GroupType GetGroupType(Group* group) { - ALE::Push(L, group->GetGroupType()); - return 1; + return group->GetGroupType(); } /** @@ -272,11 +238,9 @@ namespace LuaGroup * @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) + uint8 GetMemberGroup(Group* group, ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - ALE::Push(L, group->GetMemberGroup(guid)); - return 1; + return group->GetMemberGroup(guid); } /** @@ -284,12 +248,10 @@ namespace LuaGroup * * @param ObjectGuid guid : guid of the new leader */ - int SetLeader(lua_State* L, Group* group) + void SetLeader(Group* group, ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); group->ChangeLeader(guid); group->SendUpdate(); - return 0; } /** @@ -299,14 +261,9 @@ namespace LuaGroup * @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) + void SendPacket(Group* group, WorldPacket* data, bool ignorePlayersInBg, ObjectGuid ignore) { - 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; } /** @@ -326,33 +283,27 @@ namespace LuaGroup * @param [RemoveMethod] method : method used to remove the player * @return bool removed */ - int RemoveMember(lua_State* L, Group* group) + bool RemoveMember(Group* group, ObjectGuid guid, sol::optional method) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - uint32 method = ALE::CHECKVAL(L, 3, 0); - - ALE::Push(L, group->RemoveMember(guid, (RemoveMethod)method)); - return 1; + return group->RemoveMember(guid, (RemoveMethod)method.value_or(0)); } /** * Disbands this [Group] * */ - int Disband(lua_State* /*L*/, Group* group) + void Disband(Group* group) { group->Disband(); - return 0; } /** * Converts this [Group] to a raid [Group] * */ - int ConvertToRaid(lua_State* /*L*/, Group* group) + void ConvertToRaid(Group* group) { group->ConvertToRaid(); - return 0; } /** @@ -361,22 +312,15 @@ namespace LuaGroup * @param ObjectGuid guid : guid of the player to move * @param uint8 groupID : the subGroup's ID */ - int SetMembersGroup(lua_State* L, Group* group) + void SetMembersGroup(Group* group, ObjectGuid guid, uint8 subGroup) { - 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; - } + throw std::invalid_argument("valid subGroup ID expected"); if (!group->HasFreeSlotSubGroup(subGroup)) - return 0; + return; group->ChangeMembersGroup(guid, subGroup); - return 0; } /** @@ -386,22 +330,17 @@ namespace LuaGroup * @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) + void SetTargetIcon(Group* group, uint8 icon, ObjectGuid target, sol::optional setter) { - 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"); + throw std::invalid_argument("valid target icon expected"); - group->SetTargetIcon(icon, setter, target); - return 0; + group->SetTargetIcon(icon, setter.value_or(ObjectGuid()), target); } /** * Sets or removes a flag for a [Group] member - * + * *
      * enum GroupMemberFlags
      * {
@@ -410,26 +349,49 @@ namespace LuaGroup
      *     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) + void SetMemberFlag(Group* group, ObjectGuid target, bool apply, uint32 flag) { - 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; + group->SetGroupMemberFlag(target, apply, static_cast(flag)); } - /*int ConvertToLFG(lua_State* L, Group* group) // TODO: Implementation + /*void ConvertToLFG(Group* group) // TODO: Implementation { group->ConvertToLFG(); - return 0; }*/ -}; +} -#endif +void RegisterGroupMethods(sol::state& lua) +{ + sol::usertype type = ALEBind::NewHandleType(lua, "Group"); + + type["IsLeader"] = ALEBind::Method(&LuaGroup::IsLeader); + type["IsFull"] = ALEBind::Method(&LuaGroup::IsFull); + type["IsLFGGroup"] = ALEBind::Method(&LuaGroup::IsLFGGroup); + type["IsRaidGroup"] = ALEBind::Method(&LuaGroup::IsRaidGroup); + type["IsBGGroup"] = ALEBind::Method(&LuaGroup::IsBGGroup); + type["IsMember"] = ALEBind::Method(&LuaGroup::IsMember); + type["IsAssistant"] = ALEBind::Method(&LuaGroup::IsAssistant); + type["SameSubGroup"] = ALEBind::Method(&LuaGroup::SameSubGroup); + type["HasFreeSlotSubGroup"] = ALEBind::Method(&LuaGroup::HasFreeSlotSubGroup); + type["AddMember"] = ALEBind::Method(&LuaGroup::AddMember); + type["GetMembers"] = ALEBind::Method(&LuaGroup::GetMembers); + type["GetLeaderGUID"] = ALEBind::Method(&LuaGroup::GetLeaderGUID); + type["GetGUID"] = ALEBind::Method(&LuaGroup::GetGUID); + type["GetMemberGUID"] = ALEBind::Method(&LuaGroup::GetMemberGUID); + type["GetMembersCount"] = ALEBind::Method(&LuaGroup::GetMembersCount); + type["GetGroupType"] = ALEBind::Method(&LuaGroup::GetGroupType); + type["GetMemberGroup"] = ALEBind::Method(&LuaGroup::GetMemberGroup); + type["SetLeader"] = ALEBind::Method(&LuaGroup::SetLeader); + type["SendPacket"] = ALEBind::Method(&LuaGroup::SendPacket); + type["RemoveMember"] = ALEBind::Method(&LuaGroup::RemoveMember); + type["Disband"] = ALEBind::Method(&LuaGroup::Disband); + type["ConvertToRaid"] = ALEBind::Method(&LuaGroup::ConvertToRaid); + type["SetMembersGroup"] = ALEBind::Method(&LuaGroup::SetMembersGroup); + type["SetTargetIcon"] = ALEBind::Method(&LuaGroup::SetTargetIcon); + type["SetMemberFlag"] = ALEBind::Method(&LuaGroup::SetMemberFlag); +} diff --git a/src/LuaEngine/methods/GuildMethods.h b/src/LuaEngine/methods/GuildMethods.cpp similarity index 57% rename from src/LuaEngine/methods/GuildMethods.h rename to src/LuaEngine/methods/GuildMethods.cpp index 979f564a9e..5aca0b4cf6 100644 --- a/src/LuaEngine/methods/GuildMethods.h +++ b/src/LuaEngine/methods/GuildMethods.cpp @@ -4,8 +4,15 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef GUILDMETHODS_H -#define GUILDMETHODS_H +#include "ALEBind.h" + +#include "DatabaseEnv.h" +#include "Guild.h" +#include "ObjectAccessor.h" +#include "Player.h" +#include "WorldPacket.h" + +#include /*** * Represents a player guild. Used to manage guild members, ranks, guild bank. @@ -21,30 +28,27 @@ namespace LuaGuild * * @return table guildPlayers : table of [Player]s */ - int GetMembers(lua_State* L, Guild* guild) + sol::table GetMembers(Guild* guild, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; { std::shared_lock lock(*HashMapHolder::GetLock()); - const HashMapHolder::MapType& m = eObjectAccessor()GetPlayers(); + HashMapHolder::MapType const& m = ObjectAccessor::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); + tbl[++i] = PlayerRef(player); } } } } - lua_settop(L, tbl); // push table to top of stack - return 1; + return tbl; } /** @@ -52,10 +56,9 @@ namespace LuaGuild * * @return uint32 memberCount */ - int GetMemberCount(lua_State* L, Guild* guild) + uint32 GetMemberCount(Guild* guild) { - ALE::Push(L, guild->GetMemberCount()); - return 1; + return guild->GetMemberCount(); } /** @@ -63,10 +66,9 @@ namespace LuaGuild * * @return [Player] leader */ - int GetLeader(lua_State* L, Guild* guild) + Player* GetLeader(Guild* guild) { - ALE::Push(L, eObjectAccessor()FindPlayer(guild->GetLeaderGUID())); - return 1; + return ObjectAccessor::FindPlayer(guild->GetLeaderGUID()); } /** @@ -74,10 +76,9 @@ namespace LuaGuild * * @return ObjectGuid leaderGUID */ - int GetLeaderGUID(lua_State* L, Guild* guild) + ObjectGuid GetLeaderGUID(Guild* guild) { - ALE::Push(L, guild->GetLeaderGUID()); - return 1; + return guild->GetLeaderGUID(); } /** @@ -85,10 +86,9 @@ namespace LuaGuild * * @return uint32 entryId */ - int GetId(lua_State* L, Guild* guild) + uint32 GetId(Guild* guild) { - ALE::Push(L, guild->GetId()); - return 1; + return guild->GetId(); } /** @@ -96,10 +96,9 @@ namespace LuaGuild * * @return string guildName */ - int GetName(lua_State* L, Guild* guild) + std::string GetName(Guild* guild) { - ALE::Push(L, guild->GetName()); - return 1; + return guild->GetName(); } /** @@ -107,10 +106,9 @@ namespace LuaGuild * * @return string guildMOTD */ - int GetMOTD(lua_State* L, Guild* guild) + std::string GetMOTD(Guild* guild) { - ALE::Push(L, guild->GetMOTD()); - return 1; + return guild->GetMOTD(); } /** @@ -118,10 +116,9 @@ namespace LuaGuild * * @return string guildInfo */ - int GetInfo(lua_State* L, Guild* guild) + std::string GetInfo(Guild* guild) { - ALE::Push(L, guild->GetInfo()); - return 1; + return guild->GetInfo(); } /** @@ -129,12 +126,9 @@ namespace LuaGuild * * @param [Player] leader : the [Player] leader to change */ - int SetLeader(lua_State* L, Guild* guild) + void SetLeader(Guild* guild, Player* player) { - Player* player = ALE::CHECKOBJ(L, 2); - guild->HandleSetLeader(player->GetSession(), player->GetName()); - return 0; } /** @@ -143,12 +137,9 @@ namespace LuaGuild * @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) + void SetBankTabText(Guild* guild, uint8 tabId, std::string text) { - uint8 tabId = ALE::CHECKVAL(L, 2); - const char* text = ALE::CHECKVAL(L, 3); guild->SetBankTabText(tabId, text); - return 0; } // SendPacketToGuild(packet) @@ -157,12 +148,9 @@ namespace LuaGuild * * @param [WorldPacket] packet : the [WorldPacket] to be sent to the [Player]s */ - int SendPacket(lua_State* L, Guild* guild) + void SendPacket(Guild* guild, WorldPacket* data) { - WorldPacket* data = ALE::CHECKOBJ(L, 2); - guild->BroadcastPacket(data); - return 0; } // SendPacketToRankedInGuild(packet, rankId) @@ -172,22 +160,17 @@ namespace LuaGuild * @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) + void SendPacketToRanked(Guild* guild, WorldPacket* data, uint8 ranked) { - 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) + void Disband(Guild* guild) { guild->Disband(); - return 0; } /** @@ -198,13 +181,9 @@ namespace LuaGuild * @param [Player] player : the [Player] to be added to the guild * @param uint8 rankId : the rank ID */ - int AddMember(lua_State* L, Guild* guild) + void AddMember(Guild* guild, Player* player, sol::optional rankId) { - Player* player = ALE::CHECKOBJ(L, 2); - uint8 rankId = ALE::CHECKVAL(L, 3, GUILD_RANK_NONE); - - guild->AddMember(player->GET_GUID(), rankId); - return 0; + guild->AddMember(player->GetGUID(), rankId.value_or(GUILD_RANK_NONE)); } /** @@ -213,13 +192,9 @@ namespace LuaGuild * @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) + void DeleteMember(Guild* guild, Player* player, sol::optional isDisbanding) { - Player* player = ALE::CHECKOBJ(L, 2); - bool isDisbanding = ALE::CHECKVAL(L, 3, false); - - guild->DeleteMember(player->GET_GUID(), isDisbanding); - return 0; + guild->DeleteMember(player->GetGUID(), isDisbanding.value_or(false)); } /** @@ -228,13 +203,9 @@ namespace LuaGuild * @param [Player] player : the [Player] to be promoted/demoted * @param uint8 rankId : the rank ID */ - int SetMemberRank(lua_State* L, Guild* guild) + void SetMemberRank(Guild* guild, Player* player, uint8 newRank) { - Player* player = ALE::CHECKOBJ(L, 2); - uint8 newRank = ALE::CHECKVAL(L, 3); - - guild->ChangeMemberRank(player->GET_GUID(), newRank); - return 0; + guild->ChangeMemberRank(player->GetGUID(), newRank); } /** @@ -242,78 +213,58 @@ namespace LuaGuild * * @param string name : new name of this guild */ - int SetName(lua_State* L, Guild* guild) + void SetName(Guild* guild, std::string name) { - 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) + void UpdateMemberData(Guild* guild, Player* player, uint8 dataid, uint32 value) { - 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) + void SendMessage(Guild* guild, Player* player, sol::optional officerOnly, std::string msg, sol::optional language) { - 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; + guild->BroadcastToGuild(player->GetSession(), officerOnly.value_or(false), msg, language.value_or(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); - + void MassInviteToEvent(Guild* guild, Player* player, uint32 minLevel, uint32 maxLevel, uint32 minRank) + { 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 @@ -321,22 +272,14 @@ namespace LuaGuild * @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); - + void SwapItems(Guild* guild, Player* player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount) + { 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 @@ -345,68 +288,84 @@ namespace LuaGuild * @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; + void SwapItemsWithInventory(Guild* guild, Player* player, sol::optional toChar, uint8 tabId, uint8 slotId, uint8 playerBag, uint8 playerSlotId, uint32 splitedAmount) + { + guild->SwapItemsWithInventory(player, toChar.value_or(false), tabId, slotId, playerBag, playerSlotId, splitedAmount); } /** * Return the total bank money. - * + * * @return number totalBankMoney */ - int GetTotalBankMoney(lua_State* L, Guild* guild) - { - ALE::Push(L, guild->GetTotalBankMoney()); - return 1; + uint64 GetTotalBankMoney(Guild* guild) + { + return guild->GetTotalBankMoney(); } /** * Return the created date. - * + * * @return uint64 created date */ - int GetCreatedDate(lua_State* L, Guild* guild) - { - ALE::Push(L, guild->GetCreatedDate()); - return 1; + time_t GetCreatedDate(Guild* guild) + { + return guild->GetCreatedDate(); } /** * Resets the number of item withdraw in all tab's for all [Guild] members. */ - int ResetTimes(lua_State* /*L*/, Guild* guild) - { + void ResetTimes(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); - + bool ModifyBankMoney(Guild* guild, uint64 amount, bool add) + { CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); - ALE::Push(L, guild->ModifyBankMoney(trans, amount, add)); + bool applied = guild->ModifyBankMoney(trans, amount, add); CharacterDatabase.CommitTransaction(trans); - return 1; + return applied; } -}; -#endif +} + +void RegisterGuildMethods(sol::state& lua) +{ + sol::usertype type = ALEBind::NewHandleType(lua, "Guild"); + + type["GetMembers"] = ALEBind::Method(&LuaGuild::GetMembers); + type["GetMemberCount"] = ALEBind::Method(&LuaGuild::GetMemberCount); + type["GetLeader"] = ALEBind::Method(&LuaGuild::GetLeader); + type["GetLeaderGUID"] = ALEBind::Method(&LuaGuild::GetLeaderGUID); + type["GetId"] = ALEBind::Method(&LuaGuild::GetId); + type["GetName"] = ALEBind::Method(&LuaGuild::GetName); + type["GetMOTD"] = ALEBind::Method(&LuaGuild::GetMOTD); + type["GetInfo"] = ALEBind::Method(&LuaGuild::GetInfo); + type["SetLeader"] = ALEBind::Method(&LuaGuild::SetLeader); + type["SetBankTabText"] = ALEBind::Method(&LuaGuild::SetBankTabText); + type["SendPacket"] = ALEBind::Method(&LuaGuild::SendPacket); + type["SendPacketToRanked"] = ALEBind::Method(&LuaGuild::SendPacketToRanked); + type["Disband"] = ALEBind::Method(&LuaGuild::Disband); + type["AddMember"] = ALEBind::Method(&LuaGuild::AddMember); + type["DeleteMember"] = ALEBind::Method(&LuaGuild::DeleteMember); + type["SetMemberRank"] = ALEBind::Method(&LuaGuild::SetMemberRank); + type["SetName"] = ALEBind::Method(&LuaGuild::SetName); + type["UpdateMemberData"] = ALEBind::Method(&LuaGuild::UpdateMemberData); + type["SendMessage"] = ALEBind::Method(&LuaGuild::SendMessage); + type["MassInviteToEvent"] = ALEBind::Method(&LuaGuild::MassInviteToEvent); + type["SwapItems"] = ALEBind::Method(&LuaGuild::SwapItems); + type["SwapItemsWithInventory"] = ALEBind::Method(&LuaGuild::SwapItemsWithInventory); + type["GetTotalBankMoney"] = ALEBind::Method(&LuaGuild::GetTotalBankMoney); + type["GetCreatedDate"] = ALEBind::Method(&LuaGuild::GetCreatedDate); + type["ResetTimes"] = ALEBind::Method(&LuaGuild::ResetTimes); + type["ModifyBankMoney"] = ALEBind::Method(&LuaGuild::ModifyBankMoney); +} diff --git a/src/LuaEngine/methods/ItemMethods.h b/src/LuaEngine/methods/ItemMethods.cpp similarity index 54% rename from src/LuaEngine/methods/ItemMethods.h rename to src/LuaEngine/methods/ItemMethods.cpp index 06ddf1d4da..d75d24c3c6 100644 --- a/src/LuaEngine/methods/ItemMethods.h +++ b/src/LuaEngine/methods/ItemMethods.cpp @@ -4,8 +4,19 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef ITEMMETHODS_H -#define ITEMMETHODS_H +#include "ALEBind.h" + +#include "Bag.h" +#include "Common.h" +#include "DBCStores.h" +#include "DatabaseEnv.h" +#include "Item.h" +#include "ItemTemplate.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "SharedDefines.h" + +#include /*** * Represents an instance of an item in the game world. @@ -19,10 +30,9 @@ namespace LuaItem * * @return bool isSoulBound */ - int IsSoulBound(lua_State* L, Item* item) + bool IsSoulBound(Item* item) { - ALE::Push(L, item->IsSoulBound()); - return 1; + return item->IsSoulBound(); } /** @@ -30,10 +40,9 @@ namespace LuaItem * * @return bool isAccountBound */ - int IsBoundAccountWide(lua_State* L, Item* item) + bool IsBoundAccountWide(Item* item) { - ALE::Push(L, item->IsBoundAccountWide()); - return 1; + return item->IsBoundAccountWide(); } /** @@ -41,10 +50,9 @@ namespace LuaItem * * @return bool isBoundByEnchant */ - int IsBoundByEnchant(lua_State* L, Item* item) + bool IsBoundByEnchant(Item* item) { - ALE::Push(L, item->IsBoundByEnchant()); - return 1; + return item->IsBoundByEnchant(); } /** @@ -53,12 +61,9 @@ namespace LuaItem * @param [Player] player : the [Player] object to check the item against * @return bool isNotBound */ - int IsNotBoundToPlayer(lua_State* L, Item* item) + bool IsNotBoundToPlayer(Item* item, Player* player) { - Player* player = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, item->IsBindedNotWith(player)); - return 1; + return item->IsBindedNotWith(player); } /** @@ -66,10 +71,9 @@ namespace LuaItem * * @return bool isLocked */ - int IsLocked(lua_State* L, Item* item) + bool IsLocked(Item* item) { - ALE::Push(L, item->IsLocked()); - return 1; + return item->IsLocked(); } /** @@ -77,10 +81,9 @@ namespace LuaItem * * @return bool isBag */ - int IsBag(lua_State* L, Item* item) + bool IsBag(Item* item) { - ALE::Push(L, item->IsBag()); - return 1; + return item->IsBag(); } /** @@ -88,10 +91,9 @@ namespace LuaItem * * @return bool isCurrencyToken */ - int IsCurrencyToken(lua_State* L, Item* item) + bool IsCurrencyToken(Item* item) { - ALE::Push(L, item->IsCurrencyToken()); - return 1; + return item->IsCurrencyToken(); } /** @@ -99,10 +101,9 @@ namespace LuaItem * * @return bool isNotEmptyBag */ - int IsNotEmptyBag(lua_State* L, Item* item) + bool IsNotEmptyBag(Item* item) { - ALE::Push(L, item->IsNotEmptyBag()); - return 1; + return item->IsNotEmptyBag(); } /** @@ -110,10 +111,9 @@ namespace LuaItem * * @return bool isBroken */ - int IsBroken(lua_State* L, Item* item) + bool IsBroken(Item* item) { - ALE::Push(L, item->IsBroken()); - return 1; + return item->IsBroken(); } /** @@ -121,11 +121,9 @@ namespace LuaItem * * @return bool isTradeable */ - int CanBeTraded(lua_State* L, Item* item) + bool CanBeTraded(Item* item, sol::optional mail) { - bool mail = ALE::CHECKVAL(L, 2, false); - ALE::Push(L, item->CanBeTraded(mail)); - return 1; + return item->CanBeTraded(mail.value_or(false)); } /** @@ -133,10 +131,9 @@ namespace LuaItem * * @return bool isInTrade */ - int IsInTrade(lua_State* L, Item* item) + bool IsInTrade(Item* item) { - ALE::Push(L, item->IsInTrade()); - return 1; + return item->IsInTrade(); } /** @@ -144,10 +141,9 @@ namespace LuaItem * * @return bool isInBag */ - int IsInBag(lua_State* L, Item* item) + bool IsInBag(Item* item) { - ALE::Push(L, item->IsInBag()); - return 1; + return item->IsInBag(); } /** @@ -155,10 +151,9 @@ namespace LuaItem * * @return bool isEquipped */ - int IsEquipped(lua_State* L, Item* item) + bool IsEquipped(Item* item) { - ALE::Push(L, item->IsEquipped()); - return 1; + return item->IsEquipped(); } /** @@ -167,11 +162,9 @@ namespace LuaItem * @param uint32 questId : the [Quest] id to be checked * @return bool hasQuest */ - int HasQuest(lua_State* L, Item* item) + bool HasQuest(Item* item, uint32 quest) { - uint32 quest = ALE::CHECKVAL(L, 2); - ALE::Push(L, item->hasQuest(quest)); - return 1; + return item->hasQuest(quest); } /** @@ -179,10 +172,9 @@ namespace LuaItem * * @return bool isPotion */ - int IsPotion(lua_State* L, Item* item) + bool IsPotion(Item* item) { - ALE::Push(L, item->IsPotion()); - return 1; + return item->IsPotion(); } /** @@ -190,10 +182,9 @@ namespace LuaItem * * @return bool isWeaponVellum */ - int IsWeaponVellum(lua_State* L, Item* item) + bool IsWeaponVellum(Item* item) { - ALE::Push(L, item->IsWeaponVellum()); - return 1; + return item->IsWeaponVellum(); } /** @@ -201,10 +192,9 @@ namespace LuaItem * * @return bool isArmorVellum */ - int IsArmorVellum(lua_State* L, Item* item) + bool IsArmorVellum(Item* item) { - ALE::Push(L, item->IsArmorVellum()); - return 1; + return item->IsArmorVellum(); } /** @@ -212,16 +202,14 @@ namespace LuaItem * * @return bool isConjuredConsumable */ - int IsConjuredConsumable(lua_State* L, Item* item) + bool IsConjuredConsumable(Item* item) { - ALE::Push(L, item->IsConjuredConsumable()); - return 1; + return item->IsConjuredConsumable(); } - /*int IsRefundExpired(lua_State* L, Item* item)// TODO: Implement core support + /*bool IsRefundExpired(Item* item)// TODO: Implement core support { - ALE::Push(L, item->IsRefundExpired()); - return 1; + return item->IsRefundExpired(); }*/ /** @@ -245,15 +233,15 @@ namespace LuaItem * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the [Item]'s name in * @return string itemLink */ - int GetItemLink(lua_State* L, Item* item) + std::string GetItemLink(Item* item, sol::optional localeArg) { - uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE); + uint8 locale = localeArg.value_or(DEFAULT_LOCALE); if (locale >= TOTAL_LOCALES) - return luaL_argerror(L, 2, "valid LocaleConstant expected"); + throw std::invalid_argument("valid LocaleConstant expected"); - const ItemTemplate* temp = item->GetTemplate(); + ItemTemplate const* temp = item->GetTemplate(); std::string name = temp->Name1; - if (ItemLocale const* il = eObjectMgr->GetItemLocale(temp->ItemId)) + if (ItemLocale const* il = sObjectMgr->GetItemLocale(temp->ItemId)) { ObjectMgr::GetLocaleString(il->Name, static_cast(locale), name); } @@ -263,19 +251,19 @@ namespace LuaItem std::array const* suffix = NULL; if (itemRandPropId < 0) { - const ItemRandomSuffixEntry* itemRandEntry = sItemRandomSuffixStore.LookupEntry(-item->GetItemRandomPropertyId()); + ItemRandomSuffixEntry const* itemRandEntry = sItemRandomSuffixStore.LookupEntry(-item->GetItemRandomPropertyId()); if (itemRandEntry) suffix = &itemRandEntry->Name; } else { - const ItemRandomPropertiesEntry* itemRandEntry = sItemRandomPropertiesStore.LookupEntry(item->GetItemRandomPropertyId()); + ItemRandomPropertiesEntry const* itemRandEntry = sItemRandomPropertiesStore.LookupEntry(item->GetItemRandomPropertyId()); if (itemRandEntry) suffix = &itemRandEntry->Name; } if (suffix) { - const char* suffixName = (*suffix)[(name != temp->Name1) ? locale : uint8(DEFAULT_LOCALE)]; + char const* suffixName = (*suffix)[(name != temp->Name1) ? locale : uint8(DEFAULT_LOCALE)]; if (strcmp(suffixName, "") != 0) { name += ' '; @@ -296,8 +284,7 @@ namespace LuaItem item->GetItemRandomPropertyId() << ":" << item->GetItemSuffixFactor() << ":" << (uint32)(owner ? owner->GetLevel() : 0) << "|h[" << name << "]|h|r"; - ALE::Push(L, oss.str()); - return 1; + return oss.str(); } /** @@ -306,10 +293,9 @@ namespace LuaItem * @param [Item] item * @return uint64 ownerGUID */ - int GetOwnerGUID(lua_State* L, Item* item) + ObjectGuid GetOwnerGUID(Item* item) { - ALE::Push(L, item->GetOwnerGUID()); - return 1; + return item->GetOwnerGUID(); } /** @@ -317,10 +303,9 @@ namespace LuaItem * * @return [Player] player : the [Player] who owns the [Item] */ - int GetOwner(lua_State* L, Item* item) + Player* GetOwner(Item* item) { - ALE::Push(L, item->GetOwner()); - return 1; + return item->GetOwner(); } /** @@ -328,10 +313,9 @@ namespace LuaItem * * @return uint32 count */ - int GetCount(lua_State* L, Item* item) + uint32 GetCount(Item* item) { - ALE::Push(L, item->GetCount()); - return 1; + return item->GetCount(); } /** @@ -339,10 +323,9 @@ namespace LuaItem * * @return uint32 maxCount */ - int GetMaxStackCount(lua_State* L, Item* item) + uint32 GetMaxStackCount(Item* item) { - ALE::Push(L, item->GetMaxStackCount()); - return 1; + return item->GetMaxStackCount(); } /** @@ -350,10 +333,9 @@ namespace LuaItem * * @return uint8 slot */ - int GetSlot(lua_State* L, Item* item) + uint8 GetSlot(Item* item) { - ALE::Push(L, item->GetSlot()); - return 1; + return item->GetSlot(); } /** @@ -361,10 +343,9 @@ namespace LuaItem * * @return uint8 bagSlot */ - int GetBagSlot(lua_State* L, Item* item) + uint8 GetBagSlot(Item* item) { - ALE::Push(L, item->GetBagSlot()); - return 1; + return item->GetBagSlot(); } /** @@ -373,15 +354,12 @@ namespace LuaItem * @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 GetEnchantmentId(Item* item, uint32 enchant_slot) { - uint32 enchant_slot = ALE::CHECKVAL(L, 2); - if (enchant_slot >= MAX_INSPECTED_ENCHANTMENT_SLOT) - return luaL_argerror(L, 2, "valid EnchantmentSlot expected"); + throw std::invalid_argument("valid EnchantmentSlot expected"); - ALE::Push(L, item->GetEnchantmentId(EnchantmentSlot(enchant_slot))); - return 1; + return item->GetEnchantmentId(EnchantmentSlot(enchant_slot)); } /** @@ -390,14 +368,12 @@ namespace LuaItem * @param uint32 spellIndex : the spell index specified * @return uint32 spellId : the id of the spell */ - int GetSpellId(lua_State* L, Item* item) + int32 GetSpellId(Item* item, uint32 index) { - uint32 index = ALE::CHECKVAL(L, 2); if (index >= MAX_ITEM_PROTO_SPELLS) - return luaL_argerror(L, 2, "valid SpellIndex expected"); + throw std::invalid_argument("valid SpellIndex expected"); - ALE::Push(L, item->GetTemplate()->Spells[index].SpellId); - return 1; + return item->GetTemplate()->Spells[index].SpellId; } /** @@ -406,14 +382,12 @@ namespace LuaItem * @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 GetSpellTrigger(Item* item, uint32 index) { - uint32 index = ALE::CHECKVAL(L, 2); if (index >= MAX_ITEM_PROTO_SPELLS) - return luaL_argerror(L, 2, "valid SpellIndex expected"); + throw std::invalid_argument("valid SpellIndex expected"); - ALE::Push(L, item->GetTemplate()->Spells[index].SpellTrigger); - return 1; + return item->GetTemplate()->Spells[index].SpellTrigger; } /** @@ -421,10 +395,9 @@ namespace LuaItem * * @return uint32 class */ - int GetClass(lua_State* L, Item* item) + uint32 GetClass(Item* item) { - ALE::Push(L, item->GetTemplate()->Class); - return 1; + return item->GetTemplate()->Class; } /** @@ -432,10 +405,9 @@ namespace LuaItem * * @return uint32 subClass */ - int GetSubClass(lua_State* L, Item* item) + uint32 GetSubClass(Item* item) { - ALE::Push(L, item->GetTemplate()->SubClass); - return 1; + return item->GetTemplate()->SubClass; } /** @@ -443,10 +415,9 @@ namespace LuaItem * * @return string name */ - int GetName(lua_State* L, Item* item) + std::string GetName(Item* item) { - ALE::Push(L, item->GetTemplate()->Name1); - return 1; + return item->GetTemplate()->Name1; } /** @@ -454,10 +425,9 @@ namespace LuaItem * * @return uint32 displayId */ - int GetDisplayId(lua_State* L, Item* item) + uint32 GetDisplayId(Item* item) { - ALE::Push(L, item->GetTemplate()->DisplayInfoID); - return 1; + return item->GetTemplate()->DisplayInfoID; } /** @@ -465,10 +435,9 @@ namespace LuaItem * * @return uint32 quality */ - int GetQuality(lua_State* L, Item* item) + uint32 GetQuality(Item* item) { - ALE::Push(L, item->GetTemplate()->Quality); - return 1; + return item->GetTemplate()->Quality; } /** @@ -476,10 +445,9 @@ namespace LuaItem * * @return uint32 count */ - int GetBuyCount(lua_State* L, Item* item) + uint32 GetBuyCount(Item* item) { - ALE::Push(L, item->GetTemplate()->BuyCount); - return 1; + return item->GetTemplate()->BuyCount; } /** @@ -487,10 +455,9 @@ namespace LuaItem * * @return uint32 price */ - int GetBuyPrice(lua_State* L, Item* item) + uint32 GetBuyPrice(Item* item) { - ALE::Push(L, item->GetTemplate()->BuyPrice); - return 1; + return item->GetTemplate()->BuyPrice; } /** @@ -498,10 +465,9 @@ namespace LuaItem * * @return uint32 price */ - int GetSellPrice(lua_State* L, Item* item) + uint32 GetSellPrice(Item* item) { - ALE::Push(L, item->GetTemplate()->SellPrice); - return 1; + return item->GetTemplate()->SellPrice; } /** @@ -509,10 +475,9 @@ namespace LuaItem * * @return uint32 inventoryType */ - int GetInventoryType(lua_State* L, Item* item) + uint32 GetInventoryType(Item* item) { - ALE::Push(L, item->GetTemplate()->InventoryType); - return 1; + return item->GetTemplate()->InventoryType; } /** @@ -520,10 +485,9 @@ namespace LuaItem * * @return uint32 allowableClass */ - int GetAllowableClass(lua_State* L, Item* item) + uint32 GetAllowableClass(Item* item) { - ALE::Push(L, item->GetTemplate()->AllowableClass); - return 1; + return item->GetTemplate()->AllowableClass; } /** @@ -531,10 +495,9 @@ namespace LuaItem * * @return uint32 allowableRace */ - int GetAllowableRace(lua_State* L, Item* item) + uint32 GetAllowableRace(Item* item) { - ALE::Push(L, item->GetTemplate()->AllowableRace); - return 1; + return item->GetTemplate()->AllowableRace; } /** @@ -542,10 +505,9 @@ namespace LuaItem * * @return uint32 itemLevel */ - int GetItemLevel(lua_State* L, Item* item) + uint32 GetItemLevel(Item* item) { - ALE::Push(L, item->GetTemplate()->ItemLevel); - return 1; + return item->GetTemplate()->ItemLevel; } /** @@ -553,10 +515,9 @@ namespace LuaItem * * @return uint32 requiredLevel */ - int GetRequiredLevel(lua_State* L, Item* item) + uint32 GetRequiredLevel(Item* item) { - ALE::Push(L, item->GetTemplate()->RequiredLevel); - return 1; + return item->GetTemplate()->RequiredLevel; } /** @@ -565,10 +526,9 @@ namespace LuaItem * @param [Item] item * @return uint32 statsCount */ - int GetStatsCount(lua_State* L, Item* item) + uint32 GetStatsCount(Item* item) { - ALE::Push(L, item->GetTemplate()->StatsCount); - return 1; + return item->GetTemplate()->StatsCount; } /** @@ -576,10 +536,9 @@ namespace LuaItem * * @return uint32 randomPropertyId */ - int GetRandomProperty(lua_State* L, Item* item) + uint32 GetRandomProperty(Item* item) { - ALE::Push(L, item->GetTemplate()->RandomProperty); - return 1; + return item->GetTemplate()->RandomProperty; } /** @@ -588,10 +547,9 @@ namespace LuaItem * @param [Item] item * @return uint32 randomSuffixId */ - int GetRandomSuffix(lua_State* L, Item* item) + uint32 GetRandomSuffix(Item* item) { - ALE::Push(L, item->GetTemplate()->RandomSuffix); - return 1; + return item->GetTemplate()->RandomSuffix; } /** @@ -599,10 +557,9 @@ namespace LuaItem * * @return uint32 itemSetId */ - int GetItemSet(lua_State* L, Item* item) + uint32 GetItemSet(Item* item) { - ALE::Push(L, item->GetTemplate()->ItemSet); - return 1; + return item->GetTemplate()->ItemSet; } /** @@ -610,13 +567,12 @@ namespace LuaItem * * @return uint32 bagSize */ - int GetBagSize(lua_State* L, Item* item) + uint32 GetBagSize(Item* item) { if (Bag* bag = item->ToBag()) - ALE::Push(L, bag->GetBagSize()); - else - ALE::Push(L, 0); - return 1; + return bag->GetBagSize(); + + return 0; } /** @@ -624,10 +580,9 @@ namespace LuaItem * * @return [ItemTemplate] itemTemplate */ - int GetItemTemplate(lua_State* L, Item* item) + ItemTemplate const* GetItemTemplate(Item* item) { - ALE::Push(L, item->GetTemplate()); - return 1; + return item->GetTemplate(); } /** @@ -635,11 +590,9 @@ namespace LuaItem * * @param [Player] player : the [Player] specified */ - int SetOwner(lua_State* L, Item* item) + void SetOwner(Item* item, Player* player) { - Player* player = ALE::CHECKOBJ(L, 2); - item->SetOwnerGUID(player->GET_GUID()); - return 0; + item->SetOwnerGUID(player->GetGUID()); } /** @@ -647,14 +600,10 @@ namespace LuaItem * * @param bool setBinding */ - int SetBinding(lua_State* L, Item* item) + void SetBinding(Item* item, bool soulbound) { - bool soulbound = ALE::CHECKVAL(L, 2); - item->SetBinding(soulbound); item->SetState(ITEM_CHANGED, item->GetOwner()); - - return 0; } /** @@ -662,11 +611,9 @@ namespace LuaItem * * @param uint32 count */ - int SetCount(lua_State* L, Item* item) + void SetCount(Item* item, uint32 count) { - uint32 count = ALE::CHECKVAL(L, 2); item->SetCount(count); - return 0; } /** @@ -676,31 +623,27 @@ namespace LuaItem * @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) + bool SetEnchantment(Item* item, uint32 enchant, uint32 enchantSlot) { Player* owner = item->GetOwner(); if (!owner) { - ALE::Push(L, false); - return 1; + return false; } - uint32 enchant = ALE::CHECKVAL(L, 2); if (!sSpellItemEnchantmentStore.LookupEntry(enchant)) { - ALE::Push(L, false); - return 1; + return false; } - EnchantmentSlot slot = (EnchantmentSlot)ALE::CHECKVAL(L, 3); + EnchantmentSlot slot = (EnchantmentSlot)enchantSlot; if (slot >= MAX_INSPECTED_ENCHANTMENT_SLOT) - return luaL_argerror(L, 2, "valid EnchantmentSlot expected"); + throw std::invalid_argument("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; + return true; } @@ -709,11 +652,9 @@ namespace LuaItem * * @param uint32 randomPropId : The ID of the random property to be applied. */ - int SetRandomProperty(lua_State* L, Item* item) + void SetRandomProperty(Item* item, uint32 randomPropId) { - uint32 randomPropId = ALE::CHECKVAL(L, 2); item->SetItemRandomProperties(randomPropId); - return 0; } /** @@ -721,11 +662,9 @@ namespace LuaItem * * @param uint32 randomSuffixId : The ID of the random suffix to be applied. */ - int SetRandomSuffix(lua_State* L, Item* item) + void SetRandomSuffix(Item* item, uint32 randomPropId) { - uint32 randomPropId = ALE::CHECKVAL(L, 2); item->SetItemRandomProperties(-randomPropId); - return 0; } @@ -736,39 +675,95 @@ namespace LuaItem * @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) + bool ClearEnchantment(Item* item, uint32 enchantSlot) { Player* owner = item->GetOwner(); if (!owner) { - ALE::Push(L, false); - return 1; + return false; } - EnchantmentSlot slot = (EnchantmentSlot)ALE::CHECKVAL(L, 2); + EnchantmentSlot slot = (EnchantmentSlot)enchantSlot; if (slot >= MAX_INSPECTED_ENCHANTMENT_SLOT) - return luaL_argerror(L, 2, "valid EnchantmentSlot expected"); + throw std::invalid_argument("valid EnchantmentSlot expected"); if (!item->GetEnchantmentId(slot)) { - ALE::Push(L, false); - return 1; + return false; } owner->ApplyEnchantment(item, slot, false); item->ClearEnchantment(slot); - ALE::Push(L, true); - return 1; + return true; } /** * Saves the [Item] to the database */ - int SaveToDB(lua_State* /*L*/, Item* item) + void SaveToDB(Item* item) { CharacterDatabaseTransaction trans = CharacterDatabaseTransaction(nullptr); item->SaveToDB(trans); - return 0; } -}; -#endif +} + +void RegisterItemMethods(sol::state& lua) +{ + sol::usertype type = ALEBind::NewHandleType(lua, "Item"); + + type["IsSoulBound"] = ALEBind::Method(&LuaItem::IsSoulBound); + type["IsBoundAccountWide"] = ALEBind::Method(&LuaItem::IsBoundAccountWide); + type["IsBoundByEnchant"] = ALEBind::Method(&LuaItem::IsBoundByEnchant); + type["IsNotBoundToPlayer"] = ALEBind::Method(&LuaItem::IsNotBoundToPlayer); + type["IsLocked"] = ALEBind::Method(&LuaItem::IsLocked); + type["IsBag"] = ALEBind::Method(&LuaItem::IsBag); + type["IsCurrencyToken"] = ALEBind::Method(&LuaItem::IsCurrencyToken); + type["IsNotEmptyBag"] = ALEBind::Method(&LuaItem::IsNotEmptyBag); + type["IsBroken"] = ALEBind::Method(&LuaItem::IsBroken); + type["CanBeTraded"] = ALEBind::Method(&LuaItem::CanBeTraded); + type["IsInTrade"] = ALEBind::Method(&LuaItem::IsInTrade); + type["IsInBag"] = ALEBind::Method(&LuaItem::IsInBag); + type["IsEquipped"] = ALEBind::Method(&LuaItem::IsEquipped); + type["HasQuest"] = ALEBind::Method(&LuaItem::HasQuest); + type["IsPotion"] = ALEBind::Method(&LuaItem::IsPotion); + type["IsWeaponVellum"] = ALEBind::Method(&LuaItem::IsWeaponVellum); + type["IsArmorVellum"] = ALEBind::Method(&LuaItem::IsArmorVellum); + type["IsConjuredConsumable"] = ALEBind::Method(&LuaItem::IsConjuredConsumable); + type["GetItemLink"] = ALEBind::Method(&LuaItem::GetItemLink); + type["GetOwnerGUID"] = ALEBind::Method(&LuaItem::GetOwnerGUID); + type["GetOwner"] = ALEBind::Method(&LuaItem::GetOwner); + type["GetCount"] = ALEBind::Method(&LuaItem::GetCount); + type["GetMaxStackCount"] = ALEBind::Method(&LuaItem::GetMaxStackCount); + type["GetSlot"] = ALEBind::Method(&LuaItem::GetSlot); + type["GetBagSlot"] = ALEBind::Method(&LuaItem::GetBagSlot); + type["GetEnchantmentId"] = ALEBind::Method(&LuaItem::GetEnchantmentId); + type["GetSpellId"] = ALEBind::Method(&LuaItem::GetSpellId); + type["GetSpellTrigger"] = ALEBind::Method(&LuaItem::GetSpellTrigger); + type["GetClass"] = ALEBind::Method(&LuaItem::GetClass); + type["GetSubClass"] = ALEBind::Method(&LuaItem::GetSubClass); + type["GetName"] = ALEBind::Method(&LuaItem::GetName); + type["GetDisplayId"] = ALEBind::Method(&LuaItem::GetDisplayId); + type["GetQuality"] = ALEBind::Method(&LuaItem::GetQuality); + type["GetBuyCount"] = ALEBind::Method(&LuaItem::GetBuyCount); + type["GetBuyPrice"] = ALEBind::Method(&LuaItem::GetBuyPrice); + type["GetSellPrice"] = ALEBind::Method(&LuaItem::GetSellPrice); + type["GetInventoryType"] = ALEBind::Method(&LuaItem::GetInventoryType); + type["GetAllowableClass"] = ALEBind::Method(&LuaItem::GetAllowableClass); + type["GetAllowableRace"] = ALEBind::Method(&LuaItem::GetAllowableRace); + type["GetItemLevel"] = ALEBind::Method(&LuaItem::GetItemLevel); + type["GetRequiredLevel"] = ALEBind::Method(&LuaItem::GetRequiredLevel); + type["GetStatsCount"] = ALEBind::Method(&LuaItem::GetStatsCount); + type["GetRandomProperty"] = ALEBind::Method(&LuaItem::GetRandomProperty); + type["GetRandomSuffix"] = ALEBind::Method(&LuaItem::GetRandomSuffix); + type["GetItemSet"] = ALEBind::Method(&LuaItem::GetItemSet); + type["GetBagSize"] = ALEBind::Method(&LuaItem::GetBagSize); + type["GetItemTemplate"] = ALEBind::Method(&LuaItem::GetItemTemplate); + type["SetOwner"] = ALEBind::Method(&LuaItem::SetOwner); + type["SetBinding"] = ALEBind::Method(&LuaItem::SetBinding); + type["SetCount"] = ALEBind::Method(&LuaItem::SetCount); + type["SetEnchantment"] = ALEBind::Method(&LuaItem::SetEnchantment); + type["SetRandomProperty"] = ALEBind::Method(&LuaItem::SetRandomProperty); + type["SetRandomSuffix"] = ALEBind::Method(&LuaItem::SetRandomSuffix); + type["ClearEnchantment"] = ALEBind::Method(&LuaItem::ClearEnchantment); + type["SaveToDB"] = ALEBind::Method(&LuaItem::SaveToDB); +} diff --git a/src/LuaEngine/methods/ItemTemplateMethods.cpp b/src/LuaEngine/methods/ItemTemplateMethods.cpp new file mode 100644 index 0000000000..fc77e473e9 --- /dev/null +++ b/src/LuaEngine/methods/ItemTemplateMethods.cpp @@ -0,0 +1,235 @@ +/* +* 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 "ALEBind.h" + +#include "DBCStores.h" +#include "DBCStructure.h" +#include "ItemTemplate.h" +#include "ObjectMgr.h" +#include "SharedDefines.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 + */ + uint32 GetItemId(ItemTemplate* itemTemplate) + { + return itemTemplate->ItemId; + } + + /** + * Returns the [ItemTemplate]'s class. + * + * @return uint32 class + */ + uint32 GetClass(ItemTemplate* itemTemplate) + { + return itemTemplate->Class; + } + + /** + * Returns the [ItemTemplate]'s subclass. + * + * @return uint32 subClass + */ + uint32 GetSubClass(ItemTemplate* itemTemplate) + { + return itemTemplate->SubClass; + } + + /** + * 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 + */ + std::string GetName(ItemTemplate* itemTemplate, sol::optional locale) + { + uint32 loc_idx = locale.value_or(LocaleConstant::LOCALE_enUS); + if (loc_idx >= TOTAL_LOCALES) + throw std::invalid_argument("locale index out of range"); + + ItemLocale const* itemLocale = sObjectMgr->GetItemLocale(itemTemplate->ItemId); + std::string name = itemTemplate->Name1; + + if (itemLocale && !itemLocale->Name[loc_idx].empty()) + name = itemLocale->Name[loc_idx]; + + return name; + } + + /** + * Returns the [ItemTemplate]'s display ID. + * + * @return uint32 displayId + */ + uint32 GetDisplayId(ItemTemplate* itemTemplate) + { + return itemTemplate->DisplayInfoID; + } + + /** + * Returns the [ItemTemplate]'s quality. + * + * @return uint32 quality + */ + uint32 GetQuality(ItemTemplate* itemTemplate) + { + return itemTemplate->Quality; + } + + /** + * Returns the [ItemTemplate]'s flags. + * + * @return uint32 flags + */ + uint32 GetFlags(ItemTemplate* itemTemplate) + { + return itemTemplate->Flags; + } + + /** + * Returns the [ItemTemplate]'s extra flags. + * + * @return uint32 flags + */ + uint32 GetExtraFlags(ItemTemplate* itemTemplate) + { + return itemTemplate->Flags2; + } + + /** + * Returns the [ItemTemplate]'s default purchase count. + * + * @return uint32 buyCount + */ + uint32 GetBuyCount(ItemTemplate* itemTemplate) + { + return itemTemplate->BuyCount; + } + + /** + * Returns the [ItemTemplate]'s purchase price. + * + * @return int32 buyPrice + */ + int32 GetBuyPrice(ItemTemplate* itemTemplate) + { + return itemTemplate->BuyPrice; + } + + /** + * Returns the [ItemTemplate]'s sell price. + * + * @return uint32 sellPrice + */ + uint32 GetSellPrice(ItemTemplate* itemTemplate) + { + return itemTemplate->SellPrice; + } + + /** + * Returns the [ItemTemplate]'s inventory type. + * + * @return uint32 inventoryType + */ + uint32 GetInventoryType(ItemTemplate* itemTemplate) + { + return itemTemplate->InventoryType; + } + + /** + * Returns the [Player] classes allowed to use this [ItemTemplate]. + * + * @return uint32 allowableClass + */ + uint32 GetAllowableClass(ItemTemplate* itemTemplate) + { + return itemTemplate->AllowableClass; + } + + /** + * Returns the [Player] races allowed to use this [ItemTemplate]. + * + * @return uint32 allowableRace + */ + uint32 GetAllowableRace(ItemTemplate* itemTemplate) + { + return itemTemplate->AllowableRace; + } + + /** + * Returns the [ItemTemplate]'s item level. + * + * @return uint32 itemLevel + */ + uint32 GetItemLevel(ItemTemplate* itemTemplate) + { + return itemTemplate->ItemLevel; + } + + /** + * Returns the minimum level required to use this [ItemTemplate]. + * + * @return uint32 requiredLevel + */ + uint32 GetRequiredLevel(ItemTemplate* itemTemplate) + { + return itemTemplate->RequiredLevel; + } + + /** + * Returns the icon is used by this [ItemTemplate]. + * + * @return string itemIcon + */ + sol::optional GetIcon(ItemTemplate* itemTemplate) + { + uint32 display_id = itemTemplate->DisplayInfoID; + + // Custom or broken items can carry a display id with no DBC entry. + ItemDisplayInfoEntry const* displayInfo = sItemDisplayInfoStore.LookupEntry(display_id); + if (!displayInfo) + return sol::nullopt; + + return std::string(displayInfo->inventoryIcon); + } +} + +void RegisterItemTemplateMethods(sol::state& lua) +{ + sol::usertype type = lua.new_usertype("ItemTemplate", sol::no_constructor); + + type["GetItemId"] = &LuaItemTemplate::GetItemId; + type["GetClass"] = &LuaItemTemplate::GetClass; + type["GetSubClass"] = &LuaItemTemplate::GetSubClass; + type["GetName"] = &LuaItemTemplate::GetName; + type["GetDisplayId"] = &LuaItemTemplate::GetDisplayId; + type["GetQuality"] = &LuaItemTemplate::GetQuality; + type["GetFlags"] = &LuaItemTemplate::GetFlags; + type["GetExtraFlags"] = &LuaItemTemplate::GetExtraFlags; + type["GetBuyCount"] = &LuaItemTemplate::GetBuyCount; + type["GetBuyPrice"] = &LuaItemTemplate::GetBuyPrice; + type["GetSellPrice"] = &LuaItemTemplate::GetSellPrice; + type["GetInventoryType"] = &LuaItemTemplate::GetInventoryType; + type["GetAllowableClass"] = &LuaItemTemplate::GetAllowableClass; + type["GetAllowableRace"] = &LuaItemTemplate::GetAllowableRace; + type["GetItemLevel"] = &LuaItemTemplate::GetItemLevel; + type["GetRequiredLevel"] = &LuaItemTemplate::GetRequiredLevel; + type["GetIcon"] = &LuaItemTemplate::GetIcon; +} 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.cpp similarity index 57% rename from src/LuaEngine/methods/LootMethods.h rename to src/LuaEngine/methods/LootMethods.cpp index a48ff2d1a1..dbb8edd3b5 100644 --- a/src/LuaEngine/methods/LootMethods.h +++ b/src/LuaEngine/methods/LootMethods.cpp @@ -4,12 +4,14 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef LOOTMETHODS_H -#define LOOTMETHODS_H +#include "ALEBind.h" + +#include "LootMgr.h" +#include "Player.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 @@ -21,10 +23,9 @@ namespace LuaLoot * * @return bool isLooted */ - int IsLooted(lua_State* L, Loot* loot) + bool IsLooted(Loot* loot) { - ALE::Push(L, loot->isLooted()); - return 1; + return loot->isLooted(); } /** @@ -40,15 +41,10 @@ namespace LuaLoot * @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) + void AddItem(Loot* loot, uint32 itemid, uint8 min_count, uint8 max_count, float chance, uint16 loot_mode, sol::optional needsQuest, sol::optional allowStacking) { - 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); + bool needs_quest = needsQuest.value_or(false); + bool allow_stacking = allowStacking.value_or(true); if (allow_stacking) { @@ -61,15 +57,13 @@ namespace LuaLoot uint32 add = std::max(1u, min_count); uint32 newCount = std::min(255u, lootitem.count + add); lootitem.count = static_cast(newCount); - return 0; + return; } } } LootStoreItem newLootStoreItem(itemid, 0, chance, needs_quest, loot_mode, 0, min_count, max_count); loot->AddItem(newLootStoreItem); - - return 0; } /** @@ -79,15 +73,15 @@ namespace LuaLoot * @param uint32 count = 0 : specific count to check for. If 0, ignores count * @return bool hasItem */ - int HasItem(lua_State* L, Loot* loot) + bool HasItem(Loot* loot, sol::optional itemId, sol::optional countArg) { - uint32 itemid = ALE::CHECKVAL(L, 2, false); - uint32 count = ALE::CHECKVAL(L, 3, false); + uint32 itemid = itemId.value_or(0); + uint32 count = countArg.value_or(0); bool has_item = false; if (itemid) { - for (const LootItem &lootitem : loot->items) + for (LootItem const& lootitem : loot->items) { if (lootitem.itemid == itemid && (count == 0 || lootitem.count == count)) { @@ -98,7 +92,7 @@ namespace LuaLoot } else { - for (const LootItem &lootitem : loot->items) + for (LootItem const& lootitem : loot->items) { if (lootitem.itemid != 0) { @@ -108,66 +102,70 @@ namespace LuaLoot } } - ALE::Push(L, has_item); - return 1; + return has_item; } - /** - * 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) + // Helper for RemoveItem: erases (or decrements) matching items in one loot container. + void RemoveItemFromContainer(std::vector& container, uint32 itemid, bool isCountSpecified, uint32& remaining) { - 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(); ) { - for (auto it = container.begin(); it != container.end(); ) + if (it->itemid == itemid) { - if (it->itemid == itemid) + if (isCountSpecified) { - if (isCountSpecified) + if (it->count > remaining) { - 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; - } + it->count -= static_cast(remaining); + remaining = 0; + break; } else { + remaining -= it->count; it = container.erase(it); + if (remaining == 0) + break; continue; } } - ++it; + else + { + it = container.erase(it); + continue; + } } - }; + ++it; + } + } + + /** + * 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 + */ + void RemoveItem(Loot* loot, uint32 itemid, sol::optional isCountSpecifiedArg, sol::optional countArg) + { + bool isCountSpecified = isCountSpecifiedArg.value_or(false); + uint32 count = 0; + if (isCountSpecified) + { + if (!countArg) + throw std::invalid_argument("count expected when isCountSpecified is true"); + + count = *countArg; + } // Remove from regular items - removeFromContainer(loot->items, count); + RemoveItemFromContainer(loot->items, itemid, isCountSpecified, count); // Remove from quest items as well if (!isCountSpecified || count > 0) - removeFromContainer(loot->quest_items, count); - - return 0; + RemoveItemFromContainer(loot->quest_items, itemid, isCountSpecified, count); } /** @@ -175,10 +173,9 @@ namespace LuaLoot * * @return uint32 money : the amount of money in copper */ - int GetMoney(lua_State* L, Loot* loot) + uint32 GetMoney(Loot* loot) { - ALE::Push(L, loot->gold); - return 1; + return loot->gold; } /** @@ -186,12 +183,9 @@ namespace LuaLoot * * @param uint32 money : the amount of money to set in copper */ - int SetMoney(lua_State* L, Loot* loot) + void SetMoney(Loot* loot, uint32 gold) { - uint32 gold = ALE::CHECKVAL(L, 2); - loot->gold = gold; - return 0; } /** @@ -200,22 +194,17 @@ namespace LuaLoot * @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) + void GenerateMoney(Loot* loot, uint32 min_gold, uint32 max_gold) { - 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) + void Clear(Loot* loot) { loot->clear(); - return 0; } /** @@ -223,12 +212,9 @@ namespace LuaLoot * * @param uint32 count : the number of unlooted items */ - int SetUnlootedCount(lua_State* L, Loot* loot) + void SetUnlootedCount(Loot* loot, uint32 count) { - uint32 count = ALE::CHECKVAL(L, 2); - loot->unlootedCount = count; - return 0; } /** @@ -236,10 +222,9 @@ namespace LuaLoot * * @return uint32 unlootedCount */ - int GetUnlootedCount(lua_State* L, Loot* loot) + uint32 GetUnlootedCount(Loot* loot) { - ALE::Push(L, loot->unlootedCount); - return 1; + return loot->unlootedCount; } /** @@ -255,38 +240,26 @@ namespace LuaLoot * * @return table items : array of item tables */ - int GetItems(lua_State* L, Loot* loot) + sol::table GetItems(Loot* loot, sol::this_state s) { - lua_createtable(L, loot->items.size(), 0); - int tbl = lua_gettop(L); + sol::state_view lua(s); + sol::table tbl = lua.create_table(); 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"); + sol::table item = lua.create_table(); - ALE::Push(L, loot->items[i].itemIndex); - lua_setfield(L, -2, "index"); + item["id"] = loot->items[i].itemid; + item["index"] = loot->items[i].itemIndex; + item["count"] = static_cast(loot->items[i].count); + item["needs_quest"] = static_cast(loot->items[i].needs_quest); + item["is_looted"] = static_cast(loot->items[i].is_looted); + item["roll_winner_guid"] = loot->items[i].rollWinnerGUID; - 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); + tbl[i + 1] = item; } - lua_settop(L, tbl); - return 1; + return tbl; } /** @@ -302,38 +275,26 @@ namespace LuaLoot * * @return table quest_items : array of quest item tables */ - int GetQuestItems(lua_State* L, Loot* loot) + sol::table GetQuestItems(Loot* loot, sol::this_state s) { - lua_createtable(L, loot->quest_items.size(), 0); - int tbl = lua_gettop(L); + sol::state_view lua(s); + sol::table tbl = lua.create_table(); 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"); + sol::table item = lua.create_table(); - ALE::Push(L, loot->quest_items[i].count); - lua_setfield(L, -2, "count"); + item["id"] = loot->quest_items[i].itemid; + item["index"] = loot->quest_items[i].itemIndex; + item["count"] = static_cast(loot->quest_items[i].count); + item["needs_quest"] = static_cast(loot->quest_items[i].needs_quest); + item["is_looted"] = static_cast(loot->quest_items[i].is_looted); + item["roll_winner_guid"] = loot->quest_items[i].rollWinnerGUID; - 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); + tbl[i + 1] = item; } - lua_settop(L, tbl); - return 1; + return tbl; } /** @@ -341,7 +302,7 @@ namespace LuaLoot * * This should be called after removing items to ensure indices are sequential. */ - int UpdateItemIndex(lua_State* /*L*/, Loot* loot) + void UpdateItemIndex(Loot* loot) { uint32 index = 0; @@ -350,8 +311,6 @@ namespace LuaLoot for (unsigned int i = 0; i < loot->quest_items.size(); ++i) loot->quest_items[i].itemIndex = index++; - - return 0; } /** @@ -361,13 +320,11 @@ namespace LuaLoot * @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) + void SetItemLooted(Loot* loot, uint32 itemid, uint32 count, sol::optional lootedArg) { - uint32 itemid = ALE::CHECKVAL(L, 2); - uint32 count = ALE::CHECKVAL(L, 3); - bool looted = ALE::CHECKVAL(L, 4, true); + bool looted = lootedArg.value_or(true); - for (auto &lootItem : loot->items) + for (auto& lootItem : loot->items) { if (lootItem.itemid == itemid && (count == 0 || lootItem.count == count)) { @@ -375,7 +332,6 @@ namespace LuaLoot break; } } - return 0; } /** @@ -383,10 +339,9 @@ namespace LuaLoot * * @return bool isEmpty */ - int IsEmpty(lua_State* L, Loot* loot) + bool IsEmpty(Loot* loot) { - ALE::Push(L, loot->empty()); - return 1; + return loot->empty(); } /** @@ -394,10 +349,9 @@ namespace LuaLoot * * @return [LootType] lootType */ - int GetLootType(lua_State* L, Loot* loot) + LootType GetLootType(Loot* loot) { - ALE::Push(L, loot->loot_type); - return 1; + return loot->loot_type; } /** @@ -422,11 +376,9 @@ namespace LuaLoot * * @param [LootType] lootType : the loot type to set */ - int SetLootType(lua_State* L, Loot* loot) + void SetLootType(Loot* loot, uint32 lootType) { - uint32 lootType = ALE::CHECKVAL(L, 2); loot->loot_type = static_cast(lootType); - return 0; } /** @@ -434,10 +386,9 @@ namespace LuaLoot * * @return ObjectGuid roundRobinPlayer : the player GUID */ - int GetRoundRobinPlayer(lua_State* L, Loot* loot) + ObjectGuid GetRoundRobinPlayer(Loot* loot) { - ALE::Push(L, loot->roundRobinPlayer); - return 1; + return loot->roundRobinPlayer; } /** @@ -445,11 +396,9 @@ namespace LuaLoot * * @param ObjectGuid playerGUID : the player GUID */ - int SetRoundRobinPlayer(lua_State* L, Loot* loot) + void SetRoundRobinPlayer(Loot* loot, ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); loot->roundRobinPlayer = guid; - return 0; } /** @@ -457,10 +406,9 @@ namespace LuaLoot * * @return ObjectGuid lootOwner : the player GUID */ - int GetLootOwner(lua_State* L, Loot* loot) + ObjectGuid GetLootOwner(Loot* loot) { - ALE::Push(L, loot->lootOwnerGUID); - return 1; + return loot->lootOwnerGUID; } /** @@ -468,11 +416,9 @@ namespace LuaLoot * * @param ObjectGuid playerGUID : the player GUID */ - int SetLootOwner(lua_State* L, Loot* loot) + void SetLootOwner(Loot* loot, ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); loot->lootOwnerGUID = guid; - return 0; } /** @@ -480,10 +426,9 @@ namespace LuaLoot * * @return ObjectGuid containerGUID : the container GUID */ - int GetContainer(lua_State* L, Loot* loot) + ObjectGuid GetContainer(Loot* loot) { - ALE::Push(L, loot->containerGUID); - return 1; + return loot->containerGUID; } /** @@ -491,11 +436,9 @@ namespace LuaLoot * * @param ObjectGuid containerGUID : the container GUID */ - int SetContainer(lua_State* L, Loot* loot) + void SetContainer(Loot* loot, ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); loot->containerGUID = guid; - return 0; } /** @@ -503,10 +446,9 @@ namespace LuaLoot * * @return ObjectGuid sourceGUID : the source [WorldObject] GUID */ - int GetSourceWorldObject(lua_State* L, Loot* loot) + ObjectGuid GetSourceWorldObject(Loot* loot) { - ALE::Push(L, loot->sourceWorldObjectGUID); - return 1; + return loot->sourceWorldObjectGUID; } /** @@ -514,11 +456,9 @@ namespace LuaLoot * * @param ObjectGuid sourceGUID : the source [WorldObject] GUID */ - int SetSourceWorldObject(lua_State* L, Loot* loot) + void SetSourceWorldObject(Loot* loot, ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); loot->sourceWorldObjectGUID = guid; - return 0; } /** @@ -526,10 +466,9 @@ namespace LuaLoot * * @return bool hasQuestItems */ - int HasQuestItems(lua_State* L, Loot* loot) + bool HasQuestItems(Loot* loot) { - ALE::Push(L, !loot->quest_items.empty()); - return 1; + return !loot->quest_items.empty(); } /** @@ -537,10 +476,9 @@ namespace LuaLoot * * @return bool hasItemForAll */ - int HasItemForAll(lua_State* L, Loot* loot) + bool HasItemForAll(Loot* loot) { - ALE::Push(L, loot->hasItemForAll()); - return 1; + return loot->hasItemForAll(); } /** @@ -548,10 +486,9 @@ namespace LuaLoot * * @return bool hasOverThresholdItem */ - int HasOverThresholdItem(lua_State* L, Loot* loot) + bool HasOverThresholdItem(Loot* loot) { - ALE::Push(L, loot->hasOverThresholdItem()); - return 1; + return loot->hasOverThresholdItem(); } /** @@ -559,10 +496,9 @@ namespace LuaLoot * * @return uint32 itemCount */ - int GetItemCount(lua_State* L, Loot* loot) + uint32 GetItemCount(Loot* loot) { - ALE::Push(L, static_cast(loot->items.size() + loot->quest_items.size())); - return 1; + return static_cast(loot->items.size() + loot->quest_items.size()); } /** @@ -571,11 +507,9 @@ namespace LuaLoot * @param [Player] player : the player to check slots for * @return uint32 maxSlot */ - int GetMaxSlotForPlayer(lua_State* L, Loot* loot) + uint32 GetMaxSlotForPlayer(Loot* loot, Player* player) { - Player* player = ALE::CHECKOBJ(L, 2); - ALE::Push(L, loot->GetMaxSlotInLootFor(player)); - return 1; + return loot->GetMaxSlotInLootFor(player); } /** @@ -583,11 +517,9 @@ namespace LuaLoot * * @param [Player] player : the player to add as a looter */ - int AddLooter(lua_State* L, Loot* loot) + void AddLooter(Loot* loot, Player* player) { - Player* player = ALE::CHECKOBJ(L, 2); loot->AddLooter(player->GetGUID()); - return 0; } /** @@ -595,11 +527,46 @@ namespace LuaLoot * * @param [Player] player : the player to remove from looters */ - int RemoveLooter(lua_State* L, Loot* loot) + void RemoveLooter(Loot* loot, Player* player) { - Player* player = ALE::CHECKOBJ(L, 2); loot->RemoveLooter(player->GetGUID()); - return 0; } -}; -#endif // LOOTMETHODS_H +} + +void RegisterLootMethods(sol::state& lua) +{ + sol::usertype> type = ALEBind::NewHandleType>(lua, "Loot"); + + type["IsLooted"] = ALEBind::Method(&LuaLoot::IsLooted); + type["AddItem"] = ALEBind::Method(&LuaLoot::AddItem); + type["HasItem"] = ALEBind::Method(&LuaLoot::HasItem); + type["RemoveItem"] = ALEBind::Method(&LuaLoot::RemoveItem); + type["GetMoney"] = ALEBind::Method(&LuaLoot::GetMoney); + type["SetMoney"] = ALEBind::Method(&LuaLoot::SetMoney); + type["GenerateMoney"] = ALEBind::Method(&LuaLoot::GenerateMoney); + type["Clear"] = ALEBind::Method(&LuaLoot::Clear); + type["SetUnlootedCount"] = ALEBind::Method(&LuaLoot::SetUnlootedCount); + type["GetUnlootedCount"] = ALEBind::Method(&LuaLoot::GetUnlootedCount); + type["GetItems"] = ALEBind::Method(&LuaLoot::GetItems); + type["GetQuestItems"] = ALEBind::Method(&LuaLoot::GetQuestItems); + type["UpdateItemIndex"] = ALEBind::Method(&LuaLoot::UpdateItemIndex); + type["SetItemLooted"] = ALEBind::Method(&LuaLoot::SetItemLooted); + type["IsEmpty"] = ALEBind::Method(&LuaLoot::IsEmpty); + type["GetLootType"] = ALEBind::Method(&LuaLoot::GetLootType); + type["SetLootType"] = ALEBind::Method(&LuaLoot::SetLootType); + type["GetRoundRobinPlayer"] = ALEBind::Method(&LuaLoot::GetRoundRobinPlayer); + type["SetRoundRobinPlayer"] = ALEBind::Method(&LuaLoot::SetRoundRobinPlayer); + type["GetLootOwner"] = ALEBind::Method(&LuaLoot::GetLootOwner); + type["SetLootOwner"] = ALEBind::Method(&LuaLoot::SetLootOwner); + type["GetContainer"] = ALEBind::Method(&LuaLoot::GetContainer); + type["SetContainer"] = ALEBind::Method(&LuaLoot::SetContainer); + type["GetSourceWorldObject"] = ALEBind::Method(&LuaLoot::GetSourceWorldObject); + type["SetSourceWorldObject"] = ALEBind::Method(&LuaLoot::SetSourceWorldObject); + type["HasQuestItems"] = ALEBind::Method(&LuaLoot::HasQuestItems); + type["HasItemForAll"] = ALEBind::Method(&LuaLoot::HasItemForAll); + type["HasOverThresholdItem"] = ALEBind::Method(&LuaLoot::HasOverThresholdItem); + type["GetItemCount"] = ALEBind::Method(&LuaLoot::GetItemCount); + type["GetMaxSlotForPlayer"] = ALEBind::Method(&LuaLoot::GetMaxSlotForPlayer); + type["AddLooter"] = ALEBind::Method(&LuaLoot::AddLooter); + type["RemoveLooter"] = ALEBind::Method(&LuaLoot::RemoveLooter); +} diff --git a/src/LuaEngine/methods/MapMethods.h b/src/LuaEngine/methods/MapMethods.cpp similarity index 53% rename from src/LuaEngine/methods/MapMethods.h rename to src/LuaEngine/methods/MapMethods.cpp index 79a1a087b5..c0af274727 100644 --- a/src/LuaEngine/methods/MapMethods.h +++ b/src/LuaEngine/methods/MapMethods.cpp @@ -4,11 +4,20 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef MAPMETHODS_H -#define MAPMETHODS_H - +#include "ALEBind.h" #include "ALEInstanceAI.h" +#include "Corpse.h" +#include "Creature.h" +#include "DynamicObject.h" +#include "GameObject.h" +#include "Map.h" +#include "ObjectAccessor.h" +#include "Pet.h" +#include "Player.h" +#include "SharedDefines.h" +#include "Weather.h" + /*** * A game map, e.g. Azeroth, Eastern Kingdoms, the Molten Core, etc. * @@ -22,10 +31,9 @@ namespace LuaMap * * @return bool isArena */ - int IsArena(lua_State* L, Map* map) + bool IsArena(Map* map) { - ALE::Push(L, map->IsBattleArena()); - return 1; + return map->IsBattleArena(); } /** @@ -33,10 +41,9 @@ namespace LuaMap * * @return bool isBattleGround */ - int IsBattleground(lua_State* L, Map* map) + bool IsBattleground(Map* map) { - ALE::Push(L, map->IsBattleground()); - return 1; + return map->IsBattleground(); } /** @@ -44,10 +51,9 @@ namespace LuaMap * * @return bool isDungeon */ - int IsDungeon(lua_State* L, Map* map) + bool IsDungeon(Map* map) { - ALE::Push(L, map->IsDungeon()); - return 1; + return map->IsDungeon(); } /** @@ -55,10 +61,9 @@ namespace LuaMap * * @return bool IsEmpty */ - int IsEmpty(lua_State* L, Map* map) + bool IsEmpty(Map* map) { - ALE::Push(L, map->IsEmpty()); - return 1; + return map->IsEmpty(); } /** @@ -66,10 +71,9 @@ namespace LuaMap * * @return bool isHeroic */ - int IsHeroic(lua_State* L, Map* map) + bool IsHeroic(Map* map) { - ALE::Push(L, map->IsHeroic()); - return 1; + return map->IsHeroic(); } /** @@ -77,10 +81,9 @@ namespace LuaMap * * @return bool isRaid */ - int IsRaid(lua_State* L, Map* map) + bool IsRaid(Map* map) { - ALE::Push(L, map->IsRaid()); - return 1; + return map->IsRaid(); } /** @@ -88,10 +91,9 @@ namespace LuaMap * * @return string mapName */ - int GetName(lua_State* L, Map* map) + char const* GetName(Map* map) { - ALE::Push(L, map->GetMapName()); - return 1; + return map->GetMapName(); } /** @@ -103,15 +105,13 @@ namespace LuaMap * @param float y * @return float z */ - int GetHeight(lua_State* L, Map* map) + sol::optional GetHeight(Map* map, float x, float y, sol::optional phasemask) { - 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); + float z = map->GetHeight(phasemask.value_or(1), x, y, MAX_HEIGHT); if (z != INVALID_HEIGHT) - ALE::Push(L, z); - return 1; + return z; + + return sol::nullopt; } /** @@ -121,10 +121,9 @@ namespace LuaMap * * @return int32 difficulty */ - int GetDifficulty(lua_State* L, Map* map) + Difficulty GetDifficulty(Map* map) { - ALE::Push(L, map->GetDifficulty()); - return 1; + return map->GetDifficulty(); } /** @@ -132,10 +131,9 @@ namespace LuaMap * * @return uint32 instanceId */ - int GetInstanceId(lua_State* L, Map* map) + uint32 GetInstanceId(Map* map) { - ALE::Push(L, map->GetInstanceId()); - return 1; + return map->GetInstanceId(); } /** @@ -143,10 +141,9 @@ namespace LuaMap * * @return uint32 playerCount */ - int GetPlayerCount(lua_State* L, Map* map) + uint32 GetPlayerCount(Map* map) { - ALE::Push(L, map->GetPlayersCountExceptGMs()); - return 1; + return map->GetPlayersCountExceptGMs(); } /** @@ -154,10 +151,9 @@ namespace LuaMap * * @return uint32 mapId */ - int GetMapId(lua_State* L, Map* map) + uint32 GetMapId(Map* map) { - ALE::Push(L, map->GetId()); - return 1; + return map->GetId(); } /** @@ -169,15 +165,9 @@ namespace LuaMap * @param uint32 phasemask = PHASEMASK_NORMAL * @return uint32 areaId */ - int GetAreaId(lua_State* L, Map* map) + uint32 GetAreaId(Map* map, float x, float y, float z, sol::optional phasemask) { - 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; + return map->GetAreaId(phasemask.value_or(PHASEMASK_NORMAL), x, y, z); } /** @@ -186,37 +176,38 @@ namespace LuaMap * @param ObjectGuid guid * @return [WorldObject] object */ - int GetWorldObject(lua_State* L, Map* map) + sol::object GetWorldObject(Map* map, ObjectGuid guid, sol::this_state s) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); + WorldObject* obj = nullptr; switch (guid.GetHigh()) { - case HIGHGUID_PLAYER: - ALE::Push(L, eObjectAccessor()GetPlayer(map, guid)); + case HighGuid::Player: + obj = ObjectAccessor::GetPlayer(map, guid); break; - case HIGHGUID_TRANSPORT: - case HIGHGUID_MO_TRANSPORT: - case HIGHGUID_GAMEOBJECT: - ALE::Push(L, map->GetGameObject(guid)); + case HighGuid::Transport: + case HighGuid::Mo_Transport: + case HighGuid::GameObject: + obj = map->GetGameObject(guid); break; - case HIGHGUID_VEHICLE: - case HIGHGUID_UNIT: - ALE::Push(L, map->GetCreature(guid)); + case HighGuid::Vehicle: + case HighGuid::Unit: + obj = map->GetCreature(guid); break; - case HIGHGUID_PET: - ALE::Push(L, map->GetPet(guid)); + case HighGuid::Pet: + obj = map->GetPet(guid); break; - case HIGHGUID_DYNAMICOBJECT: - ALE::Push(L, map->GetDynamicObject(guid)); + case HighGuid::DynamicObject: + obj = map->GetDynamicObject(guid); break; - case HIGHGUID_CORPSE: - ALE::Push(L, map->GetCorpse(guid)); + case HighGuid::Corpse: + obj = map->GetCorpse(guid); break; default: break; } - return 1; + + return ALEBind::ToLuaDynamic(sol::state_view(s), obj); } /** @@ -236,16 +227,11 @@ namespace LuaMap * @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) + void SetWeather(Map* map, uint32 zoneId, uint32 weatherType, float grade) { - 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; } /** @@ -256,33 +242,30 @@ namespace LuaMap * * @return table instance_data : instance data table, or `nil` */ - int GetInstanceData(lua_State* L, Map* map) + sol::object GetInstanceData(Map* map, sol::this_state s) { - ALEInstanceAI* iAI = NULL; + ALEInstanceAI* iAI = nullptr; if (InstanceMap* inst = map->ToInstanceMap()) iAI = dynamic_cast(inst->GetInstanceScript()); + sol::state_view lua(s); if (iAI) - ALE::GetALE(L)->PushInstanceData(L, iAI, false); - else - ALE::Push(L); // nil + return sol::make_object(lua, sALE->GetInstanceData(iAI)); - return 1; + return sol::make_object(lua, sol::lua_nil); } /** * Saves the [Map]'s instance data to the database. */ - int SaveInstanceData(lua_State* /*L*/, Map* map) + void SaveInstanceData(Map* map) { - ALEInstanceAI* iAI = NULL; + ALEInstanceAI* iAI = nullptr; if (InstanceMap* inst = map->ToInstanceMap()) iAI = dynamic_cast(inst->GetInstanceScript()); if (iAI) iAI->SaveToDB(); - - return 0; } /** @@ -298,12 +281,11 @@ namespace LuaMap * @param [TeamId] team : optional check team of the [Player], Alliance, Horde or Neutral (All) * @return table mapPlayers */ - int GetPlayers(lua_State* L, Map* map) + sol::table GetPlayers(Map* map, sol::optional teamArg, sol::this_state s) { - uint32 team = ALE::CHECKVAL(L, 2, TEAM_NEUTRAL); + uint32 team = teamArg.value_or(TEAM_NEUTRAL); - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; Map::PlayerList const& players = map->GetPlayers(); @@ -313,90 +295,100 @@ namespace LuaMap if (!player) continue; if (player->GetSession() && (team >= TEAM_NEUTRAL || player->GetTeamId() == team)) - { - ALE::Push(L, player); - lua_rawseti(L, tbl, ++i); - } + tbl[++i] = PlayerRef(player); } - lua_settop(L, tbl); - return 1; + return tbl; } /** * Returns a table with all the current [Creature]s in the map - * + * * @return table mapCreatures */ - int GetCreatures(lua_State* L, Map* map) + sol::table GetCreatures(Map* map, sol::this_state s) { - const auto& creatures = map->GetCreatureBySpawnIdStore(); + auto const& creatures = map->GetCreatureBySpawnIdStore(); - lua_createtable(L, creatures.size(), 0); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); - for (const auto& pair : creatures) + for (auto const& pair : creatures) { Creature* creature = pair.second; - - ALE::Push(L, creature); - lua_rawseti(L, tbl, creature->GetSpawnId()); + tbl[creature->GetSpawnId()] = CreatureRef(creature); } - lua_settop(L, tbl); - return 1; + return tbl; } /** * 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) + sol::table GetCreaturesByAreaId(Map* map, sol::optional areaIdArg, sol::this_state s) { - int32 areaId = ALE::CHECKVAL(L, 2, -1); + int32 areaId = areaIdArg.value_or(-1); std::vector filteredCreatures; - for (const auto& pair : map->GetCreatureBySpawnIdStore()) + for (auto const& 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); + sol::table tbl = sol::state_view(s).create_table(); for (Creature* creature : filteredCreatures) - { - ALE::Push(L, creature); - lua_rawseti(L, tbl, creature->GetSpawnId()); - } + tbl[creature->GetSpawnId()] = CreatureRef(creature); - lua_settop(L, tbl); - return 1; + return tbl; } - /** * Returns a table of all [Transport]s on the [Map] * * @return table transports */ - int GetTransports(lua_State* L, Map* map) + sol::table GetTransports(Map* map, sol::this_state s) { TransportsContainer const& transports = map->GetAllTransports(); - lua_createtable(L, transports.size(), 0); + + sol::table tbl = sol::state_view(s).create_table(); int i = 1; + for (Transport* transport : transports) - { - ALE::Push(L, transport); - lua_rawseti(L, -2, i++); - } - return 1; + tbl[i++] = TransportRef(transport); + + return tbl; } -}; -#endif +} + +void RegisterMapMethods(sol::state& lua) +{ + sol::usertype type = ALEBind::NewHandleType(lua, "Map"); + + type["IsArena"] = ALEBind::Method(&LuaMap::IsArena); + type["IsBattleground"] = ALEBind::Method(&LuaMap::IsBattleground); + type["IsDungeon"] = ALEBind::Method(&LuaMap::IsDungeon); + type["IsEmpty"] = ALEBind::Method(&LuaMap::IsEmpty); + type["IsHeroic"] = ALEBind::Method(&LuaMap::IsHeroic); + type["IsRaid"] = ALEBind::Method(&LuaMap::IsRaid); + type["GetName"] = ALEBind::Method(&LuaMap::GetName); + type["GetHeight"] = ALEBind::Method(&LuaMap::GetHeight); + type["GetDifficulty"] = ALEBind::Method(&LuaMap::GetDifficulty); + type["GetInstanceId"] = ALEBind::Method(&LuaMap::GetInstanceId); + type["GetPlayerCount"] = ALEBind::Method(&LuaMap::GetPlayerCount); + type["GetMapId"] = ALEBind::Method(&LuaMap::GetMapId); + type["GetAreaId"] = ALEBind::Method(&LuaMap::GetAreaId); + type["GetWorldObject"] = ALEBind::Method(&LuaMap::GetWorldObject); + type["SetWeather"] = ALEBind::Method(&LuaMap::SetWeather); + type["GetInstanceData"] = ALEBind::Method(&LuaMap::GetInstanceData); + type["SaveInstanceData"] = ALEBind::Method(&LuaMap::SaveInstanceData); + type["GetPlayers"] = ALEBind::Method(&LuaMap::GetPlayers); + type["GetCreatures"] = ALEBind::Method(&LuaMap::GetCreatures); + type["GetCreaturesByAreaId"] = ALEBind::Method(&LuaMap::GetCreaturesByAreaId); + type["GetTransports"] = ALEBind::Method(&LuaMap::GetTransports); +} diff --git a/src/LuaEngine/methods/ObjectMethods.h b/src/LuaEngine/methods/ObjectMethods.cpp similarity index 63% rename from src/LuaEngine/methods/ObjectMethods.h rename to src/LuaEngine/methods/ObjectMethods.cpp index e99ce4f319..5f6253d153 100644 --- a/src/LuaEngine/methods/ObjectMethods.h +++ b/src/LuaEngine/methods/ObjectMethods.cpp @@ -4,8 +4,10 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef OBJECTMETHODS_H -#define OBJECTMETHODS_H +#include "ALEBind.h" + +#include "Object.h" +#include "UpdateFields.h" /*** * A basic game object (either an [Item] or a [WorldObject]). @@ -31,13 +33,9 @@ namespace LuaObject * @param uint32 flag : the flag to check for in the flags data * @return bool hasFlag */ - int HasFlag(lua_State* L, Object* obj) + bool HasFlag(Object* obj, uint16 index, uint32 flag) { - uint16 index = ALE::CHECKVAL(L, 2); - uint32 flag = ALE::CHECKVAL(L, 3); - - ALE::Push(L, obj->HasFlag(index, flag)); - return 1; + return obj->HasFlag(index, flag); } /** @@ -45,21 +43,19 @@ namespace LuaObject * * @return bool inWorld */ - int IsInWorld(lua_State* L, Object* obj) + bool IsInWorld(Object* obj) { - ALE::Push(L, obj->IsInWorld()); - return 1; + return obj->IsInWorld(); } /** - * Returns 'true' if the [Object] is a player, 'false' otherwise. - * - * @return bool IsPlayer - */ - int IsPlayer(lua_State* L, Object* obj) + * Returns 'true' if the [Object] is a player, 'false' otherwise. + * + * @return bool IsPlayer + */ + bool IsPlayer(Object* obj) { - ALE::Push(L, obj->IsPlayer()); - return 1; + return obj->IsPlayer(); } /** @@ -68,11 +64,9 @@ namespace LuaObject * @param uint16 index * @return int32 value */ - int GetInt32Value(lua_State* L, Object* obj) + int32 GetInt32Value(Object* obj, uint16 index) { - uint16 index = ALE::CHECKVAL(L, 2); - ALE::Push(L, obj->GetInt32Value(index)); - return 1; + return obj->GetInt32Value(index); } /** @@ -81,11 +75,9 @@ namespace LuaObject * @param uint16 index * @return uint32 value */ - int GetUInt32Value(lua_State* L, Object* obj) + uint32 GetUInt32Value(Object* obj, uint16 index) { - uint16 index = ALE::CHECKVAL(L, 2); - ALE::Push(L, obj->GetUInt32Value(index)); - return 1; + return obj->GetUInt32Value(index); } /** @@ -94,11 +86,9 @@ namespace LuaObject * @param uint16 index * @return float value */ - int GetFloatValue(lua_State* L, Object* obj) + float GetFloatValue(Object* obj, uint16 index) { - uint16 index = ALE::CHECKVAL(L, 2); - ALE::Push(L, obj->GetFloatValue(index)); - return 1; + return obj->GetFloatValue(index); } /** @@ -110,12 +100,9 @@ namespace LuaObject * @param uint8 offset : should be 0, 1, 2, or 3 * @return uint8 value */ - int GetByteValue(lua_State* L, Object* obj) + uint8 GetByteValue(Object* obj, uint16 index, uint8 offset) { - uint16 index = ALE::CHECKVAL(L, 2); - uint8 offset = ALE::CHECKVAL(L, 3); - ALE::Push(L, obj->GetByteValue(index, offset)); - return 1; + return obj->GetByteValue(index, offset); } /** @@ -127,12 +114,9 @@ namespace LuaObject * @param uint8 offset : should be 0 or 1 * @return uint16 value */ - int GetUInt16Value(lua_State* L, Object* obj) + uint16 GetUInt16Value(Object* obj, uint16 index, uint8 offset) { - uint16 index = ALE::CHECKVAL(L, 2); - uint8 offset = ALE::CHECKVAL(L, 3); - ALE::Push(L, obj->GetUInt16Value(index, offset)); - return 1; + return obj->GetUInt16Value(index, offset); } /** @@ -142,10 +126,9 @@ namespace LuaObject * * @return float scale */ - int GetScale(lua_State* L, Object* obj) + float GetScale(Object* obj) { - ALE::Push(L, obj->GetFloatValue(OBJECT_FIELD_SCALE_X)); - return 1; + return obj->GetFloatValue(OBJECT_FIELD_SCALE_X); } /** @@ -155,10 +138,9 @@ namespace LuaObject * * @return uint32 entry */ - int GetEntry(lua_State* L, Object* obj) + uint32 GetEntry(Object* obj) { - ALE::Push(L, obj->GetEntry()); - return 1; + return obj->GetEntry(); } /** @@ -173,10 +155,9 @@ namespace LuaObject * * @return ObjectGuid guid */ - int GetGUID(lua_State* L, Object* obj) + ObjectGuid GetGUID(Object* obj) { - ALE::Push(L, obj->GET_GUID()); - return 1; + return obj->GetGUID(); } /** @@ -191,10 +172,9 @@ namespace LuaObject * * @return uint32 guidLow */ - int GetGUIDLow(lua_State* L, Object* obj) + uint32 GetGUIDLow(Object* obj) { - ALE::Push(L, obj->GetGUID().GetCounter()); - return 1; + return obj->GetGUID().GetCounter(); } /** @@ -214,10 +194,9 @@ namespace LuaObject * * @return uint8 typeID */ - int GetTypeId(lua_State* L, Object* obj) + uint8 GetTypeId(Object* obj) { - ALE::Push(L, obj->GetTypeId()); - return 1; + return obj->GetTypeId(); } /** @@ -226,11 +205,9 @@ namespace LuaObject * @param uint16 index * @return uint64 value */ - int GetUInt64Value(lua_State* L, Object* obj) + uint64 GetUInt64Value(Object* obj, uint16 index) { - uint16 index = ALE::CHECKVAL(L, 2); - ALE::Push(L, obj->GetUInt64Value(index)); - return 1; + return obj->GetUInt64Value(index); } /** @@ -243,13 +220,9 @@ namespace LuaObject * @param uint16 index * @param uint32 value */ - int SetFlag(lua_State* L, Object* obj) + void SetFlag(Object* obj, uint16 index, uint32 flag) { - uint16 index = ALE::CHECKVAL(L, 2); - uint32 flag = ALE::CHECKVAL(L, 3); - obj->SetFlag(index, flag); - return 0; } /** @@ -258,12 +231,9 @@ namespace LuaObject * @param uint16 index * @param int32 value */ - int SetInt32Value(lua_State* L, Object* obj) + void SetInt32Value(Object* obj, uint16 index, int32 value) { - uint16 index = ALE::CHECKVAL(L, 2); - int32 value = ALE::CHECKVAL(L, 3); obj->SetInt32Value(index, value); - return 0; } /** @@ -272,12 +242,9 @@ namespace LuaObject * @param uint16 index * @param uint32 value */ - int SetUInt32Value(lua_State* L, Object* obj) + void SetUInt32Value(Object* obj, uint16 index, uint32 value) { - uint16 index = ALE::CHECKVAL(L, 2); - uint32 value = ALE::CHECKVAL(L, 3); obj->SetUInt32Value(index, value); - return 0; } /** @@ -286,12 +253,9 @@ namespace LuaObject * @param uint16 index * @param uint32 value */ - int UpdateUInt32Value(lua_State* L, Object* obj) + void UpdateUInt32Value(Object* obj, uint16 index, uint32 value) { - uint16 index = ALE::CHECKVAL(L, 2); - uint32 value = ALE::CHECKVAL(L, 3); obj->UpdateUInt32Value(index, value); - return 0; } /** @@ -300,13 +264,9 @@ namespace LuaObject * @param uint16 index * @param float value */ - int SetFloatValue(lua_State* L, Object* obj) + void SetFloatValue(Object* obj, uint16 index, float value) { - uint16 index = ALE::CHECKVAL(L, 2); - float value = ALE::CHECKVAL(L, 3); - obj->SetFloatValue(index, value); - return 0; } /** @@ -316,13 +276,9 @@ namespace LuaObject * @param uint8 offset : should be 0, 1, 2, or 3 * @param uint8 value */ - int SetByteValue(lua_State* L, Object* obj) + void SetByteValue(Object* obj, uint16 index, uint8 offset, uint8 value) { - 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; } /** @@ -332,13 +288,9 @@ namespace LuaObject * @param uint8 offset : should be 0 or 1 * @param uint16 value */ - int SetUInt16Value(lua_State* L, Object* obj) + void SetUInt16Value(Object* obj, uint16 index, uint8 offset, uint16 value) { - 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; } /** @@ -348,13 +300,9 @@ namespace LuaObject * @param uint8 offset : should be 0 or 1 * @param int16 value */ - int SetInt16Value(lua_State* L, Object* obj) + void SetInt16Value(Object* obj, uint16 index, uint8 offset, int16 value) { - 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; } /** @@ -362,12 +310,9 @@ namespace LuaObject * * @param float scale */ - int SetScale(lua_State* L, Object* obj) + void SetScale(Object* obj, float scale) { - float size = ALE::CHECKVAL(L, 2); - - obj->SetObjectScale(size); - return 0; + obj->SetObjectScale(scale); } /** @@ -376,12 +321,9 @@ namespace LuaObject * @param uint16 index * @param uint64 value */ - int SetUInt64Value(lua_State* L, Object* obj) + void SetUInt64Value(Object* obj, uint16 index, uint64 value) { - uint16 index = ALE::CHECKVAL(L, 2); - uint64 value = ALE::CHECKVAL(L, 3); obj->SetUInt64Value(index, value); - return 0; } /** @@ -390,13 +332,9 @@ namespace LuaObject * @param uint16 index * @param uint32 flag */ - int RemoveFlag(lua_State* L, Object* obj) + void RemoveFlag(Object* obj, uint16 index, uint32 flag) { - uint16 index = ALE::CHECKVAL(L, 2); - uint32 flag = ALE::CHECKVAL(L, 3); - obj->RemoveFlag(index, flag); - return 0; } /** @@ -406,10 +344,9 @@ namespace LuaObject * * @return [Corpse] corpse : the [Object] as a [Corpse], or `nil` */ - int ToCorpse(lua_State* L, Object* obj) + Corpse* ToCorpse(Object* obj) { - ALE::Push(L, obj->ToCorpse()); - return 1; + return obj->ToCorpse(); } /** @@ -419,10 +356,9 @@ namespace LuaObject * * @return [GameObject] gameObject : the [Object] as a [GameObject], or `nil` */ - int ToGameObject(lua_State* L, Object* obj) + GameObject* ToGameObject(Object* obj) { - ALE::Push(L, obj->ToGameObject()); - return 1; + return obj->ToGameObject(); } /** @@ -432,10 +368,9 @@ namespace LuaObject * * @return [Unit] unit : the [Object] as a [Unit], or `nil` */ - int ToUnit(lua_State* L, Object* obj) + Unit* ToUnit(Object* obj) { - ALE::Push(L, obj->ToUnit()); - return 1; + return obj->ToUnit(); } /** @@ -445,10 +380,9 @@ namespace LuaObject * * @return [Creature] creature : the [Object] as a [Creature], or `nil` */ - int ToCreature(lua_State* L, Object* obj) + Creature* ToCreature(Object* obj) { - ALE::Push(L, obj->ToCreature()); - return 1; + return obj->ToCreature(); } /** @@ -458,10 +392,44 @@ namespace LuaObject * * @return [Player] player : the [Object] as a [Player], or `nil` */ - int ToPlayer(lua_State* L, Object* obj) + Player* ToPlayer(Object* obj) { - ALE::Push(L, obj->ToPlayer()); - return 1; + return obj->ToPlayer(); } -}; -#endif +} + +void RegisterObjectMethods(sol::state& lua) +{ + sol::usertype type = ALEBind::NewHandleType(lua, "Object"); + + type["HasFlag"] = ALEBind::Method(&LuaObject::HasFlag); + type["IsInWorld"] = ALEBind::Method(&LuaObject::IsInWorld); + type["IsPlayer"] = ALEBind::Method(&LuaObject::IsPlayer); + type["GetInt32Value"] = ALEBind::Method(&LuaObject::GetInt32Value); + type["GetUInt32Value"] = ALEBind::Method(&LuaObject::GetUInt32Value); + type["GetFloatValue"] = ALEBind::Method(&LuaObject::GetFloatValue); + type["GetByteValue"] = ALEBind::Method(&LuaObject::GetByteValue); + type["GetUInt16Value"] = ALEBind::Method(&LuaObject::GetUInt16Value); + type["GetScale"] = ALEBind::Method(&LuaObject::GetScale); + type["GetEntry"] = ALEBind::Method(&LuaObject::GetEntry); + type["GetGUID"] = ALEBind::Method(&LuaObject::GetGUID); + type["GetGUIDLow"] = ALEBind::Method(&LuaObject::GetGUIDLow); + type["GetTypeId"] = ALEBind::Method(&LuaObject::GetTypeId); + type["GetUInt64Value"] = ALEBind::Method(&LuaObject::GetUInt64Value); + type["SetFlag"] = ALEBind::Method(&LuaObject::SetFlag); + type["SetInt32Value"] = ALEBind::Method(&LuaObject::SetInt32Value); + type["SetUInt32Value"] = ALEBind::Method(&LuaObject::SetUInt32Value); + type["UpdateUInt32Value"] = ALEBind::Method(&LuaObject::UpdateUInt32Value); + type["SetFloatValue"] = ALEBind::Method(&LuaObject::SetFloatValue); + type["SetByteValue"] = ALEBind::Method(&LuaObject::SetByteValue); + type["SetUInt16Value"] = ALEBind::Method(&LuaObject::SetUInt16Value); + type["SetInt16Value"] = ALEBind::Method(&LuaObject::SetInt16Value); + type["SetScale"] = ALEBind::Method(&LuaObject::SetScale); + type["SetUInt64Value"] = ALEBind::Method(&LuaObject::SetUInt64Value); + type["RemoveFlag"] = ALEBind::Method(&LuaObject::RemoveFlag); + type["ToCorpse"] = ALEBind::Method(&LuaObject::ToCorpse); + type["ToGameObject"] = ALEBind::Method(&LuaObject::ToGameObject); + type["ToUnit"] = ALEBind::Method(&LuaObject::ToUnit); + type["ToCreature"] = ALEBind::Method(&LuaObject::ToCreature); + type["ToPlayer"] = ALEBind::Method(&LuaObject::ToPlayer); +} diff --git a/src/LuaEngine/methods/PetMethods.h b/src/LuaEngine/methods/PetMethods.cpp similarity index 61% rename from src/LuaEngine/methods/PetMethods.h rename to src/LuaEngine/methods/PetMethods.cpp index 790da82379..5cbc809392 100644 --- a/src/LuaEngine/methods/PetMethods.h +++ b/src/LuaEngine/methods/PetMethods.cpp @@ -4,8 +4,11 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef PETMETHODS_H -#define PETMETHODS_H +#include "ALEBind.h" + +#include "Item.h" +#include "Pet.h" +#include "SpellMgr.h" /*** * Non-[Player] controlled companions that fight alongside their owners. @@ -31,10 +34,9 @@ namespace LuaPet * * @return [PetType] petType */ - int GetPetType(lua_State* L, Pet* pet) + PetType GetPetType(Pet* pet) { - ALE::Push(L, pet->getPetType()); - return 1; + return pet->getPetType(); } /** @@ -51,11 +53,9 @@ namespace LuaPet * * @param [PetType] petType : the pet type to set */ - int SetPetType(lua_State* L, Pet* pet) + void SetPetType(Pet* pet, uint32 petType) { - uint32 petType = ALE::CHECKVAL(L, 2); pet->setPetType(static_cast(petType)); - return 0; } /** @@ -63,10 +63,9 @@ namespace LuaPet * * @return bool isControlled */ - int IsControlled(lua_State* L, Pet* pet) + bool IsControlled(Pet* pet) { - ALE::Push(L, pet->isControlled()); - return 1; + return pet->isControlled(); } /** @@ -74,10 +73,9 @@ namespace LuaPet * * @return bool isTemporary */ - int IsTemporarySummoned(lua_State* L, Pet* pet) + bool IsTemporarySummoned(Pet* pet) { - ALE::Push(L, pet->isTemporarySummoned()); - return 1; + return pet->isTemporarySummoned(); } /** @@ -86,11 +84,9 @@ namespace LuaPet * @param [Player] owner : the player to check ownership for * @return bool isPermanent */ - int IsPermanentPetFor(lua_State* L, Pet* pet) + bool IsPermanentPetFor(Pet* pet, Player* owner) { - Player* owner = ALE::CHECKOBJ(L, 2); - ALE::Push(L, pet->IsPermanentPetFor(owner)); - return 1; + return pet->IsPermanentPetFor(owner); } /** @@ -99,11 +95,9 @@ namespace LuaPet * @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) + bool CreateBaseAtCreature(Pet* pet, Creature* creature) { - Creature* creature = ALE::CHECKOBJ(L, 2); - ALE::Push(L, pet->CreateBaseAtCreature(creature)); - return 1; + return pet->CreateBaseAtCreature(creature); } /** @@ -111,10 +105,9 @@ namespace LuaPet * * @return uint32 duration : remaining time in milliseconds, 0 if permanent */ - int GetDuration(lua_State* L, Pet* pet) + int64 GetDuration(Pet* pet) { - ALE::Push(L, pet->GetDuration().count()); - return 1; + return pet->GetDuration().count(); } /** @@ -122,11 +115,9 @@ namespace LuaPet * * @param uint32 duration : duration in milliseconds, 0 for permanent */ - int SetDuration(lua_State* L, Pet* pet) + void SetDuration(Pet* pet, uint32 duration) { - uint32 duration = ALE::CHECKVAL(L, 2); pet->SetDuration(Milliseconds(duration)); - return 0; } /** @@ -143,10 +134,9 @@ namespace LuaPet * * @return [HappinessState] happinessState */ - int GetHappinessState(lua_State* L, Pet* pet) + HappinessState GetHappinessState(Pet* pet) { - ALE::Push(L, pet->GetHappinessState()); - return 1; + return pet->GetHappinessState(); } /** @@ -154,11 +144,9 @@ namespace LuaPet * * @param uint32 xp : amount of experience to give */ - int GivePetXP(lua_State* L, Pet* pet) + void GivePetXP(Pet* pet, uint32 xp) { - uint32 xp = ALE::CHECKVAL(L, 2); pet->GivePetXP(xp); - return 0; } /** @@ -166,11 +154,9 @@ namespace LuaPet * * @param uint8 level : the level to set */ - int GivePetLevel(lua_State* L, Pet* pet) + void GivePetLevel(Pet* pet, uint8 level) { - uint8 level = ALE::CHECKVAL(L, 2); pet->GivePetLevel(level); - return 0; } /** @@ -178,10 +164,9 @@ namespace LuaPet * * The pet's level will be adjusted based on the owner's level and pet scaling rules. */ - int SynchronizeLevelWithOwner(lua_State* /*L*/, Pet* pet) + void SynchronizeLevelWithOwner(Pet* pet) { pet->SynchronizeLevelWithOwner(); - return 0; } /** @@ -190,11 +175,9 @@ namespace LuaPet * @param [Item] item : the item to check * @return bool canEat */ - int HaveInDiet(lua_State* L, Pet* pet) + bool HaveInDiet(Pet* pet, Item* item) { - Item* item = ALE::CHECKOBJ(L, 2); - ALE::Push(L, pet->HaveInDiet(item->GetTemplate())); - return 1; + return pet->HaveInDiet(item->GetTemplate()); } /** @@ -203,11 +186,9 @@ namespace LuaPet * @param uint32 itemLevel : the level of the food item * @return uint32 benefitLevel */ - int GetCurrentFoodBenefitLevel(lua_State* L, Pet* pet) + uint32 GetCurrentFoodBenefitLevel(Pet* pet, uint32 itemLevel) { - uint32 itemLevel = ALE::CHECKVAL(L, 2); - ALE::Push(L, pet->GetCurrentFoodBenefitLevel(itemLevel)); - return 1; + return pet->GetCurrentFoodBenefitLevel(itemLevel); } /** @@ -216,16 +197,11 @@ namespace LuaPet * @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) + void ToggleAutocast(Pet* pet, uint32 spellId, bool apply) { - 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; } /** @@ -233,10 +209,9 @@ namespace LuaPet * * This includes racial passives and pet-specific passive abilities. */ - int LearnPetPassives(lua_State* /*L*/, Pet* pet) + void LearnPetPassives(Pet* pet) { pet->LearnPetPassives(); - return 0; } /** @@ -246,24 +221,18 @@ namespace LuaPet * @param [Unit] target : the target for the spell * @param bool isPositive = false : whether the spell is beneficial */ - int CastWhenWillAvailable(lua_State* L, Pet* pet) + void CastWhenWillAvailable(Pet* pet, uint32 spellId, Unit* target, sol::optional isPositive) { - 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; + pet->CastWhenWillAvailable(spellId, target, oldTarget, isPositive.value_or(false)); } /** * Clears any queued spell that was set to cast when available. */ - int ClearCastWhenWillAvailable(lua_State* /*L*/, Pet* pet) + void ClearCastWhenWillAvailable(Pet* pet) { pet->ClearCastWhenWillAvailable(); - return 0; } /** @@ -306,15 +275,13 @@ namespace LuaPet * @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) + bool AddSpell(Pet* pet, uint32 spellId, sol::optional active, sol::optional state, + sol::optional type) { - 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; + return pet->addSpell(spellId, + static_cast(active.value_or(ACT_DECIDE)), + static_cast(state.value_or(PETSPELL_NEW)), + static_cast(type.value_or(PETSPELL_NORMAL))); } /** @@ -323,11 +290,9 @@ namespace LuaPet * @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) + bool LearnSpell(Pet* pet, uint32 spellId) { - uint32 spellId = ALE::CHECKVAL(L, 2); - ALE::Push(L, pet->learnSpell(spellId)); - return 1; + return pet->learnSpell(spellId); } /** @@ -335,11 +300,9 @@ namespace LuaPet * * @param uint32 spellId : the base spell ID */ - int LearnSpellHighRank(lua_State* L, Pet* pet) + void LearnSpellHighRank(Pet* pet, uint32 spellId) { - uint32 spellId = ALE::CHECKVAL(L, 2); pet->learnSpellHighRank(spellId); - return 0; } /** @@ -347,10 +310,9 @@ namespace LuaPet * * This teaches the pet all spells it should know at its current level. */ - int InitLevelupSpellsForLevel(lua_State* /*L*/, Pet* pet) + void InitLevelupSpellsForLevel(Pet* pet) { pet->InitLevelupSpellsForLevel(); - return 0; } /** @@ -361,14 +323,9 @@ namespace LuaPet * @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) + bool UnlearnSpell(Pet* pet, uint32 spellId, sol::optional learnPrev, sol::optional clearAb) { - 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; + return pet->unlearnSpell(spellId, learnPrev.value_or(false), clearAb.value_or(true)); } /** @@ -379,23 +336,17 @@ namespace LuaPet * @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) + bool RemoveSpell(Pet* pet, uint32 spellId, sol::optional learnPrev, sol::optional clearAb) { - 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; + return pet->removeSpell(spellId, learnPrev.value_or(false), clearAb.value_or(true)); } /** * Cleans up the [Pet]'s action bar, removing invalid spells. */ - int CleanupActionBar(lua_State* /*L*/, Pet* pet) + void CleanupActionBar(Pet* pet) { pet->CleanupActionBar(); - return 0; } /** @@ -403,10 +354,9 @@ namespace LuaPet * * @return string actionBarData : the action bar data as a string */ - int GenerateActionBarData(lua_State* L, Pet* pet) + std::string GenerateActionBarData(Pet* pet) { - ALE::Push(L, pet->GenerateActionBarData()); - return 1; + return pet->GenerateActionBarData(); } /** @@ -414,10 +364,9 @@ namespace LuaPet * * This sets up the basic spells the pet should have when first created. */ - int InitPetCreateSpells(lua_State* /*L*/, Pet* pet) + void InitPetCreateSpells(Pet* pet) { pet->InitPetCreateSpells(); - return 0; } /** @@ -425,10 +374,9 @@ namespace LuaPet * * @return bool success : `true` if talents were reset successfully */ - int ResetTalents(lua_State* L, Pet* pet) + bool ResetTalents(Pet* pet) { - ALE::Push(L, pet->resetTalents()); - return 1; + return pet->resetTalents(); } /** @@ -436,10 +384,9 @@ namespace LuaPet * * This assigns talent points based on the pet's level. */ - int InitTalentForLevel(lua_State* /*L*/, Pet* pet) + void InitTalentForLevel(Pet* pet) { pet->InitTalentForLevel(); - return 0; } /** @@ -448,11 +395,9 @@ namespace LuaPet * @param uint8 level : the level to check * @return uint8 maxTalentPoints */ - int GetMaxTalentPointsForLevel(lua_State* L, Pet* pet) + uint8 GetMaxTalentPointsForLevel(Pet* pet, uint8 level) { - uint8 level = ALE::CHECKVAL(L, 2); - ALE::Push(L, pet->GetMaxTalentPointsForLevel(level)); - return 1; + return pet->GetMaxTalentPointsForLevel(level); } /** @@ -460,10 +405,9 @@ namespace LuaPet * * @return uint8 freeTalentPoints */ - int GetFreeTalentPoints(lua_State* L, Pet* pet) + uint8 GetFreeTalentPoints(Pet* pet) { - ALE::Push(L, pet->GetFreeTalentPoints()); - return 1; + return pet->GetFreeTalentPoints(); } /** @@ -471,11 +415,9 @@ namespace LuaPet * * @param uint8 points : the number of free talent points to set */ - int SetFreeTalentPoints(lua_State* L, Pet* pet) + void SetFreeTalentPoints(Pet* pet, uint8 points) { - uint8 points = ALE::CHECKVAL(L, 2); pet->SetFreeTalentPoints(points); - return 0; } /** @@ -483,10 +425,9 @@ namespace LuaPet * * @return uint32 usedTalentCount */ - int GetUsedTalentCount(lua_State* L, Pet* pet) + uint32 GetUsedTalentCount(Pet* pet) { - ALE::Push(L, pet->m_usedTalentCount); - return 1; + return pet->m_usedTalentCount; } /** @@ -494,11 +435,9 @@ namespace LuaPet * * @param uint32 count : the number of used talents to set */ - int SetUsedTalentCount(lua_State* L, Pet* pet) + void SetUsedTalentCount(Pet* pet, uint32 count) { - uint32 count = ALE::CHECKVAL(L, 2); pet->m_usedTalentCount = count; - return 0; } /** @@ -506,10 +445,9 @@ namespace LuaPet * * @return uint64 auraUpdateMask */ - int GetAuraUpdateMaskForRaid(lua_State* L, Pet* pet) + uint64 GetAuraUpdateMaskForRaid(Pet* pet) { - ALE::Push(L, pet->GetAuraUpdateMaskForRaid()); - return 1; + return pet->GetAuraUpdateMaskForRaid(); } /** @@ -517,20 +455,17 @@ namespace LuaPet * * @param uint8 slot : the aura slot to set */ - int SetAuraUpdateMaskForRaid(lua_State* L, Pet* pet) + void SetAuraUpdateMaskForRaid(Pet* pet, uint8 slot) { - 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) + void ResetAuraUpdateMaskForRaid(Pet* pet) { pet->ResetAuraUpdateMaskForRaid(); - return 0; } /** @@ -538,10 +473,9 @@ namespace LuaPet * * @return [Player] owner : the pet's owner */ - int GetOwner(lua_State* L, Pet* pet) + Player* GetOwner(Pet* pet) { - ALE::Push(L, pet->GetOwner()); - return 1; + return pet->GetOwner(); } /** @@ -549,10 +483,9 @@ namespace LuaPet * * @return bool hasTempSpell */ - int HasTempSpell(lua_State* L, Pet* pet) + bool HasTempSpell(Pet* pet) { - ALE::Push(L, pet->HasTempSpell()); - return 1; + return pet->HasTempSpell(); } /** @@ -560,10 +493,9 @@ namespace LuaPet * * @return bool isRemoved */ - int IsRemoved(lua_State* L, Pet* pet) + bool IsRemoved(Pet* pet) { - ALE::Push(L, pet->m_removed); - return 1; + return pet->m_removed; } /** @@ -571,11 +503,9 @@ namespace LuaPet * * @param bool removed : `true` to mark as removed, `false` otherwise */ - int SetRemoved(lua_State* L, Pet* pet) + void SetRemoved(Pet* pet, bool removed) { - bool removed = ALE::CHECKVAL(L, 2); pet->m_removed = removed; - return 0; } /** @@ -583,10 +513,9 @@ namespace LuaPet * * @return uint8 autoSpellCount */ - int GetPetAutoSpellSize(lua_State* L, Pet* pet) + uint8 GetPetAutoSpellSize(Pet* pet) { - ALE::Push(L, pet->GetPetAutoSpellSize()); - return 1; + return pet->GetPetAutoSpellSize(); } /** @@ -595,11 +524,9 @@ namespace LuaPet * @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) + uint32 GetPetAutoSpellOnPos(Pet* pet, uint8 pos) { - uint8 pos = ALE::CHECKVAL(L, 2); - ALE::Push(L, pet->GetPetAutoSpellOnPos(pos)); - return 1; + return pet->GetPetAutoSpellOnPos(pos); } /** @@ -618,11 +545,9 @@ namespace LuaPet * * @param [PetSaveMode] mode : the save mode to use */ - int SavePetToDB(lua_State* L, Pet* pet) + void SavePetToDB(Pet* pet, uint32 mode) { - uint32 mode = ALE::CHECKVAL(L, 2); pet->SavePetToDB(static_cast(mode)); - return 0; } /** @@ -642,12 +567,9 @@ namespace LuaPet * @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) + void Remove(Pet* pet, uint32 mode, sol::optional returnReagent) { - uint32 mode = ALE::CHECKVAL(L, 2); - bool returnReagent = ALE::CHECKVAL(L, 3, false); - pet->Remove(static_cast(mode), returnReagent); - return 0; + pet->Remove(static_cast(mode), returnReagent.value_or(false)); } /** @@ -655,11 +577,60 @@ namespace LuaPet * * @return bool isBeingLoaded */ - int IsBeingLoaded(lua_State* L, Pet* pet) + bool IsBeingLoaded(Pet* pet) { - ALE::Push(L, pet->isBeingLoaded()); - return 1; + return pet->isBeingLoaded(); } -}; -#endif // PETMETHODS_H +} +void RegisterPetMethods(sol::state& lua) +{ + sol::usertype type = ALEBind::NewHandleType(lua, "Pet"); + + type["GetPetType"] = ALEBind::Method(&LuaPet::GetPetType); + type["SetPetType"] = ALEBind::Method(&LuaPet::SetPetType); + type["IsControlled"] = ALEBind::Method(&LuaPet::IsControlled); + type["IsTemporarySummoned"] = ALEBind::Method(&LuaPet::IsTemporarySummoned); + type["IsPermanentPetFor"] = ALEBind::Method(&LuaPet::IsPermanentPetFor); + type["CreateBaseAtCreature"] = ALEBind::Method(&LuaPet::CreateBaseAtCreature); + type["GetDuration"] = ALEBind::Method(&LuaPet::GetDuration); + type["SetDuration"] = ALEBind::Method(&LuaPet::SetDuration); + type["GetHappinessState"] = ALEBind::Method(&LuaPet::GetHappinessState); + type["GivePetXP"] = ALEBind::Method(&LuaPet::GivePetXP); + type["GivePetLevel"] = ALEBind::Method(&LuaPet::GivePetLevel); + type["SynchronizeLevelWithOwner"] = ALEBind::Method(&LuaPet::SynchronizeLevelWithOwner); + type["HaveInDiet"] = ALEBind::Method(&LuaPet::HaveInDiet); + type["GetCurrentFoodBenefitLevel"] = ALEBind::Method(&LuaPet::GetCurrentFoodBenefitLevel); + type["ToggleAutocast"] = ALEBind::Method(&LuaPet::ToggleAutocast); + type["LearnPetPassives"] = ALEBind::Method(&LuaPet::LearnPetPassives); + type["CastWhenWillAvailable"] = ALEBind::Method(&LuaPet::CastWhenWillAvailable); + type["ClearCastWhenWillAvailable"] = ALEBind::Method(&LuaPet::ClearCastWhenWillAvailable); + type["AddSpell"] = ALEBind::Method(&LuaPet::AddSpell); + type["LearnSpell"] = ALEBind::Method(&LuaPet::LearnSpell); + type["LearnSpellHighRank"] = ALEBind::Method(&LuaPet::LearnSpellHighRank); + type["InitLevelupSpellsForLevel"] = ALEBind::Method(&LuaPet::InitLevelupSpellsForLevel); + type["UnlearnSpell"] = ALEBind::Method(&LuaPet::UnlearnSpell); + type["RemoveSpell"] = ALEBind::Method(&LuaPet::RemoveSpell); + type["CleanupActionBar"] = ALEBind::Method(&LuaPet::CleanupActionBar); + type["GenerateActionBarData"] = ALEBind::Method(&LuaPet::GenerateActionBarData); + type["InitPetCreateSpells"] = ALEBind::Method(&LuaPet::InitPetCreateSpells); + type["ResetTalents"] = ALEBind::Method(&LuaPet::ResetTalents); + type["InitTalentForLevel"] = ALEBind::Method(&LuaPet::InitTalentForLevel); + type["GetMaxTalentPointsForLevel"] = ALEBind::Method(&LuaPet::GetMaxTalentPointsForLevel); + type["GetFreeTalentPoints"] = ALEBind::Method(&LuaPet::GetFreeTalentPoints); + type["SetFreeTalentPoints"] = ALEBind::Method(&LuaPet::SetFreeTalentPoints); + type["GetUsedTalentCount"] = ALEBind::Method(&LuaPet::GetUsedTalentCount); + type["SetUsedTalentCount"] = ALEBind::Method(&LuaPet::SetUsedTalentCount); + type["GetAuraUpdateMaskForRaid"] = ALEBind::Method(&LuaPet::GetAuraUpdateMaskForRaid); + type["SetAuraUpdateMaskForRaid"] = ALEBind::Method(&LuaPet::SetAuraUpdateMaskForRaid); + type["ResetAuraUpdateMaskForRaid"] = ALEBind::Method(&LuaPet::ResetAuraUpdateMaskForRaid); + type["GetOwner"] = ALEBind::Method(&LuaPet::GetOwner); + type["HasTempSpell"] = ALEBind::Method(&LuaPet::HasTempSpell); + type["IsRemoved"] = ALEBind::Method(&LuaPet::IsRemoved); + type["SetRemoved"] = ALEBind::Method(&LuaPet::SetRemoved); + type["GetPetAutoSpellSize"] = ALEBind::Method(&LuaPet::GetPetAutoSpellSize); + type["GetPetAutoSpellOnPos"] = ALEBind::Method(&LuaPet::GetPetAutoSpellOnPos); + type["SavePetToDB"] = ALEBind::Method(&LuaPet::SavePetToDB); + type["Remove"] = ALEBind::Method(&LuaPet::Remove); + type["IsBeingLoaded"] = ALEBind::Method(&LuaPet::IsBeingLoaded); +} diff --git a/src/LuaEngine/methods/PlayerMethods.h b/src/LuaEngine/methods/PlayerMethods.cpp similarity index 56% rename from src/LuaEngine/methods/PlayerMethods.h rename to src/LuaEngine/methods/PlayerMethods.cpp index c39801fc98..cef549382d 100644 --- a/src/LuaEngine/methods/PlayerMethods.h +++ b/src/LuaEngine/methods/PlayerMethods.cpp @@ -4,12 +4,34 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef PLAYERMETHODS_H -#define PLAYERMETHODS_H +#include "ALEBind.h" +#include "AccountMgr.h" +#include "AchievementMgr.h" +#include "AuctionHouseMgr.h" +#include "Bag.h" +#include "CharacterCache.h" #include "Chat.h" +#include "DBCStores.h" +#include "DatabaseEnv.h" #include "GameTime.h" #include "GossipDef.h" +#include "Group.h" +#include "GroupMgr.h" +#include "Guild.h" +#include "GuildMgr.h" +#include "InstanceSaveMgr.h" +#include "Item.h" +#include "ObjectMgr.h" +#include "Opcodes.h" +#include "Pet.h" +#include "Player.h" +#include "QuestDef.h" +#include "ReputationMgr.h" +#include "SpellInfo.h" +#include "SpellMgr.h" +#include "WorldPacket.h" +#include "WorldSession.h" /*** * Inherits all methods from: [Object], [WorldObject], [Unit] @@ -21,10 +43,9 @@ namespace LuaPlayer * * @return bool canTitanGrip */ - int CanTitanGrip(lua_State* L, Player* player) + bool CanTitanGrip(Player* player) { - ALE::Push(L, player->CanTitanGrip()); - return 1; + return player->CanTitanGrip(); } /** @@ -34,15 +55,13 @@ namespace LuaPlayer * @param uint8 spec : specified spec. 0 for primary, 1 for secondary. * @return bool hasTalent */ - int HasTalent(lua_State* L, Player* player) + sol::optional HasTalent(Player* player, uint32 spellId, uint8 spec) { - 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; + return sol::nullopt; + + return player->HasTalent(spellId, spec); } /** @@ -51,11 +70,9 @@ namespace LuaPlayer * @param uint32 achievementId * @return bool hasAchieved */ - int HasAchieved(lua_State* L, Player* player) + bool HasAchieved(Player* player, uint32 achievementId) { - uint32 achievementId = ALE::CHECKVAL(L, 2); - ALE::Push(L, player->HasAchieved(achievementId)); - return 1; + return player->HasAchieved(achievementId); } /** @@ -64,20 +81,14 @@ namespace LuaPlayer * @param uint32 criteriaId * @return uint32 progress : progress value or nil */ - int GetAchievementCriteriaProgress(lua_State* L, Player* player) + sol::optional GetAchievementCriteriaProgress(Player* player, uint32 criteriaId) { - uint32 criteriaId = ALE::CHECKVAL(L, 2); - const AchievementCriteriaEntry* criteria = sAchievementCriteriaStore.LookupEntry(criteriaId); + AchievementCriteriaEntry const* 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; + return progress->counter; + + return sol::nullopt; } /** @@ -86,12 +97,9 @@ namespace LuaPlayer * @param uint32 questId * @return bool hasQuest */ - int HasQuest(lua_State* L, Player* player) + bool HasQuest(Player* player, uint32 quest) { - uint32 quest = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->IsActiveQuest(quest)); - return 1; + return player->IsActiveQuest(quest); } /** @@ -100,12 +108,9 @@ namespace LuaPlayer * @param uint32 skill * @return bool hasSkill */ - int HasSkill(lua_State* L, Player* player) + bool HasSkill(Player* player, uint32 skill) { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->HasSkill(skill)); - return 1; + return player->HasSkill(skill); } /** @@ -114,12 +119,9 @@ namespace LuaPlayer * @param uint32 spellId * @return bool hasSpell */ - int HasSpell(lua_State* L, Player* player) + bool HasSpell(Player* player, uint32 id) { - uint32 id = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->HasSpell(id)); - return 1; + return player->HasSpell(id); } /** @@ -128,12 +130,9 @@ namespace LuaPlayer * @param uint32 flag * @return bool hasLoginFlag */ - int HasAtLoginFlag(lua_State* L, Player* player) + bool HasAtLoginFlag(Player* player, uint32 flag) { - uint32 flag = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->HasAtLoginFlag((AtLoginFlags)flag)); - return 1; + return player->HasAtLoginFlag((AtLoginFlags)flag); } /** @@ -142,12 +141,9 @@ namespace LuaPlayer * @param int32 entry : entry of a [GameObject] * @return bool hasQuest */ - int HasQuestForGO(lua_State* L, Player* player) + bool HasQuestForGO(Player* player, int32 entry) { - int32 entry = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->HasQuestForGO(entry)); - return 1; + return player->HasQuestForGO(entry); } /** @@ -156,15 +152,15 @@ namespace LuaPlayer * @param uint32 titleId * @return bool hasTitle */ - int HasTitle(lua_State* L, Player* player) + sol::optional HasTitle(Player* player, uint32 id) { - uint32 id = ALE::CHECKVAL(L, 2); CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id); if (titleInfo) - ALE::Push(L, player->HasTitle(titleInfo)); - return 1; + return player->HasTitle(titleInfo); + + return sol::nullopt; } - + /** * Returns `true` if the [Player] has the given amount of item entry specified, `false` otherwise. * @@ -173,29 +169,24 @@ namespace LuaPlayer * @param bool check_bank = false : determines if the item can be in player bank * @return bool hasItem */ - int HasItem(lua_State* L, Player* player) + bool HasItem(Player* player, uint32 itemId, sol::optional countArg, sol::optional checkBankArg) { - 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; + uint32 count = countArg.value_or(1); + bool check_bank = checkBankArg.value_or(false); + return player->HasItemCount(itemId, count, check_bank); } - + /** * 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) + bool HasQuestForItem(Player* player, uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->HasQuestForItem(entry)); - return 1; + return player->HasQuestForItem(entry); } - + /** * Returns `true` if the [Player] can use the item or item entry specified, `false` otherwise. * @@ -205,21 +196,20 @@ namespace LuaPlayer * @param uint32 entry : entry of the item * @return bool canUse */ - int CanUseItem(lua_State* L, Player* player) + bool CanUseItem(Player* player, sol::object itemOrEntry) { - Item* item = ALE::CHECKOBJ(L, 2, false); - if (item) - ALE::Push(L, player->CanUseItem(item) == EQUIP_ERR_OK); - else + if (itemOrEntry.is()) { - 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); + Item* item = itemOrEntry.as().Require(); + return player->CanUseItem(item) == EQUIP_ERR_OK; } - return 1; + + uint32 entry = itemOrEntry.as(); + ItemTemplate const* temp = sObjectMgr->GetItemTemplate(entry); + if (temp) + return player->CanUseItem(temp) == EQUIP_ERR_OK; + + return false; } /** @@ -228,12 +218,9 @@ namespace LuaPlayer * @param uint32 spellId * @return bool hasSpellCooldown */ - int HasSpellCooldown(lua_State* L, Player* player) + bool HasSpellCooldown(Player* player, uint32 spellId) { - uint32 spellId = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->HasSpellCooldown(spellId)); - return 1; + return player->HasSpellCooldown(spellId); } /** @@ -242,12 +229,9 @@ namespace LuaPlayer * @param uint32 entryId * @return bool hasSpellCooldown */ - int CanShareQuest(lua_State* L, Player* player) + bool CanShareQuest(Player* player, uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->CanShareQuest(entry)); - return 1; + return player->CanShareQuest(entry); } /** @@ -255,10 +239,9 @@ namespace LuaPlayer * * @return bool canSpeak */ - int CanSpeak(lua_State* L, Player* player) + bool CanSpeak(Player* player) { - ALE::Push(L, player->CanSpeak()); - return 1; + return player->CanSpeak(); } /** @@ -266,10 +249,9 @@ namespace LuaPlayer * * @return bool canUninviteFromGroup */ - int CanUninviteFromGroup(lua_State* L, Player* player) + bool CanUninviteFromGroup(Player* player) { - ALE::Push(L, player->CanUninviteFromGroup() == ERR_PARTY_RESULT_OK); - return 1; + return player->CanUninviteFromGroup() == ERR_PARTY_RESULT_OK; } /** @@ -277,10 +259,9 @@ namespace LuaPlayer * * @return bool canFly */ - int CanFly(lua_State* L, Player* player) + bool CanFly(Player* player) { - ALE::Push(L, player->CanFly()); - return 1; + return player->CanFly(); } /** @@ -288,10 +269,9 @@ namespace LuaPlayer * * @return bool isInWater */ - int IsInWater(lua_State* L, Player* player) + bool IsInWater(Player* player) { - ALE::Push(L, player->IsInWater()); - return 1; + return player->IsInWater(); } /** @@ -299,10 +279,9 @@ namespace LuaPlayer * * @return bool isMoving */ - int IsMoving(lua_State* L, Player* player) // enable for unit when mangos support it + bool IsMoving(Player* player) // enable for unit when mangos support it { - ALE::Push(L, player->isMoving()); - return 1; + return player->isMoving(); } /** @@ -310,10 +289,9 @@ namespace LuaPlayer * * @return bool isFlying */ - int IsFlying(lua_State* L, Player* player) // enable for unit when mangos support it + bool IsFlying(Player* player) // enable for unit when mangos support it { - ALE::Push(L, player->IsFlying()); - return 1; + return player->IsFlying(); } /** @@ -321,7 +299,7 @@ namespace LuaPlayer * * @return uint32 freeSlots */ - int GetInventoryFreeSlots(lua_State* L, Player* player) + uint32 GetInventoryFreeSlots(Player* player) { uint32 freeSlots = 0; @@ -345,8 +323,7 @@ namespace LuaPlayer } } - ALE::Push(L, freeSlots); - return 1; + return freeSlots; } /** @@ -354,7 +331,7 @@ namespace LuaPlayer * * @return uint32 freeSlots */ - int GetBankFreeSlots(lua_State* L, Player* player) + uint32 GetBankFreeSlots(Player* player) { uint32 freeSlots = 0; @@ -378,53 +355,47 @@ namespace LuaPlayer } } - ALE::Push(L, freeSlots); - return 1; + return freeSlots; } - /** * Returns `true` if the [Player] has a Tank Specialization, `false` otherwise. * * @return bool HasTankSpec */ - int HasTankSpec(lua_State* L, Player* player) + bool HasTankSpec(Player* player) { - ALE::Push(L, player->HasTankSpec()); - return 1; + return player->HasTankSpec(); } - + /** * Returns `true` if the [Player] has a Melee Specialization, `false` otherwise. * * @return bool HasMeleeSpec */ - int HasMeleeSpec(lua_State* L, Player* player) + bool HasMeleeSpec(Player* player) { - ALE::Push(L, player->HasMeleeSpec()); - return 1; + return player->HasMeleeSpec(); } - + /** * Returns `true` if the [Player] has a Caster Specialization, `false` otherwise. * * @return bool HasCasterSpec */ - int HasCasterSpec(lua_State* L, Player* player) + bool HasCasterSpec(Player* player) { - ALE::Push(L, player->HasCasterSpec()); - return 1; + return player->HasCasterSpec(); } - + /** * Returns `true` if the [Player] has a Heal Specialization, `false` otherwise. * * @return bool HasHealSpec */ - int HasHealSpec(lua_State* L, Player* player) + bool HasHealSpec(Player* player) { - ALE::Push(L, player->HasHealSpec()); - return 1; + return player->HasHealSpec(); } /** @@ -432,10 +403,9 @@ namespace LuaPlayer * * @return bool isInGroup */ - int IsInGroup(lua_State* L, Player* player) + bool IsInGroup(Player* player) { - ALE::Push(L, (player->GetGroup() != NULL)); - return 1; + return player->GetGroup() != nullptr; } /** @@ -443,10 +413,9 @@ namespace LuaPlayer * * @return bool isInGuild */ - int IsInGuild(lua_State* L, Player* player) + bool IsInGuild(Player* player) { - ALE::Push(L, (player->GetGuildId() != 0)); - return 1; + return player->GetGuildId() != 0; } /** @@ -456,10 +425,9 @@ namespace LuaPlayer * * @return bool isGM */ - int IsGM(lua_State* L, Player* player) + bool IsGM(Player* player) { - ALE::Push(L, player->IsGameMaster()); - return 1; + return player->IsGameMaster(); } /** @@ -468,14 +436,12 @@ namespace LuaPlayer * @param uint32 type * @return bool isInArenaTeam */ - int IsInArenaTeam(lua_State* L, Player* player) + bool IsInArenaTeam(Player* player, uint32 type) { - 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; + return true; + + return false; } /** @@ -483,10 +449,9 @@ namespace LuaPlayer * * @return bool isImmune */ - int IsImmuneToDamage(lua_State* L, Player* player) + bool IsImmuneToDamage(Player* player) { - ALE::Push(L, player->isTotalImmune()); - return 1; + return player->isTotalImmune(); } /** @@ -495,18 +460,13 @@ namespace LuaPlayer * @param uint32 questId * @return bool canCompleteRepeatableQuest */ - int CanCompleteRepeatableQuest(lua_State* L, Player* player) + bool CanCompleteRepeatableQuest(Player* player, uint32 questId) { - uint32 questId = ALE::CHECKVAL(L, 2); - const Quest* quest = sObjectMgr->GetQuestTemplate(questId); // Retrieve the Quest object + Quest const* quest = sObjectMgr->GetQuestTemplate(questId); // Retrieve the Quest object if (!quest) - { - ALE::Push(L, false); - return 1; - } + return false; - ALE::Push(L, player->CanCompleteRepeatableQuest(quest)); - return 1; + return player->CanCompleteRepeatableQuest(quest); } /** @@ -515,18 +475,13 @@ namespace LuaPlayer * @param uint32 questId * @return bool canRewardQuest */ - int CanRewardQuest(lua_State* L, Player* player) + bool CanRewardQuest(Player* player, uint32 questId) { - uint32 questId = ALE::CHECKVAL(L, 2); - const Quest* quest = sObjectMgr->GetQuestTemplate(questId); // Retrieve the Quest object + Quest const* quest = sObjectMgr->GetQuestTemplate(questId); // Retrieve the Quest object if (!quest) - { - ALE::Push(L, false); - return 1; - } + return false; - ALE::Push(L, player->CanRewardQuest(quest, true)); // Modify the second argument as needed - return 1; + return player->CanRewardQuest(quest, true); // Modify the second argument as needed } /** @@ -535,12 +490,9 @@ namespace LuaPlayer * @param uint32 entry * @return bool canComplete */ - int CanCompleteQuest(lua_State* L, Player* player) + bool CanCompleteQuest(Player* player, uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->CanCompleteQuest(entry)); - return 1; + return player->CanCompleteQuest(entry); } /** @@ -548,10 +500,9 @@ namespace LuaPlayer * * @return bool isHorde */ - int IsHorde(lua_State* L, Player* player) + bool IsHorde(Player* player) { - ALE::Push(L, (player->GetTeamId() == TEAM_HORDE)); - return 1; + return player->GetTeamId() == TEAM_HORDE; } /** @@ -559,10 +510,9 @@ namespace LuaPlayer * * @return bool isAlliance */ - int IsAlliance(lua_State* L, Player* player) + bool IsAlliance(Player* player) { - ALE::Push(L, (player->GetTeamId() == TEAM_ALLIANCE)); - return 1; + return player->GetTeamId() == TEAM_ALLIANCE; } /** @@ -570,10 +520,9 @@ namespace LuaPlayer * * @return bool isDND */ - int IsDND(lua_State* L, Player* player) + bool IsDND(Player* player) { - ALE::Push(L, player->isDND()); - return 1; + return player->isDND(); } /** @@ -581,10 +530,9 @@ namespace LuaPlayer * * @return bool isAFK */ - int IsAFK(lua_State* L, Player* player) + bool IsAFK(Player* player) { - ALE::Push(L, player->isAFK()); - return 1; + return player->isAFK(); } /** @@ -592,10 +540,9 @@ namespace LuaPlayer * * @return bool isFalling */ - int IsFalling(lua_State* L, Player* player) + bool IsFalling(Player* player) { - ALE::Push(L, player->IsFalling()); - return 1; + return player->IsFalling(); } /** @@ -605,11 +552,9 @@ namespace LuaPlayer * @param [Player] target : the player to check visibility from * @return bool isGroupVisible */ - int IsGroupVisibleFor(lua_State* L, Player* player) + bool IsGroupVisibleFor(Player* player, Player* target) { - Player* target = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->IsGroupVisibleFor(target)); - return 1; + return player->IsGroupVisibleFor(target); } /** @@ -618,11 +563,9 @@ namespace LuaPlayer * @param [Player] player * @return bool isInSameRaidWith */ - int IsInSameRaidWith(lua_State* L, Player* player) + bool IsInSameRaidWith(Player* player, Player* target) { - Player* target = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->IsInSameRaidWith(target)); - return 1; + return player->IsInSameRaidWith(target); } /** @@ -631,11 +574,9 @@ namespace LuaPlayer * @param [Player] player * @return bool isInSameGroupWith */ - int IsInSameGroupWith(lua_State* L, Player* player) + bool IsInSameGroupWith(Player* player, Player* target) { - Player* target = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->IsInSameGroupWith(target)); - return 1; + return player->IsInSameGroupWith(target); } /** @@ -644,12 +585,9 @@ namespace LuaPlayer * @param [Unit] unit * @return bool isHonorOrXPTarget */ - int IsHonorOrXPTarget(lua_State* L, Player* player) + bool IsHonorOrXPTarget(Player* player, Unit* victim) { - Unit* victim = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, player->isHonorOrXPTarget(victim)); - return 1; + return player->isHonorOrXPTarget(victim); } /** @@ -658,12 +596,9 @@ namespace LuaPlayer * @param [Player] player * @return bool isVisibleForPlayer */ - int IsVisibleForPlayer(lua_State* L, Player* player) + bool IsVisibleForPlayer(Player* player, Player* target) { - Player* target = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, player->IsVisibleGloballyFor(target)); - return 1; + return player->IsVisibleGloballyFor(target); } /** @@ -672,10 +607,9 @@ namespace LuaPlayer * @param [Player] player * @return bool isVisible */ - int IsGMVisible(lua_State* L, Player* player) + bool IsGMVisible(Player* player) { - ALE::Push(L, player->isGMVisible()); - return 1; + return player->isGMVisible(); } /** @@ -683,10 +617,9 @@ namespace LuaPlayer * * @return bool isTaxiCheater */ - int IsTaxiCheater(lua_State* L, Player* player) + bool IsTaxiCheater(Player* player) { - ALE::Push(L, player->isTaxiCheater()); - return 1; + return player->isTaxiCheater(); } /** @@ -695,10 +628,9 @@ namespace LuaPlayer * @param [Player] player * @return bool isGMChat */ - int IsGMChat(lua_State* L, Player* player) + bool IsGMChat(Player* player) { - ALE::Push(L, player->isGMChat()); - return 1; + return player->isGMChat(); } /** @@ -706,10 +638,9 @@ namespace LuaPlayer * * @return bool isAcceptingWhispers */ - int IsAcceptingWhispers(lua_State* L, Player* player) + bool IsAcceptingWhispers(Player* player) { - ALE::Push(L, player->isAcceptWhispers()); - return 1; + return player->isAcceptWhispers(); } /** @@ -717,10 +648,9 @@ namespace LuaPlayer * * @return bool isRested */ - int IsRested(lua_State* L, Player* player) + bool IsRested(Player* player) { - ALE::Push(L, player->GetRestBonus() > 0.0f); - return 1; + return player->GetRestBonus() > 0.0f; } /** @@ -728,10 +658,9 @@ namespace LuaPlayer * * @return bool inBattlegroundQueue */ - int InBattlegroundQueue(lua_State* L, Player* player) + bool InBattlegroundQueue(Player* player) { - ALE::Push(L, player->InBattlegroundQueue()); - return 1; + return player->InBattlegroundQueue(); } /** @@ -739,10 +668,9 @@ namespace LuaPlayer * * @return bool inArena */ - int InArena(lua_State* L, Player* player) + bool InArena(Player* player) { - ALE::Push(L, player->InArena()); - return 1; + return player->InArena(); } /** @@ -750,10 +678,9 @@ namespace LuaPlayer * * @return bool inBattleGround */ - int InBattleground(lua_State* L, Player* player) + bool InBattleground(Player* player) { - ALE::Push(L, player->InBattleground()); - return 1; + return player->InBattleground(); } /** @@ -761,10 +688,9 @@ namespace LuaPlayer * * @return bool canBlock */ - int CanBlock(lua_State* L, Player* player) + bool CanBlock(Player* player) { - ALE::Push(L, player->CanBlock()); - return 1; + return player->CanBlock(); } /** @@ -772,10 +698,9 @@ namespace LuaPlayer * * @return bool canParry */ - int CanParry(lua_State* L, Player* player) + bool CanParry(Player* player) { - ALE::Push(L, player->CanParry()); - return 1; + return player->CanParry(); } /** @@ -783,10 +708,9 @@ namespace LuaPlayer * * @return uint8 specCount */ - int GetSpecsCount(lua_State* L, Player* player) + uint8 GetSpecsCount(Player* player) { - ALE::Push(L, player->GetSpecsCount()); - return 1; + return player->GetSpecsCount(); } /** @@ -794,10 +718,9 @@ namespace LuaPlayer * * @return uint32 specId */ - int GetActiveSpec(lua_State* L, Player* player) + uint8 GetActiveSpec(Player* player) { - ALE::Push(L, player->GetActiveSpec()); - return 1; + return player->GetActiveSpec(); } /** @@ -805,10 +728,9 @@ namespace LuaPlayer * * @return uint32 phasemask */ - int GetPhaseMaskForSpawn(lua_State* L, Player* player) + uint32 GetPhaseMaskForSpawn(Player* player) { - ALE::Push(L, player->GetPhaseMaskForSpawn()); - return 1; + return player->GetPhaseMaskForSpawn(); } /** @@ -816,10 +738,10 @@ namespace LuaPlayer * * @return uint32 achievementPoints */ - int GetAchievementPoints(lua_State* L, Player* player) + uint32 GetAchievementPoints(Player* player) { uint32 count = 0; - const CompletedAchievementMap& completedAchievements = player->GetAchievementMgr()->GetCompletedAchievements(); + CompletedAchievementMap const& completedAchievements = player->GetAchievementMgr()->GetCompletedAchievements(); for (auto& pair : completedAchievements) { AchievementEntry const* achievement = sAchievementStore.LookupEntry(pair.first); @@ -829,8 +751,7 @@ namespace LuaPlayer } } - ALE::Push(L, count); - return 1; + return count; } /** @@ -838,22 +759,21 @@ namespace LuaPlayer * * @return uint32 achievementsCount */ - int GetCompletedAchievementsCount(lua_State* L, Player* player) + uint32 GetCompletedAchievementsCount(Player* player, sol::optional countFeatsOfStrengthArg) { uint32 count = 0; - bool countFeatsOfStrength = ALE::CHECKVAL(L, 2, false); - const CompletedAchievementMap& completedAchievements = player->GetAchievementMgr()->GetCompletedAchievements(); + bool countFeatsOfStrength = countFeatsOfStrengthArg.value_or(false); + CompletedAchievementMap const& completedAchievements = player->GetAchievementMgr()->GetCompletedAchievements(); for (auto& pair : completedAchievements) { AchievementEntry const* achievement = sAchievementStore.LookupEntry(pair.first); if (achievement && (achievement->categoryId != 81 || countFeatsOfStrength)) - { - count++; + { + count++; } } - ALE::Push(L, count); - return 1; + return count; } /** @@ -861,10 +781,9 @@ namespace LuaPlayer * * @return uint32 arenaPoints */ - int GetArenaPoints(lua_State* L, Player* player) + uint32 GetArenaPoints(Player* player) { - ALE::Push(L, player->GetArenaPoints()); - return 1; + return player->GetArenaPoints(); } /** @@ -872,10 +791,9 @@ namespace LuaPlayer * * @return uint32 honorPoints */ - int GetHonorPoints(lua_State* L, Player* player) + uint32 GetHonorPoints(Player* player) { - ALE::Push(L, player->GetHonorPoints()); - return 1; + return player->GetHonorPoints(); } /** @@ -883,10 +801,9 @@ namespace LuaPlayer * * @return uint32 todayHonorPoints */ - int GetTodayHonorPoints(lua_State* L, Player* player) + uint32 GetTodayHonorPoints(Player* player) { - ALE::Push(L, player->GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION)); - return 1; + return player->GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION); } /** @@ -894,10 +811,9 @@ namespace LuaPlayer * * @return uint32 yesterdayHonorPoints */ - int GetYesterdayHonorPoints(lua_State* L, Player* player) + uint32 GetYesterdayHonorPoints(Player* player) { - ALE::Push(L, player->GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION)); - return 1; + return player->GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION); } /** @@ -905,10 +821,9 @@ namespace LuaPlayer * * @return uint32 blockValue */ - int GetShieldBlockValue(lua_State* L, Player* player) + uint32 GetShieldBlockValue(Player* player) { - ALE::Push(L, player->GetShieldBlockValue()); - return 1; + return player->GetShieldBlockValue(); } /** @@ -917,12 +832,9 @@ namespace LuaPlayer * @param uint32 spellId * @return uint32 spellCooldownDelay */ - int GetSpellCooldownDelay(lua_State* L, Player* player) + uint32 GetSpellCooldownDelay(Player* player, uint32 spellId) { - uint32 spellId = ALE::CHECKVAL(L, 2); - - ALE::Push(L, uint32(player->GetSpellCooldownDelay(spellId))); - return 1; + return uint32(player->GetSpellCooldownDelay(spellId)); } /** @@ -930,10 +842,9 @@ namespace LuaPlayer * * @return uint32 latency */ - int GetLatency(lua_State* L, Player* player) + uint32 GetLatency(Player* player) { - ALE::Push(L, player->GetSession()->GetLatency()); - return 1; + return player->GetSession()->GetLatency(); } /** @@ -941,10 +852,9 @@ namespace LuaPlayer * * @return uint32 championingFaction */ - int GetChampioningFaction(lua_State* L, Player* player) + uint32 GetChampioningFaction(Player* player) { - ALE::Push(L, player->GetChampioningFaction()); - return 1; + return player->GetChampioningFaction(); } /** @@ -952,10 +862,9 @@ namespace LuaPlayer * * @return uint8 subGroup */ - int GetOriginalSubGroup(lua_State* L, Player* player) + uint8 GetOriginalSubGroup(Player* player) { - ALE::Push(L, player->GetOriginalSubGroup()); - return 1; + return player->GetOriginalSubGroup(); } /** @@ -963,10 +872,9 @@ namespace LuaPlayer * * @return [Group] group */ - int GetOriginalGroup(lua_State* L, Player* player) + Group* GetOriginalGroup(Player* player) { - ALE::Push(L, player->GetOriginalGroup()); - return 1; + return player->GetOriginalGroup(); } /** @@ -975,12 +883,9 @@ namespace LuaPlayer * @param float radius * @return [Player] player */ - int GetNextRandomRaidMember(lua_State* L, Player* player) + Player* GetNextRandomRaidMember(Player* player, float radius) { - float radius = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetNextRandomRaidMember(radius)); - return 1; + return player->GetNextRandomRaidMember(radius); } /** @@ -988,10 +893,9 @@ namespace LuaPlayer * * @return uint8 subGroup */ - int GetSubGroup(lua_State* L, Player* player) + uint8 GetSubGroup(Player* player) { - ALE::Push(L, player->GetSubGroup()); - return 1; + return player->GetSubGroup(); } /** @@ -999,10 +903,9 @@ namespace LuaPlayer * * @return [Group] group */ - int GetGroupInvite(lua_State* L, Player* player) + Group* GetGroupInvite(Player* player) { - ALE::Push(L, player->GetGroupInvite()); - return 1; + return player->GetGroupInvite(); } /** @@ -1010,10 +913,9 @@ namespace LuaPlayer * * @return uint32 xp */ - int GetXP(lua_State* L, Player* player) + uint32 GetXP(Player* player) { - ALE::Push(L, player->GetUInt32Value(PLAYER_XP)); - return 1; + return player->GetUInt32Value(PLAYER_XP); } /** @@ -1022,12 +924,9 @@ namespace LuaPlayer * @param uint32 xp * @return uint32 xpBonus */ - int GetXPRestBonus(lua_State* L, Player* player) + uint32 GetXPRestBonus(Player* player, uint32 xp) { - uint32 xp = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetXPRestBonus(xp)); - return 1; + return player->GetXPRestBonus(xp); } /** @@ -1035,10 +934,9 @@ namespace LuaPlayer * * @return [BattleGroundTypeId] typeId */ - int GetBattlegroundTypeId(lua_State* L, Player* player) + BattlegroundTypeId GetBattlegroundTypeId(Player* player) { - ALE::Push(L, player->GetBattlegroundTypeId()); - return 1; + return player->GetBattlegroundTypeId(); } /** @@ -1046,10 +944,9 @@ namespace LuaPlayer * * @return uint32 battleGroundId */ - int GetBattlegroundId(lua_State* L, Player* player) + uint32 GetBattlegroundId(Player* player) { - ALE::Push(L, player->GetBattlegroundId()); - return 1; + return player->GetBattlegroundId(); } /** @@ -1058,12 +955,9 @@ namespace LuaPlayer * @param uint32 faction * @return [ReputationRank] rank */ - int GetReputationRank(lua_State* L, Player* player) + ReputationRank GetReputationRank(Player* player, uint32 faction) { - uint32 faction = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetReputationRank(faction)); - return 1; + return player->GetReputationRank(faction); } /** @@ -1071,10 +965,9 @@ namespace LuaPlayer * * @return uint16 drunkValue */ - int GetDrunkValue(lua_State* L, Player* player) + uint16 GetDrunkValue(Player* player) { - ALE::Push(L, player->GetDrunkValue()); - return 1; + return player->GetDrunkValue(); } /** @@ -1083,12 +976,9 @@ namespace LuaPlayer * @param uint32 skill * @param int16 bonusVal */ - int GetSkillTempBonusValue(lua_State* L, Player* player) + int16 GetSkillTempBonusValue(Player* player, uint32 skill) { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetSkillTempBonusValue(skill)); - return 1; + return player->GetSkillTempBonusValue(skill); } /** @@ -1097,12 +987,9 @@ namespace LuaPlayer * @param uint32 skill * @param int16 bonusVal */ - int GetSkillPermBonusValue(lua_State* L, Player* player) + int16 GetSkillPermBonusValue(Player* player, uint32 skill) { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetSkillPermBonusValue(skill)); - return 1; + return player->GetSkillPermBonusValue(skill); } /** @@ -1111,12 +998,9 @@ namespace LuaPlayer * @param uint32 skill * @return uint16 pureVal */ - int GetPureSkillValue(lua_State* L, Player* player) + uint16 GetPureSkillValue(Player* player, uint32 skill) { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetPureSkillValue(skill)); - return 1; + return player->GetPureSkillValue(skill); } /** @@ -1125,12 +1009,9 @@ namespace LuaPlayer * @param uint32 skill * @return uint16 baseVal */ - int GetBaseSkillValue(lua_State* L, Player* player) + uint16 GetBaseSkillValue(Player* player, uint32 skill) { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetBaseSkillValue(skill)); - return 1; + return player->GetBaseSkillValue(skill); } /** @@ -1139,12 +1020,9 @@ namespace LuaPlayer * @param uint32 skill * @return uint16 val */ - int GetSkillValue(lua_State* L, Player* player) + uint16 GetSkillValue(Player* player, uint32 skill) { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetSkillValue(skill)); - return 1; + return player->GetSkillValue(skill); } /** @@ -1153,12 +1031,9 @@ namespace LuaPlayer * @param uint32 skill * @return uint16 pureVal */ - int GetPureMaxSkillValue(lua_State* L, Player* player) + uint16 GetPureMaxSkillValue(Player* player, uint32 skill) { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetPureMaxSkillValue(skill)); - return 1; + return player->GetPureMaxSkillValue(skill); } /** @@ -1167,12 +1042,9 @@ namespace LuaPlayer * @param uint32 skill * @return uint16 val */ - int GetMaxSkillValue(lua_State* L, Player* player) + uint16 GetMaxSkillValue(Player* player, uint32 skill) { - uint32 skill = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetMaxSkillValue(skill)); - return 1; + return player->GetMaxSkillValue(skill); } /** @@ -1180,10 +1052,9 @@ namespace LuaPlayer * * @return float bonus */ - int GetManaBonusFromIntellect(lua_State* L, Player* player) + float GetManaBonusFromIntellect(Player* player) { - ALE::Push(L, player->GetManaBonusFromIntellect()); - return 1; + return player->GetManaBonusFromIntellect(); } /** @@ -1191,10 +1062,9 @@ namespace LuaPlayer * * @return float bonus */ - int GetHealthBonusFromStamina(lua_State* L, Player* player) + float GetHealthBonusFromStamina(Player* player) { - ALE::Push(L, player->GetHealthBonusFromStamina()); - return 1; + return player->GetHealthBonusFromStamina(); } /** @@ -1203,11 +1073,10 @@ namespace LuaPlayer * @param bool isRaid = true : argument is TrinityCore only * @return int32 difficulty */ - int GetDifficulty(lua_State* L, Player* player) + Difficulty GetDifficulty(Player* player, sol::optional isRaidArg) { - bool isRaid = ALE::CHECKVAL(L, 2, true); - ALE::Push(L, player->GetDifficulty(isRaid)); - return 1; + bool isRaid = isRaidArg.value_or(true); + return player->GetDifficulty(isRaid); } /** @@ -1215,10 +1084,9 @@ namespace LuaPlayer * * @return uint32 guildRank */ - int GetGuildRank(lua_State* L, Player* player) // TODO: Move to Guild Methods + uint8 GetGuildRank(Player* player) // TODO: Move to Guild Methods { - ALE::Push(L, player->GetRank()); - return 1; + return player->GetRank(); } /** @@ -1226,10 +1094,9 @@ namespace LuaPlayer * * @return uint32 freeTalentPointAmt */ - int GetFreeTalentPoints(lua_State* L, Player* player) + uint32 GetFreeTalentPoints(Player* player) { - ALE::Push(L, player->GetFreeTalentPoints()); - return 1; + return player->GetFreeTalentPoints(); } /** @@ -1237,12 +1104,12 @@ namespace LuaPlayer * * @return string guildName */ - int GetGuildName(lua_State* L, Player* player) + sol::optional GetGuildName(Player* player) { if (!player->GetGuildId()) - return 1; - ALE::Push(L, eGuildMgr->GetGuildNameById(player->GetGuildId())); - return 1; + return sol::nullopt; + + return sGuildMgr->GetGuildNameById(player->GetGuildId()); } /** @@ -1251,12 +1118,9 @@ namespace LuaPlayer * @param uint32 faction * @return int32 reputationAmt */ - int GetReputation(lua_State* L, Player* player) + int32 GetReputation(Player* player, uint32 faction) { - uint32 faction = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetReputationMgr().GetReputation(faction)); - return 1; + return player->GetReputationMgr().GetReputation(faction); } /** @@ -1264,10 +1128,9 @@ namespace LuaPlayer * * @return [Unit] target */ - int GetComboTarget(lua_State* L, Player* player) + Unit* GetComboTarget(Player* player) { - ALE::Push(L, player->GetComboTarget()); - return 1; + return player->GetComboTarget(); } /** @@ -1275,10 +1138,9 @@ namespace LuaPlayer * * @return uint8 comboPoints */ - int GetComboPoints(lua_State* L, Player* player) + uint8 GetComboPoints(Player* player) { - ALE::Push(L, player->GetComboPoints()); - return 1; + return player->GetComboPoints(); } /** @@ -1286,10 +1148,9 @@ namespace LuaPlayer * * @return uint32 inGameTime */ - int GetInGameTime(lua_State* L, Player* player) + uint32 GetInGameTime(Player* player) { - ALE::Push(L, player->GetInGameTime()); - return 1; + return player->GetInGameTime(); } /** @@ -1298,12 +1159,9 @@ namespace LuaPlayer * @param uint32 questId * @return [QuestStatus] questStatus */ - int GetQuestStatus(lua_State* L, Player* player) + QuestStatus GetQuestStatus(Player* player, uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetQuestStatus(entry)); - return 1; + return player->GetQuestStatus(entry); } /** @@ -1312,12 +1170,9 @@ namespace LuaPlayer * @param uint32 questId * @return bool questRewardStatus */ - int GetQuestRewardStatus(lua_State* L, Player* player) + bool GetQuestRewardStatus(Player* player, uint32 questId) { - uint32 questId = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetQuestRewardStatus(questId)); - return 1; + return player->GetQuestRewardStatus(questId); } /** @@ -1327,13 +1182,9 @@ namespace LuaPlayer * @param int32 entry : entry of required [Creature] * @return uint16 count */ - int GetReqKillOrCastCurrentCount(lua_State* L, Player* player) + uint16 GetReqKillOrCastCurrentCount(Player* player, uint32 questId, int32 entry) { - uint32 questId = ALE::CHECKVAL(L, 2); - int32 entry = ALE::CHECKVAL(L, 3); - - ALE::Push(L, player->GetReqKillOrCastCurrentCount(questId, entry)); - return 1; + return player->GetReqKillOrCastCurrentCount(questId, entry); } /** @@ -1342,12 +1193,9 @@ namespace LuaPlayer * @param uint32 questId * @return [QuestStatus] questRewardStatus */ - int GetQuestLevel(lua_State* L, Player* player) + int32 GetQuestLevel(Player* player, Quest* quest) { - Quest* quest = ALE::CHECKOBJ(L, 2); - - ALE::Push(L, player->GetQuestLevel(quest)); - return 1; + return player->GetQuestLevel(quest); } /** @@ -1356,15 +1204,13 @@ namespace LuaPlayer * @param uint8 slot * @return [Item] item */ - int GetEquippedItemBySlot(lua_State* L, Player* player) + Item* GetEquippedItemBySlot(Player* player, uint8 slot) { - uint8 slot = ALE::CHECKVAL(L, 2); if (slot >= EQUIPMENT_SLOT_END) - return 1; + return nullptr; Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); - ALE::Push(L, item); - return 1; + return item; } /** @@ -1372,10 +1218,9 @@ namespace LuaPlayer * * @return float restBonus */ - int GetRestBonus(lua_State* L, Player* player) + float GetRestBonus(Player* player) { - ALE::Push(L, player->GetRestBonus()); - return 1; + return player->GetRestBonus(); } /** @@ -1383,10 +1228,9 @@ namespace LuaPlayer * * @return uint8 tag */ - int GetChatTag(lua_State* L, Player* player) + uint8 GetChatTag(Player* player) { - ALE::Push(L, player->GetChatTag()); - return 1; + return player->GetChatTag(); } /** @@ -1414,13 +1258,9 @@ namespace LuaPlayer * @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) + Item* GetItemByPos(Player* player, uint8 bag, uint8 slot) { - uint8 bag = ALE::CHECKVAL(L, 2); - uint8 slot = ALE::CHECKVAL(L, 3); - - ALE::Push(L, player->GetItemByPos(bag, slot)); - return 1; + return player->GetItemByPos(bag, slot); } /** @@ -1431,12 +1271,9 @@ namespace LuaPlayer * @param ObjectGuid guid : an item guid * @return [Item] item */ - int GetItemByGUID(lua_State* L, Player* player) + Item* GetItemByGUID(Player* player, ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetItemByGuid(guid)); - return 1; + return player->GetItemByGuid(guid); } /** @@ -1444,19 +1281,13 @@ namespace LuaPlayer * * @return uint32 mailCount */ - int GetMailCount(lua_State* L, Player* player) + uint32 GetMailCount(Player* player) { - const CharacterCacheEntry* cache = sCharacterCache->GetCharacterCacheByGuid(player->GetGUID()); + CharacterCacheEntry const* cache = sCharacterCache->GetCharacterCacheByGuid(player->GetGUID()); if (cache) - { - ALE::Push(L, static_cast(cache->MailCount)); - } - else - { - ALE::Push(L, player->GetMailSize()); - } + return static_cast(cache->MailCount); - return 1; + return player->GetMailSize(); } /** @@ -1465,12 +1296,9 @@ namespace LuaPlayer * @param ObjectGuid guid : an item guid * @return [Item] item */ - int GetMailItem(lua_State* L, Player* player) + Item* GetMailItem(Player* player, ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetMItem(guid.GetCounter())); - return 1; + return player->GetMItem(guid.GetCounter()); } /** @@ -1481,25 +1309,20 @@ namespace LuaPlayer * @param uint32 entryId * @return [Item] item */ - int GetItemByEntry(lua_State* L, Player* player) + Item* GetItemByEntry(Player* player, uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 2); - - ALE::Push(L, player->GetItemByEntry(entry)); - return 1; + return player->GetItemByEntry(entry); } - + /** * 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) + uint32 GetGossipTextId(Player* player, WorldObject* obj) { - WorldObject* obj = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->GetGossipTextId(obj)); - return 1; + return player->GetGossipTextId(obj); } /** @@ -1507,10 +1330,9 @@ namespace LuaPlayer * * @return [Unit] unit */ - int GetSelection(lua_State* L, Player* player) + Unit* GetSelection(Player* player) { - ALE::Push(L, player->GetSelectedUnit()); - return 1; + return player->GetSelectedUnit(); } /** @@ -1518,10 +1340,9 @@ namespace LuaPlayer * * @return [AccountTypes] gmRank */ - int GetGMRank(lua_State* L, Player* player) + AccountTypes GetGMRank(Player* player) { - ALE::Push(L, player->GetSession()->GetSecurity()); - return 1; + return player->GetSession()->GetSecurity(); } /** @@ -1529,10 +1350,9 @@ namespace LuaPlayer * * @return uint32 coinage */ - int GetCoinage(lua_State* L, Player* player) + uint32 GetCoinage(Player* player) { - ALE::Push(L, player->GetMoney()); - return 1; + return player->GetMoney(); } /** @@ -1540,10 +1360,9 @@ namespace LuaPlayer * * @return uint32 guildId */ - int GetGuildId(lua_State* L, Player* player) + uint32 GetGuildId(Player* player) { - ALE::Push(L, player->GetGuildId()); - return 1; + return player->GetGuildId(); } /** @@ -1551,12 +1370,11 @@ namespace LuaPlayer * * @return [TeamId] teamId */ - int GetTeam(lua_State* L, Player* player) + TeamId GetTeam(Player* player) { - ALE::Push(L, player->GetTeamId()); - return 1; + return player->GetTeamId(); } - + /** * Returns amount of the specified [Item] the [Player] has. * @@ -1564,12 +1382,10 @@ namespace LuaPlayer * @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 GetItemCount(Player* player, uint32 entry, sol::optional checkinBankArg) { - uint32 entry = ALE::CHECKVAL(L, 2); - bool checkinBank = ALE::CHECKVAL(L, 3, false); - ALE::Push(L, player->GetItemCount(entry, checkinBank)); - return 1; + bool checkinBank = checkinBankArg.value_or(false); + return player->GetItemCount(entry, checkinBank); } /** @@ -1577,10 +1393,9 @@ namespace LuaPlayer * * @return uint32 lifeTimeKils */ - int GetLifetimeKills(lua_State* L, Player* player) + uint32 GetLifetimeKills(Player* player) { - ALE::Push(L, player->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS)); - return 1; + return player->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS); } /** @@ -1588,10 +1403,9 @@ namespace LuaPlayer * * @return uint32 todayKills */ - int GetTodayKills(lua_State* L, Player* player) + uint32 GetTodayKills(Player* player) { - ALE::Push(L, uint32(player->GetUInt16Value(PLAYER_FIELD_KILLS, 0))); - return 1; + return uint32(player->GetUInt16Value(PLAYER_FIELD_KILLS, 0)); } /** @@ -1599,10 +1413,9 @@ namespace LuaPlayer * * @return uint32 yesterdayKills */ - int GetYesterdayKills(lua_State* L, Player* player) + uint32 GetYesterdayKills(Player* player) { - ALE::Push(L, uint32(player->GetUInt16Value(PLAYER_FIELD_KILLS, 1))); - return 1; + return uint32(player->GetUInt16Value(PLAYER_FIELD_KILLS, 1)); } /** @@ -1610,10 +1423,9 @@ namespace LuaPlayer * * @return string ip */ - int GetPlayerIP(lua_State* L, Player* player) + std::string GetPlayerIP(Player* player) { - ALE::Push(L, player->GetSession()->GetRemoteAddress()); - return 1; + return player->GetSession()->GetRemoteAddress(); } /** @@ -1621,10 +1433,9 @@ namespace LuaPlayer * * @return uint32 currLevelPlayTime */ - int GetLevelPlayedTime(lua_State* L, Player* player) + uint32 GetLevelPlayedTime(Player* player) { - ALE::Push(L, player->GetLevelPlayedTime()); - return 1; + return player->GetLevelPlayedTime(); } /** @@ -1632,10 +1443,9 @@ namespace LuaPlayer * * @return uint32 totalPlayTime */ - int GetTotalPlayedTime(lua_State* L, Player* player) + uint32 GetTotalPlayedTime(Player* player) { - ALE::Push(L, player->GetTotalPlayedTime()); - return 1; + return player->GetTotalPlayedTime(); } /** @@ -1643,10 +1453,9 @@ namespace LuaPlayer * * @return [Guild] guild */ - int GetGuild(lua_State* L, Player* player) + Guild* GetGuild(Player* player) { - ALE::Push(L, eGuildMgr->GetGuildById(player->GetGuildId())); - return 1; + return sGuildMgr->GetGuildById(player->GetGuildId()); } /** @@ -1654,10 +1463,9 @@ namespace LuaPlayer * * @return [Group] group */ - int GetGroup(lua_State* L, Player* player) + Group* GetGroup(Player* player) { - ALE::Push(L, player->GetGroup()); - return 1; + return player->GetGroup(); } /** @@ -1665,10 +1473,9 @@ namespace LuaPlayer * * @return uint32 accountId */ - int GetAccountId(lua_State* L, Player* player) + uint32 GetAccountId(Player* player) { - ALE::Push(L, player->GetSession()->GetAccountId()); - return 1; + return player->GetSession()->GetAccountId(); } /** @@ -1676,12 +1483,13 @@ namespace LuaPlayer * * @return string accountName */ - int GetAccountName(lua_State* L, Player* player) + sol::optional GetAccountName(Player* player) { std::string accName; if (AccountMgr::GetName(player->GetSession()->GetAccountId(), accName)) - ALE::Push(L, accName); - return 1; + return accName; + + return sol::nullopt; } /** @@ -1689,12 +1497,11 @@ namespace LuaPlayer * * @return int32 questcount */ - int GetCompletedQuestsCount(lua_State* L, Player* player) + uint32 GetCompletedQuestsCount(Player* player) { uint32 count = player->GetRewardedQuestCount(); - ALE::Push(L, count); - return 1; + return count; } /** @@ -1702,10 +1509,9 @@ namespace LuaPlayer * * @return [Corpse] corpse */ - int GetCorpse(lua_State* L, Player* player) + Corpse* GetCorpse(Player* player) { - ALE::Push(L, player->GetCorpse()); - return 1; + return player->GetCorpse(); } /** @@ -1713,10 +1519,9 @@ namespace LuaPlayer * * @return int localeIndex */ - int GetDbLocaleIndex(lua_State* L, Player* player) + LocaleConstant GetDbLocaleIndex(Player* player) { - ALE::Push(L, player->GetSession()->GetSessionDbLocaleIndex()); - return 1; + return player->GetSession()->GetSessionDbLocaleIndex(); } /** @@ -1724,10 +1529,9 @@ namespace LuaPlayer * * @return [LocaleConstant] locale */ - int GetDbcLocale(lua_State* L, Player* player) + LocaleConstant GetDbcLocale(Player* player) { - ALE::Push(L, player->GetSession()->GetSessionDbcLocale()); - return 1; + return player->GetSession()->GetSessionDbcLocale(); } /** @@ -1735,12 +1539,9 @@ namespace LuaPlayer * * @return table nodes : A table containing the IDs of the known taxi nodes */ - int GetKnownTaxiNodes(lua_State* L, Player* player) + sol::table GetKnownTaxiNodes(Player* player, sol::this_state s) { - if (!player) - return 0; - - lua_newtable(L); + sol::table tbl = sol::state_view(s).create_table(); ByteBuffer data; player->m_taxi.AppendTaximaskTo(data, false); @@ -1757,47 +1558,22 @@ namespace LuaPlayer if (mask & (1u << bit)) { uint32 nodeId = (i * 32) + bit + 1; - lua_pushinteger(L, nodeId); - lua_rawseti(L, -2, idx++); + tbl[idx++] = nodeId; } } } - return 1; + return tbl; } - /*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) + void SetPlayerLock(Player* player, sol::optional applyArg) { - bool apply = ALE::CHECKVAL(L, 2, true); + bool apply = applyArg.value_or(true); if (apply) { @@ -1809,7 +1585,6 @@ namespace LuaPlayer player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED | UNIT_FLAG_SILENCED); player->SetClientControl(player, 1); } - return 0; } /** @@ -1817,12 +1592,9 @@ namespace LuaPlayer * * @param uint32 flag */ - int SetAtLoginFlag(lua_State* L, Player* player) + void SetAtLoginFlag(Player* player, uint32 flag) { - uint32 flag = ALE::CHECKVAL(L, 2); - player->SetAtLoginFlag((AtLoginFlags)flag); - return 0; } /** @@ -1830,14 +1602,12 @@ namespace LuaPlayer * * @param uint32 sheatheState */ - int SetSheath(lua_State* L, Player* player) + void SetSheath(Player* player, uint32 sheathed) { - uint32 sheathed = ALE::CHECKVAL(L, 2); if (sheathed >= MAX_SHEATH_STATE) - return 0; + return; player->SetSheath((SheathState)sheathed); - return 0; } /** @@ -1845,12 +1615,9 @@ namespace LuaPlayer * * @param uint8 drunkValue */ - int SetDrunkValue(lua_State* L, Player* player) + void SetDrunkValue(Player* player, uint8 newDrunkValue) { - uint8 newDrunkValue = ALE::CHECKVAL(L, 2); - player->SetDrunkValue(newDrunkValue); - return 0; } /** @@ -1858,12 +1625,9 @@ namespace LuaPlayer * * @param uint8 raceId */ - int SetFactionForRace(lua_State* L, Player* player) + void SetFactionForRace(Player* player, uint8 race) { - uint8 race = ALE::CHECKVAL(L, 2); - player->SetFactionForRace(race); - return 0; } /** @@ -1874,15 +1638,9 @@ namespace LuaPlayer * @param uint16 currVal * @param uint16 maxVal */ - int SetSkill(lua_State* L, Player* player) + void SetSkill(Player* player, uint16 id, uint16 step, uint16 currVal, uint16 maxVal) { - 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; } /** @@ -1890,15 +1648,12 @@ namespace LuaPlayer * * @param uint8 rank */ - int SetGuildRank(lua_State* L, Player* player) // TODO: Move to Guild Methods + void SetGuildRank(Player* player, uint8 rank) // TODO: Move to Guild Methods { - uint8 rank = ALE::CHECKVAL(L, 2); - if (!player->GetGuildId()) - return 0; + return; player->SetRank(rank); - return 0; } /** @@ -1906,13 +1661,10 @@ namespace LuaPlayer * * @param uint32 talentPointAmt */ - int SetFreeTalentPoints(lua_State* L, Player* player) + void SetFreeTalentPoints(Player* player, uint32 points) { - uint32 points = ALE::CHECKVAL(L, 2); - player->SetFreeTalentPoints(points); player->SendTalentsInfoData(false); - return 0; } /** @@ -1921,14 +1673,10 @@ namespace LuaPlayer * @param uint32 factionId * @param int32 reputationValue */ - int SetReputation(lua_State* L, Player* player) + void SetReputation(Player* player, uint32 faction, int32 value) { - 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; } /** @@ -1937,15 +1685,12 @@ namespace LuaPlayer * @param uint32 entry : entry of a quest * @param uint32 status */ - int SetQuestStatus(lua_State* L, Player* player) + void SetQuestStatus(Player* player, uint32 entry, uint32 status) { - uint32 entry = ALE::CHECKVAL(L, 2); - uint32 status = ALE::CHECKVAL(L, 3); if (status >= MAX_QUEST_STATUS) - return 0; + return; player->SetQuestStatus(entry, (QuestStatus)status); - return 0; } /** @@ -1953,12 +1698,9 @@ namespace LuaPlayer * * @param float restBonus */ - int SetRestBonus(lua_State* L, Player* player) + void SetRestBonus(Player* player, float bonus) { - float bonus = ALE::CHECKVAL(L, 2); - player->SetRestBonus(bonus); - return 0; } /** @@ -1966,12 +1708,11 @@ namespace LuaPlayer * * @param bool acceptWhispers = true */ - int SetAcceptWhispers(lua_State* L, Player* player) + void SetAcceptWhispers(Player* player, sol::optional onArg) { - bool on = ALE::CHECKVAL(L, 2, true); + bool on = onArg.value_or(true); player->SetAcceptWhispers(on); - return 0; } /** @@ -1979,12 +1720,11 @@ namespace LuaPlayer * * @param bool on = true */ - int SetPvPDeath(lua_State* L, Player* player) + void SetPvPDeath(Player* player, sol::optional onArg) { - bool on = ALE::CHECKVAL(L, 2, true); + bool on = onArg.value_or(true); player->SetPvPDeath(on); - return 0; } /** @@ -1992,12 +1732,11 @@ namespace LuaPlayer * * @param bool gmVisible = true */ - int SetGMVisible(lua_State* L, Player* player) + void SetGMVisible(Player* player, sol::optional onArg) { - bool on = ALE::CHECKVAL(L, 2, true); + bool on = onArg.value_or(true); player->SetGMVisible(on); - return 0; } /** @@ -2005,27 +1744,15 @@ namespace LuaPlayer * * @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) + void SetKnownTaxiNodes(Player* player, sol::table nodes) + { + for (auto const& kv : nodes) { - uint32 nodeId = luaL_checkinteger(L, -1); - - if (nodeId > 0) + uint32 nodeId = kv.second.as(); + + if (nodeId > 0) player->m_taxi.SetTaximaskNode(nodeId); - - lua_pop(L, 1); } - - return 0; } /** @@ -2033,12 +1760,11 @@ namespace LuaPlayer * * @param bool taxiCheat = true */ - int SetTaxiCheat(lua_State* L, Player* player) + void SetTaxiCheat(Player* player, sol::optional onArg) { - bool on = ALE::CHECKVAL(L, 2, true); + bool on = onArg.value_or(true); player->SetTaxiCheater(on); - return 0; } /** @@ -2046,12 +1772,11 @@ namespace LuaPlayer * * @param bool on = true */ - int SetGMChat(lua_State* L, Player* player) + void SetGMChat(Player* player, sol::optional onArg) { - bool on = ALE::CHECKVAL(L, 2, true); + bool on = onArg.value_or(true); player->SetGMChat(on); - return 0; } /** @@ -2059,12 +1784,11 @@ namespace LuaPlayer * * @param bool setGmMode = true */ - int SetGameMaster(lua_State* L, Player* player) + void SetGameMaster(Player* player, sol::optional onArg) { - bool on = ALE::CHECKVAL(L, 2, true); + bool on = onArg.value_or(true); player->SetGameMaster(on); - return 0; } /** @@ -2075,10 +1799,8 @@ namespace LuaPlayer * * @param [Gender] gender */ - int SetGender(lua_State* L, Player* player) + void SetGender(Player* player, uint32 _gender) { - uint32 _gender = ALE::CHECKVAL(L, 2); - Gender gender; switch (_gender) { @@ -2089,13 +1811,12 @@ namespace LuaPlayer gender = GENDER_FEMALE; break; default: - return luaL_argerror(L, 2, "valid Gender expected"); + throw std::invalid_argument("valid Gender expected"); } player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender); player->SetByteValue(PLAYER_BYTES_3, 0, gender); player->InitDisplayIds(); - return 0; } /** @@ -2103,11 +1824,9 @@ namespace LuaPlayer * * @param uint32 arenaPoints */ - int SetArenaPoints(lua_State* L, Player* player) + void SetArenaPoints(Player* player, uint32 arenaP) { - uint32 arenaP = ALE::CHECKVAL(L, 2); player->SetArenaPoints(arenaP); - return 0; } /** @@ -2115,11 +1834,9 @@ namespace LuaPlayer * * @param uint32 honorPoints */ - int SetHonorPoints(lua_State* L, Player* player) + void SetHonorPoints(Player* player, uint32 honorP) { - uint32 honorP = ALE::CHECKVAL(L, 2); player->SetHonorPoints(honorP); - return 0; } /** @@ -2127,11 +1844,9 @@ namespace LuaPlayer * * @param uint32 honorableKills */ - int SetLifetimeKills(lua_State* L, Player* player) + void SetLifetimeKills(Player* player, uint32 val) { - uint32 val = ALE::CHECKVAL(L, 2); player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, val); - return 0; } /** @@ -2139,11 +1854,9 @@ namespace LuaPlayer * * @param uint32 copperAmt */ - int SetCoinage(lua_State* L, Player* player) + void SetCoinage(Player* player, uint32 amt) { - uint32 amt = ALE::CHECKVAL(L, 2); player->SetMoney(amt); - return 0; } /** @@ -2155,17 +1868,10 @@ namespace LuaPlayer * @param uint32 mapId : Map ID * @param uint32 areaId : Area ID */ - int SetBindPoint(lua_State* L, Player* player) + void SetBindPoint(Player* player, float x, float y, float z, uint32 mapId, uint32 areaId) { - 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; } /** @@ -2173,13 +1879,11 @@ namespace LuaPlayer * * @param uint32 titleId */ - int SetKnownTitle(lua_State* L, Player* player) + void SetKnownTitle(Player* player, uint32 id) { - uint32 id = ALE::CHECKVAL(L, 2); CharTitlesEntry const* t = sCharTitlesStore.LookupEntry(id); if (t) player->SetTitle(t, false); - return 0; } /** @@ -2187,43 +1891,31 @@ namespace LuaPlayer * * @param uint32 achievementid */ - int SetAchievement(lua_State* L, Player* player) + void SetAchievement(Player* player, uint32 id) { - 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) + void ResetAchievements(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) + void SendShowMailBox(Player* player, sol::optional guidArg) { - ObjectGuid guid = ALE::CHECKVAL(L, 2, player->GET_GUID()); + ObjectGuid guid = guidArg.value_or(player->GetGUID()); player->GetSession()->SendShowMailBox(guid); - return 0; } /** @@ -2231,12 +1923,9 @@ namespace LuaPlayer * * @param int32 amount */ - int ModifyArenaPoints(lua_State* L, Player* player) + void ModifyArenaPoints(Player* player, int32 amount) { - int32 amount = ALE::CHECKVAL(L, 2); - player->ModifyArenaPoints(amount); - return 0; } /** @@ -2244,21 +1933,17 @@ namespace LuaPlayer * * @param int32 amount */ - int ModifyHonorPoints(lua_State* L, Player* player) + void ModifyHonorPoints(Player* player, int32 amount) { - int32 amount = ALE::CHECKVAL(L, 2); - player->ModifyHonorPoints(amount); - return 0; } /** * Saves the [Player] to the database */ - int SaveToDB(lua_State* /*L*/, Player* player) + void SaveToDB(Player* player) { player->SaveToDB(false, false); - return 0; } /** @@ -2266,20 +1951,17 @@ namespace LuaPlayer * * @param [Unit] summoner */ - int SummonPlayer(lua_State* L, Player* player) + void SummonPlayer(Player* player, Unit* summoner) { - 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 << summoner->GetGUID(); data << uint32(summoner->GetZoneId()); data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); player->GetSession()->SendPacket(&data); - return 0; } /** @@ -2287,15 +1969,13 @@ namespace LuaPlayer * * @param uint32 muteTime */ - int Mute(lua_State* L, Player* player) + void Mute(Player* player, uint32 muteseconds) { - 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; } /** @@ -2303,18 +1983,15 @@ namespace LuaPlayer * * @param uint32 entry : quest entry */ - int RewardQuest(lua_State* L, Player* player) + void RewardQuest(Player* player, uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 2); - - Quest const* quest = eObjectMgr->GetQuestTemplate(entry); + Quest const* quest = sObjectMgr->GetQuestTemplate(entry); // If player doesn't have the quest if (!quest || player->GetQuestStatus(entry) != QUEST_STATUS_COMPLETE) - return 0; + return; player->RewardQuest(quest, 0, player); - return 0; } /** @@ -2322,20 +1999,17 @@ namespace LuaPlayer * * @param [Unit] sender */ - int SendAuctionMenu(lua_State* L, Player* player) + void SendAuctionMenu(Player* player, Unit* unit) { - Unit* unit = ALE::CHECKOBJ(L, 2); - AuctionHouseEntry const* ahEntry = AuctionHouseMgr::GetAuctionHouseEntryFromFactionTemplate(unit->GetFaction()); if (!ahEntry) - return 0; + return; WorldPacket data(MSG_AUCTION_HELLO, 12); - data << unit->GET_GUID(); + data << unit->GetGUID(); data << uint32(ahEntry->houseId); data << uint8(1); player->GetSession()->SendPacket(&data); - return 0; } /** @@ -2343,21 +2017,17 @@ namespace LuaPlayer * * @param [Creature] sender */ - int SendTaxiMenu(lua_State* L, Player* player) + void SendTaxiMenu(Player* player, Creature* creature) { - 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) + void SendSpiritResurrect(Player* player) { player->GetSession()->SendSpiritResurrect(); - return 0; } /** @@ -2365,12 +2035,9 @@ namespace LuaPlayer * * @param [WorldObject] sender */ - int SendTabardVendorActivate(lua_State* L, Player* player) + void SendTabardVendorActivate(Player* player, WorldObject* obj) { - WorldObject* obj = ALE::CHECKOBJ(L, 2); - - player->GetSession()->SendTabardVendorActivate(obj->GET_GUID()); - return 0; + player->GetSession()->SendTabardVendorActivate(obj->GetGUID()); } /** @@ -2378,24 +2045,20 @@ namespace LuaPlayer * * @param [WorldObject] sender */ - int SendShowBank(lua_State* L, Player* player) + void SendShowBank(Player* player, WorldObject* obj) { - WorldObject* obj = ALE::CHECKOBJ(L, 2); - - player->GetSession()->SendShowBank(obj->GET_GUID()); - return 0; + player->GetSession()->SendShowBank(obj->GetGUID()); } - + /** * Sends a vendor window to the [Player] from the [WorldObject] specified. * * @param [WorldObject] sender * @param uint32 vendorId = 0 : optional entry ID to use for the vendor item list, overriding the sender's default inventory */ - int SendListInventory(lua_State* L, Player* player) + void SendListInventory(Player* player, WorldObject* obj, sol::optional vendorIdArg) { - WorldObject* obj = ALE::CHECKOBJ(L, 2); - uint32 vendorId = ALE::CHECKVAL(L, 3, 0); + uint32 vendorId = vendorIdArg.value_or(0); Creature* creature = obj->ToCreature(); bool addedVendorFlag = false; @@ -2405,12 +2068,10 @@ namespace LuaPlayer addedVendorFlag = true; } - player->GetSession()->SendListInventory(obj->GET_GUID(), vendorId); + player->GetSession()->SendListInventory(obj->GetGUID(), vendorId); if (addedVendorFlag) creature->RemoveNpcFlag(UNIT_NPC_FLAG_VENDOR); - - return 0; } /** @@ -2418,12 +2079,9 @@ namespace LuaPlayer * * @param [Creature] sender */ - int SendTrainerList(lua_State* L, Player* player) + void SendTrainerList(Player* player, Creature* obj) { - Creature* obj = ALE::CHECKOBJ(L, 2); - player->GetSession()->SendTrainerList(obj); - return 0; } /** @@ -2431,13 +2089,10 @@ namespace LuaPlayer * * @param [Player] invitee */ - int SendGuildInvite(lua_State* L, Player* player) + void SendGuildInvite(Player* player, Player* plr) { - Player* plr = ALE::CHECKOBJ(L, 2); - if (Guild* guild = player->GetGuild()) guild->HandleInviteMember(player->GetSession(), plr->GetName()); - return 0; } /** @@ -2446,13 +2101,9 @@ namespace LuaPlayer * @param uint32 field * @param uint32 value */ - int SendUpdateWorldState(lua_State* L, Player* player) + void SendUpdateWorldState(Player* player, uint32 field, uint32 value) { - uint32 field = ALE::CHECKVAL(L, 2); - uint32 value = ALE::CHECKVAL(L, 3); - player->SendUpdateWorldState(field, value); - return 0; } /** @@ -2460,21 +2111,19 @@ namespace LuaPlayer * * @param bool saveToDb = true */ - int LogoutPlayer(lua_State* L, Player* player) + void LogoutPlayer(Player* player, sol::optional saveArg) { - bool save = ALE::CHECKVAL(L, 2, true); + bool save = saveArg.value_or(true); player->GetSession()->LogoutPlayer(save); - return 0; } /** * Forcefully removes the [Player] from a [BattleGround] raid group */ - int RemoveFromBattlegroundRaid(lua_State* /*L*/, Player* player) + void RemoveFromBattlegroundRaid(Player* player) { player->RemoveFromBattlegroundOrBattlefieldRaid(); - return 0; } /** @@ -2485,24 +2134,22 @@ namespace LuaPlayer * @param uint32 map = true * @param uint32 difficulty = 0 */ - int UnbindInstance(lua_State* L, Player* player) + void UnbindInstance(Player* player, uint32 map, sol::optional difficultyArg) { - uint32 map = ALE::CHECKVAL(L, 2); - uint32 difficulty = ALE::CHECKVAL(L, 3, 0); + uint32 difficulty = difficultyArg.value_or(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) + void UnbindAllInstances(Player* player) { for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { - const BoundInstancesMap& binds = sInstanceSaveMgr->PlayerGetBoundInstances(player->GetGUID(), Difficulty(i)); + BoundInstancesMap const& binds = sInstanceSaveMgr->PlayerGetBoundInstances(player->GetGUID(), Difficulty(i)); for (BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end();) { if (itr->first != player->GetMapId()) @@ -2516,8 +2163,6 @@ namespace LuaPlayer } } } - - return 0; } /** @@ -2525,11 +2170,9 @@ namespace LuaPlayer * * @param bool teleToEntry = true */ - int LeaveBattleground(lua_State* L, Player* player) + void LeaveBattleground(Player* player) { - (void)L; // ensure that the variable is referenced in order to pass compiler checks player->LeaveBattleground(); - return 0; } /** @@ -2539,14 +2182,12 @@ namespace LuaPlayer * @param bool cost = true * @param float discountMod = 1.0 */ - int DurabilityRepair(lua_State* L, Player* player) + void DurabilityRepair(Player* player, uint16 position, sol::optional takeCostArg, sol::optional discountModArg) { - uint16 position = ALE::CHECKVAL(L, 2); - bool takeCost = ALE::CHECKVAL(L, 3, true); - float discountMod = ALE::CHECKVAL(L, 4, 1.0f); + bool takeCost = takeCostArg.value_or(true); + float discountMod = discountModArg.value_or(1.0f); player->DurabilityRepair(position, takeCost, discountMod, false); - return 0; } /** @@ -2556,14 +2197,13 @@ namespace LuaPlayer * @param float discountMod = 1.0 * @param bool guidBank = false */ - int DurabilityRepairAll(lua_State* L, Player* player) + void DurabilityRepairAll(Player* player, sol::optional takeCostArg, sol::optional discountModArg, sol::optional guildBankArg) { - bool takeCost = ALE::CHECKVAL(L, 2, true); - float discountMod = ALE::CHECKVAL(L, 3, 1.0f); - bool guildBank = ALE::CHECKVAL(L, 4, false); + bool takeCost = takeCostArg.value_or(true); + float discountMod = discountModArg.value_or(1.0f); + bool guildBank = guildBankArg.value_or(false); player->DurabilityRepairAll(takeCost, discountMod, guildBank); - return 0; } /** @@ -2571,13 +2211,10 @@ namespace LuaPlayer * * @param int32 slot */ - int DurabilityPointLossForEquipSlot(lua_State* L, Player* player) + void DurabilityPointLossForEquipSlot(Player* player, int32 slot) { - int32 slot = ALE::CHECKVAL(L, 2); - if (slot >= EQUIPMENT_SLOT_START && slot < EQUIPMENT_SLOT_END) player->DurabilityPointLossForEquipSlot((EquipmentSlots)slot); - return 0; } /** @@ -2588,13 +2225,11 @@ namespace LuaPlayer * @param int32 points * @param bool inventory = true */ - int DurabilityPointsLossAll(lua_State* L, Player* player) + void DurabilityPointsLossAll(Player* player, int32 points, sol::optional inventoryArg) { - int32 points = ALE::CHECKVAL(L, 2); - bool inventory = ALE::CHECKVAL(L, 3, true); + bool inventory = inventoryArg.value_or(true); player->DurabilityPointsLossAll(points, inventory); - return 0; } /** @@ -2603,13 +2238,9 @@ namespace LuaPlayer * @param [Item] item * @param int32 points */ - int DurabilityPointsLoss(lua_State* L, Player* player) + void DurabilityPointsLoss(Player* player, Item* item, int32 points) { - Item* item = ALE::CHECKOBJ(L, 2); - int32 points = ALE::CHECKVAL(L, 3); - player->DurabilityPointsLoss(item, points); - return 0; } /** @@ -2618,13 +2249,9 @@ namespace LuaPlayer * @param [Item] item * @param double percent */ - int DurabilityLoss(lua_State* L, Player* player) + void DurabilityLoss(Player* player, Item* item, double percent) { - Item* item = ALE::CHECKOBJ(L, 2); - double percent = ALE::CHECKVAL(L, 3); - player->DurabilityLoss(item, percent); - return 0; } /** @@ -2633,34 +2260,30 @@ namespace LuaPlayer * @param double percent * @param bool inventory = true */ - int DurabilityLossAll(lua_State* L, Player* player) + void DurabilityLossAll(Player* player, double percent, sol::optional inventoryArg) { - double percent = ALE::CHECKVAL(L, 2); - bool inventory = ALE::CHECKVAL(L, 3, true); + bool inventory = inventoryArg.value_or(true); player->DurabilityLossAll(percent, inventory); - return 0; } /** * Kills the [Player] */ - int KillPlayer(lua_State* /*L*/, Player* player) + void KillPlayer(Player* player) { player->KillPlayer(); - return 0; } /** * Forces the [Player] to leave a [Group] */ - int RemoveFromGroup(lua_State* /*L*/, Player* player) + void RemoveFromGroup(Player* player) { if (!player->GetGroup()) - return 0; + return; player->RemoveFromGroup(); - return 0; } /** @@ -2668,10 +2291,9 @@ namespace LuaPlayer * * @return uint32 resetCost */ - int ResetTalentsCost(lua_State* L, Player* player) + uint32 ResetTalentsCost(Player* player) { - ALE::Push(L, player->resetTalentsCost()); - return 1; + return player->resetTalentsCost(); } /** @@ -2679,13 +2301,12 @@ namespace LuaPlayer * * @param bool noCost = true */ - int ResetTalents(lua_State* L, Player* player) + void ResetTalents(Player* player, sol::optional noCostArg) { - bool no_cost = ALE::CHECKVAL(L, 2, true); + bool no_cost = noCostArg.value_or(true); player->resetTalents(no_cost); player->SendTalentsInfoData(false); - return 0; } /** @@ -2693,21 +2314,17 @@ namespace LuaPlayer * * @param uint32 entry : entry of a [Spell] */ - int RemoveSpell(lua_State* L, Player* player) + void RemoveSpell(Player* player, uint32 entry) { - 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) + void ClearComboPoints(Player* player) { player->ClearComboPoints(); - return 0; } /** @@ -2716,13 +2333,9 @@ namespace LuaPlayer * @param [Unit] target * @param int8 count */ - int AddComboPoints(lua_State* L, Player* player) + void AddComboPoints(Player* player, Unit* target, int8 count) { - Unit* target = ALE::CHECKOBJ(L, 2); - int8 count = ALE::CHECKVAL(L, 3); - player->AddComboPoints(target, count); - return 0; } /** @@ -2731,13 +2344,9 @@ namespace LuaPlayer * @param uint32 entry : entry of a [Creature] * @param [Creature] creature */ - int TalkedToCreature(lua_State* L, Player* player) + void TalkedToCreature(Player* player, uint32 entry, Creature* creature) { - uint32 entry = ALE::CHECKVAL(L, 2); - Creature* creature = ALE::CHECKOBJ(L, 3); - - player->TalkedToCreature(entry, creature->GET_GUID()); - return 0; + player->TalkedToCreature(entry, creature->GetGUID()); } /** @@ -2745,12 +2354,9 @@ namespace LuaPlayer * * @param uint32 entry : entry of a [Creature] */ - int KilledMonsterCredit(lua_State* L, Player* player) + void KilledMonsterCredit(Player* player, uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 2); - - player->KilledMonsterCredit(entry, player->GET_GUID()); - return 0; + player->KilledMonsterCredit(entry, player->GetGUID()); } /** @@ -2759,13 +2365,9 @@ namespace LuaPlayer * @param uint32 quest : entry of a quest * @param [WorldObject] obj */ - int GroupEventHappens(lua_State* L, Player* player) + void GroupEventHappens(Player* player, uint32 questId, WorldObject* obj) { - uint32 questId = ALE::CHECKVAL(L, 2); - WorldObject* obj = ALE::CHECKOBJ(L, 3); - player->GroupEventHappens(questId, obj); - return 0; } /** @@ -2773,12 +2375,9 @@ namespace LuaPlayer * * @param uint32 quest : entry of a [Quest] */ - int AreaExploredOrEventHappens(lua_State* L, Player* player) + void AreaExploredOrEventHappens(Player* player, uint32 questId) { - uint32 questId = ALE::CHECKVAL(L, 2); - player->AreaExploredOrEventHappens(questId); - return 0; } /** @@ -2786,12 +2385,9 @@ namespace LuaPlayer * * @param uint32 entry : entry of a [Quest] */ - int FailQuest(lua_State* L, Player* player) + void FailQuest(Player* player, uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 2); - player->FailQuest(entry); - return 0; } /** @@ -2799,12 +2395,9 @@ namespace LuaPlayer * * @param uint32 entry : quest entry */ - int IncompleteQuest(lua_State* L, Player* player) + void IncompleteQuest(Player* player, uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 2); - player->IncompleteQuest(entry); - return 0; } /** @@ -2814,15 +2407,13 @@ namespace LuaPlayer * * @param uint32 entry : quest entry */ - int CompleteQuest(lua_State* L, Player* player) + void CompleteQuest(Player* player, uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 2); - - Quest const* quest = eObjectMgr->GetQuestTemplate(entry); + Quest const* quest = sObjectMgr->GetQuestTemplate(entry); // If player doesn't have the quest if (!quest || player->GetQuestStatus(entry) == QUEST_STATUS_NONE) - return 0; + return; // Add quest items for quests that require items for (uint8 x = 0; x < QUEST_ITEM_OBJECTIVES_COUNT; ++x) @@ -2888,7 +2479,6 @@ namespace LuaPlayer player->ModifyMoney(-ReqOrRewMoney); player->CompleteQuest(entry); - return 0; } /** @@ -2896,26 +2486,23 @@ namespace LuaPlayer * * @param uint32 entry : quest entry */ - int AddQuest(lua_State* L, Player* player) + void AddQuest(Player* player, uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 2); - - Quest const* quest = eObjectMgr->GetQuestTemplate(entry); + Quest const* quest = sObjectMgr->GetQuestTemplate(entry); if (!quest) - return 0; + return; // 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; + for (auto const& pair : *itc) + { + if (pair.second.StartQuest == entry) + return; + } // ok, normal (creature/GO starting) quest if (player->CanAddQuest(quest, true)) - player->AddQuestAndCheckCompletion(quest, NULL); - - return 0; + player->AddQuestAndCheckCompletion(quest, nullptr); } /** @@ -2923,14 +2510,12 @@ namespace LuaPlayer * * @param uint32 entry : quest entry */ - int RemoveQuest(lua_State* L, Player* player) + void RemoveQuest(Player* player, uint32 entry) { - uint32 entry = ALE::CHECKVAL(L, 2); - - Quest const* quest = eObjectMgr->GetQuestTemplate(entry); + Quest const* quest = sObjectMgr->GetQuestTemplate(entry); if (!quest) - return 0; + return; // remove all quest entries for 'entry' from quest log for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot) @@ -2953,7 +2538,6 @@ namespace LuaPlayer player->RemoveActiveQuest(entry, false); player->RemoveRewardedQuest(entry); - return 0; } /** @@ -2964,13 +2548,9 @@ namespace LuaPlayer * @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) + void Whisper(Player* player, std::string const& text, uint32 lang, Player* receiver) { - 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; } /** @@ -2978,12 +2558,9 @@ namespace LuaPlayer * * @param string emoteText */ - int TextEmote(lua_State* L, Player* player) + void TextEmote(Player* player, std::string const& text) { - std::string text = ALE::CHECKVAL(L, 2); - player->TextEmote(text); - return 0; } /** @@ -2992,12 +2569,9 @@ namespace LuaPlayer * @param string text : text for the [Player] to yells * @param uint32 lang : language the [Player] will speak */ - int Yell(lua_State* L, Player* player) + void Yell(Player* player, std::string const& text, uint32 lang) { - std::string text = ALE::CHECKVAL(L, 2); - uint32 lang = ALE::CHECKVAL(L, 3); player->Yell(text, (Language)lang); - return 0; } /** @@ -3006,12 +2580,9 @@ namespace LuaPlayer * @param string text : text for the [Player] to say * @param uint32 lang : language the [Player] will speak */ - int Say(lua_State* L, Player* player) + void Say(Player* player, std::string const& text, uint32 lang) { - std::string text = ALE::CHECKVAL(L, 2); - uint32 lang = ALE::CHECKVAL(L, 3); player->Say(text, (Language)lang); - return 0; } /** @@ -3020,31 +2591,27 @@ namespace LuaPlayer * @param uint32 xp : experience to give * @param [Unit] victim = nil */ - int GiveXP(lua_State* L, Player* player) + void GiveXP(Player* player, uint32 xp, sol::optional victimArg) { - uint32 xp = ALE::CHECKVAL(L, 2); - Unit* victim = ALE::CHECKOBJ(L, 3, false); + Unit* victim = victimArg ? victimArg->Resolve() : nullptr; player->GiveXP(xp, victim); - return 0; } /** * Toggle the [Player]s 'Do Not Disturb' flag */ - int ToggleDND(lua_State* /*L*/, Player* player) + void ToggleDND(Player* player) { player->ToggleDND(); - return 0; } /** * Toggle the [Player]s 'Away From Keyboard' flag */ - int ToggleAFK(lua_State* /*L*/, Player* player) + void ToggleAFK(Player* player) { player->ToggleAFK(); - return 0; } /** @@ -3088,27 +2655,26 @@ namespace LuaPlayer * @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) + Item* EquipItem(Player* player, sol::object itemOrEntry, uint32 slot) { uint16 dest = 0; - Item* item = ALE::CHECKOBJ(L, 2, false); - uint32 slot = ALE::CHECKVAL(L, 3); + Item* item = itemOrEntry.is() ? itemOrEntry.as().Require() : nullptr; if (slot >= INVENTORY_SLOT_BAG_END) - return 1; + return nullptr; if (!item) { - uint32 entry = ALE::CHECKVAL(L, 2); + uint32 entry = itemOrEntry.as(); item = Item::CreateItem(entry, 1, player); if (!item) - return 1; + return nullptr; InventoryResult result = player->CanEquipItem(slot, dest, item, false); if (result != EQUIP_ERR_OK) { delete item; - return 1; + return nullptr; } player->ItemAddedQuestCheck(entry, 1); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, entry, 1); @@ -3117,15 +2683,15 @@ namespace LuaPlayer { InventoryResult result = player->CanEquipItem(slot, dest, item, false); if (result != EQUIP_ERR_OK) - return 1; + return nullptr; player->RemoveItem(item->GetBagSlot(), item->GetSlot(), true); } - ALE::Push(L, player->EquipItem(dest, item, true)); + Item* equippedItem = player->EquipItem(dest, item, true); player->AutoUnequipOffhandIfNeed(); - return 1; + return equippedItem; } - + /** * Returns true if the player can equip the given [Item] or item entry to the given slot, false otherwise. * @@ -3136,39 +2702,28 @@ namespace LuaPlayer * @param uint32 slot : equipment slot to test * @return bool canEquip */ - int CanEquipItem(lua_State* L, Player* player) + bool CanEquipItem(Player* player, sol::object itemOrEntry, uint32 slot) { - Item* item = ALE::CHECKOBJ(L, 2, false); - uint32 slot = ALE::CHECKVAL(L, 3); + Item* item = itemOrEntry.is() ? itemOrEntry.as().Require() : nullptr; if (slot >= EQUIPMENT_SLOT_END) - { - ALE::Push(L, false); - return 1; - } + return false; if (!item) { - uint32 entry = ALE::CHECKVAL(L, 2); + uint32 entry = itemOrEntry.as(); uint16 dest; InventoryResult msg = player->CanEquipNewItem(slot, dest, entry, false); if (msg != EQUIP_ERR_OK) - { - ALE::Push(L, false); - return 1; - } + return false; } else { uint16 dest; InventoryResult msg = player->CanEquipItem(slot, dest, item, false); if (msg != EQUIP_ERR_OK) - { - ALE::Push(L, false); - return 1; - } + return false; } - ALE::Push(L, true); - return 1; + return true; } /** @@ -3176,22 +2731,19 @@ namespace LuaPlayer * * @param uint32 titleId */ - int UnsetKnownTitle(lua_State* L, Player* player) + void UnsetKnownTitle(Player* player, uint32 id) { - 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) + void AdvanceSkillsToMax(Player* player) { player->UpdateSkillsToMaxSkillsForLevel(); - return 0; } /** @@ -3199,12 +2751,10 @@ namespace LuaPlayer * * @param uint32 skillStep */ - int AdvanceAllSkills(lua_State* L, Player* player) + void AdvanceAllSkills(Player* player, uint32 step) { - uint32 step = ALE::CHECKVAL(L, 2); - if (!step) - return 0; + return; for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i) { @@ -3217,8 +2767,6 @@ namespace LuaPlayer player->UpdateSkill(entry->id, step); } } - - return 0; } /** @@ -3228,17 +2776,14 @@ namespace LuaPlayer * @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) + bool AdvanceSkill(Player* player, uint32 _skillId, uint32 _step) { - 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; + return success; } /** @@ -3250,22 +2795,15 @@ namespace LuaPlayer * @param float zCoord * @param float orientation */ - int Teleport(lua_State* L, Player* player) + bool Teleport(Player* player, uint32 mapId, float x, float y, float z, float o) { - 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; + return player->TeleportTo(mapId, x, y, z, o); } /** @@ -3274,14 +2812,12 @@ namespace LuaPlayer * @param [Player] player * @param uint32 kills */ - int AddLifetimeKills(lua_State* L, Player* player) + void AddLifetimeKills(Player* player, uint32 val) { - 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. * @@ -3289,10 +2825,9 @@ namespace LuaPlayer * @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) + Item* AddItem(Player* player, uint32 itemId, sol::optional itemCountArg) { - uint32 itemId = ALE::CHECKVAL(L, 2); - uint32 itemCount = ALE::CHECKVAL(L, 3, 1); + uint32 itemCount = itemCountArg.value_or(1); uint32 noSpaceForCount = 0; ItemPosCountVec dest; @@ -3301,16 +2836,15 @@ namespace LuaPlayer itemCount -= noSpaceForCount; if (itemCount == 0 || dest.empty()) - return 1; + return nullptr; Item* item = player->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); if (item) player->SendNewItem(item, itemCount, true, false); - ALE::Push(L, item); - return 1; + return item; } - + /** * Removes the given amount of the specified [Item] from the player. * @@ -3320,23 +2854,18 @@ namespace LuaPlayer * @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) + void RemoveItem(Player* player, sol::object itemOrEntry, uint32 itemCount) { - Item* item = ALE::CHECKOBJ(L, 2, false); - uint32 itemCount = ALE::CHECKVAL(L, 3); + Item* item = itemOrEntry.is() ? itemOrEntry.as().Require() : nullptr; if (!item) { - uint32 itemId = ALE::CHECKVAL(L, 2); + uint32 itemId = itemOrEntry.as(); 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; } /** @@ -3344,14 +2873,12 @@ namespace LuaPlayer * * @param uint32 val : kills to remove */ - int RemoveLifetimeKills(lua_State* L, Player* player) + void RemoveLifetimeKills(Player* player, uint32 val) { - 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; } /** @@ -3360,12 +2887,10 @@ namespace LuaPlayer * @param uint32 spellId * @param bool update = true */ - int ResetSpellCooldown(lua_State* L, Player* player) + void ResetSpellCooldown(Player* player, uint32 spellId, sol::optional updateArg) { - uint32 spellId = ALE::CHECKVAL(L, 2); - bool update = ALE::CHECKVAL(L, 3, true); + bool update = updateArg.value_or(true); player->RemoveSpellCooldown(spellId, update); - return 0; } /** @@ -3374,23 +2899,20 @@ namespace LuaPlayer * @param uint32 category * @param bool update = true */ - int ResetTypeCooldowns(lua_State* L, Player* player) + void ResetTypeCooldowns(Player* player, uint32 category, sol::optional updateArg) { - uint32 category = ALE::CHECKVAL(L, 2); - bool update = ALE::CHECKVAL(L, 3, true); + bool update = updateArg.value_or(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) + void ResetAllCooldowns(Player* player) { player->RemoveAllSpellCooldown(); - return 0; } /** @@ -3398,12 +2920,10 @@ namespace LuaPlayer * * @param string message */ - int SendBroadcastMessage(lua_State* L, Player* player) + void SendBroadcastMessage(Player* player, std::string const& message) { - const char* message = ALE::CHECKVAL(L, 2); - if (std::string(message).length() > 0) + if (message.length() > 0) ChatHandler(player->GetSession()).SendSysMessage(message); - return 0; } /** @@ -3411,12 +2931,10 @@ namespace LuaPlayer * * @param string message */ - int SendAreaTriggerMessage(lua_State* L, Player* player) + void SendAreaTriggerMessage(Player* player, std::string const& msg) { - std::string msg = ALE::CHECKVAL(L, 2); if (msg.length() > 0) player->GetSession()->SendAreaTriggerMessage("{}", msg.c_str()); - return 0; } /** @@ -3424,12 +2942,10 @@ namespace LuaPlayer * * @param string message */ - int SendNotification(lua_State* L, Player* player) + void SendNotification(Player* player, std::string const& msg) { - std::string msg = ALE::CHECKVAL(L, 2); if (msg.length() > 0) ChatHandler(player->GetSession()).SendNotification("{}", msg); - return 0; } /** @@ -3438,15 +2954,13 @@ namespace LuaPlayer * @param [WorldPacket] packet * @param bool selfOnly = true */ - int SendPacket(lua_State* L, Player* player) + void SendPacket(Player* player, WorldPacket* data, sol::optional selfOnlyArg) { - WorldPacket* data = ALE::CHECKOBJ(L, 2); - bool selfOnly = ALE::CHECKVAL(L, 3, true); + bool selfOnly = selfOnlyArg.value_or(true); if (selfOnly) player->GetSession()->SendPacket(data); else player->SendMessageToSet(data, true); - return 0; } /** @@ -3458,35 +2972,28 @@ namespace LuaPlayer * @param [Player] receiver * */ - int SendAddonMessage(lua_State* L, Player* player) + void SendAddonMessage(Player* player, std::string const& prefix, std::string const& message, uint8 channel, Player* receiver) { - 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 << player->GetGUID(); data << uint32(0); - data << receiver->GET_GUID(); + data << receiver->GetGUID(); 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) + void KickPlayer(Player* player) { player->GetSession()->KickPlayer(); - return 0; } /** @@ -3494,12 +3001,9 @@ namespace LuaPlayer * * @param int32 copperAmt : negative to remove, positive to add */ - int ModifyMoney(lua_State* L, Player* player) + void ModifyMoney(Player* player, int32 amt) { - int32 amt = ALE::CHECKVAL(L, 2); - player->ModifyMoney(amt); - return 1; } /** @@ -3507,11 +3011,9 @@ namespace LuaPlayer * * @param uint32 spellId */ - int LearnSpell(lua_State* L, Player* player) + void LearnSpell(Player* player, uint32 id) { - uint32 id = ALE::CHECKVAL(L, 2); player->learnSpell(id); - return 0; } /** @@ -3520,25 +3022,19 @@ namespace LuaPlayer * @param uint32 talent_id * @param uint32 talentRank */ - int LearnTalent(lua_State* L, Player* player) + void LearnTalent(Player* player, uint32 id, uint32 rank) { - 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) + void RunCommand(Player* player, std::string command) { - 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); @@ -3546,8 +3042,6 @@ namespace LuaPlayer auto handler = ChatHandler(player->GetSession()); handler._ParseCommands(command); - - return 0; } /** @@ -3556,15 +3050,10 @@ namespace LuaPlayer * @param uint32 glyphId * @param uint32 slotIndex */ - int SetGlyph(lua_State* L, Player* player) + void SetGlyph(Player* player, uint32 glyphId, uint32 slotIndex) { - 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; } /** @@ -3573,20 +3062,17 @@ namespace LuaPlayer * @param [uint32] slotIndex * @return [uint32] glyphId */ - int GetGlyph(lua_State* L, Player* player) + uint32 GetGlyph(Player* player, uint32 slotIndex) { - auto slotIndex = ALE::CHECKVAL(L, 2); - ALE::Push(L,player->GetGlyph(slotIndex)); - return 1; + return player->GetGlyph(slotIndex); } /** * 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) + void RemoveArenaSpellCooldowns(Player* player) { player->RemoveArenaSpellCooldowns(); - return 0; } /** @@ -3595,21 +3081,20 @@ namespace LuaPlayer * @param float healthPercent = 100.0f * @param bool ressSickness = false */ - int ResurrectPlayer(lua_State* L, Player* player) + void ResurrectPlayer(Player* player, sol::optional percentArg, sol::optional sicknessArg) { - float percent = ALE::CHECKVAL(L, 2, 100.0f); - bool sickness = ALE::CHECKVAL(L, 3, false); + float percent = percentArg.value_or(100.0f); + bool sickness = sicknessArg.value_or(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. + * 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] @@ -3622,15 +3107,11 @@ namespace LuaPlayer * @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) + void GossipMenuAddItem(Player* player, uint32 _icon, std::string const& msg, uint32 _sender, uint32 _intid, sol::optional codeArg, sol::optional promptMsgArg, sol::optional moneyArg) { - 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); + bool _code = codeArg.value_or(false); + std::string _promptMsg = promptMsgArg.value_or(""); + uint32 _money = moneyArg.value_or(0); if (player->PlayerTalkClass->GetGossipMenu().GetMenuItemCount() < GOSSIP_MAX_MENU_ITEMS) { player->PlayerTalkClass->GetGossipMenu().AddMenuItem(-1, _icon, msg, _sender, _intid, _promptMsg, _money, @@ -3638,9 +3119,8 @@ namespace LuaPlayer } else { - return luaL_error(L, "GossipMenuItem not added. Reached Max amount of possible GossipMenuItems in this GossipMenu"); + throw std::runtime_error("GossipMenuItem not added. Reached Max amount of possible GossipMenuItems in this GossipMenu"); } - return 0; } /** @@ -3648,10 +3128,9 @@ namespace LuaPlayer * * See also: [Player:GossipMenuAddItem], [Player:GossipAddQuests], [Player:GossipSendMenu], [Player:GossipClearMenu] */ - int GossipComplete(lua_State* /*L*/, Player* player) + void GossipComplete(Player* player) { player->PlayerTalkClass->SendCloseGossip(); - return 0; } /** @@ -3668,31 +3147,30 @@ namespace LuaPlayer * @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) + void GossipSendMenu(Player* player, uint32 npc_text, Object* sender, sol::optional menuIdArg) { - 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); + if (!menuIdArg) + throw std::invalid_argument("menu_id is mandatory when the sender is a Player"); + + uint32 menu_id = *menuIdArg; player->PlayerTalkClass->GetGossipMenu().SetMenuId(menu_id); } - player->PlayerTalkClass->SendGossipMenu(npc_text, sender->GET_GUID()); - return 0; + player->PlayerTalkClass->SendGossipMenu(npc_text, sender->GetGUID()); } /** * 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) + void GossipClearMenu(Player* player) { player->PlayerTalkClass->ClearMenus(); - return 0; } /** @@ -3700,12 +3178,9 @@ namespace LuaPlayer * * @param uint32 pathId : pathId from DBC or [Global:AddTaxiPath] */ - int StartTaxi(lua_State* L, Player* player) + void StartTaxi(Player* player, uint32 pathId) { - uint32 pathId = ALE::CHECKVAL(L, 2); - player->ActivateTaxiPathTo(pathId); - return 0; } /** @@ -3718,15 +3193,8 @@ namespace LuaPlayer * @param uint32 data * @param string iconText */ - int GossipSendPOI(lua_State* L, Player* player) + void GossipSendPOI(Player* player, float x, float y, uint32 icon, uint32 flags, uint32 data, std::string const& iconText) { - 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; @@ -3735,7 +3203,6 @@ namespace LuaPlayer packet << data; packet << iconText; player->GetSession()->SendPacket(&packet); - return 0; } /** @@ -3743,21 +3210,18 @@ namespace LuaPlayer * * @param [WorldObject] source : a questgiver with quests */ - int GossipAddQuests(lua_State* L, Player* player) + void GossipAddQuests(Player* player, WorldObject* source) { - 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()); + player->PrepareQuestMenu(source->GetGUID()); } else if (source->GetTypeId() == TYPEID_GAMEOBJECT) { if (source->ToGameObject()->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) - player->PrepareQuestMenu(source->GET_GUID()); + player->PrepareQuestMenu(source->GetGUID()); } - return 0; } /** @@ -3766,26 +3230,23 @@ namespace LuaPlayer * @param uint32 questId : entry of a quest * @param bool activateAccept = true : auto finish the quest */ - int SendQuestTemplate(lua_State* L, Player* player) + void SendQuestTemplate(Player* player, uint32 questId, sol::optional activateAcceptArg) { - uint32 questId = ALE::CHECKVAL(L, 2); - bool activateAccept = ALE::CHECKVAL(L, 3, true); + bool activateAccept = activateAcceptArg.value_or(true); - Quest const* quest = eObjectMgr->GetQuestTemplate(questId); + Quest const* quest = sObjectMgr->GetQuestTemplate(questId); if (!quest) - return 0; + return; - player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GET_GUID(), activateAccept); - return 0; + player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), activateAccept); } /** * Converts [Player]'s corpse to bones */ - int SpawnBones(lua_State* /*L*/, Player* player) + void SpawnBones(Player* player) { player->SpawnCorpseBones(); - return 0; } /** @@ -3793,11 +3254,9 @@ namespace LuaPlayer * * @param [Player] looter */ - int RemovedInsignia(lua_State* L, Player* player) + void RemovedInsignia(Player* player, Player* looter) { - Player* looter = ALE::CHECKOBJ(L, 2); player->RemovedInsignia(looter); - return 0; } /** @@ -3806,15 +3265,10 @@ namespace LuaPlayer * @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) + bool GroupInvite(Player* player, Player* invited) { - Player* invited = ALE::CHECKOBJ(L, 2); - if (invited->GetGroup() || invited->GetGroupInvite()) - { - ALE::Push(L, false); - return 1; - } + return false; // Get correct existing group if any Group* group = player->GetGroup(); @@ -3846,8 +3300,7 @@ namespace LuaPlayer invited->GetSession()->SendPacket(&data); } - ALE::Push(L, success); - return 1; + return success; } /** @@ -3856,12 +3309,10 @@ namespace LuaPlayer * @param [Player] invited : player to add to group * @return [Group] createdGroup : the created group or nil */ - int GroupCreate(lua_State* L, Player* player) + Group* GroupCreate(Player* player, Player* invited) { - Player* invited = ALE::CHECKOBJ(L, 2); - if (player->GetGroup() || invited->GetGroup()) - return 0; + return nullptr; if (player->GetGroupInvite()) player->UninviteFromGroup(); @@ -3873,7 +3324,7 @@ namespace LuaPlayer if (!group->AddLeaderInvite(player)) { delete group; - return 0; + return nullptr; } // Forming a new group, create it @@ -3885,10 +3336,9 @@ namespace LuaPlayer } if (!group->AddMember(invited)) - return 0; + return nullptr; group->BroadcastGroupUpdate(); - ALE::Push(L, group); - return 1; + return group; } /** @@ -3896,12 +3346,9 @@ namespace LuaPlayer * * @param uint32 CinematicSequenceId : entry of a cinematic */ - int SendCinematicStart(lua_State* L, Player* player) + void SendCinematicStart(Player* player, uint32 CinematicSequenceId) { - uint32 CinematicSequenceId = ALE::CHECKVAL(L, 2); - player->SendCinematicStart(CinematicSequenceId); - return 0; } /** @@ -3909,12 +3356,9 @@ namespace LuaPlayer * * @param uint32 MovieId : entry of a movie */ - int SendMovieStart(lua_State* L, Player* player) + void SendMovieStart(Player* player, uint32 MovieId) { - uint32 MovieId = ALE::CHECKVAL(L, 2); - player->SendMovieStart(MovieId); - return 0; } /** @@ -3924,13 +3368,9 @@ namespace LuaPlayer * @param uint32 index * @param uint32 value */ - int UpdatePlayerSetting(lua_State* L, Player* player) + void UpdatePlayerSetting(Player* player, std::string const& source, uint32 index, uint32 value) { - 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; } /** @@ -3939,13 +3379,10 @@ namespace LuaPlayer * @param string source * @param uint32 index */ - int GetPlayerSettingValue(lua_State* L, Player* player) + uint32 GetPlayerSettingValue(Player* player, std::string const& source, uint32 index) { - 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; + return value; } /** @@ -3953,10 +3390,9 @@ namespace LuaPlayer * * @return [Player] trader : the player trading, or nil */ - int GetTrader(lua_State* L, Player* player) + Player* GetTrader(Player* player) { - ALE::Push(L, player->GetTrader()); - return 1; + return player->GetTrader(); } /** @@ -3965,111 +3401,21 @@ namespace LuaPlayer * @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) + void SetSpellPower(Player* player, int value, sol::optional applyArg) { - int value = ALE::CHECKVAL(L, 2); - bool apply = ALE::CHECKVAL(L, 3, false); + bool apply = applyArg.value_or(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) + void SetBonusTalentCount(Player* player, uint32 value) { - uint32 value = ALE::CHECKVAL(L, 2); - player->SetBonusTalentCount(value); - return 0; } /** @@ -4077,34 +3423,29 @@ namespace LuaPlayer * * @return uint32 bonusTalent */ - int GetBonusTalentCount(lua_State* L, Player* player) + uint32 GetBonusTalentCount(Player* player) { - ALE::Push(L, player->GetBonusTalentCount()); - return 1; + return player->GetBonusTalentCount(); } - + /** * Returns the [Player] spells list * * @return table playerSpells */ - int GetSpells(lua_State* L, Player* player) + sol::table GetSpells(Player* player, sol::this_state s) { - std::list list; - lua_createtable(L, list.size(), 0); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); 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); + tbl[++i] = spellInfo->Id; } - lua_settop(L, tbl); - return 1; + return tbl; } /** @@ -4112,12 +3453,9 @@ namespace LuaPlayer * * @param uint32 count = count of bonus talent */ - int AddBonusTalent(lua_State* L, Player* player) + void AddBonusTalent(Player* player, uint32 count) { - uint32 count = ALE::CHECKVAL(L, 2); - player->AddBonusTalent(count); - return 0; } /** @@ -4125,14 +3463,11 @@ namespace LuaPlayer * * @param uint32 count = count of bonus talent */ - int RemoveBonusTalent(lua_State* L, Player* player) + void RemoveBonusTalent(Player* player, uint32 count) { - uint32 count = ALE::CHECKVAL(L, 2); - player->RemoveBonusTalent(count); - return 0; } - + /** * Returns the [Player] homebind location. * @@ -4142,22 +3477,16 @@ namespace LuaPlayer * - 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) + sol::table GetHomebind(Player* player, sol::this_state s) { - 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"); + sol::table tbl = sol::state_view(s).create_table(); - lua_pushnumber(L, player->m_homebindY); - lua_setfield(L, -2, "y"); + tbl["mapId"] = player->m_homebindMapId; + tbl["x"] = player->m_homebindX; + tbl["y"] = player->m_homebindY; + tbl["z"] = player->m_homebindZ; - lua_pushnumber(L, player->m_homebindZ); - lua_setfield(L, -2, "z"); - - return 1; + return tbl; } /** @@ -4165,10 +3494,9 @@ namespace LuaPlayer * * @param string tele : The name of the predefined teleport location. */ - int TeleportTo(lua_State* L, Player* player) + void TeleportTo(Player* player, std::string const& tele) { - std::string tele = ALE::CHECKVAL(L, 2); - const GameTele* game_tele = sObjectMgr->GetGameTele(tele); + GameTele const* game_tele = sObjectMgr->GetGameTele(tele); if (player->IsInFlight()) { @@ -4177,7 +3505,6 @@ namespace LuaPlayer } player->TeleportTo(game_tele->mapId, game_tele->position_x, game_tele->position_y, game_tele->position_z, game_tele->orientation); - return 0; } /** @@ -4185,10 +3512,9 @@ namespace LuaPlayer * * @return [Pet] pet : the player's pet, or `nil` if no pet */ - int GetPet(lua_State* L, Player* player) + Pet* GetPet(Player* player) { - ALE::Push(L, player->GetPet()); - return 1; + return player->GetPet(); } /** @@ -4196,10 +3522,9 @@ namespace LuaPlayer * * @return bool isMaxLevel */ - int IsMaxLevel(lua_State* L, Player* player) + bool IsMaxLevel(Player* player) { - ALE::Push(L, player->IsMaxLevel()); - return 1; + return player->IsMaxLevel(); } /** @@ -4215,20 +3540,13 @@ namespace LuaPlayer * @param uint32 healthPct = 0 : initial health percentage * @return [Pet] pet : the summoned pet, or `nil` if failed */ - int SummonPet(lua_State* L, Player* player) + Pet* SummonPet(Player* player, uint32 entry, float x, float y, float z, float ang, uint32 petType, sol::optional durationArg, sol::optional healthPctArg) { - 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); + uint32 duration = durationArg.value_or(0); + uint32 healthPct = healthPctArg.value_or(0); Pet* pet = player->SummonPet(entry, x, y, z, ang, static_cast(petType), Milliseconds(duration), healthPct); - ALE::Push(L, pet); - return 1; + return pet; } /** @@ -4236,10 +3554,9 @@ namespace LuaPlayer * * @return float averageItemLevel */ - int GetAverageItemLevel(lua_State* L, Player* player) + float GetAverageItemLevel(Player* player) { - ALE::Push(L, player->GetAverageItemLevel()); - return 1; + return player->GetAverageItemLevel(); } /** @@ -4254,22 +3571,19 @@ namespace LuaPlayer * @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) + Pet* CreatePet(Player* player, sol::object creatureOrEntry, sol::optional spellIDArg) { - if (lua_gettop(L) == 2) - { - uint32 creatureEntry = ALE::CHECKVAL(L, 2); - Pet* pet = player->CreatePet(creatureEntry); - ALE::Push(L, pet); - } - else + if (creatureOrEntry.is()) { - Creature* creatureTarget = ALE::CHECKOBJ(L, 2); - uint32 spellID = ALE::CHECKVAL(L, 3, 0); + Creature* creatureTarget = creatureOrEntry.as().Require(); + uint32 spellID = spellIDArg.value_or(0); Pet* pet = player->CreatePet(creatureTarget, spellID); - ALE::Push(L, pet); + return pet; } - return 1; + + uint32 creatureEntry = creatureOrEntry.as(); + Pet* pet = player->CreatePet(creatureEntry); + return pet; } /** @@ -4278,11 +3592,9 @@ namespace LuaPlayer * @param uint32 questId * @return bool isDailyQuestDone */ - int IsDailyQuestDone(lua_State* L, Player* player) + bool IsDailyQuestDone(Player* player, uint32 questId) { - uint32 questId = ALE::CHECKVAL(L, 2); - ALE::Push(L, player->IsDailyQuestDone(questId)); - return 1; + return player->IsDailyQuestDone(questId); } /** @@ -4290,10 +3602,9 @@ namespace LuaPlayer * * The pet can be resummoned later. Used during teleportation, mounting, etc. */ - int UnsummonPetTemporarily(lua_State* /*L*/, Player* player) + void UnsummonPetTemporarily(Player* player) { player->UnsummonPetTemporaryIfAny(); - return 0; } /** @@ -4301,11 +3612,9 @@ namespace LuaPlayer * * @param uint32 flag : the player flag to set */ - int SetPlayerFlag(lua_State* L, Player* player) + void SetPlayerFlag(Player* player, uint32 flag) { - uint32 flag = ALE::CHECKVAL(L, 2); player->SetPlayerFlag((PlayerFlags)flag); - return 0; } /** @@ -4315,13 +3624,10 @@ namespace LuaPlayer * @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) + void RemovePet(Player* player, Pet* pet, uint32 mode, sol::optional returnReagentArg) { - Pet* pet = ALE::CHECKOBJ(L, 2); - uint32 mode = ALE::CHECKVAL(L, 3); - bool returnReagent = ALE::CHECKVAL(L, 4, false); + bool returnReagent = returnReagentArg.value_or(false); player->RemovePet(pet, static_cast(mode), returnReagent); - return 1; } /** @@ -4329,11 +3635,9 @@ namespace LuaPlayer * * @param uint32 flag : the player flag to remove */ - int RemovePlayerFlag(lua_State* L, Player* player) + void RemovePlayerFlag(Player* player, uint32 flag) { - uint32 flag = ALE::CHECKVAL(L, 2); player->RemovePlayerFlag((PlayerFlags)flag); - return 0; } /** @@ -4341,10 +3645,9 @@ namespace LuaPlayer * * @return bool canResurrect */ - int CanPetResurrect(lua_State* L, Player* player) + bool CanPetResurrect(Player* player) { - ALE::Push(L, player->CanPetResurrect()); - return 1; + return player->CanPetResurrect(); } /** @@ -4354,12 +3657,9 @@ namespace LuaPlayer * @param uint32 maximum : the maximum value * @return uint32 randomValue : a random number between min and max */ - int DoRandomRoll(lua_State* L, Player* player) + uint32 DoRandomRoll(Player* player, uint32 minimum, uint32 maximum) { - uint32 minimum = ALE::CHECKVAL(L, 2); - uint32 maximum = ALE::CHECKVAL(L, 3); - ALE::Push(L, player->DoRandomRoll(minimum, maximum)); - return 1; + return player->DoRandomRoll(minimum, maximum); } /** @@ -4367,10 +3667,9 @@ namespace LuaPlayer * * @return bool isPvP */ - int IsPvP(lua_State* L, Player* player) + bool IsPvP(Player* player) { - ALE::Push(L, player->IsPvP()); - return 1; + return player->IsPvP(); } /** @@ -4378,10 +3677,9 @@ namespace LuaPlayer * * @return bool isFFAPvP */ - int IsFFAPvP(lua_State* L, Player* player) + bool IsFFAPvP(Player* player) { - ALE::Push(L, player->IsFFAPvP()); - return 1; + return player->IsFFAPvP(); } /** @@ -4389,10 +3687,9 @@ namespace LuaPlayer * * @return bool isUsingLfg */ - int IsUsingLfg(lua_State* L, Player* player) + bool IsUsingLfg(Player* player) { - ALE::Push(L, player->IsUsingLfg()); - return 1; + return player->IsUsingLfg(); } /** @@ -4400,10 +3697,9 @@ namespace LuaPlayer * * @return bool inRandomLfgDungeon */ - int InRandomLfgDungeon(lua_State* L, Player* player) + bool InRandomLfgDungeon(Player* player) { - ALE::Push(L, player->inRandomLfgDungeon()); - return 1; + return player->inRandomLfgDungeon(); } /** @@ -4412,11 +3708,9 @@ namespace LuaPlayer * @param [Object] questGiver : the quest giver object * @return bool canInteract */ - int CanInteractWithQuestGiver(lua_State* L, Player* player) + bool CanInteractWithQuestGiver(Player* player, Object* questGiver) { - Object* questGiver = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->CanInteractWithQuestGiver(questGiver)); - return 1; + return player->CanInteractWithQuestGiver(questGiver); } /** @@ -4425,11 +3719,9 @@ namespace LuaPlayer * @param [Quest] quest : the quest to check * @return bool canSeeStartQuest */ - int CanSeeStartQuest(lua_State* L, Player* player) + bool CanSeeStartQuest(Player* player, Quest const* quest) { - Quest const* quest = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->CanSeeStartQuest(quest)); - return 1; + return player->CanSeeStartQuest(quest); } /** @@ -4437,10 +3729,9 @@ namespace LuaPlayer * * @return bool hasExistingPet */ - int IsExistPet(lua_State* L, Player* player) + bool IsExistPet(Player* player) { - ALE::Push(L, player->IsExistPet()); - return 1; + return player->IsExistPet(); } /** @@ -4450,22 +3741,19 @@ namespace LuaPlayer * @param bool msg : whether to send error messages * @return bool canTakeQuest */ - int CanTakeQuest(lua_State* L, Player* player) + bool CanTakeQuest(Player* player, Quest const* quest, sol::optional msgArg) { - Quest const* quest = ALE::CHECKOBJ(L, 2); - bool msg = ALE::CHECKVAL(L, 3, true); - ALE::Push(L, player->CanTakeQuest(quest, msg)); - return 1; + bool msg = msgArg.value_or(true); + return player->CanTakeQuest(quest, msg); } /** * Resets the [Player]'s pet talents. * */ - int ResetPetTalents(lua_State* /*L*/, Player* player) + void ResetPetTalents(Player* player) { player->ResetPetTalents(); - return 0; } /** @@ -4475,12 +3763,10 @@ namespace LuaPlayer * @param bool msg : whether to send error messages * @return bool canAddQuest */ - int CanAddQuest(lua_State* L, Player* player) + bool CanAddQuest(Player* player, Quest const* quest, sol::optional msgArg) { - Quest const* quest = ALE::CHECKOBJ(L, 2); - bool msg = ALE::CHECKVAL(L, 3, true); - ALE::Push(L, player->CanAddQuest(quest, msg)); - return 1; + bool msg = msgArg.value_or(true); + return player->CanAddQuest(quest, msg); } /** @@ -4491,13 +3777,9 @@ namespace LuaPlayer * @param uint8 newfacialhair : the new facial hair * @return uint32 cost : the cost in copper */ - int GetBarberShopCost(lua_State* L, Player* player) + uint32 GetBarberShopCost(Player* player, uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair) { - 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; + return player->GetBarberShopCost(newhairstyle, newhaircolor, newfacialhair); } /** @@ -4506,11 +3788,10 @@ namespace LuaPlayer * @param [WorldObject] target : the target to check sight range for (optional) * @return float sightRange */ - int GetSightRange(lua_State* L, Player* player) + float GetSightRange(Player* player, sol::optional targetArg) { - WorldObject* target = ALE::CHECKOBJ(L, 2, false); - ALE::Push(L, player->GetSightRange(target)); - return 1; + WorldObject* target = targetArg ? targetArg->Resolve() : nullptr; + return player->GetSightRange(target); } /** @@ -4523,16 +3804,11 @@ namespace LuaPlayer * @param bool noQuestBonus : whether to skip quest bonus * @return float reputationGain */ - int CalculateReputationGain(lua_State* L, Player* player) + float CalculateReputationGain(Player* player, uint32 source, uint32 creatureOrQuestLevel, float rep, uint32 faction, sol::optional noQuestBonusArg) { - 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; + bool noQuestBonus = noQuestBonusArg.value_or(false); + + return player->CalculateReputationGain((ReputationSource)source, creatureOrQuestLevel, rep, faction, noQuestBonus); } /** @@ -4542,21 +3818,17 @@ namespace LuaPlayer * @param uint32 damage : damage amount * @return uint32 actualDamage : the actual damage dealt */ - int EnvironmentalDamage(lua_State* L, Player* player) + uint32 EnvironmentalDamage(Player* player, uint32 type, uint32 damage) { - uint32 type = ALE::CHECKVAL(L, 2); - uint32 damage = ALE::CHECKVAL(L, 3); - ALE::Push(L, player->EnvironmentalDamage((EnviromentalDamage)type, damage)); - return 1; + return player->EnvironmentalDamage((EnviromentalDamage)type, damage); } /** * Initializes taxi nodes for the [Player]'s current level. */ - int InitTaxiNodesForLevel(lua_State* /*L*/, Player* player) + void InitTaxiNodesForLevel(Player* player) { player->InitTaxiNodesForLevel(); - return 0; } /** @@ -4566,13 +3838,9 @@ namespace LuaPlayer * @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) + void LearnPetTalent(Player* player, ObjectGuid petGuid, uint32 talentId, uint32 talentRank) { - 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; } /** @@ -4581,11 +3849,9 @@ namespace LuaPlayer * @param uint32 bitIndex : the title bit index to check * @return bool hasTitle */ - int HasTitleByIndex(lua_State* L, Player* player) + bool HasTitleByIndex(Player* player, uint32 bitIndex) { - uint32 bitIndex = ALE::CHECKVAL(L, 2); - ALE::Push(L, player->HasTitle(bitIndex)); - return 1; + return player->HasTitle(bitIndex); } /** @@ -4594,11 +3860,9 @@ namespace LuaPlayer * @param [WorldObject] target : the target to check distance to * @return bool isAtGroupRewardDistance */ - int IsAtGroupRewardDistance(lua_State* L, Player* player) + bool IsAtGroupRewardDistance(Player* player, WorldObject const* target) { - WorldObject const* target = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->IsAtGroupRewardDistance(target)); - return 1; + return player->IsAtGroupRewardDistance(target); } /** @@ -4607,11 +3871,9 @@ namespace LuaPlayer * @param [WorldObject] target : the target to check distance to * @return bool isAtLootRewardDistance */ - int IsAtLootRewardDistance(lua_State* L, Player* player) + bool IsAtLootRewardDistance(Player* player, WorldObject const* target) { - WorldObject const* target = ALE::CHECKOBJ(L, 2); - ALE::Push(L, player->IsAtLootRewardDistance(target)); - return 1; + return player->IsAtLootRewardDistance(target); } /** @@ -4619,11 +3881,9 @@ namespace LuaPlayer * * @param uint32 questId : the quest entry ID to abandon */ - int AbandonQuest(lua_State* L, Player* player) + void AbandonQuest(Player* player, uint32 questId) { - uint32 questId = ALE::CHECKVAL(L, 2); player->AbandonQuest(questId); - return 0; } /** @@ -4631,10 +3891,9 @@ namespace LuaPlayer * * @return bool canTameExoticPets : `true` if the player can tame exotic pets, `false` otherwise */ - int CanTameExoticPets(lua_State* L, Player* player) + bool CanTameExoticPets(Player* player) { - ALE::Push(L, player->CanTameExoticPets()); - return 1; + return player->CanTameExoticPets(); } /** @@ -4642,10 +3901,9 @@ namespace LuaPlayer * * @return uint32 proficiencyFlags : bitmask of weapon proficiencies */ - int GetWeaponProficiency(lua_State* L, Player* player) + uint32 GetWeaponProficiency(Player* player) { - ALE::Push(L, player->GetWeaponProficiency()); - return 1; + return player->GetWeaponProficiency(); } /** @@ -4653,10 +3911,9 @@ namespace LuaPlayer * * @return uint32 petNumber : the temporary unsummoned pet number */ - int GetTemporaryUnsummonedPetNumber(lua_State* L, Player* player) + uint32 GetTemporaryUnsummonedPetNumber(Player* player) { - ALE::Push(L, player->GetTemporaryUnsummonedPetNumber()); - return 1; + return player->GetTemporaryUnsummonedPetNumber(); } /** @@ -4664,10 +3921,9 @@ namespace LuaPlayer * * @return uint32 proficiencyFlags : bitmask of armor proficiencies */ - int GetArmorProficiency(lua_State* L, Player* player) + uint32 GetArmorProficiency(Player* player) { - ALE::Push(L, player->GetArmorProficiency()); - return 1; + return player->GetArmorProficiency(); } /** @@ -4675,11 +3931,9 @@ namespace LuaPlayer * * @param uint32 petNumber : the pet number to set */ - int SetTemporaryUnsummonedPetNumber(lua_State* L, Player* player) + void SetTemporaryUnsummonedPetNumber(Player* player, uint32 petNumber) { - uint32 petNumber = ALE::CHECKVAL(L, 2); player->SetTemporaryUnsummonedPetNumber(petNumber); - return 0; } /** @@ -4687,21 +3941,18 @@ namespace LuaPlayer * * @param uint32 flag : weapon proficiency flag to add */ - int AddWeaponProficiency(lua_State* L, Player* player) + void AddWeaponProficiency(Player* player, uint32 flag) { - 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) + void ResummonPetTemporaryUnSummonedIfAny(Player* player) { player->ResummonPetTemporaryUnSummonedIfAny(); - return 0; } /** @@ -4709,11 +3960,9 @@ namespace LuaPlayer * * @param uint32 flag : armor proficiency flag to add */ - int AddArmorProficiency(lua_State* L, Player* player) + void AddArmorProficiency(Player* player, uint32 flag) { - uint32 flag = ALE::CHECKVAL(L, 2); player->AddArmorProficiency(flag); - return 0; } /** @@ -4722,10 +3971,9 @@ namespace LuaPlayer * * @return bool isPetNeedBeTemporaryUnsummoned : `true` if the pet needs to be temporarily unsummoned, `false` otherwise */ - int IsPetNeedBeTemporaryUnsummoned(lua_State* L, Player* player) + bool IsPetNeedBeTemporaryUnsummoned(Player* player) { - ALE::Push(L, player->IsPetNeedBeTemporaryUnsummoned()); - return 1; + return player->IsPetNeedBeTemporaryUnsummoned(); } /** @@ -4733,20 +3981,17 @@ namespace LuaPlayer * * @param uint32 itemEntry : ammo item entry ID */ - int SetAmmo(lua_State* L, Player* player) + void SetAmmo(Player* player, uint32 itemEntry) { - uint32 itemEntry = ALE::CHECKVAL(L, 2); player->SetAmmo(itemEntry); - return 0; } /** * Removes the [Player]'s ammo. */ - int RemoveAmmo(lua_State* /*L*/, Player* player) + void RemoveAmmo(Player* player) { player->RemoveAmmo(); - return 0; } /** @@ -4754,10 +3999,9 @@ namespace LuaPlayer * * @return float ammoDPS : damage per second from ammo */ - int GetAmmoDPS(lua_State* L, Player* player) + float GetAmmoDPS(Player* player) { - ALE::Push(L, player->GetAmmoDPS()); - return 1; + return player->GetAmmoDPS(); } /** @@ -4766,11 +4010,9 @@ namespace LuaPlayer * @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) + bool CanResummonPet(Player* player, uint32 spellId) { - uint32 spellId = ALE::CHECKVAL(L, 2); - ALE::Push(L, player->CanResummonPet(spellId)); - return 1; + return player->CanResummonPet(spellId); } /** @@ -4778,10 +4020,9 @@ namespace LuaPlayer * * @return [Item] shield : the equipped shield or nil */ - int GetShield(lua_State* L, Player* player) + Item* GetShield(Player* player) { - ALE::Push(L, player->GetShield()); - return 1; + return player->GetShield(); } /** @@ -4789,10 +4030,9 @@ namespace LuaPlayer * * @return uint32 petNumber : the last pet number */ - int GetLastPetNumber(lua_State* L, Player* player) + uint32 GetLastPetNumber(Player* player) { - ALE::Push(L, player->GetLastPetNumber()); - return 1; + return player->GetLastPetNumber(); } /** @@ -4800,10 +4040,9 @@ namespace LuaPlayer * * @return bool canTeleport */ - int CanTeleport(lua_State* L, Player* player) + bool CanTeleport(Player* player) { - ALE::Push(L, player->CanTeleport()); - return 1; + return player->CanTeleport(); } /** @@ -4811,11 +4050,9 @@ namespace LuaPlayer * * @param uint32 petNumber : the pet number to set */ - int SetLastPetNumber(lua_State* L, Player* player) + void SetLastPetNumber(Player* player, uint32 petNumber) { - uint32 petNumber = ALE::CHECKVAL(L, 2); player->SetLastPetNumber(petNumber); - return 0; } /** @@ -4823,11 +4060,9 @@ namespace LuaPlayer * * @param bool canTeleport : true to allow teleportation, false to disallow */ - int SetCanTeleport(lua_State* L, Player* player) + void SetCanTeleport(Player* player, bool canTeleport) { - bool canTeleport = ALE::CHECKVAL(L, 2); player->SetCanTeleport(canTeleport); - return 0; } /** @@ -4835,10 +4070,9 @@ namespace LuaPlayer * * @return uint32 petSpell : the pet spell ID */ - int GetLastPetSpell(lua_State* L, Player* player) + uint32 GetLastPetSpell(Player* player) { - ALE::Push(L, player->GetLastPetSpell()); - return 1; + return player->GetLastPetSpell(); } /** @@ -4846,10 +4080,9 @@ namespace LuaPlayer * * @return uint32 runesState : current runes state bitmask */ - int GetRunesState(lua_State* L, Player* player) + uint8 GetRunesState(Player* player) { - ALE::Push(L, player->GetRunesState()); - return 1; + return player->GetRunesState(); } /** @@ -4857,11 +4090,9 @@ namespace LuaPlayer * * @param uint32 petSpell : the pet spell ID to set */ - int SetLastPetSpell(lua_State* L, Player* player) + void SetLastPetSpell(Player* player, uint32 petSpell) { - uint32 petSpell = ALE::CHECKVAL(L, 2); player->SetLastPetSpell(petSpell); - return 0; } /** @@ -4869,10 +4100,9 @@ namespace LuaPlayer * * @return bool isSpectator */ - int IsSpectator(lua_State* L, Player* player) + bool IsSpectator(Player* player) { - ALE::Push(L, player->IsSpectator()); - return 1; + return player->IsSpectator(); } /** @@ -4880,11 +4110,9 @@ namespace LuaPlayer * * @param bool isSpectator : true to set as spectator, false otherwise */ - int SetIsSpectator(lua_State* L, Player* player) + void SetIsSpectator(Player* player, bool isSpectator) { - bool isSpectator = ALE::CHECKVAL(L, 2); player->SetIsSpectator(isSpectator); - return 0; } /** @@ -4892,10 +4120,9 @@ namespace LuaPlayer * * @return bool canSeeDKPet */ - int CanSeeDKPet(lua_State* L, Player* player) + bool CanSeeDKPet(Player* player) { - ALE::Push(L, player->CanSeeDKPet()); - return 1; + return player->CanSeeDKPet(); } /** @@ -4903,10 +4130,9 @@ namespace LuaPlayer * * @return [WorldObject] viewpoint : the object the player is viewing from */ - int GetViewpoint(lua_State* L, Player* player) + WorldObject* GetViewpoint(Player* player) { - ALE::Push(L, player->GetViewpoint()); - return 1; + return player->GetViewpoint(); } /** @@ -4914,11 +4140,9 @@ namespace LuaPlayer * * @param bool show : `true` to show DK pets, `false` to hide them */ - int SetShowDKPet(lua_State* L, Player* player) + void SetShowDKPet(Player* player, bool show) { - bool show = ALE::CHECKVAL(L, 2); player->SetShowDKPet(show); - return 0; } /** @@ -4926,21 +4150,18 @@ namespace LuaPlayer * * @param [WorldObject] target : the object to view from */ - int SetViewpoint(lua_State* L, Player* player) + void SetViewpoint(Player* player, WorldObject* target, sol::optional applyArg) { - WorldObject* target = ALE::CHECKOBJ(L, 2); - bool apply = ALE::CHECKVAL(L, 3, false); + bool apply = applyArg.value_or(false); player->SetViewpoint(target, apply); - return 0; } /** * Toggles instant flight mode for the [Player]. */ - int ToggleInstantFlight(lua_State* /*L*/, Player* player) + void ToggleInstantFlight(Player* player) { player->ToggleInstantFlight(); - return 0; } /** @@ -4948,10 +4169,9 @@ namespace LuaPlayer * * @return uint32 creationTime : Unix timestamp of character creation */ - int GetCreationTime(lua_State* L, Player* player) + uint32 GetCreationTime(Player* player) { - ALE::Push(L, static_cast(player->GetCreationTime().count())); - return 1; + return static_cast(player->GetCreationTime().count()); } /** @@ -4959,11 +4179,9 @@ namespace LuaPlayer * * @param uint32 creationTime : Unix timestamp to set as creation time */ - int SetCreationTime(lua_State* L, Player* player) + void SetCreationTime(Player* player, uint32 creationTime) { - uint32 creationTime = ALE::CHECKVAL(L, 2); player->SetCreationTime(Seconds(creationTime)); - return 0; } /** @@ -4971,12 +4189,11 @@ namespace LuaPlayer * * @return float dodgeChance : dodge percentage from agility stat */ - int GetDodgeFromAgility(lua_State* L, Player* player) + float GetDodgeFromAgility(Player* player) { float diminishing, nondiminishing; player->GetDodgeFromAgility(diminishing, nondiminishing); - ALE::Push(L, diminishing + nondiminishing); - return 1; + return diminishing + nondiminishing; } /** @@ -4984,10 +4201,9 @@ namespace LuaPlayer * * @return float critChance : melee crit percentage from agility stat */ - int GetMeleeCritFromAgility(lua_State* L, Player* player) + float GetMeleeCritFromAgility(Player* player) { - ALE::Push(L, player->GetMeleeCritFromAgility()); - return 1; + return player->GetMeleeCritFromAgility(); } /** @@ -4995,10 +4211,9 @@ namespace LuaPlayer * * @return float critChance : spell crit percentage from intellect stat */ - int GetSpellCritFromIntellect(lua_State* L, Player* player) + float GetSpellCritFromIntellect(Player* player) { - ALE::Push(L, player->GetSpellCritFromIntellect()); - return 1; + return player->GetSpellCritFromIntellect(); } /** @@ -5007,13 +4222,12 @@ namespace LuaPlayer * @param uint32 slot : inventory slot number * @return [Item] item : the item in the specified slot or nil */ - int GetInventoryItem(lua_State* L, Player* player) + Item* GetInventoryItem(Player* player, uint32 slot) { - 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; + return nullptr; + + return player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); } /** @@ -5022,13 +4236,12 @@ namespace LuaPlayer * @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) + Item* GetBankItem(Player* player, uint32 slot) { - 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; + return nullptr; + + return player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot + BANK_SLOT_ITEM_START); } /** @@ -5037,14 +4250,12 @@ namespace LuaPlayer * @param uint16 slot : quest log slot * @return uint32 questId : quest ID or 0 if slot is invalid */ - int GetQuestSlotQuestId(lua_State* L, Player* player) + sol::optional GetQuestSlotQuestId(Player* player, uint16 slot) { - uint16 slot = ALE::CHECKVAL(L, 2); if (slot > MAX_QUEST_LOG_SIZE) - return 0; + return sol::nullopt; - ALE::Push(L, player->GetQuestSlotQuestId(slot)); - return 1; + return player->GetQuestSlotQuestId(slot); } /** @@ -5052,11 +4263,10 @@ namespace LuaPlayer * * @param bool activate = false : true to enable flying, false to disable */ - int SetCanFly(lua_State* L, Player* player) + void SetCanFly(Player* player, sol::optional activateArg) { - bool activate = ALE::CHECKVAL(L, 2, false); + bool activate = activateArg.value_or(false); player->SetCanFly(activate); - return 0; } /** @@ -5097,15 +4307,11 @@ namespace LuaPlayer * */ - int ApplyRatingMod(lua_State* L, Player* player) + void ApplyRatingMod(Player* player, int32 stat, float value, sol::optional applyArg) { - int32 stat = ALE::CHECKVAL(L, 2); - - float value = ALE::CHECKVAL(L, 3); - bool apply = ALE::CHECKVAL(L, 4, false); + bool apply = applyArg.value_or(false); player->ApplyRatingMod(CombatRating(stat), value, apply); - return 0; } /** @@ -5114,24 +4320,12 @@ namespace LuaPlayer * @param uint32 nodeId * @return bool known */ - int HasKnownTaxiNode(lua_State* L, Player* player) + bool HasKnownTaxiNode(Player* player, uint32 nodeId) { - if (!player) - { - ALE::Push(L, false); - return 1; - } - - uint32 nodeId = ALE::CHECKVAL(L, 2); - if (nodeId == 0) - { - ALE::Push(L, false); - return 1; - } + return false; - ALE::Push(L, player->m_taxi.IsTaximaskNodeKnown(nodeId)); - return 1; + return player->m_taxi.IsTaximaskNodeKnown(nodeId); } /** @@ -5139,30 +4333,26 @@ namespace LuaPlayer * * @return bool isBot */ - int IsBot(lua_State* L, Player* player) + bool IsBot(Player* player) { #if defined(MOD_PLAYERBOTS) - ALE::Push(L, player->GetSession()->IsBot()); + return player->GetSession()->IsBot(); #else (void)player; - ALE::Push(L, false); + return false; #endif - return 1; } - + /** * Returns the [Player]s spent talent points in each talent tree for the active spec * * @return uint8 tree1, uint8 tree2, uint8 tree3 */ - int GetTalentTreePoints(lua_State* L, Player* player) + std::tuple GetTalentTreePoints(Player* player) { uint8 specPoints[3] = {0, 0, 0}; player->GetTalentTreePoints(specPoints); - ALE::Push(L, specPoints[0]); - ALE::Push(L, specPoints[1]); - ALE::Push(L, specPoints[2]); - return 3; + return std::tuple(specPoints[0], specPoints[1], specPoints[2]); } /** @@ -5170,11 +4360,348 @@ namespace LuaPlayer * * @return uint8 treeIndex */ - int GetMostPointsTalentTree(lua_State* L, Player* player) + uint8 GetMostPointsTalentTree(Player* player) { - ALE::Push(L, player->GetMostPointsTalentTree()); - return 1; + return player->GetMostPointsTalentTree(); } -}; -#endif - +} +void RegisterPlayerMethods(sol::state& lua) +{ + sol::usertype type = ALEBind::NewHandleType(lua, "Player"); + + type["GetInventoryFreeSlots" ] = ALEBind::Method(&LuaPlayer::GetInventoryFreeSlots); + type["GetBankFreeSlots" ] = ALEBind::Method(&LuaPlayer::GetBankFreeSlots); + type["GetSelection" ] = ALEBind::Method(&LuaPlayer::GetSelection); + type["GetGMRank" ] = ALEBind::Method(&LuaPlayer::GetGMRank); + type["GetGuildId" ] = ALEBind::Method(&LuaPlayer::GetGuildId); + type["GetCoinage" ] = ALEBind::Method(&LuaPlayer::GetCoinage); + type["GetTeam" ] = ALEBind::Method(&LuaPlayer::GetTeam); + type["GetItemCount" ] = ALEBind::Method(&LuaPlayer::GetItemCount); + type["GetGroup" ] = ALEBind::Method(&LuaPlayer::GetGroup); + type["GetGuild" ] = ALEBind::Method(&LuaPlayer::GetGuild); + type["GetAccountId" ] = ALEBind::Method(&LuaPlayer::GetAccountId); + type["GetAccountName" ] = ALEBind::Method(&LuaPlayer::GetAccountName); + type["GetCompletedQuestsCount" ] = ALEBind::Method(&LuaPlayer::GetCompletedQuestsCount); + type["GetArenaPoints" ] = ALEBind::Method(&LuaPlayer::GetArenaPoints); + type["GetHonorPoints" ] = ALEBind::Method(&LuaPlayer::GetHonorPoints); + type["GetTodayHonorPoints" ] = ALEBind::Method(&LuaPlayer::GetTodayHonorPoints); + type["GetYesterdayHonorPoints" ] = ALEBind::Method(&LuaPlayer::GetYesterdayHonorPoints); + type["GetLifetimeKills" ] = ALEBind::Method(&LuaPlayer::GetLifetimeKills); + type["GetTodayKills" ] = ALEBind::Method(&LuaPlayer::GetTodayKills); + type["GetYesterdayKills" ] = ALEBind::Method(&LuaPlayer::GetYesterdayKills); + type["GetPlayerIP" ] = ALEBind::Method(&LuaPlayer::GetPlayerIP); + type["GetLevelPlayedTime" ] = ALEBind::Method(&LuaPlayer::GetLevelPlayedTime); + type["GetTotalPlayedTime" ] = ALEBind::Method(&LuaPlayer::GetTotalPlayedTime); + type["GetItemByPos" ] = ALEBind::Method(&LuaPlayer::GetItemByPos); + type["GetItemByEntry" ] = ALEBind::Method(&LuaPlayer::GetItemByEntry); + type["GetItemByGUID" ] = ALEBind::Method(&LuaPlayer::GetItemByGUID); + type["GetMailCount" ] = ALEBind::Method(&LuaPlayer::GetMailCount); + type["GetMailItem" ] = ALEBind::Method(&LuaPlayer::GetMailItem); + type["GetReputation" ] = ALEBind::Method(&LuaPlayer::GetReputation); + type["GetEquippedItemBySlot" ] = ALEBind::Method(&LuaPlayer::GetEquippedItemBySlot); + type["GetQuestLevel" ] = ALEBind::Method(&LuaPlayer::GetQuestLevel); + type["GetChatTag" ] = ALEBind::Method(&LuaPlayer::GetChatTag); + type["GetRestBonus" ] = ALEBind::Method(&LuaPlayer::GetRestBonus); + type["GetPhaseMaskForSpawn" ] = ALEBind::Method(&LuaPlayer::GetPhaseMaskForSpawn); + type["GetAchievementPoints" ] = ALEBind::Method(&LuaPlayer::GetAchievementPoints); + type["GetCompletedAchievementsCount" ] = ALEBind::Method(&LuaPlayer::GetCompletedAchievementsCount); + type["GetReqKillOrCastCurrentCount" ] = ALEBind::Method(&LuaPlayer::GetReqKillOrCastCurrentCount); + type["GetQuestStatus" ] = ALEBind::Method(&LuaPlayer::GetQuestStatus); + type["GetInGameTime" ] = ALEBind::Method(&LuaPlayer::GetInGameTime); + type["GetComboPoints" ] = ALEBind::Method(&LuaPlayer::GetComboPoints); + type["GetComboTarget" ] = ALEBind::Method(&LuaPlayer::GetComboTarget); + type["GetGuildName" ] = ALEBind::Method(&LuaPlayer::GetGuildName); + type["GetFreeTalentPoints" ] = ALEBind::Method(&LuaPlayer::GetFreeTalentPoints); + type["GetActiveSpec" ] = ALEBind::Method(&LuaPlayer::GetActiveSpec); + type["GetSpecsCount" ] = ALEBind::Method(&LuaPlayer::GetSpecsCount); + type["GetSpellCooldownDelay" ] = ALEBind::Method(&LuaPlayer::GetSpellCooldownDelay); + type["GetGuildRank" ] = ALEBind::Method(&LuaPlayer::GetGuildRank); + type["GetDifficulty" ] = ALEBind::Method(&LuaPlayer::GetDifficulty); + type["GetHealthBonusFromStamina" ] = ALEBind::Method(&LuaPlayer::GetHealthBonusFromStamina); + type["GetManaBonusFromIntellect" ] = ALEBind::Method(&LuaPlayer::GetManaBonusFromIntellect); + type["GetMaxSkillValue" ] = ALEBind::Method(&LuaPlayer::GetMaxSkillValue); + type["GetPureMaxSkillValue" ] = ALEBind::Method(&LuaPlayer::GetPureMaxSkillValue); + type["GetSkillValue" ] = ALEBind::Method(&LuaPlayer::GetSkillValue); + type["GetBaseSkillValue" ] = ALEBind::Method(&LuaPlayer::GetBaseSkillValue); + type["GetPureSkillValue" ] = ALEBind::Method(&LuaPlayer::GetPureSkillValue); + type["GetSkillPermBonusValue" ] = ALEBind::Method(&LuaPlayer::GetSkillPermBonusValue); + type["GetSkillTempBonusValue" ] = ALEBind::Method(&LuaPlayer::GetSkillTempBonusValue); + type["GetReputationRank" ] = ALEBind::Method(&LuaPlayer::GetReputationRank); + type["GetDrunkValue" ] = ALEBind::Method(&LuaPlayer::GetDrunkValue); + type["GetBattlegroundId" ] = ALEBind::Method(&LuaPlayer::GetBattlegroundId); + type["GetBattlegroundTypeId" ] = ALEBind::Method(&LuaPlayer::GetBattlegroundTypeId); + type["GetXP" ] = ALEBind::Method(&LuaPlayer::GetXP); + type["GetXPRestBonus" ] = ALEBind::Method(&LuaPlayer::GetXPRestBonus); + type["GetGroupInvite" ] = ALEBind::Method(&LuaPlayer::GetGroupInvite); + type["GetSubGroup" ] = ALEBind::Method(&LuaPlayer::GetSubGroup); + type["GetNextRandomRaidMember" ] = ALEBind::Method(&LuaPlayer::GetNextRandomRaidMember); + type["GetOriginalGroup" ] = ALEBind::Method(&LuaPlayer::GetOriginalGroup); + type["GetOriginalSubGroup" ] = ALEBind::Method(&LuaPlayer::GetOriginalSubGroup); + type["GetChampioningFaction" ] = ALEBind::Method(&LuaPlayer::GetChampioningFaction); + type["GetLatency" ] = ALEBind::Method(&LuaPlayer::GetLatency); + type["GetDbLocaleIndex" ] = ALEBind::Method(&LuaPlayer::GetDbLocaleIndex); + type["GetDbcLocale" ] = ALEBind::Method(&LuaPlayer::GetDbcLocale); + type["GetCorpse" ] = ALEBind::Method(&LuaPlayer::GetCorpse); + type["GetGossipTextId" ] = ALEBind::Method(&LuaPlayer::GetGossipTextId); + type["GetQuestRewardStatus" ] = ALEBind::Method(&LuaPlayer::GetQuestRewardStatus); + type["GetShieldBlockValue" ] = ALEBind::Method(&LuaPlayer::GetShieldBlockValue); + type["GetPlayerSettingValue" ] = ALEBind::Method(&LuaPlayer::GetPlayerSettingValue); + type["GetTrader" ] = ALEBind::Method(&LuaPlayer::GetTrader); + type["GetBonusTalentCount" ] = ALEBind::Method(&LuaPlayer::GetBonusTalentCount); + type["GetKnownTaxiNodes" ] = ALEBind::Method(&LuaPlayer::GetKnownTaxiNodes); + type["GetPet" ] = ALEBind::Method(&LuaPlayer::GetPet); + type["GetTemporaryUnsummonedPetNumber" ] = ALEBind::Method(&LuaPlayer::GetTemporaryUnsummonedPetNumber); + type["GetLastPetNumber" ] = ALEBind::Method(&LuaPlayer::GetLastPetNumber); + type["GetLastPetSpell" ] = ALEBind::Method(&LuaPlayer::GetLastPetSpell); + type["GetQuestSlotQuestId" ] = ALEBind::Method(&LuaPlayer::GetQuestSlotQuestId); + type["GetTalentTreePoints" ] = ALEBind::Method(&LuaPlayer::GetTalentTreePoints); + type["GetMostPointsTalentTree" ] = ALEBind::Method(&LuaPlayer::GetMostPointsTalentTree); + type["SetTemporaryUnsummonedPetNumber" ] = ALEBind::Method(&LuaPlayer::SetTemporaryUnsummonedPetNumber); + type["SetLastPetNumber" ] = ALEBind::Method(&LuaPlayer::SetLastPetNumber); + type["SetLastPetSpell" ] = ALEBind::Method(&LuaPlayer::SetLastPetSpell); + type["SetShowDKPet" ] = ALEBind::Method(&LuaPlayer::SetShowDKPet); + type["AdvanceSkillsToMax" ] = ALEBind::Method(&LuaPlayer::AdvanceSkillsToMax); + type["AdvanceSkill" ] = ALEBind::Method(&LuaPlayer::AdvanceSkill); + type["AdvanceAllSkills" ] = ALEBind::Method(&LuaPlayer::AdvanceAllSkills); + type["AddLifetimeKills" ] = ALEBind::Method(&LuaPlayer::AddLifetimeKills); + type["SetCoinage" ] = ALEBind::Method(&LuaPlayer::SetCoinage); + type["SetKnownTitle" ] = ALEBind::Method(&LuaPlayer::SetKnownTitle); + type["UnsetKnownTitle" ] = ALEBind::Method(&LuaPlayer::UnsetKnownTitle); + type["SetBindPoint" ] = ALEBind::Method(&LuaPlayer::SetBindPoint); + type["SetArenaPoints" ] = ALEBind::Method(&LuaPlayer::SetArenaPoints); + type["SetHonorPoints" ] = ALEBind::Method(&LuaPlayer::SetHonorPoints); + type["SetSpellPower" ] = ALEBind::Method(&LuaPlayer::SetSpellPower); + type["SetLifetimeKills" ] = ALEBind::Method(&LuaPlayer::SetLifetimeKills); + type["SetGameMaster" ] = ALEBind::Method(&LuaPlayer::SetGameMaster); + type["SetGMChat" ] = ALEBind::Method(&LuaPlayer::SetGMChat); + type["SetKnownTaxiNodes" ] = ALEBind::Method(&LuaPlayer::SetKnownTaxiNodes); + type["SetTaxiCheat" ] = ALEBind::Method(&LuaPlayer::SetTaxiCheat); + type["SetGMVisible" ] = ALEBind::Method(&LuaPlayer::SetGMVisible); + type["SetPvPDeath" ] = ALEBind::Method(&LuaPlayer::SetPvPDeath); + type["SetAcceptWhispers" ] = ALEBind::Method(&LuaPlayer::SetAcceptWhispers); + type["SetRestBonus" ] = ALEBind::Method(&LuaPlayer::SetRestBonus); + type["SetQuestStatus" ] = ALEBind::Method(&LuaPlayer::SetQuestStatus); + type["SetReputation" ] = ALEBind::Method(&LuaPlayer::SetReputation); + type["SetFreeTalentPoints" ] = ALEBind::Method(&LuaPlayer::SetFreeTalentPoints); + type["SetGuildRank" ] = ALEBind::Method(&LuaPlayer::SetGuildRank); + type["SetSkill" ] = ALEBind::Method(&LuaPlayer::SetSkill); + type["SetFactionForRace" ] = ALEBind::Method(&LuaPlayer::SetFactionForRace); + type["SetDrunkValue" ] = ALEBind::Method(&LuaPlayer::SetDrunkValue); + type["SetAtLoginFlag" ] = ALEBind::Method(&LuaPlayer::SetAtLoginFlag); + type["SetPlayerLock" ] = ALEBind::Method(&LuaPlayer::SetPlayerLock); + type["SetGender" ] = ALEBind::Method(&LuaPlayer::SetGender); + type["SetSheath" ] = ALEBind::Method(&LuaPlayer::SetSheath); + type["SetBonusTalentCount" ] = ALEBind::Method(&LuaPlayer::SetBonusTalentCount); + type["AddBonusTalent" ] = ALEBind::Method(&LuaPlayer::AddBonusTalent); + type["RemoveBonusTalent" ] = ALEBind::Method(&LuaPlayer::RemoveBonusTalent); + type["GetHomebind" ] = ALEBind::Method(&LuaPlayer::GetHomebind); + type["GetSpells" ] = ALEBind::Method(&LuaPlayer::GetSpells); + type["GetAverageItemLevel" ] = ALEBind::Method(&LuaPlayer::GetAverageItemLevel); + type["GetBarberShopCost" ] = ALEBind::Method(&LuaPlayer::GetBarberShopCost); + type["GetSightRange" ] = ALEBind::Method(&LuaPlayer::GetSightRange); + type["GetWeaponProficiency" ] = ALEBind::Method(&LuaPlayer::GetWeaponProficiency); + type["GetArmorProficiency" ] = ALEBind::Method(&LuaPlayer::GetArmorProficiency); + type["GetAmmoDPS" ] = ALEBind::Method(&LuaPlayer::GetAmmoDPS); + type["GetShield" ] = ALEBind::Method(&LuaPlayer::GetShield); + type["GetRunesState" ] = ALEBind::Method(&LuaPlayer::GetRunesState); + type["GetViewpoint" ] = ALEBind::Method(&LuaPlayer::GetViewpoint); + type["GetDodgeFromAgility" ] = ALEBind::Method(&LuaPlayer::GetDodgeFromAgility); + type["GetMeleeCritFromAgility" ] = ALEBind::Method(&LuaPlayer::GetMeleeCritFromAgility); + type["GetSpellCritFromIntellect" ] = ALEBind::Method(&LuaPlayer::GetSpellCritFromIntellect); + type["GetInventoryItem" ] = ALEBind::Method(&LuaPlayer::GetInventoryItem); + type["GetBankItem" ] = ALEBind::Method(&LuaPlayer::GetBankItem); + type["GetCreationTime" ] = ALEBind::Method(&LuaPlayer::GetCreationTime); + type["SetCanFly" ] = ALEBind::Method(&LuaPlayer::SetCanFly); + type["HasTankSpec" ] = ALEBind::Method(&LuaPlayer::HasTankSpec); + type["HasMeleeSpec" ] = ALEBind::Method(&LuaPlayer::HasMeleeSpec); + type["HasCasterSpec" ] = ALEBind::Method(&LuaPlayer::HasCasterSpec); + type["HasHealSpec" ] = ALEBind::Method(&LuaPlayer::HasHealSpec); + type["IsInGroup" ] = ALEBind::Method(&LuaPlayer::IsInGroup); + type["IsInGuild" ] = ALEBind::Method(&LuaPlayer::IsInGuild); + type["IsGM" ] = ALEBind::Method(&LuaPlayer::IsGM); + type["IsImmuneToDamage" ] = ALEBind::Method(&LuaPlayer::IsImmuneToDamage); + type["IsAlliance" ] = ALEBind::Method(&LuaPlayer::IsAlliance); + type["IsHorde" ] = ALEBind::Method(&LuaPlayer::IsHorde); + type["HasTitle" ] = ALEBind::Method(&LuaPlayer::HasTitle); + type["HasItem" ] = ALEBind::Method(&LuaPlayer::HasItem); + type["Teleport" ] = ALEBind::Method(&LuaPlayer::Teleport); + type["AddItem" ] = ALEBind::Method(&LuaPlayer::AddItem); + type["IsInArenaTeam" ] = ALEBind::Method(&LuaPlayer::IsInArenaTeam); + type["CanRewardQuest" ] = ALEBind::Method(&LuaPlayer::CanRewardQuest); + type["CanCompleteRepeatableQuest" ] = ALEBind::Method(&LuaPlayer::CanCompleteRepeatableQuest); + type["CanCompleteQuest" ] = ALEBind::Method(&LuaPlayer::CanCompleteQuest); + type["CanEquipItem" ] = ALEBind::Method(&LuaPlayer::CanEquipItem); + type["IsFalling" ] = ALEBind::Method(&LuaPlayer::IsFalling); + type["ToggleAFK" ] = ALEBind::Method(&LuaPlayer::ToggleAFK); + type["ToggleDND" ] = ALEBind::Method(&LuaPlayer::ToggleDND); + type["IsAFK" ] = ALEBind::Method(&LuaPlayer::IsAFK); + type["IsDND" ] = ALEBind::Method(&LuaPlayer::IsDND); + type["IsAcceptingWhispers" ] = ALEBind::Method(&LuaPlayer::IsAcceptingWhispers); + type["IsGMChat" ] = ALEBind::Method(&LuaPlayer::IsGMChat); + type["IsTaxiCheater" ] = ALEBind::Method(&LuaPlayer::IsTaxiCheater); + type["IsGMVisible" ] = ALEBind::Method(&LuaPlayer::IsGMVisible); + type["HasQuest" ] = ALEBind::Method(&LuaPlayer::HasQuest); + type["InBattlegroundQueue" ] = ALEBind::Method(&LuaPlayer::InBattlegroundQueue); + type["CanSpeak" ] = ALEBind::Method(&LuaPlayer::CanSpeak); + type["HasAtLoginFlag" ] = ALEBind::Method(&LuaPlayer::HasAtLoginFlag); + type["HasAchieved" ] = ALEBind::Method(&LuaPlayer::HasAchieved); + type["GetAchievementCriteriaProgress" ] = ALEBind::Method(&LuaPlayer::GetAchievementCriteriaProgress); + type["SetAchievement" ] = ALEBind::Method(&LuaPlayer::SetAchievement); + type["CanUninviteFromGroup" ] = ALEBind::Method(&LuaPlayer::CanUninviteFromGroup); + type["IsRested" ] = ALEBind::Method(&LuaPlayer::IsRested); + type["IsVisibleForPlayer" ] = ALEBind::Method(&LuaPlayer::IsVisibleForPlayer); + type["HasQuestForItem" ] = ALEBind::Method(&LuaPlayer::HasQuestForItem); + type["HasQuestForGO" ] = ALEBind::Method(&LuaPlayer::HasQuestForGO); + type["CanShareQuest" ] = ALEBind::Method(&LuaPlayer::CanShareQuest); + type["HasTalent" ] = ALEBind::Method(&LuaPlayer::HasTalent); + type["IsInSameGroupWith" ] = ALEBind::Method(&LuaPlayer::IsInSameGroupWith); + type["IsInSameRaidWith" ] = ALEBind::Method(&LuaPlayer::IsInSameRaidWith); + type["IsGroupVisibleFor" ] = ALEBind::Method(&LuaPlayer::IsGroupVisibleFor); + type["HasSkill" ] = ALEBind::Method(&LuaPlayer::HasSkill); + type["IsHonorOrXPTarget" ] = ALEBind::Method(&LuaPlayer::IsHonorOrXPTarget); + type["CanParry" ] = ALEBind::Method(&LuaPlayer::CanParry); + type["CanBlock" ] = ALEBind::Method(&LuaPlayer::CanBlock); + type["CanTitanGrip" ] = ALEBind::Method(&LuaPlayer::CanTitanGrip); + type["InBattleground" ] = ALEBind::Method(&LuaPlayer::InBattleground); + type["InArena" ] = ALEBind::Method(&LuaPlayer::InArena); + type["CanUseItem" ] = ALEBind::Method(&LuaPlayer::CanUseItem); + type["HasSpell" ] = ALEBind::Method(&LuaPlayer::HasSpell); + type["HasSpellCooldown" ] = ALEBind::Method(&LuaPlayer::HasSpellCooldown); + type["IsInWater" ] = ALEBind::Method(&LuaPlayer::IsInWater); + type["CanFly" ] = ALEBind::Method(&LuaPlayer::CanFly); + type["IsMoving" ] = ALEBind::Method(&LuaPlayer::IsMoving); + type["IsFlying" ] = ALEBind::Method(&LuaPlayer::IsFlying); + type["CanPetResurrect" ] = ALEBind::Method(&LuaPlayer::CanPetResurrect); + type["IsExistPet" ] = ALEBind::Method(&LuaPlayer::IsExistPet); + type["CanTameExoticPets" ] = ALEBind::Method(&LuaPlayer::CanTameExoticPets); + type["IsPetNeedBeTemporaryUnsummoned" ] = ALEBind::Method(&LuaPlayer::IsPetNeedBeTemporaryUnsummoned); + type["CanResummonPet" ] = ALEBind::Method(&LuaPlayer::CanResummonPet); + type["CanSeeDKPet" ] = ALEBind::Method(&LuaPlayer::CanSeeDKPet); + type["IsMaxLevel" ] = ALEBind::Method(&LuaPlayer::IsMaxLevel); + type["IsDailyQuestDone" ] = ALEBind::Method(&LuaPlayer::IsDailyQuestDone); + type["IsPvP" ] = ALEBind::Method(&LuaPlayer::IsPvP); + type["IsFFAPvP" ] = ALEBind::Method(&LuaPlayer::IsFFAPvP); + type["IsUsingLfg" ] = ALEBind::Method(&LuaPlayer::IsUsingLfg); + type["InRandomLfgDungeon" ] = ALEBind::Method(&LuaPlayer::InRandomLfgDungeon); + type["CanInteractWithQuestGiver" ] = ALEBind::Method(&LuaPlayer::CanInteractWithQuestGiver); + type["CanSeeStartQuest" ] = ALEBind::Method(&LuaPlayer::CanSeeStartQuest); + type["CanTakeQuest" ] = ALEBind::Method(&LuaPlayer::CanTakeQuest); + type["CanAddQuest" ] = ALEBind::Method(&LuaPlayer::CanAddQuest); + type["CalculateReputationGain" ] = ALEBind::Method(&LuaPlayer::CalculateReputationGain); + type["HasTitleByIndex" ] = ALEBind::Method(&LuaPlayer::HasTitleByIndex); + type["IsAtGroupRewardDistance" ] = ALEBind::Method(&LuaPlayer::IsAtGroupRewardDistance); + type["IsAtLootRewardDistance" ] = ALEBind::Method(&LuaPlayer::IsAtLootRewardDistance); + type["CanTeleport" ] = ALEBind::Method(&LuaPlayer::CanTeleport); + type["IsSpectator" ] = ALEBind::Method(&LuaPlayer::IsSpectator); + type["HasKnownTaxiNode" ] = ALEBind::Method(&LuaPlayer::HasKnownTaxiNode); + type["IsBot" ] = ALEBind::Method(&LuaPlayer::IsBot); + type["GossipMenuAddItem" ] = ALEBind::Method(&LuaPlayer::GossipMenuAddItem); + type["GossipSendMenu" ] = ALEBind::Method(&LuaPlayer::GossipSendMenu); + type["GossipComplete" ] = ALEBind::Method(&LuaPlayer::GossipComplete); + type["GossipClearMenu" ] = ALEBind::Method(&LuaPlayer::GossipClearMenu); + type["SendBroadcastMessage" ] = ALEBind::Method(&LuaPlayer::SendBroadcastMessage); + type["SendAreaTriggerMessage" ] = ALEBind::Method(&LuaPlayer::SendAreaTriggerMessage); + type["SendNotification" ] = ALEBind::Method(&LuaPlayer::SendNotification); + type["SendPacket" ] = ALEBind::Method(&LuaPlayer::SendPacket); + type["SendAddonMessage" ] = ALEBind::Method(&LuaPlayer::SendAddonMessage); + type["ModifyMoney" ] = ALEBind::Method(&LuaPlayer::ModifyMoney); + type["LearnSpell" ] = ALEBind::Method(&LuaPlayer::LearnSpell); + type["LearnTalent" ] = ALEBind::Method(&LuaPlayer::LearnTalent); + type["RunCommand" ] = ALEBind::Method(&LuaPlayer::RunCommand); + type["SetGlyph" ] = ALEBind::Method(&LuaPlayer::SetGlyph); + type["GetGlyph" ] = ALEBind::Method(&LuaPlayer::GetGlyph); + type["RemoveArenaSpellCooldowns" ] = ALEBind::Method(&LuaPlayer::RemoveArenaSpellCooldowns); + type["RemoveItem" ] = ALEBind::Method(&LuaPlayer::RemoveItem); + type["RemoveLifetimeKills" ] = ALEBind::Method(&LuaPlayer::RemoveLifetimeKills); + type["ResurrectPlayer" ] = ALEBind::Method(&LuaPlayer::ResurrectPlayer); + type["EquipItem" ] = ALEBind::Method(&LuaPlayer::EquipItem); + type["ResetSpellCooldown" ] = ALEBind::Method(&LuaPlayer::ResetSpellCooldown); + type["ResetTypeCooldowns" ] = ALEBind::Method(&LuaPlayer::ResetTypeCooldowns); + type["ResetAllCooldowns" ] = ALEBind::Method(&LuaPlayer::ResetAllCooldowns); + type["GiveXP" ] = ALEBind::Method(&LuaPlayer::GiveXP); + type["Say" ] = ALEBind::Method(&LuaPlayer::Say); + type["Yell" ] = ALEBind::Method(&LuaPlayer::Yell); + type["TextEmote" ] = ALEBind::Method(&LuaPlayer::TextEmote); + type["Whisper" ] = ALEBind::Method(&LuaPlayer::Whisper); + type["CompleteQuest" ] = ALEBind::Method(&LuaPlayer::CompleteQuest); + type["IncompleteQuest" ] = ALEBind::Method(&LuaPlayer::IncompleteQuest); + type["FailQuest" ] = ALEBind::Method(&LuaPlayer::FailQuest); + type["AddQuest" ] = ALEBind::Method(&LuaPlayer::AddQuest); + type["RemoveQuest" ] = ALEBind::Method(&LuaPlayer::RemoveQuest); + type["AreaExploredOrEventHappens" ] = ALEBind::Method(&LuaPlayer::AreaExploredOrEventHappens); + type["GroupEventHappens" ] = ALEBind::Method(&LuaPlayer::GroupEventHappens); + type["KilledMonsterCredit" ] = ALEBind::Method(&LuaPlayer::KilledMonsterCredit); + type["TalkedToCreature" ] = ALEBind::Method(&LuaPlayer::TalkedToCreature); + type["ResetPetTalents" ] = ALEBind::Method(&LuaPlayer::ResetPetTalents); + type["AddComboPoints" ] = ALEBind::Method(&LuaPlayer::AddComboPoints); + type["ClearComboPoints" ] = ALEBind::Method(&LuaPlayer::ClearComboPoints); + type["RemoveSpell" ] = ALEBind::Method(&LuaPlayer::RemoveSpell); + type["ResetTalents" ] = ALEBind::Method(&LuaPlayer::ResetTalents); + type["ResetTalentsCost" ] = ALEBind::Method(&LuaPlayer::ResetTalentsCost); + type["RemoveFromGroup" ] = ALEBind::Method(&LuaPlayer::RemoveFromGroup); + type["KillPlayer" ] = ALEBind::Method(&LuaPlayer::KillPlayer); + type["DurabilityLossAll" ] = ALEBind::Method(&LuaPlayer::DurabilityLossAll); + type["DurabilityLoss" ] = ALEBind::Method(&LuaPlayer::DurabilityLoss); + type["DurabilityPointsLoss" ] = ALEBind::Method(&LuaPlayer::DurabilityPointsLoss); + type["DurabilityPointsLossAll" ] = ALEBind::Method(&LuaPlayer::DurabilityPointsLossAll); + type["DurabilityPointLossForEquipSlot" ] = ALEBind::Method(&LuaPlayer::DurabilityPointLossForEquipSlot); + type["DurabilityRepairAll" ] = ALEBind::Method(&LuaPlayer::DurabilityRepairAll); + type["DurabilityRepair" ] = ALEBind::Method(&LuaPlayer::DurabilityRepair); + type["ModifyHonorPoints" ] = ALEBind::Method(&LuaPlayer::ModifyHonorPoints); + type["ModifyArenaPoints" ] = ALEBind::Method(&LuaPlayer::ModifyArenaPoints); + type["LeaveBattleground" ] = ALEBind::Method(&LuaPlayer::LeaveBattleground); + type["UnbindInstance" ] = ALEBind::Method(&LuaPlayer::UnbindInstance); + type["UnbindAllInstances" ] = ALEBind::Method(&LuaPlayer::UnbindAllInstances); + type["RemoveFromBattlegroundRaid" ] = ALEBind::Method(&LuaPlayer::RemoveFromBattlegroundRaid); + type["ResetAchievements" ] = ALEBind::Method(&LuaPlayer::ResetAchievements); + type["KickPlayer" ] = ALEBind::Method(&LuaPlayer::KickPlayer); + type["LogoutPlayer" ] = ALEBind::Method(&LuaPlayer::LogoutPlayer); + type["SendTrainerList" ] = ALEBind::Method(&LuaPlayer::SendTrainerList); + type["SendListInventory" ] = ALEBind::Method(&LuaPlayer::SendListInventory); + type["SendShowBank" ] = ALEBind::Method(&LuaPlayer::SendShowBank); + type["SendTabardVendorActivate" ] = ALEBind::Method(&LuaPlayer::SendTabardVendorActivate); + type["SendSpiritResurrect" ] = ALEBind::Method(&LuaPlayer::SendSpiritResurrect); + type["SendTaxiMenu" ] = ALEBind::Method(&LuaPlayer::SendTaxiMenu); + type["SendUpdateWorldState" ] = ALEBind::Method(&LuaPlayer::SendUpdateWorldState); + type["RewardQuest" ] = ALEBind::Method(&LuaPlayer::RewardQuest); + type["SendAuctionMenu" ] = ALEBind::Method(&LuaPlayer::SendAuctionMenu); + type["SendShowMailBox" ] = ALEBind::Method(&LuaPlayer::SendShowMailBox); + type["StartTaxi" ] = ALEBind::Method(&LuaPlayer::StartTaxi); + type["GossipSendPOI" ] = ALEBind::Method(&LuaPlayer::GossipSendPOI); + type["GossipAddQuests" ] = ALEBind::Method(&LuaPlayer::GossipAddQuests); + type["SendQuestTemplate" ] = ALEBind::Method(&LuaPlayer::SendQuestTemplate); + type["SpawnBones" ] = ALEBind::Method(&LuaPlayer::SpawnBones); + type["RemovedInsignia" ] = ALEBind::Method(&LuaPlayer::RemovedInsignia); + type["SendGuildInvite" ] = ALEBind::Method(&LuaPlayer::SendGuildInvite); + type["Mute" ] = ALEBind::Method(&LuaPlayer::Mute); + type["SummonPlayer" ] = ALEBind::Method(&LuaPlayer::SummonPlayer); + type["SaveToDB" ] = ALEBind::Method(&LuaPlayer::SaveToDB); + type["GroupInvite" ] = ALEBind::Method(&LuaPlayer::GroupInvite); + type["GroupCreate" ] = ALEBind::Method(&LuaPlayer::GroupCreate); + type["SendCinematicStart" ] = ALEBind::Method(&LuaPlayer::SendCinematicStart); + type["SendMovieStart" ] = ALEBind::Method(&LuaPlayer::SendMovieStart); + type["UpdatePlayerSetting" ] = ALEBind::Method(&LuaPlayer::UpdatePlayerSetting); + type["TeleportTo" ] = ALEBind::Method(&LuaPlayer::TeleportTo); + type["SummonPet" ] = ALEBind::Method(&LuaPlayer::SummonPet); + type["CreatePet" ] = ALEBind::Method(&LuaPlayer::CreatePet); + type["UnsummonPetTemporarily" ] = ALEBind::Method(&LuaPlayer::UnsummonPetTemporarily); + type["RemovePet" ] = ALEBind::Method(&LuaPlayer::RemovePet); + type["LearnPetTalent" ] = ALEBind::Method(&LuaPlayer::LearnPetTalent); + type["ResummonPetTemporaryUnSummonedIfAny"] = ALEBind::Method(&LuaPlayer::ResummonPetTemporaryUnSummonedIfAny); + type["SetPlayerFlag" ] = ALEBind::Method(&LuaPlayer::SetPlayerFlag); + type["RemovePlayerFlag" ] = ALEBind::Method(&LuaPlayer::RemovePlayerFlag); + type["DoRandomRoll" ] = ALEBind::Method(&LuaPlayer::DoRandomRoll); + type["EnvironmentalDamage" ] = ALEBind::Method(&LuaPlayer::EnvironmentalDamage); + type["InitTaxiNodesForLevel" ] = ALEBind::Method(&LuaPlayer::InitTaxiNodesForLevel); + type["AbandonQuest" ] = ALEBind::Method(&LuaPlayer::AbandonQuest); + type["AddWeaponProficiency" ] = ALEBind::Method(&LuaPlayer::AddWeaponProficiency); + type["AddArmorProficiency" ] = ALEBind::Method(&LuaPlayer::AddArmorProficiency); + type["SetAmmo" ] = ALEBind::Method(&LuaPlayer::SetAmmo); + type["RemoveAmmo" ] = ALEBind::Method(&LuaPlayer::RemoveAmmo); + type["SetCanTeleport" ] = ALEBind::Method(&LuaPlayer::SetCanTeleport); + type["SetIsSpectator" ] = ALEBind::Method(&LuaPlayer::SetIsSpectator); + type["SetViewpoint" ] = ALEBind::Method(&LuaPlayer::SetViewpoint); + type["ToggleInstantFlight" ] = ALEBind::Method(&LuaPlayer::ToggleInstantFlight); + type["SetCreationTime" ] = ALEBind::Method(&LuaPlayer::SetCreationTime); + type["ApplyRatingMod" ] = ALEBind::Method(&LuaPlayer::ApplyRatingMod); +} diff --git a/src/LuaEngine/methods/QuestMethods.h b/src/LuaEngine/methods/QuestMethods.cpp similarity index 72% rename from src/LuaEngine/methods/QuestMethods.h rename to src/LuaEngine/methods/QuestMethods.cpp index 7969cad751..28023654e0 100644 --- a/src/LuaEngine/methods/QuestMethods.h +++ b/src/LuaEngine/methods/QuestMethods.cpp @@ -4,8 +4,9 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef QUESTMETHODS_H -#define QUESTMETHODS_H +#include "ALEBind.h" + +#include "QuestDef.h" /*** * Represents a quest in the game, including its objectives, rewards, and conditions. @@ -51,11 +52,9 @@ namespace LuaQuest * @param [QuestFlags] flag : all available flags can be seen above * @return bool hasFlag */ - int HasFlag(lua_State* L, Quest* quest) + bool HasFlag(Quest* quest, uint32 flag) { - uint32 flag = ALE::CHECKVAL(L, 2); - ALE::Push(L, quest->HasFlag(flag)); - return 1; + return quest->HasFlag(flag); } /** @@ -63,10 +62,9 @@ namespace LuaQuest * * @return bool isDaily */ - int IsDaily(lua_State* L, Quest* quest) + bool IsDaily(Quest* quest) { - ALE::Push(L, quest->IsDaily()); - return 1; + return quest->IsDaily(); } /** @@ -74,10 +72,9 @@ namespace LuaQuest * * @return bool isRepeatable */ - int IsRepeatable(lua_State* L, Quest* quest) + bool IsRepeatable(Quest* quest) { - ALE::Push(L, quest->IsRepeatable()); - return 1; + return quest->IsRepeatable(); } /** @@ -85,10 +82,9 @@ namespace LuaQuest * * @return uint32 entryId */ - int GetId(lua_State* L, Quest* quest) + uint32 GetId(Quest* quest) { - ALE::Push(L, quest->GetQuestId()); - return 1; + return quest->GetQuestId(); } /** @@ -96,10 +92,9 @@ namespace LuaQuest * * @return uint32 level */ - int GetLevel(lua_State* L, Quest* quest) + int32 GetLevel(Quest* quest) { - ALE::Push(L, quest->GetQuestLevel()); - return 1; + return quest->GetQuestLevel(); } /** @@ -107,10 +102,9 @@ namespace LuaQuest * * @return uint32 minLevel */ - int GetMinLevel(lua_State* L, Quest* quest) + uint32 GetMinLevel(Quest* quest) { - ALE::Push(L, quest->GetMinLevel()); - return 1; + return quest->GetMinLevel(); } /** @@ -118,10 +112,9 @@ namespace LuaQuest * * @return int32 entryId */ - int GetNextQuestId(lua_State* L, Quest* quest) + uint32 GetNextQuestId(Quest* quest) { - ALE::Push(L, quest->GetNextQuestId()); - return 1; + return quest->GetNextQuestId(); } /** @@ -129,10 +122,9 @@ namespace LuaQuest * * @return int32 entryId */ - int GetPrevQuestId(lua_State* L, Quest* quest) + int32 GetPrevQuestId(Quest* quest) { - ALE::Push(L, quest->GetPrevQuestId()); - return 1; + return quest->GetPrevQuestId(); } /** @@ -140,10 +132,9 @@ namespace LuaQuest * * @return int32 entryId */ - int GetNextQuestInChain(lua_State* L, Quest* quest) + uint32 GetNextQuestInChain(Quest* quest) { - ALE::Push(L, quest->GetNextQuestInChain()); - return 1; + return quest->GetNextQuestInChain(); } /** @@ -151,10 +142,9 @@ namespace LuaQuest * * @return [QuestFlags] flags */ - int GetFlags(lua_State* L, Quest* quest) + uint32 GetFlags(Quest* quest) { - ALE::Push(L, quest->GetFlags()); - return 1; + return quest->GetFlags(); } /** @@ -164,16 +154,30 @@ namespace LuaQuest * * @return uint32 type */ - int GetType(lua_State* L, Quest* quest) + uint32 GetType(Quest* quest) { - ALE::Push(L, quest->GetType()); - return 1; + return quest->GetType(); } - /*int GetMaxLevel(lua_State* L, Quest* quest) + /*uint32 GetMaxLevel(Quest* quest) { - ALE::Push(L, quest->GetMaxLevel()); - return 1; + return quest->GetMaxLevel(); }*/ -}; -#endif +} + +void RegisterQuestMethods(sol::state& lua) +{ + sol::usertype type = lua.new_usertype("Quest", sol::no_constructor); + + type["HasFlag"] = &LuaQuest::HasFlag; + type["IsDaily"] = &LuaQuest::IsDaily; + type["IsRepeatable"] = &LuaQuest::IsRepeatable; + type["GetId"] = &LuaQuest::GetId; + type["GetLevel"] = &LuaQuest::GetLevel; + type["GetMinLevel"] = &LuaQuest::GetMinLevel; + type["GetNextQuestId"] = &LuaQuest::GetNextQuestId; + type["GetPrevQuestId"] = &LuaQuest::GetPrevQuestId; + type["GetNextQuestInChain"] = &LuaQuest::GetNextQuestInChain; + type["GetFlags"] = &LuaQuest::GetFlags; + type["GetType"] = &LuaQuest::GetType; +} diff --git a/src/LuaEngine/methods/RollMethods.h b/src/LuaEngine/methods/RollMethods.cpp similarity index 57% rename from src/LuaEngine/methods/RollMethods.h rename to src/LuaEngine/methods/RollMethods.cpp index fdcbd0bb36..47e0b96b02 100644 --- a/src/LuaEngine/methods/RollMethods.h +++ b/src/LuaEngine/methods/RollMethods.cpp @@ -4,8 +4,7 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef ROLLMETHODS_H -#define ROLLMETHODS_H +#include "ALEBind.h" #include "Group.h" @@ -23,10 +22,9 @@ namespace LuaRoll * * @return ObjectGuid guid */ - int GetItemGUID(lua_State* L, Roll* roll) + uint32 GetItemGUID(Roll* roll) { - ALE::Push(L, roll->itemGUID.GetCounter()); - return 1; + return roll->itemGUID.GetCounter(); } /** @@ -34,10 +32,9 @@ namespace LuaRoll * * @return uint32 entry */ - int GetItemId(lua_State* L, Roll* roll) + uint32 GetItemId(Roll* roll) { - ALE::Push(L, roll->itemid); - return 1; + return roll->itemid; } /** @@ -45,10 +42,9 @@ namespace LuaRoll * * @return int32 randomPropId */ - int GetItemRandomPropId(lua_State* L, Roll* roll) + int32 GetItemRandomPropId(Roll* roll) { - ALE::Push(L, roll->itemRandomPropId); - return 1; + return roll->itemRandomPropId; } /** @@ -56,10 +52,9 @@ namespace LuaRoll * * @return uint32 randomSuffix */ - int GetItemRandomSuffix(lua_State* L, Roll* roll) + uint32 GetItemRandomSuffix(Roll* roll) { - ALE::Push(L, roll->itemRandomSuffix); - return 1; + return roll->itemRandomSuffix; } /** @@ -67,10 +62,9 @@ namespace LuaRoll * * @return uint8 count */ - int GetItemCount(lua_State* L, Roll* roll) + uint8 GetItemCount(Roll* roll) { - ALE::Push(L, roll->itemCount); - return 1; + return roll->itemCount; } /** @@ -92,26 +86,18 @@ namespace LuaRoll * @param ObjectGuid guid * @return [RollVote] vote */ - int GetPlayerVote(lua_State* L, Roll* roll) + sol::optional GetPlayerVote(Roll* roll, ObjectGuid guid) { - ObjectGuid guid = ALE::CHECKVAL(L, 2); - - bool found = false; + sol::optional vote; for (std::pair& pair : roll->playerVote) { if (pair.first == guid) { - ALE::Push(L, pair.second); - found = true; + vote = pair.second; } } - if (!found) - { - ALE::Push(L); - } - - return 1; + return vote; } /** @@ -120,20 +106,17 @@ namespace LuaRoll * * @return table guids */ - int GetPlayerVoteGUIDs(lua_State* L, Roll* roll) + sol::table GetPlayerVoteGUIDs(Roll* roll, sol::this_state s) { - lua_newtable(L); - int table = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 1; for (std::pair& pair : roll->playerVote) { - ALE::Push(L, pair.first); - lua_rawseti(L, table, i); + tbl[i] = pair.first; ++i; } - lua_settop(L, table); // push table to top of stack - return 1; + return tbl; } /** @@ -141,10 +124,9 @@ namespace LuaRoll * * @return uint8 playersCount */ - int GetTotalPlayersRolling(lua_State* L, Roll* roll) + uint8 GetTotalPlayersRolling(Roll* roll) { - ALE::Push(L, roll->totalPlayersRolling); - return 1; + return roll->totalPlayersRolling; } /** @@ -152,10 +134,9 @@ namespace LuaRoll * * @return uint8 playersCount */ - int GetTotalNeed(lua_State* L, Roll* roll) + uint8 GetTotalNeed(Roll* roll) { - ALE::Push(L, roll->totalNeed); - return 1; + return roll->totalNeed; } /** @@ -163,10 +144,9 @@ namespace LuaRoll * * @return uint8 playersCount */ - int GetTotalGreed(lua_State* L, Roll* roll) + uint8 GetTotalGreed(Roll* roll) { - ALE::Push(L, roll->totalGreed); - return 1; + return roll->totalGreed; } /** @@ -174,10 +154,9 @@ namespace LuaRoll * * @return uint8 playersCount */ - int GetTotalPass(lua_State* L, Roll* roll) + uint8 GetTotalPass(Roll* roll) { - ALE::Push(L, roll->totalPass); - return 1; + return roll->totalPass; } /** @@ -185,10 +164,9 @@ namespace LuaRoll * * @return uint8 slot */ - int GetItemSlot(lua_State* L, Roll* roll) + uint8 GetItemSlot(Roll* roll) { - ALE::Push(L, roll->itemSlot); - return 1; + return roll->itemSlot; } /** @@ -201,7 +179,7 @@ namespace LuaRoll * 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 * }; @@ -209,11 +187,27 @@ namespace LuaRoll * * @return [RollMask] rollMask */ - int GetRollVoteMask(lua_State* L, Roll* roll) + uint8 GetRollVoteMask(Roll* roll) { - ALE::Push(L, roll->rollVoteMask); - return 1; + return roll->rollVoteMask; } } -#endif +void RegisterRollMethods(sol::state& lua) +{ + sol::usertype> type = ALEBind::NewHandleType>(lua, "Roll"); + + type["GetItemGUID"] = ALEBind::Method(&LuaRoll::GetItemGUID); + type["GetItemId"] = ALEBind::Method(&LuaRoll::GetItemId); + type["GetItemRandomPropId"] = ALEBind::Method(&LuaRoll::GetItemRandomPropId); + type["GetItemRandomSuffix"] = ALEBind::Method(&LuaRoll::GetItemRandomSuffix); + type["GetItemCount"] = ALEBind::Method(&LuaRoll::GetItemCount); + type["GetPlayerVote"] = ALEBind::Method(&LuaRoll::GetPlayerVote); + type["GetPlayerVoteGUIDs"] = ALEBind::Method(&LuaRoll::GetPlayerVoteGUIDs); + type["GetTotalPlayersRolling"] = ALEBind::Method(&LuaRoll::GetTotalPlayersRolling); + type["GetTotalNeed"] = ALEBind::Method(&LuaRoll::GetTotalNeed); + type["GetTotalGreed"] = ALEBind::Method(&LuaRoll::GetTotalGreed); + type["GetTotalPass"] = ALEBind::Method(&LuaRoll::GetTotalPass); + type["GetItemSlot"] = ALEBind::Method(&LuaRoll::GetItemSlot); + type["GetRollVoteMask"] = ALEBind::Method(&LuaRoll::GetRollVoteMask); +} diff --git a/src/LuaEngine/methods/SpellEntryMethods.h b/src/LuaEngine/methods/SpellEntryMethods.cpp similarity index 60% rename from src/LuaEngine/methods/SpellEntryMethods.h rename to src/LuaEngine/methods/SpellEntryMethods.cpp index 615c2e50e4..07c52ab054 100644 --- a/src/LuaEngine/methods/SpellEntryMethods.h +++ b/src/LuaEngine/methods/SpellEntryMethods.cpp @@ -4,8 +4,12 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef SPELLENTRYMETHODS_H -#define SPELLENTRYMETHODS_H +#include "ALEBind.h" + +#include "DBCStores.h" +#include "DBCStructure.h" +#include "SpellInfo.h" +#include "SpellMgr.h" /*** * Represents spell data loaded from the DBCs, including effects, costs, attributes, and requirements. @@ -21,10 +25,9 @@ namespace LuaSpellEntry * * @return uint32 id */ - int GetId(lua_State* L, SpellEntry* entry) + uint32 GetId(SpellEntry* entry) { - ALE::Push(L, entry->Id); - return 1; + return entry->Id; } /** @@ -32,10 +35,9 @@ namespace LuaSpellEntry * * @return uint32 categoryId */ - int GetCategory(lua_State* L, SpellEntry* entry) + uint32 GetCategory(SpellEntry* entry) { - ALE::Push(L, entry->Category); - return 1; + return entry->Category; } /** @@ -43,10 +45,9 @@ namespace LuaSpellEntry * * @return uint32 dispelId */ - int GetDispel(lua_State* L, SpellEntry* entry) + uint32 GetDispel(SpellEntry* entry) { - ALE::Push(L, entry->Dispel); - return 1; + return entry->Dispel; } /** @@ -54,10 +55,9 @@ namespace LuaSpellEntry * * @return uint32 mechanicId */ - int GetMechanic(lua_State* L, SpellEntry* entry) + uint32 GetMechanic(SpellEntry* entry) { - ALE::Push(L, entry->Mechanic); - return 1; + return entry->Mechanic; } /** @@ -65,10 +65,9 @@ namespace LuaSpellEntry * * @return uint32 attribute : bitmask, but returned as uint32 */ - int GetAttributes(lua_State* L, SpellEntry* entry) + uint32 GetAttributes(SpellEntry* entry) { - ALE::Push(L, entry->Attributes); - return 1; + return entry->Attributes; } /** @@ -76,10 +75,9 @@ namespace LuaSpellEntry * * @return uint32 attributeEx : bitmask, but returned as uint32 */ - int GetAttributesEx(lua_State* L, SpellEntry* entry) + uint32 GetAttributesEx(SpellEntry* entry) { - ALE::Push(L, entry->AttributesEx); - return 1; + return entry->AttributesEx; } /** @@ -87,10 +85,9 @@ namespace LuaSpellEntry * * @return uint32 attributeEx2 : bitmask, but returned as uint32 */ - int GetAttributesEx2(lua_State* L, SpellEntry* entry) + uint32 GetAttributesEx2(SpellEntry* entry) { - ALE::Push(L, entry->AttributesEx2); - return 1; + return entry->AttributesEx2; } /** @@ -98,10 +95,9 @@ namespace LuaSpellEntry * * @return uint32 attributeEx3 : bitmask, but returned as uint32 */ - int GetAttributesEx3(lua_State* L, SpellEntry* entry) + uint32 GetAttributesEx3(SpellEntry* entry) { - ALE::Push(L, entry->AttributesEx3); - return 1; + return entry->AttributesEx3; } /** @@ -109,10 +105,9 @@ namespace LuaSpellEntry * * @return uint32 attributeEx4 : bitmask, but returned as uint32 */ - int GetAttributesEx4(lua_State* L, SpellEntry* entry) + uint32 GetAttributesEx4(SpellEntry* entry) { - ALE::Push(L, entry->AttributesEx4); - return 1; + return entry->AttributesEx4; } /** @@ -120,10 +115,9 @@ namespace LuaSpellEntry * * @return uint32 attributeEx5 : bitmask, but returned as uint32 */ - int GetAttributesEx5(lua_State* L, SpellEntry* entry) + uint32 GetAttributesEx5(SpellEntry* entry) { - ALE::Push(L, entry->AttributesEx5); - return 1; + return entry->AttributesEx5; } /** @@ -131,10 +125,9 @@ namespace LuaSpellEntry * * @return uint32 attributeEx6 : bitmask, but returned as uint32 */ - int GetAttributesEx6(lua_State* L, SpellEntry* entry) + uint32 GetAttributesEx6(SpellEntry* entry) { - ALE::Push(L, entry->AttributesEx6); - return 1; + return entry->AttributesEx6; } /** @@ -142,10 +135,9 @@ namespace LuaSpellEntry * * @return uint32 attributeEx7 : bitmask, but returned as uint32 */ - int GetAttributesEx7(lua_State* L, SpellEntry* entry) + uint32 GetAttributesEx7(SpellEntry* entry) { - ALE::Push(L, entry->AttributesEx7); - return 1; + return entry->AttributesEx7; } /** @@ -153,10 +145,9 @@ namespace LuaSpellEntry * * @return uint32 stance : bitmask, but returned as uint32 */ - int GetStances(lua_State* L, SpellEntry* entry) + uint32 GetStances(SpellEntry* entry) { - ALE::Push(L, entry->Stances); - return 1; + return entry->Stances; } /** @@ -166,10 +157,9 @@ namespace LuaSpellEntry * * @return uint32 stancesNotMask */ - int GetStancesNot(lua_State* L, SpellEntry* entry) + uint32 GetStancesNot(SpellEntry* entry) { - ALE::Push(L, entry->StancesNot); - return 1; + return entry->StancesNot; } /** @@ -177,10 +167,9 @@ namespace LuaSpellEntry * * @return uint32 target : bitmasks, but returned as uint32. */ - int GetTargets(lua_State* L, SpellEntry* entry) + uint32 GetTargets(SpellEntry* entry) { - ALE::Push(L, entry->Targets); - return 1; + return entry->Targets; } /** @@ -188,10 +177,9 @@ namespace LuaSpellEntry * * @return uint32 targetCreatureType : bitmasks, but returned as uint32. */ - int GetTargetCreatureType(lua_State* L, SpellEntry* entry) + uint32 GetTargetCreatureType(SpellEntry* entry) { - ALE::Push(L, entry->TargetCreatureType); - return 1; + return entry->TargetCreatureType; } /** @@ -201,10 +189,9 @@ namespace LuaSpellEntry * * @return uint32 spellFocusId */ - int GetRequiresSpellFocus(lua_State* L, SpellEntry* entry) + uint32 GetRequiresSpellFocus(SpellEntry* entry) { - ALE::Push(L, entry->RequiresSpellFocus); - return 1; + return entry->RequiresSpellFocus; } /** @@ -214,10 +201,9 @@ namespace LuaSpellEntry * * @return uint32 facingFlags */ - int GetFacingCasterFlags(lua_State* L, SpellEntry* entry) + uint32 GetFacingCasterFlags(SpellEntry* entry) { - ALE::Push(L, entry->FacingCasterFlags); - return 1; + return entry->FacingCasterFlags; } /** @@ -227,10 +213,9 @@ namespace LuaSpellEntry * * @return uint32 casterAuraState */ - int GetCasterAuraState(lua_State* L, SpellEntry* entry) + uint32 GetCasterAuraState(SpellEntry* entry) { - ALE::Push(L, entry->CasterAuraState); - return 1; + return entry->CasterAuraState; } /** @@ -240,10 +225,9 @@ namespace LuaSpellEntry * * @return uint32 targetAuraState */ - int GetTargetAuraState(lua_State* L, SpellEntry* entry) + uint32 GetTargetAuraState(SpellEntry* entry) { - ALE::Push(L, entry->TargetAuraState); - return 1; + return entry->TargetAuraState; } /** @@ -253,10 +237,9 @@ namespace LuaSpellEntry * * @return uint32 casterAuraStateNot */ - int GetCasterAuraStateNot(lua_State* L, SpellEntry* entry) + uint32 GetCasterAuraStateNot(SpellEntry* entry) { - ALE::Push(L, entry->CasterAuraStateNot); - return 1; + return entry->CasterAuraStateNot; } /** @@ -266,10 +249,9 @@ namespace LuaSpellEntry * * @return uint32 targetAuraStateNot */ - int GetTargetAuraStateNot(lua_State* L, SpellEntry* entry) + uint32 GetTargetAuraStateNot(SpellEntry* entry) { - ALE::Push(L, entry->TargetAuraStateNot); - return 1; + return entry->TargetAuraStateNot; } /** @@ -279,10 +261,9 @@ namespace LuaSpellEntry * * @return uint32 casterAuraSpellId */ - int GetCasterAuraSpell(lua_State* L, SpellEntry* entry) + uint32 GetCasterAuraSpell(SpellEntry* entry) { - ALE::Push(L, entry->CasterAuraSpell); - return 1; + return entry->CasterAuraSpell; } /** @@ -292,10 +273,9 @@ namespace LuaSpellEntry * * @return uint32 targetAuraSpellId */ - int GetTargetAuraSpell(lua_State* L, SpellEntry* entry) + uint32 GetTargetAuraSpell(SpellEntry* entry) { - ALE::Push(L, entry->TargetAuraSpell); - return 1; + return entry->TargetAuraSpell; } /** @@ -305,10 +285,9 @@ namespace LuaSpellEntry * * @return uint32 excludeCasterAuraSpellId */ - int GetExcludeCasterAuraSpell(lua_State* L, SpellEntry* entry) + uint32 GetExcludeCasterAuraSpell(SpellEntry* entry) { - ALE::Push(L, entry->ExcludeCasterAuraSpell); - return 1; + return entry->ExcludeCasterAuraSpell; } /** @@ -318,10 +297,9 @@ namespace LuaSpellEntry * * @return uint32 excludeTargetAuraSpellId */ - int GetExcludeTargetAuraSpell(lua_State* L, SpellEntry* entry) + uint32 GetExcludeTargetAuraSpell(SpellEntry* entry) { - ALE::Push(L, entry->ExcludeTargetAuraSpell); - return 1; + return entry->ExcludeTargetAuraSpell; } /** @@ -331,10 +309,9 @@ namespace LuaSpellEntry * * @return uint32 castingTimeIndex */ - int GetCastingTimeIndex(lua_State* L, SpellEntry* entry) + uint32 GetCastingTimeIndex(SpellEntry* entry) { - ALE::Push(L, entry->CastingTimeIndex); - return 1; + return entry->CastingTimeIndex; } /** @@ -342,10 +319,9 @@ namespace LuaSpellEntry * * @return uint32 recoveryTime */ - int GetRecoveryTime(lua_State* L, SpellEntry* entry) + uint32 GetRecoveryTime(SpellEntry* entry) { - ALE::Push(L, entry->RecoveryTime); - return 1; + return entry->RecoveryTime; } /** @@ -353,10 +329,9 @@ namespace LuaSpellEntry * * @return uint32 categoryRecoveryTime : in milliseconds, returned as uint32 */ - int GetCategoryRecoveryTime(lua_State* L, SpellEntry* entry) + uint32 GetCategoryRecoveryTime(SpellEntry* entry) { - ALE::Push(L, entry->CategoryRecoveryTime); - return 1; + return entry->CategoryRecoveryTime; } /** @@ -366,10 +341,9 @@ namespace LuaSpellEntry * * @return uint32 interruptFlags */ - int GetInterruptFlags(lua_State* L, SpellEntry* entry) + uint32 GetInterruptFlags(SpellEntry* entry) { - ALE::Push(L, entry->InterruptFlags); - return 1; + return entry->InterruptFlags; } /** @@ -379,10 +353,9 @@ namespace LuaSpellEntry * * @return uint32 auraInterruptFlags */ - int GetAuraInterruptFlags(lua_State* L, SpellEntry* entry) + uint32 GetAuraInterruptFlags(SpellEntry* entry) { - ALE::Push(L, entry->AuraInterruptFlags); - return 1; + return entry->AuraInterruptFlags; } /** @@ -392,10 +365,9 @@ namespace LuaSpellEntry * * @return uint32 channelInterruptFlags */ - int GetChannelInterruptFlags(lua_State* L, SpellEntry* entry) + uint32 GetChannelInterruptFlags(SpellEntry* entry) { - ALE::Push(L, entry->ChannelInterruptFlags); - return 1; + return entry->ChannelInterruptFlags; } /** @@ -405,10 +377,9 @@ namespace LuaSpellEntry * * @return uint32 procFlags */ - int GetProcFlags(lua_State* L, SpellEntry* entry) + uint32 GetProcFlags(SpellEntry* entry) { - ALE::Push(L, entry->ProcFlags); - return 1; + return entry->ProcFlags; } /** @@ -416,10 +387,9 @@ namespace LuaSpellEntry * * @return uint32 procChance */ - int GetProcChance(lua_State* L, SpellEntry* entry) + uint32 GetProcChance(SpellEntry* entry) { - ALE::Push(L, entry->ProcChance); - return 1; + return entry->ProcChance; } /** @@ -427,10 +397,9 @@ namespace LuaSpellEntry * * @return uint32 procCharges */ - int GetProcCharges(lua_State* L, SpellEntry* entry) + uint32 GetProcCharges(SpellEntry* entry) { - ALE::Push(L, entry->ProcCharges); - return 1; + return entry->ProcCharges; } /** @@ -438,10 +407,9 @@ namespace LuaSpellEntry * * @return uint32 maxLevel : the [SpellEntry] max level. */ - int GetMaxLevel(lua_State* L, SpellEntry* entry) + uint32 GetMaxLevel(SpellEntry* entry) { - ALE::Push(L, entry->MaxLevel); - return 1; + return entry->MaxLevel; } /** @@ -449,10 +417,9 @@ namespace LuaSpellEntry * * @return uint32 baseLevel */ - int GetBaseLevel(lua_State* L, SpellEntry* entry) + uint32 GetBaseLevel(SpellEntry* entry) { - ALE::Push(L, entry->BaseLevel); - return 1; + return entry->BaseLevel; } /** @@ -460,10 +427,9 @@ namespace LuaSpellEntry * * @return uint32 spellLevel */ - int GetSpellLevel(lua_State* L, SpellEntry* entry) + uint32 GetSpellLevel(SpellEntry* entry) { - ALE::Push(L, entry->SpellLevel); - return 1; + return entry->SpellLevel; } /** @@ -471,10 +437,9 @@ namespace LuaSpellEntry * * @return uint32 durationIndex */ - int GetDurationIndex(lua_State* L, SpellEntry* entry) + uint32 GetDurationIndex(SpellEntry* entry) { - ALE::Push(L, entry->DurationIndex); - return 1; + return entry->DurationIndex; } /** @@ -482,10 +447,9 @@ namespace LuaSpellEntry * * @return uint32 powerTypeId */ - int GetPowerType(lua_State* L, SpellEntry* entry) + uint32 GetPowerType(SpellEntry* entry) { - ALE::Push(L, entry->PowerType); - return 1; + return entry->PowerType; } /** @@ -493,10 +457,9 @@ namespace LuaSpellEntry * * @return uint32 manaCost */ - int GetManaCost(lua_State* L, SpellEntry* entry) + uint32 GetManaCost(SpellEntry* entry) { - ALE::Push(L, entry->ManaCost); - return 1; + return entry->ManaCost; } /** @@ -504,10 +467,9 @@ namespace LuaSpellEntry * * @return uint32 manaCostPerLevel */ - int GetManaCostPerlevel(lua_State* L, SpellEntry* entry) + uint32 GetManaCostPerlevel(SpellEntry* entry) { - ALE::Push(L, entry->ManaCostPerlevel); - return 1; + return entry->ManaCostPerlevel; } /** @@ -515,10 +477,9 @@ namespace LuaSpellEntry * * @return uint32 manaPerSecond */ - int GetManaPerSecond(lua_State* L, SpellEntry* entry) + uint32 GetManaPerSecond(SpellEntry* entry) { - ALE::Push(L, entry->ManaPerSecond); - return 1; + return entry->ManaPerSecond; } /** @@ -526,10 +487,9 @@ namespace LuaSpellEntry * * @return uint32 manaPerSecondPerLevel */ - int GetManaPerSecondPerLevel(lua_State* L, SpellEntry* entry) + uint32 GetManaPerSecondPerLevel(SpellEntry* entry) { - ALE::Push(L, entry->ManaPerSecondPerLevel); - return 1; + return entry->ManaPerSecondPerLevel; } /** @@ -537,10 +497,9 @@ namespace LuaSpellEntry * * @return uint32 rangeIndex */ - int GetRangeIndex(lua_State* L, SpellEntry* entry) + uint32 GetRangeIndex(SpellEntry* entry) { - ALE::Push(L, entry->RangeIndex); - return 1; + return entry->RangeIndex; } /** @@ -548,10 +507,9 @@ namespace LuaSpellEntry * * @return uint32 speed */ - int GetSpeed(lua_State* L, SpellEntry* entry) + float GetSpeed(SpellEntry* entry) { - ALE::Push(L, entry->Speed); - return 1; + return entry->Speed; } /** @@ -559,10 +517,9 @@ namespace LuaSpellEntry * * @return uint32 stackAmount */ - int GetStackAmount(lua_State* L, SpellEntry* entry) + uint32 GetStackAmount(SpellEntry* entry) { - ALE::Push(L, entry->StackAmount); - return 1; + return entry->StackAmount; } /** @@ -570,20 +527,17 @@ namespace LuaSpellEntry * * @return table totem */ - int GetTotem(lua_State* L, SpellEntry* entry) + sol::table GetTotem(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->Totem.size(); ++index) { - ALE::Push(L, entry->Totem[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->Totem[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -591,20 +545,17 @@ namespace LuaSpellEntry * * @return table reagent */ - int GetReagent(lua_State* L, SpellEntry* entry) + sol::table GetReagent(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->Reagent.size(); ++index) { - ALE::Push(L, entry->Reagent[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->Reagent[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -612,20 +563,17 @@ namespace LuaSpellEntry * * @return table reagentCount */ - int GetReagentCount(lua_State* L, SpellEntry* entry) + sol::table GetReagentCount(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->ReagentCount.size(); ++index) { - ALE::Push(L, entry->ReagentCount[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->ReagentCount[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -633,10 +581,9 @@ namespace LuaSpellEntry * * @return uint32 equippedItemClassId */ - int GetEquippedItemClass(lua_State* L, SpellEntry* entry) + int32 GetEquippedItemClass(SpellEntry* entry) { - ALE::Push(L, entry->EquippedItemClass); - return 1; + return entry->EquippedItemClass; } /** @@ -644,10 +591,9 @@ namespace LuaSpellEntry * * @return uint32 equippedItemSubClassMasks : bitmasks, returned as uint32. */ - int GetEquippedItemSubClassMask(lua_State* L, SpellEntry* entry) + int32 GetEquippedItemSubClassMask(SpellEntry* entry) { - ALE::Push(L, entry->EquippedItemSubClassMask); - return 1; + return entry->EquippedItemSubClassMask; } /** @@ -655,10 +601,9 @@ namespace LuaSpellEntry * * @return uint32 equippedItemInventoryTypeMasks : bitmasks, returned as uint32. */ - int GetEquippedItemInventoryTypeMask(lua_State* L, SpellEntry* entry) + int32 GetEquippedItemInventoryTypeMask(SpellEntry* entry) { - ALE::Push(L, entry->EquippedItemInventoryTypeMask); - return 1; + return entry->EquippedItemInventoryTypeMask; } /** @@ -666,20 +611,17 @@ namespace LuaSpellEntry * * @return table effect */ - int GetEffect(lua_State* L, SpellEntry* entry) + sol::table GetEffect(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->Effect.size(); ++index) { - ALE::Push(L, entry->Effect[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->Effect[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -687,20 +629,17 @@ namespace LuaSpellEntry * * @return table effectDieSides */ - int GetEffectDieSides(lua_State* L, SpellEntry* entry) + sol::table GetEffectDieSides(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectDieSides.size(); ++index) { - ALE::Push(L, entry->EffectDieSides[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectDieSides[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -708,20 +647,17 @@ namespace LuaSpellEntry * * @return table effectRealPointsPerLevel */ - int GetEffectRealPointsPerLevel(lua_State* L, SpellEntry* entry) + sol::table GetEffectRealPointsPerLevel(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectRealPointsPerLevel.size(); ++index) { - ALE::Push(L, entry->EffectRealPointsPerLevel[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectRealPointsPerLevel[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -729,20 +665,17 @@ namespace LuaSpellEntry * * @return table effectBasePoints */ - int GetEffectBasePoints(lua_State* L, SpellEntry* entry) + sol::table GetEffectBasePoints(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectBasePoints.size(); ++index) { - ALE::Push(L, entry->EffectBasePoints[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectBasePoints[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -750,20 +683,17 @@ namespace LuaSpellEntry * * @return table effectMechanic */ - int GetEffectMechanic(lua_State* L, SpellEntry* entry) + sol::table GetEffectMechanic(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectMechanic.size(); ++index) { - ALE::Push(L, entry->EffectMechanic[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectMechanic[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -771,20 +701,17 @@ namespace LuaSpellEntry * * @return table effectImplicitTargetA */ - int GetEffectImplicitTargetA(lua_State* L, SpellEntry* entry) + sol::table GetEffectImplicitTargetA(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectImplicitTargetA.size(); ++index) { - ALE::Push(L, entry->EffectImplicitTargetA[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectImplicitTargetA[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -792,20 +719,17 @@ namespace LuaSpellEntry * * @return table effectImplicitTargetB */ - int GetEffectImplicitTargetB(lua_State* L, SpellEntry* entry) + sol::table GetEffectImplicitTargetB(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectImplicitTargetB.size(); ++index) { - ALE::Push(L, entry->EffectImplicitTargetB[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectImplicitTargetB[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -813,20 +737,17 @@ namespace LuaSpellEntry * * @return table effectRadiusIndex */ - int GetEffectRadiusIndex(lua_State* L, SpellEntry* entry) + sol::table GetEffectRadiusIndex(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectRadiusIndex.size(); ++index) { - ALE::Push(L, entry->EffectRadiusIndex[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectRadiusIndex[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -834,20 +755,17 @@ namespace LuaSpellEntry * * @return table effectApplyAura */ - int GetEffectApplyAuraName(lua_State* L, SpellEntry* entry) + sol::table GetEffectApplyAuraName(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectApplyAuraName.size(); ++index) { - ALE::Push(L, entry->EffectApplyAuraName[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectApplyAuraName[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -855,20 +773,17 @@ namespace LuaSpellEntry * * @return table effectAmplitude */ - int GetEffectAmplitude(lua_State* L, SpellEntry* entry) + sol::table GetEffectAmplitude(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectAmplitude.size(); ++index) { - ALE::Push(L, entry->EffectAmplitude[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectAmplitude[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -876,20 +791,17 @@ namespace LuaSpellEntry * * @return table effectValueMultiplier */ - int GetEffectValueMultiplier(lua_State* L, SpellEntry* entry) + sol::table GetEffectValueMultiplier(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectValueMultiplier.size(); ++index) { - ALE::Push(L, entry->EffectValueMultiplier[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectValueMultiplier[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -897,20 +809,17 @@ namespace LuaSpellEntry * * @return table effectChainTarget */ - int GetEffectChainTarget(lua_State* L, SpellEntry* entry) + sol::table GetEffectChainTarget(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectChainTarget.size(); ++index) { - ALE::Push(L, entry->EffectChainTarget[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectChainTarget[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -918,20 +827,17 @@ namespace LuaSpellEntry * * @return table effectItemType */ - int GetEffectItemType(lua_State* L, SpellEntry* entry) + sol::table GetEffectItemType(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectItemType.size(); ++index) { - ALE::Push(L, entry->EffectItemType[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectItemType[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -939,20 +845,17 @@ namespace LuaSpellEntry * * @return table effectMiscValueA */ - int GetEffectMiscValue(lua_State* L, SpellEntry* entry) + sol::table GetEffectMiscValue(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectMiscValue.size(); ++index) { - ALE::Push(L, entry->EffectMiscValue[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectMiscValue[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -960,20 +863,17 @@ namespace LuaSpellEntry * * @return table effectMiscValueB */ - int GetEffectMiscValueB(lua_State* L, SpellEntry* entry) + sol::table GetEffectMiscValueB(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectMiscValueB.size(); ++index) { - ALE::Push(L, entry->EffectMiscValueB[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectMiscValueB[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -981,20 +881,17 @@ namespace LuaSpellEntry * * @return table effectTriggerSpell */ - int GetEffectTriggerSpell(lua_State* L, SpellEntry* entry) + sol::table GetEffectTriggerSpell(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectTriggerSpell.size(); ++index) { - ALE::Push(L, entry->EffectTriggerSpell[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectTriggerSpell[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -1002,20 +899,17 @@ namespace LuaSpellEntry * * @return table effectPointsPerComboPoint : returns a table containing all the effect points per combo point values of [SpellEntry] */ - int GetEffectPointsPerComboPoint(lua_State* L, SpellEntry* entry) + sol::table GetEffectPointsPerComboPoint(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectPointsPerComboPoint.size(); ++index) { - ALE::Push(L, entry->EffectPointsPerComboPoint[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectPointsPerComboPoint[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -1026,20 +920,17 @@ namespace LuaSpellEntry * * @return table effectSpellClassMask : table of [SpellFamilyFlags] per effect */ - int GetEffectSpellClassMask(lua_State* L, SpellEntry* entry) + sol::table GetEffectSpellClassMask(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectSpellClassMask.size(); ++index) { - ALE::Push(L, entry->EffectSpellClassMask[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = static_cast(entry->EffectSpellClassMask[index]); } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -1047,20 +938,17 @@ namespace LuaSpellEntry * * @return table spellVisuals : returns a table containing both spellVisuals for [SpellEntry]. */ - int GetSpellVisual(lua_State* L, SpellEntry* entry) + sol::table GetSpellVisual(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->SpellVisual.size(); ++index) { - ALE::Push(L, entry->SpellVisual[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->SpellVisual[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -1068,10 +956,9 @@ namespace LuaSpellEntry * * @return uint32 spellIconId */ - int GetSpellIconID(lua_State* L, SpellEntry* entry) + uint32 GetSpellIconID(SpellEntry* entry) { - ALE::Push(L, entry->SpellIconID); - return 1; + return entry->SpellIconID; } /** @@ -1079,10 +966,9 @@ namespace LuaSpellEntry * * @return uint32 activeIconId */ - int GetActiveIconID(lua_State* L, SpellEntry* entry) + uint32 GetActiveIconID(SpellEntry* entry) { - ALE::Push(L, entry->ActiveIconID); - return 1; + return entry->ActiveIconID; } /** @@ -1090,10 +976,9 @@ namespace LuaSpellEntry * * @return uint32 spellPriority */ - int GetSpellPriority(lua_State* L, SpellEntry* entry) + uint32 GetSpellPriority(SpellEntry* entry) { - ALE::Push(L, entry->SpellPriority); - return 1; + return entry->SpellPriority; } /** @@ -1101,20 +986,17 @@ namespace LuaSpellEntry * * @return table spellNames */ - int GetSpellName(lua_State* L, SpellEntry* entry) + sol::table GetSpellName(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->SpellName.size(); ++index) { - ALE::Push(L, entry->SpellName[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->SpellName[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -1122,20 +1004,17 @@ namespace LuaSpellEntry * * @return table spellRanks */ - int GetRank(lua_State* L, SpellEntry* entry) + sol::table GetRank(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->Rank.size(); ++index) { - ALE::Push(L, entry->Rank[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->Rank[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -1143,10 +1022,9 @@ namespace LuaSpellEntry * * @return uint32 manaCostPercentage : the mana cost in percentage, returned as uint32. */ - int GetManaCostPercentage(lua_State* L, SpellEntry* entry) + uint32 GetManaCostPercentage(SpellEntry* entry) { - ALE::Push(L, entry->ManaCostPercentage); - return 1; + return entry->ManaCostPercentage; } /** @@ -1154,10 +1032,9 @@ namespace LuaSpellEntry * * @return uint32 globalCooldownTime */ - int GetStartRecoveryCategory(lua_State* L, SpellEntry* entry) + uint32 GetStartRecoveryCategory(SpellEntry* entry) { - ALE::Push(L, entry->StartRecoveryCategory); - return 1; + return entry->StartRecoveryCategory; } /** @@ -1165,10 +1042,9 @@ namespace LuaSpellEntry * * @return uint32 globalCooldownCategory */ - int GetStartRecoveryTime(lua_State* L, SpellEntry* entry) + uint32 GetStartRecoveryTime(SpellEntry* entry) { - ALE::Push(L, entry->StartRecoveryTime); - return 1; + return entry->StartRecoveryTime; } /** @@ -1176,10 +1052,9 @@ namespace LuaSpellEntry * * @return uint32 maxTargetLevel */ - int GetMaxTargetLevel(lua_State* L, SpellEntry* entry) + uint32 GetMaxTargetLevel(SpellEntry* entry) { - ALE::Push(L, entry->MaxTargetLevel); - return 1; + return entry->MaxTargetLevel; } /** @@ -1189,10 +1064,9 @@ namespace LuaSpellEntry * * @return uint32 spellFamilyName */ - int GetSpellFamilyName(lua_State* L, SpellEntry* entry) + uint32 GetSpellFamilyName(SpellEntry* entry) { - ALE::Push(L, entry->SpellFamilyName); - return 1; + return entry->SpellFamilyName; } /** @@ -1202,10 +1076,9 @@ namespace LuaSpellEntry * * @return uint64 spellFamilyFlags */ - int GetSpellFamilyFlags(lua_State* L, SpellEntry* entry) + bool GetSpellFamilyFlags(SpellEntry* entry) { - ALE::Push(L, entry->SpellFamilyFlags); - return 1; + return entry->SpellFamilyFlags; } /** @@ -1213,10 +1086,9 @@ namespace LuaSpellEntry * * @return uint32 maxAffectedTargets */ - int GetMaxAffectedTargets(lua_State* L, SpellEntry* entry) + uint32 GetMaxAffectedTargets(SpellEntry* entry) { - ALE::Push(L, entry->MaxAffectedTargets); - return 1; + return entry->MaxAffectedTargets; } /** @@ -1224,10 +1096,9 @@ namespace LuaSpellEntry * * @return uint32 spellDamageTypeId */ - int GetDmgClass(lua_State* L, SpellEntry* entry) + uint32 GetDmgClass(SpellEntry* entry) { - ALE::Push(L, entry->DmgClass); - return 1; + return entry->DmgClass; } /** @@ -1235,10 +1106,9 @@ namespace LuaSpellEntry * * @return uint32 preventionTypeId */ - int GetPreventionType(lua_State* L, SpellEntry* entry) + uint32 GetPreventionType(SpellEntry* entry) { - ALE::Push(L, entry->PreventionType); - return 1; + return entry->PreventionType; } /** @@ -1246,20 +1116,17 @@ namespace LuaSpellEntry * * @return table effectDamageMultipliers */ - int GetEffectDamageMultiplier(lua_State* L, SpellEntry* entry) + sol::table GetEffectDamageMultiplier(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectDamageMultiplier.size(); ++index) { - ALE::Push(L, entry->EffectDamageMultiplier[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectDamageMultiplier[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -1267,20 +1134,17 @@ namespace LuaSpellEntry * * @return table totemCategory */ - int GetTotemCategory(lua_State* L, SpellEntry* entry) + sol::table GetTotemCategory(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->TotemCategory.size(); ++index) { - ALE::Push(L, entry->TotemCategory[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->TotemCategory[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -1290,10 +1154,9 @@ namespace LuaSpellEntry * * @return uint32 areaGroupId */ - int GetAreaGroupId(lua_State* L, SpellEntry* entry) + int32 GetAreaGroupId(SpellEntry* entry) { - ALE::Push(L, entry->AreaGroupId); - return 1; + return entry->AreaGroupId; } /** @@ -1301,10 +1164,9 @@ namespace LuaSpellEntry * * @return uint32 schoolMask : bitmask, returned as uint32. */ - int GetSchoolMask(lua_State* L, SpellEntry* entry) + uint32 GetSchoolMask(SpellEntry* entry) { - ALE::Push(L, entry->SchoolMask); - return 1; + return entry->SchoolMask; } /** @@ -1312,10 +1174,9 @@ namespace LuaSpellEntry * * @return uint32 runeCostId */ - int GetRuneCostID(lua_State* L, SpellEntry* entry) + uint32 GetRuneCostID(SpellEntry* entry) { - ALE::Push(L, entry->RuneCostID); - return 1; + return entry->RuneCostID; } /** @@ -1323,20 +1184,17 @@ namespace LuaSpellEntry * * @return table effectBonusMultipliers */ - int GetEffectBonusMultiplier(lua_State* L, SpellEntry* entry) + sol::table GetEffectBonusMultiplier(SpellEntry* entry, sol::this_state s) { - lua_newtable(L); - int tbl = lua_gettop(L); + sol::table tbl = sol::state_view(s).create_table(); uint32 i = 0; for (size_t index = 0; index < entry->EffectBonusMultiplier.size(); ++index) { - ALE::Push(L, entry->EffectBonusMultiplier[index]); - lua_rawseti(L, tbl, ++i); + tbl[++i] = entry->EffectBonusMultiplier[index]; } - - lua_settop(L, tbl); // push table to top of stack - return 1; + + return tbl; } /** @@ -1344,17 +1202,14 @@ namespace LuaSpellEntry * * @param uint32 category : the new category value */ - int SetCategory(lua_State* L, SpellEntry* entry) + void SetCategory(SpellEntry* entry, uint32 category) { - 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; } /** @@ -1362,17 +1217,14 @@ namespace LuaSpellEntry * * @param uint32 dispel : the new dispel type value */ - int SetDispel(lua_State* L, SpellEntry* entry) + void SetDispel(SpellEntry* entry, uint32 dispel) { - uint32 dispel = ALE::CHECKVAL(L, 2); entry->Dispel = dispel; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->Dispel = dispel; } - - return 0; } /** @@ -1380,17 +1232,14 @@ namespace LuaSpellEntry * * @param uint32 mechanic : the new mechanic value */ - int SetMechanic(lua_State* L, SpellEntry* entry) + void SetMechanic(SpellEntry* entry, uint32 mechanic) { - uint32 mechanic = ALE::CHECKVAL(L, 2); entry->Mechanic = mechanic; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->Mechanic = mechanic; } - - return 0; } /** @@ -1398,17 +1247,14 @@ namespace LuaSpellEntry * * @param uint32 attributes : the new attributes bitmask */ - int SetAttributes(lua_State* L, SpellEntry* entry) + void SetAttributes(SpellEntry* entry, uint32 attributes) { - uint32 attributes = ALE::CHECKVAL(L, 2); entry->Attributes = attributes; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->Attributes = attributes; } - - return 0; } /** @@ -1416,17 +1262,14 @@ namespace LuaSpellEntry * * @param uint32 attributesEx : the new attributesEx bitmask */ - int SetAttributesEx(lua_State* L, SpellEntry* entry) + void SetAttributesEx(SpellEntry* entry, uint32 attributesEx) { - uint32 attributesEx = ALE::CHECKVAL(L, 2); entry->AttributesEx = attributesEx; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->AttributesEx = attributesEx; } - - return 0; } /** @@ -1434,17 +1277,14 @@ namespace LuaSpellEntry * * @param uint32 attributesEx2 : the new attributesEx2 bitmask */ - int SetAttributesEx2(lua_State* L, SpellEntry* entry) + void SetAttributesEx2(SpellEntry* entry, uint32 attributesEx2) { - uint32 attributesEx2 = ALE::CHECKVAL(L, 2); entry->AttributesEx2 = attributesEx2; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->AttributesEx2 = attributesEx2; } - - return 0; } /** @@ -1452,17 +1292,14 @@ namespace LuaSpellEntry * * @param uint32 attributesEx3 : the new attributesEx3 bitmask */ - int SetAttributesEx3(lua_State* L, SpellEntry* entry) + void SetAttributesEx3(SpellEntry* entry, uint32 attributesEx3) { - uint32 attributesEx3 = ALE::CHECKVAL(L, 2); entry->AttributesEx3 = attributesEx3; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->AttributesEx3 = attributesEx3; } - - return 0; } /** @@ -1470,17 +1307,14 @@ namespace LuaSpellEntry * * @param uint32 attributesEx4 : the new attributesEx4 bitmask */ - int SetAttributesEx4(lua_State* L, SpellEntry* entry) + void SetAttributesEx4(SpellEntry* entry, uint32 attributesEx4) { - uint32 attributesEx4 = ALE::CHECKVAL(L, 2); entry->AttributesEx4 = attributesEx4; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->AttributesEx4 = attributesEx4; } - - return 0; } /** @@ -1488,17 +1322,14 @@ namespace LuaSpellEntry * * @param uint32 attributesEx5 : the new attributesEx5 bitmask */ - int SetAttributesEx5(lua_State* L, SpellEntry* entry) + void SetAttributesEx5(SpellEntry* entry, uint32 attributesEx5) { - uint32 attributesEx5 = ALE::CHECKVAL(L, 2); entry->AttributesEx5 = attributesEx5; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->AttributesEx5 = attributesEx5; } - - return 0; } /** @@ -1506,17 +1337,14 @@ namespace LuaSpellEntry * * @param uint32 attributesEx6 : the new attributesEx6 bitmask */ - int SetAttributesEx6(lua_State* L, SpellEntry* entry) + void SetAttributesEx6(SpellEntry* entry, uint32 attributesEx6) { - uint32 attributesEx6 = ALE::CHECKVAL(L, 2); entry->AttributesEx6 = attributesEx6; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->AttributesEx6 = attributesEx6; } - - return 0; } /** @@ -1524,17 +1352,14 @@ namespace LuaSpellEntry * * @param uint32 attributesEx7 : the new attributesEx7 bitmask */ - int SetAttributesEx7(lua_State* L, SpellEntry* entry) + void SetAttributesEx7(SpellEntry* entry, uint32 attributesEx7) { - uint32 attributesEx7 = ALE::CHECKVAL(L, 2); entry->AttributesEx7 = attributesEx7; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->AttributesEx7 = attributesEx7; } - - return 0; } /** @@ -1542,17 +1367,14 @@ namespace LuaSpellEntry * * @param uint32 stances : the new stances bitmask */ - int SetStances(lua_State* L, SpellEntry* entry) + void SetStances(SpellEntry* entry, uint32 stances) { - uint32 stances = ALE::CHECKVAL(L, 2); entry->Stances = stances; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->Stances = stances; } - - return 0; } /** @@ -1560,17 +1382,14 @@ namespace LuaSpellEntry * * @param uint32 stancesNot : the new stancesNot bitmask */ - int SetStancesNot(lua_State* L, SpellEntry* entry) + void SetStancesNot(SpellEntry* entry, uint32 stancesNot) { - uint32 stancesNot = ALE::CHECKVAL(L, 2); entry->StancesNot = stancesNot; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->StancesNot = stancesNot; } - - return 0; } /** @@ -1578,17 +1397,14 @@ namespace LuaSpellEntry * * @param uint32 targets : the new targets bitmask */ - int SetTargets(lua_State* L, SpellEntry* entry) + void SetTargets(SpellEntry* entry, uint32 targets) { - uint32 targets = ALE::CHECKVAL(L, 2); entry->Targets = targets; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->Targets = targets; } - - return 0; } /** @@ -1596,17 +1412,14 @@ namespace LuaSpellEntry * * @param uint32 targetCreatureType : the new target creature type bitmask */ - int SetTargetCreatureType(lua_State* L, SpellEntry* entry) + void SetTargetCreatureType(SpellEntry* entry, uint32 targetCreatureType) { - uint32 targetCreatureType = ALE::CHECKVAL(L, 2); entry->TargetCreatureType = targetCreatureType; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->TargetCreatureType = targetCreatureType; } - - return 0; } /** @@ -1614,17 +1427,14 @@ namespace LuaSpellEntry * * @param uint32 requiresSpellFocus : the new requires spell focus value */ - int SetRequiresSpellFocus(lua_State* L, SpellEntry* entry) + void SetRequiresSpellFocus(SpellEntry* entry, uint32 requiresSpellFocus) { - uint32 requiresSpellFocus = ALE::CHECKVAL(L, 2); entry->RequiresSpellFocus = requiresSpellFocus; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->RequiresSpellFocus = requiresSpellFocus; } - - return 0; } /** @@ -1632,17 +1442,14 @@ namespace LuaSpellEntry * * @param uint32 facingCasterFlags : the new facing caster flags value */ - int SetFacingCasterFlags(lua_State* L, SpellEntry* entry) + void SetFacingCasterFlags(SpellEntry* entry, uint32 facingCasterFlags) { - uint32 facingCasterFlags = ALE::CHECKVAL(L, 2); entry->FacingCasterFlags = facingCasterFlags; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->FacingCasterFlags = facingCasterFlags; } - - return 0; } /** @@ -1650,17 +1457,14 @@ namespace LuaSpellEntry * * @param uint32 casterAuraState : the new caster aura state value */ - int SetCasterAuraState(lua_State* L, SpellEntry* entry) + void SetCasterAuraState(SpellEntry* entry, uint32 casterAuraState) { - uint32 casterAuraState = ALE::CHECKVAL(L, 2); entry->CasterAuraState = casterAuraState; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->CasterAuraState = casterAuraState; } - - return 0; } /** @@ -1668,17 +1472,14 @@ namespace LuaSpellEntry * * @param uint32 targetAuraState : the new target aura state value */ - int SetTargetAuraState(lua_State* L, SpellEntry* entry) + void SetTargetAuraState(SpellEntry* entry, uint32 targetAuraState) { - uint32 targetAuraState = ALE::CHECKVAL(L, 2); entry->TargetAuraState = targetAuraState; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->TargetAuraState = targetAuraState; } - - return 0; } /** @@ -1686,17 +1487,14 @@ namespace LuaSpellEntry * * @param uint32 casterAuraStateNot : the new caster aura state not value */ - int SetCasterAuraStateNot(lua_State* L, SpellEntry* entry) + void SetCasterAuraStateNot(SpellEntry* entry, uint32 casterAuraStateNot) { - uint32 casterAuraStateNot = ALE::CHECKVAL(L, 2); entry->CasterAuraStateNot = casterAuraStateNot; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->CasterAuraStateNot = casterAuraStateNot; } - - return 0; } /** @@ -1704,17 +1502,14 @@ namespace LuaSpellEntry * * @param uint32 targetAuraStateNot : the new target aura state not value */ - int SetTargetAuraStateNot(lua_State* L, SpellEntry* entry) + void SetTargetAuraStateNot(SpellEntry* entry, uint32 targetAuraStateNot) { - uint32 targetAuraStateNot = ALE::CHECKVAL(L, 2); entry->TargetAuraStateNot = targetAuraStateNot; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->TargetAuraStateNot = targetAuraStateNot; } - - return 0; } /** @@ -1722,17 +1517,14 @@ namespace LuaSpellEntry * * @param uint32 casterAuraSpell : the new caster aura spell ID */ - int SetCasterAuraSpell(lua_State* L, SpellEntry* entry) + void SetCasterAuraSpell(SpellEntry* entry, uint32 casterAuraSpell) { - uint32 casterAuraSpell = ALE::CHECKVAL(L, 2); entry->CasterAuraSpell = casterAuraSpell; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->CasterAuraSpell = casterAuraSpell; } - - return 0; } /** @@ -1740,17 +1532,14 @@ namespace LuaSpellEntry * * @param uint32 targetAuraSpell : the new target aura spell ID */ - int SetTargetAuraSpell(lua_State* L, SpellEntry* entry) + void SetTargetAuraSpell(SpellEntry* entry, uint32 targetAuraSpell) { - uint32 targetAuraSpell = ALE::CHECKVAL(L, 2); entry->TargetAuraSpell = targetAuraSpell; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->TargetAuraSpell = targetAuraSpell; } - - return 0; } /** @@ -1758,17 +1547,14 @@ namespace LuaSpellEntry * * @param uint32 excludeCasterAuraSpell : the new exclude caster aura spell ID */ - int SetExcludeCasterAuraSpell(lua_State* L, SpellEntry* entry) + void SetExcludeCasterAuraSpell(SpellEntry* entry, uint32 excludeCasterAuraSpell) { - uint32 excludeCasterAuraSpell = ALE::CHECKVAL(L, 2); entry->ExcludeCasterAuraSpell = excludeCasterAuraSpell; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->ExcludeCasterAuraSpell = excludeCasterAuraSpell; } - - return 0; } /** @@ -1776,17 +1562,14 @@ namespace LuaSpellEntry * * @param uint32 excludeTargetAuraSpell : the new exclude target aura spell ID */ - int SetExcludeTargetAuraSpell(lua_State* L, SpellEntry* entry) + void SetExcludeTargetAuraSpell(SpellEntry* entry, uint32 excludeTargetAuraSpell) { - uint32 excludeTargetAuraSpell = ALE::CHECKVAL(L, 2); entry->ExcludeTargetAuraSpell = excludeTargetAuraSpell; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->ExcludeTargetAuraSpell = excludeTargetAuraSpell; } - - return 0; } /** @@ -1794,17 +1577,14 @@ namespace LuaSpellEntry * * @param uint32 recoveryTime : the new recovery time value */ - int SetRecoveryTime(lua_State* L, SpellEntry* entry) + void SetRecoveryTime(SpellEntry* entry, uint32 recoveryTime) { - uint32 recoveryTime = ALE::CHECKVAL(L, 2); entry->RecoveryTime = recoveryTime; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->RecoveryTime = recoveryTime; } - - return 0; } /** @@ -1812,17 +1592,14 @@ namespace LuaSpellEntry * * @param uint32 categoryRecoveryTime : the new category recovery time value in milliseconds */ - int SetCategoryRecoveryTime(lua_State* L, SpellEntry* entry) + void SetCategoryRecoveryTime(SpellEntry* entry, uint32 categoryRecoveryTime) { - uint32 categoryRecoveryTime = ALE::CHECKVAL(L, 2); entry->CategoryRecoveryTime = categoryRecoveryTime; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->CategoryRecoveryTime = categoryRecoveryTime; } - - return 0; } /** @@ -1830,17 +1607,14 @@ namespace LuaSpellEntry * * @param uint32 interruptFlags : the new interrupt flags bitmask */ - int SetInterruptFlags(lua_State* L, SpellEntry* entry) + void SetInterruptFlags(SpellEntry* entry, uint32 interruptFlags) { - uint32 interruptFlags = ALE::CHECKVAL(L, 2); entry->InterruptFlags = interruptFlags; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->InterruptFlags = interruptFlags; } - - return 0; } /** @@ -1848,17 +1622,14 @@ namespace LuaSpellEntry * * @param uint32 auraInterruptFlags : the new aura interrupt flags bitmask */ - int SetAuraInterruptFlags(lua_State* L, SpellEntry* entry) + void SetAuraInterruptFlags(SpellEntry* entry, uint32 auraInterruptFlags) { - uint32 auraInterruptFlags = ALE::CHECKVAL(L, 2); entry->AuraInterruptFlags = auraInterruptFlags; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->AuraInterruptFlags = auraInterruptFlags; } - - return 0; } /** @@ -1866,17 +1637,14 @@ namespace LuaSpellEntry * * @param uint32 channelInterruptFlags : the new channel interrupt flags bitmask */ - int SetChannelInterruptFlags(lua_State* L, SpellEntry* entry) + void SetChannelInterruptFlags(SpellEntry* entry, uint32 channelInterruptFlags) { - uint32 channelInterruptFlags = ALE::CHECKVAL(L, 2); entry->ChannelInterruptFlags = channelInterruptFlags; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->ChannelInterruptFlags = channelInterruptFlags; } - - return 0; } /** @@ -1884,17 +1652,14 @@ namespace LuaSpellEntry * * @param uint32 procFlags : the new proc flags bitmask */ - int SetProcFlags(lua_State* L, SpellEntry* entry) + void SetProcFlags(SpellEntry* entry, uint32 procFlags) { - uint32 procFlags = ALE::CHECKVAL(L, 2); entry->ProcFlags = procFlags; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->ProcFlags = procFlags; } - - return 0; } /** @@ -1902,17 +1667,14 @@ namespace LuaSpellEntry * * @param uint32 procChance : the new proc chance value */ - int SetProcChance(lua_State* L, SpellEntry* entry) + void SetProcChance(SpellEntry* entry, uint32 procChance) { - uint32 procChance = ALE::CHECKVAL(L, 2); entry->ProcChance = procChance; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->ProcChance = procChance; } - - return 0; } /** @@ -1920,17 +1682,14 @@ namespace LuaSpellEntry * * @param uint32 procCharges : the new proc charges value */ - int SetProcCharges(lua_State* L, SpellEntry* entry) + void SetProcCharges(SpellEntry* entry, uint32 procCharges) { - uint32 procCharges = ALE::CHECKVAL(L, 2); entry->ProcCharges = procCharges; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->ProcCharges = procCharges; } - - return 0; } /** @@ -1938,17 +1697,14 @@ namespace LuaSpellEntry * * @param uint32 maxLevel : the new max level value */ - int SetMaxLevel(lua_State* L, SpellEntry* entry) + void SetMaxLevel(SpellEntry* entry, uint32 maxLevel) { - uint32 maxLevel = ALE::CHECKVAL(L, 2); entry->MaxLevel = maxLevel; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->MaxLevel = maxLevel; } - - return 0; } /** @@ -1956,17 +1712,14 @@ namespace LuaSpellEntry * * @param uint32 baseLevel : the new base level value */ - int SetBaseLevel(lua_State* L, SpellEntry* entry) + void SetBaseLevel(SpellEntry* entry, uint32 baseLevel) { - uint32 baseLevel = ALE::CHECKVAL(L, 2); entry->BaseLevel = baseLevel; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->BaseLevel = baseLevel; } - - return 0; } /** @@ -1974,17 +1727,14 @@ namespace LuaSpellEntry * * @param uint32 spellLevel : the new spell level value */ - int SetSpellLevel(lua_State* L, SpellEntry* entry) + void SetSpellLevel(SpellEntry* entry, uint32 spellLevel) { - uint32 spellLevel = ALE::CHECKVAL(L, 2); entry->SpellLevel = spellLevel; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->SpellLevel = spellLevel; } - - return 0; } /** @@ -1992,17 +1742,14 @@ namespace LuaSpellEntry * * @param uint32 manaCost : the new mana cost value */ - int SetManaCost(lua_State* L, SpellEntry* entry) + void SetManaCost(SpellEntry* entry, uint32 manaCost) { - uint32 manaCost = ALE::CHECKVAL(L, 2); entry->ManaCost = manaCost; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->ManaCost = manaCost; } - - return 0; } /** @@ -2010,17 +1757,14 @@ namespace LuaSpellEntry * * @param uint32 powerType : the new power type ID */ - int SetPowerType(lua_State* L, SpellEntry* entry) + void SetPowerType(SpellEntry* entry, uint32 powerType) { - uint32 powerType = ALE::CHECKVAL(L, 2); entry->PowerType = powerType; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->PowerType = powerType; } - - return 0; } /** @@ -2028,17 +1772,14 @@ namespace LuaSpellEntry * * @param uint32 manaCostPerlevel : the new mana cost per level value */ - int SetManaCostPerlevel(lua_State* L, SpellEntry* entry) + void SetManaCostPerlevel(SpellEntry* entry, uint32 manaCostPerlevel) { - uint32 manaCostPerlevel = ALE::CHECKVAL(L, 2); entry->ManaCostPerlevel = manaCostPerlevel; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->ManaCostPerlevel = manaCostPerlevel; } - - return 0; } /** @@ -2046,17 +1787,14 @@ namespace LuaSpellEntry * * @param uint32 manaPerSecond : the new mana per second value */ - int SetManaPerSecond(lua_State* L, SpellEntry* entry) + void SetManaPerSecond(SpellEntry* entry, uint32 manaPerSecond) { - uint32 manaPerSecond = ALE::CHECKVAL(L, 2); entry->ManaPerSecond = manaPerSecond; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->ManaPerSecond = manaPerSecond; } - - return 0; } /** @@ -2064,17 +1802,14 @@ namespace LuaSpellEntry * * @param uint32 manaPerSecondPerLevel : the new mana per second per level value */ - int SetManaPerSecondPerLevel(lua_State* L, SpellEntry* entry) + void SetManaPerSecondPerLevel(SpellEntry* entry, uint32 manaPerSecondPerLevel) { - uint32 manaPerSecondPerLevel = ALE::CHECKVAL(L, 2); entry->ManaPerSecondPerLevel = manaPerSecondPerLevel; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->ManaPerSecondPerLevel = manaPerSecondPerLevel; } - - return 0; } /** @@ -2082,17 +1817,14 @@ namespace LuaSpellEntry * * @param float speed : the new speed value */ - int SetSpeed(lua_State* L, SpellEntry* entry) + void SetSpeed(SpellEntry* entry, float speed) { - float speed = ALE::CHECKVAL(L, 2); entry->Speed = speed; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->Speed = speed; } - - return 0; } /** @@ -2100,17 +1832,14 @@ namespace LuaSpellEntry * * @param uint32 stackAmount : the new stack amount value */ - int SetStackAmount(lua_State* L, SpellEntry* entry) + void SetStackAmount(SpellEntry* entry, uint32 stackAmount) { - uint32 stackAmount = ALE::CHECKVAL(L, 2); entry->StackAmount = stackAmount; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->StackAmount = stackAmount; } - - return 0; } /** @@ -2118,17 +1847,14 @@ namespace LuaSpellEntry * * @param int32 equippedItemClass : the new equipped item class value */ - int SetEquippedItemClass(lua_State* L, SpellEntry* entry) + void SetEquippedItemClass(SpellEntry* entry, int32 equippedItemClass) { - int32 equippedItemClass = ALE::CHECKVAL(L, 2); entry->EquippedItemClass = equippedItemClass; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->EquippedItemClass = equippedItemClass; } - - return 0; } /** @@ -2136,17 +1862,14 @@ namespace LuaSpellEntry * * @param int32 equippedItemSubClassMask : the new equipped item sub class mask bitmasks */ - int SetEquippedItemSubClassMask(lua_State* L, SpellEntry* entry) + void SetEquippedItemSubClassMask(SpellEntry* entry, int32 equippedItemSubClassMask) { - int32 equippedItemSubClassMask = ALE::CHECKVAL(L, 2); entry->EquippedItemSubClassMask = equippedItemSubClassMask; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->EquippedItemSubClassMask = equippedItemSubClassMask; } - - return 0; } /** @@ -2154,17 +1877,14 @@ namespace LuaSpellEntry * * @param int32 equippedItemInventoryTypeMask : the new equipped item inventory type mask bitmasks */ - int SetEquippedItemInventoryTypeMask(lua_State* L, SpellEntry* entry) + void SetEquippedItemInventoryTypeMask(SpellEntry* entry, int32 equippedItemInventoryTypeMask) { - int32 equippedItemInventoryTypeMask = ALE::CHECKVAL(L, 2); entry->EquippedItemInventoryTypeMask = equippedItemInventoryTypeMask; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->EquippedItemInventoryTypeMask = equippedItemInventoryTypeMask; } - - return 0; } /** @@ -2172,17 +1892,14 @@ namespace LuaSpellEntry * * @param uint32 spellIconID : the new spell icon ID value */ - int SetSpellIconID(lua_State* L, SpellEntry* entry) + void SetSpellIconID(SpellEntry* entry, uint32 spellIconID) { - uint32 spellIconID = ALE::CHECKVAL(L, 2); entry->SpellIconID = spellIconID; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->SpellIconID = spellIconID; } - - return 0; } /** @@ -2190,17 +1907,14 @@ namespace LuaSpellEntry * * @param uint32 activeIconID : the new active icon ID value */ - int SetActiveIconID(lua_State* L, SpellEntry* entry) + void SetActiveIconID(SpellEntry* entry, uint32 activeIconID) { - uint32 activeIconID = ALE::CHECKVAL(L, 2); entry->ActiveIconID = activeIconID; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->ActiveIconID = activeIconID; } - - return 0; } /** @@ -2208,17 +1922,14 @@ namespace LuaSpellEntry * * @param uint32 spellPriority : the new spell priority value */ - int SetSpellPriority(lua_State* L, SpellEntry* entry) + void SetSpellPriority(SpellEntry* entry, uint32 spellPriority) { - uint32 spellPriority = ALE::CHECKVAL(L, 2); entry->SpellPriority = spellPriority; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->SpellPriority = spellPriority; } - - return 0; } /** @@ -2226,17 +1937,14 @@ namespace LuaSpellEntry * * @param uint32 manaCostPercentage : the new mana cost percentage value */ - int SetManaCostPercentage(lua_State* L, SpellEntry* entry) + void SetManaCostPercentage(SpellEntry* entry, uint32 manaCostPercentage) { - uint32 manaCostPercentage = ALE::CHECKVAL(L, 2); entry->ManaCostPercentage = manaCostPercentage; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->ManaCostPercentage = manaCostPercentage; } - - return 0; } /** @@ -2244,17 +1952,14 @@ namespace LuaSpellEntry * * @param uint32 startRecoveryCategory : the new start recovery category value */ - int SetStartRecoveryCategory(lua_State* L, SpellEntry* entry) + void SetStartRecoveryCategory(SpellEntry* entry, uint32 startRecoveryCategory) { - uint32 startRecoveryCategory = ALE::CHECKVAL(L, 2); entry->StartRecoveryCategory = startRecoveryCategory; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->StartRecoveryCategory = startRecoveryCategory; } - - return 0; } /** @@ -2262,17 +1967,14 @@ namespace LuaSpellEntry * * @param uint32 startRecoveryTime : the new start recovery time value */ - int SetStartRecoveryTime(lua_State* L, SpellEntry* entry) + void SetStartRecoveryTime(SpellEntry* entry, uint32 startRecoveryTime) { - uint32 startRecoveryTime = ALE::CHECKVAL(L, 2); entry->StartRecoveryTime = startRecoveryTime; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->StartRecoveryTime = startRecoveryTime; } - - return 0; } /** @@ -2280,17 +1982,14 @@ namespace LuaSpellEntry * * @param uint32 maxTargetLevel : the new max target level value */ - int SetMaxTargetLevel(lua_State* L, SpellEntry* entry) + void SetMaxTargetLevel(SpellEntry* entry, uint32 maxTargetLevel) { - uint32 maxTargetLevel = ALE::CHECKVAL(L, 2); entry->MaxTargetLevel = maxTargetLevel; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->MaxTargetLevel = maxTargetLevel; } - - return 0; } /** @@ -2298,17 +1997,14 @@ namespace LuaSpellEntry * * @param uint32 spellFamilyName : the new spell family name value */ - int SetSpellFamilyName(lua_State* L, SpellEntry* entry) + void SetSpellFamilyName(SpellEntry* entry, uint32 spellFamilyName) { - uint32 spellFamilyName = ALE::CHECKVAL(L, 2); entry->SpellFamilyName = spellFamilyName; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->SpellFamilyName = spellFamilyName; } - - return 0; } /** @@ -2316,17 +2012,14 @@ namespace LuaSpellEntry * * @param uint32 maxAffectedTargets : the new max affected targets value */ - int SetMaxAffectedTargets(lua_State* L, SpellEntry* entry) + void SetMaxAffectedTargets(SpellEntry* entry, uint32 maxAffectedTargets) { - uint32 maxAffectedTargets = ALE::CHECKVAL(L, 2); entry->MaxAffectedTargets = maxAffectedTargets; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->MaxAffectedTargets = maxAffectedTargets; } - - return 0; } /** @@ -2334,17 +2027,14 @@ namespace LuaSpellEntry * * @param uint32 dmgClass : the new damage class ID value */ - int SetDmgClass(lua_State* L, SpellEntry* entry) + void SetDmgClass(SpellEntry* entry, uint32 dmgClass) { - uint32 dmgClass = ALE::CHECKVAL(L, 2); entry->DmgClass = dmgClass; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->DmgClass = dmgClass; } - - return 0; } /** @@ -2352,17 +2042,14 @@ namespace LuaSpellEntry * * @param uint32 preventionType : the new prevention type ID value */ - int SetPreventionType(lua_State* L, SpellEntry* entry) + void SetPreventionType(SpellEntry* entry, uint32 preventionType) { - uint32 preventionType = ALE::CHECKVAL(L, 2); entry->PreventionType = preventionType; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->PreventionType = preventionType; } - - return 0; } /** @@ -2370,17 +2057,14 @@ namespace LuaSpellEntry * * @param uint32 schoolMask : the new school mask bitmask value */ - int SetSchoolMask(lua_State* L, SpellEntry* entry) + void SetSchoolMask(SpellEntry* entry, uint32 schoolMask) { - uint32 schoolMask = ALE::CHECKVAL(L, 2); entry->SchoolMask = schoolMask; if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry->Id)) { const_cast(spellInfo)->SchoolMask = schoolMask; } - - return 0; } /** @@ -2388,18 +2072,170 @@ namespace LuaSpellEntry * * @param uint32 runeCostID : the new rune cost ID value */ - int SetRuneCostID(lua_State* L, SpellEntry* entry) + void SetRuneCostID(SpellEntry* entry, uint32 runeCostID) { - 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 +void RegisterSpellEntryMethods(sol::state& lua) +{ + sol::usertype type = lua.new_usertype("SpellEntry", sol::no_constructor); + + type["GetId"] = &LuaSpellEntry::GetId; + type["GetCategory"] = &LuaSpellEntry::GetCategory; + type["GetDispel"] = &LuaSpellEntry::GetDispel; + type["GetMechanic"] = &LuaSpellEntry::GetMechanic; + type["GetAttributes"] = &LuaSpellEntry::GetAttributes; + type["GetAttributesEx"] = &LuaSpellEntry::GetAttributesEx; + type["GetAttributesEx2"] = &LuaSpellEntry::GetAttributesEx2; + type["GetAttributesEx3"] = &LuaSpellEntry::GetAttributesEx3; + type["GetAttributesEx4"] = &LuaSpellEntry::GetAttributesEx4; + type["GetAttributesEx5"] = &LuaSpellEntry::GetAttributesEx5; + type["GetAttributesEx6"] = &LuaSpellEntry::GetAttributesEx6; + type["GetAttributesEx7"] = &LuaSpellEntry::GetAttributesEx7; + type["GetStances"] = &LuaSpellEntry::GetStances; + type["GetStancesNot"] = &LuaSpellEntry::GetStancesNot; + type["GetTargets"] = &LuaSpellEntry::GetTargets; + type["GetTargetCreatureType"] = &LuaSpellEntry::GetTargetCreatureType; + type["GetRequiresSpellFocus"] = &LuaSpellEntry::GetRequiresSpellFocus; + type["GetFacingCasterFlags"] = &LuaSpellEntry::GetFacingCasterFlags; + type["GetCasterAuraState"] = &LuaSpellEntry::GetCasterAuraState; + type["GetTargetAuraState"] = &LuaSpellEntry::GetTargetAuraState; + type["GetCasterAuraStateNot"] = &LuaSpellEntry::GetCasterAuraStateNot; + type["GetTargetAuraStateNot"] = &LuaSpellEntry::GetTargetAuraStateNot; + type["GetCasterAuraSpell"] = &LuaSpellEntry::GetCasterAuraSpell; + type["GetTargetAuraSpell"] = &LuaSpellEntry::GetTargetAuraSpell; + type["GetExcludeCasterAuraSpell"] = &LuaSpellEntry::GetExcludeCasterAuraSpell; + type["GetExcludeTargetAuraSpell"] = &LuaSpellEntry::GetExcludeTargetAuraSpell; + type["GetCastingTimeIndex"] = &LuaSpellEntry::GetCastingTimeIndex; + type["GetRecoveryTime"] = &LuaSpellEntry::GetRecoveryTime; + type["GetCategoryRecoveryTime"] = &LuaSpellEntry::GetCategoryRecoveryTime; + type["GetInterruptFlags"] = &LuaSpellEntry::GetInterruptFlags; + type["GetAuraInterruptFlags"] = &LuaSpellEntry::GetAuraInterruptFlags; + type["GetChannelInterruptFlags"] = &LuaSpellEntry::GetChannelInterruptFlags; + type["GetProcFlags"] = &LuaSpellEntry::GetProcFlags; + type["GetProcChance"] = &LuaSpellEntry::GetProcChance; + type["GetProcCharges"] = &LuaSpellEntry::GetProcCharges; + type["GetMaxLevel"] = &LuaSpellEntry::GetMaxLevel; + type["GetBaseLevel"] = &LuaSpellEntry::GetBaseLevel; + type["GetSpellLevel"] = &LuaSpellEntry::GetSpellLevel; + type["GetDurationIndex"] = &LuaSpellEntry::GetDurationIndex; + type["GetPowerType"] = &LuaSpellEntry::GetPowerType; + type["GetManaCost"] = &LuaSpellEntry::GetManaCost; + type["GetManaCostPerlevel"] = &LuaSpellEntry::GetManaCostPerlevel; + type["GetManaPerSecond"] = &LuaSpellEntry::GetManaPerSecond; + type["GetManaPerSecondPerLevel"] = &LuaSpellEntry::GetManaPerSecondPerLevel; + type["GetRangeIndex"] = &LuaSpellEntry::GetRangeIndex; + type["GetSpeed"] = &LuaSpellEntry::GetSpeed; + type["GetStackAmount"] = &LuaSpellEntry::GetStackAmount; + type["GetTotem"] = &LuaSpellEntry::GetTotem; + type["GetReagent"] = &LuaSpellEntry::GetReagent; + type["GetReagentCount"] = &LuaSpellEntry::GetReagentCount; + type["GetEquippedItemClass"] = &LuaSpellEntry::GetEquippedItemClass; + type["GetEquippedItemSubClassMask"] = &LuaSpellEntry::GetEquippedItemSubClassMask; + type["GetEquippedItemInventoryTypeMask"] = &LuaSpellEntry::GetEquippedItemInventoryTypeMask; + type["GetEffect"] = &LuaSpellEntry::GetEffect; + type["GetEffectDieSides"] = &LuaSpellEntry::GetEffectDieSides; + type["GetEffectRealPointsPerLevel"] = &LuaSpellEntry::GetEffectRealPointsPerLevel; + type["GetEffectBasePoints"] = &LuaSpellEntry::GetEffectBasePoints; + type["GetEffectMechanic"] = &LuaSpellEntry::GetEffectMechanic; + type["GetEffectImplicitTargetA"] = &LuaSpellEntry::GetEffectImplicitTargetA; + type["GetEffectImplicitTargetB"] = &LuaSpellEntry::GetEffectImplicitTargetB; + type["GetEffectRadiusIndex"] = &LuaSpellEntry::GetEffectRadiusIndex; + type["GetEffectApplyAuraName"] = &LuaSpellEntry::GetEffectApplyAuraName; + type["GetEffectAmplitude"] = &LuaSpellEntry::GetEffectAmplitude; + type["GetEffectValueMultiplier"] = &LuaSpellEntry::GetEffectValueMultiplier; + type["GetEffectChainTarget"] = &LuaSpellEntry::GetEffectChainTarget; + type["GetEffectItemType"] = &LuaSpellEntry::GetEffectItemType; + type["GetEffectMiscValue"] = &LuaSpellEntry::GetEffectMiscValue; + type["GetEffectMiscValueB"] = &LuaSpellEntry::GetEffectMiscValueB; + type["GetEffectTriggerSpell"] = &LuaSpellEntry::GetEffectTriggerSpell; + type["GetEffectPointsPerComboPoint"] = &LuaSpellEntry::GetEffectPointsPerComboPoint; + type["GetEffectSpellClassMask"] = &LuaSpellEntry::GetEffectSpellClassMask; + type["GetSpellVisual"] = &LuaSpellEntry::GetSpellVisual; + type["GetSpellIconID"] = &LuaSpellEntry::GetSpellIconID; + type["GetActiveIconID"] = &LuaSpellEntry::GetActiveIconID; + type["GetSpellPriority"] = &LuaSpellEntry::GetSpellPriority; + type["GetSpellName"] = &LuaSpellEntry::GetSpellName; + type["GetRank"] = &LuaSpellEntry::GetRank; + type["GetManaCostPercentage"] = &LuaSpellEntry::GetManaCostPercentage; + type["GetStartRecoveryCategory"] = &LuaSpellEntry::GetStartRecoveryCategory; + type["GetStartRecoveryTime"] = &LuaSpellEntry::GetStartRecoveryTime; + type["GetMaxTargetLevel"] = &LuaSpellEntry::GetMaxTargetLevel; + type["GetSpellFamilyName"] = &LuaSpellEntry::GetSpellFamilyName; + type["GetSpellFamilyFlags"] = &LuaSpellEntry::GetSpellFamilyFlags; + type["GetMaxAffectedTargets"] = &LuaSpellEntry::GetMaxAffectedTargets; + type["GetDmgClass"] = &LuaSpellEntry::GetDmgClass; + type["GetPreventionType"] = &LuaSpellEntry::GetPreventionType; + type["GetEffectDamageMultiplier"] = &LuaSpellEntry::GetEffectDamageMultiplier; + type["GetTotemCategory"] = &LuaSpellEntry::GetTotemCategory; + type["GetAreaGroupId"] = &LuaSpellEntry::GetAreaGroupId; + type["GetSchoolMask"] = &LuaSpellEntry::GetSchoolMask; + type["GetRuneCostID"] = &LuaSpellEntry::GetRuneCostID; + type["GetEffectBonusMultiplier"] = &LuaSpellEntry::GetEffectBonusMultiplier; + type["SetCategory"] = &LuaSpellEntry::SetCategory; + type["SetDispel"] = &LuaSpellEntry::SetDispel; + type["SetMechanic"] = &LuaSpellEntry::SetMechanic; + type["SetAttributes"] = &LuaSpellEntry::SetAttributes; + type["SetAttributesEx"] = &LuaSpellEntry::SetAttributesEx; + type["SetAttributesEx2"] = &LuaSpellEntry::SetAttributesEx2; + type["SetAttributesEx3"] = &LuaSpellEntry::SetAttributesEx3; + type["SetAttributesEx4"] = &LuaSpellEntry::SetAttributesEx4; + type["SetAttributesEx5"] = &LuaSpellEntry::SetAttributesEx5; + type["SetAttributesEx6"] = &LuaSpellEntry::SetAttributesEx6; + type["SetAttributesEx7"] = &LuaSpellEntry::SetAttributesEx7; + type["SetStances"] = &LuaSpellEntry::SetStances; + type["SetStancesNot"] = &LuaSpellEntry::SetStancesNot; + type["SetTargets"] = &LuaSpellEntry::SetTargets; + type["SetTargetCreatureType"] = &LuaSpellEntry::SetTargetCreatureType; + type["SetRequiresSpellFocus"] = &LuaSpellEntry::SetRequiresSpellFocus; + type["SetFacingCasterFlags"] = &LuaSpellEntry::SetFacingCasterFlags; + type["SetCasterAuraState"] = &LuaSpellEntry::SetCasterAuraState; + type["SetTargetAuraState"] = &LuaSpellEntry::SetTargetAuraState; + type["SetCasterAuraStateNot"] = &LuaSpellEntry::SetCasterAuraStateNot; + type["SetTargetAuraStateNot"] = &LuaSpellEntry::SetTargetAuraStateNot; + type["SetCasterAuraSpell"] = &LuaSpellEntry::SetCasterAuraSpell; + type["SetTargetAuraSpell"] = &LuaSpellEntry::SetTargetAuraSpell; + type["SetExcludeCasterAuraSpell"] = &LuaSpellEntry::SetExcludeCasterAuraSpell; + type["SetExcludeTargetAuraSpell"] = &LuaSpellEntry::SetExcludeTargetAuraSpell; + type["SetRecoveryTime"] = &LuaSpellEntry::SetRecoveryTime; + type["SetCategoryRecoveryTime"] = &LuaSpellEntry::SetCategoryRecoveryTime; + type["SetInterruptFlags"] = &LuaSpellEntry::SetInterruptFlags; + type["SetAuraInterruptFlags"] = &LuaSpellEntry::SetAuraInterruptFlags; + type["SetChannelInterruptFlags"] = &LuaSpellEntry::SetChannelInterruptFlags; + type["SetProcFlags"] = &LuaSpellEntry::SetProcFlags; + type["SetProcChance"] = &LuaSpellEntry::SetProcChance; + type["SetProcCharges"] = &LuaSpellEntry::SetProcCharges; + type["SetMaxLevel"] = &LuaSpellEntry::SetMaxLevel; + type["SetBaseLevel"] = &LuaSpellEntry::SetBaseLevel; + type["SetSpellLevel"] = &LuaSpellEntry::SetSpellLevel; + type["SetManaCost"] = &LuaSpellEntry::SetManaCost; + type["SetPowerType"] = &LuaSpellEntry::SetPowerType; + type["SetManaCostPerlevel"] = &LuaSpellEntry::SetManaCostPerlevel; + type["SetManaPerSecond"] = &LuaSpellEntry::SetManaPerSecond; + type["SetManaPerSecondPerLevel"] = &LuaSpellEntry::SetManaPerSecondPerLevel; + type["SetSpeed"] = &LuaSpellEntry::SetSpeed; + type["SetStackAmount"] = &LuaSpellEntry::SetStackAmount; + type["SetEquippedItemClass"] = &LuaSpellEntry::SetEquippedItemClass; + type["SetEquippedItemSubClassMask"] = &LuaSpellEntry::SetEquippedItemSubClassMask; + type["SetEquippedItemInventoryTypeMask"] = &LuaSpellEntry::SetEquippedItemInventoryTypeMask; + type["SetSpellIconID"] = &LuaSpellEntry::SetSpellIconID; + type["SetActiveIconID"] = &LuaSpellEntry::SetActiveIconID; + type["SetSpellPriority"] = &LuaSpellEntry::SetSpellPriority; + type["SetManaCostPercentage"] = &LuaSpellEntry::SetManaCostPercentage; + type["SetStartRecoveryCategory"] = &LuaSpellEntry::SetStartRecoveryCategory; + type["SetStartRecoveryTime"] = &LuaSpellEntry::SetStartRecoveryTime; + type["SetMaxTargetLevel"] = &LuaSpellEntry::SetMaxTargetLevel; + type["SetSpellFamilyName"] = &LuaSpellEntry::SetSpellFamilyName; + type["SetMaxAffectedTargets"] = &LuaSpellEntry::SetMaxAffectedTargets; + type["SetDmgClass"] = &LuaSpellEntry::SetDmgClass; + type["SetPreventionType"] = &LuaSpellEntry::SetPreventionType; + type["SetSchoolMask"] = &LuaSpellEntry::SetSchoolMask; + type["SetRuneCostID"] = &LuaSpellEntry::SetRuneCostID; +} diff --git a/src/LuaEngine/methods/SpellInfoMethods.h b/src/LuaEngine/methods/SpellInfoMethods.cpp similarity index 59% rename from src/LuaEngine/methods/SpellInfoMethods.h rename to src/LuaEngine/methods/SpellInfoMethods.cpp index 3b69015718..d05ed9d214 100644 --- a/src/LuaEngine/methods/SpellInfoMethods.h +++ b/src/LuaEngine/methods/SpellInfoMethods.cpp @@ -4,8 +4,11 @@ * Please see the included DOCS/LICENSE.md for more information */ -#ifndef SPELLINFOMETHODS_H -#define SPELLINFOMETHODS_H +#include "ALEBind.h" + +#include "Common.h" +#include "SharedDefines.h" +#include "SpellInfo.h" /*** * Represents spell metadata used for behavior, targeting, attributes, mechanics, auras, and conditions. @@ -39,13 +42,11 @@ namespace LuaSpellInfo * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the [SpellInfo]'s name * @return [string] name */ - int GetName(lua_State* L, SpellInfo* spell_info) + char const* GetName(SpellInfo* spell_info, sol::optional locale) { - uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE); - ALE::Push(L, spell_info->SpellName[static_cast(locale)]); - return 1; + return spell_info->SpellName[static_cast(locale.value_or(DEFAULT_LOCALE))]; } - + /** * Checks if the [SpellInfo] has a specific attribute. * @@ -53,7 +54,7 @@ namespace LuaSpellInfo * Attributes are divided into different categories (from 0 to 8 in this context). * * Here is how each attribute is inspected: - * + * *
      * 0 : SpellAttr0
      * 1 : SpellAttr1
@@ -70,16 +71,14 @@ namespace LuaSpellInfo
      * @param [uint32] attribute : the specific attribute to check.
      * @return [bool] has_attribute
      */
-    int HasAttribute(lua_State* L, SpellInfo* spell_info)
+    bool HasAttribute(SpellInfo* spell_info, int8 attributeType, uint32 attribute)
     {
-        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)
+        if (attributeType == -1)
+            hasAttribute = spell_info->HasAttribute(static_cast(attribute));
+        else
+        {
+            switch (attributeType)
             {
                 case 0:
                     hasAttribute = spell_info->HasAttribute(static_cast(attribute));
@@ -110,10 +109,9 @@ namespace LuaSpellInfo
             }
         }
 
-        ALE::Push(L, hasAttribute);
-        return 1;
+        return hasAttribute;
     }
-    
+
     /**
      * Retrieves the attributes of the [SpellInfo] based on the attribute type.
      *
@@ -136,16 +134,15 @@ namespace LuaSpellInfo
      * @param [int8] attributeType : The type of the attribute.
      * @return [uint32] attributes
      */
-    int GetAttributes(lua_State* L, SpellInfo* spell_info)
+    uint32 GetAttributes(SpellInfo* spell_info, int8 attributeType)
     {
-        int8 attributeType = ALE::CHECKVAL(L, 2);
-        uint32 attributes;
+        uint32 attributes = 0;
 
-        if ( attributeType == -1 ) {
+        if (attributeType == -1)
             attributes = spell_info->AttributesCu;
-        }
-        else {
-            switch(attributeType)
+        else
+        {
+            switch (attributeType)
             {
                 case 0:
                     attributes = spell_info->Attributes;
@@ -174,42 +171,39 @@ namespace LuaSpellInfo
             }
         }
 
-        ALE::Push(L, attributes);
-        return 1;
+        return attributes;
     }
-    
+
     /**
      * 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)
+    bool IsAffectingArea(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsAffectingArea());
-        return 1;
+        return spell_info->IsAffectingArea();
     }
-    
+
     /**
      * 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. 
+     * 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)
+    uint32 GetCategory(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->GetCategory());
-        return 1;
+        return spell_info->GetCategory();
     }
-    
+
     /**
      * Checks if the [SpellInfo] has a specific effect.
      *
@@ -217,57 +211,50 @@ namespace LuaSpellInfo
      * 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 
+     * @return [bool] has_effect
      */
-    int HasEffect(lua_State* L, SpellInfo* spell_info)
+    bool HasEffect(SpellInfo* spell_info, uint8 effect)
     {
-        uint8 effect = ALE::CHECKVAL(L, 2);
-        ALE::Push(L, spell_info->HasEffect(static_cast(effect)));
-        return 1;
+        return spell_info->HasEffect(static_cast(effect));
     }
-    
+
     /**
      * Checks if the [SpellInfo] has a specific aura.
      *
-     * An aura represents a status change or modification due to a spell or ability. 
+     * 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)
+    bool HasAura(SpellInfo* spell_info, uint32 aura)
     {
-        uint32 aura = ALE::CHECKVAL(L, 2);
-        ALE::Push(L, spell_info->HasAura(static_cast(aura)));
-        return 1;
+        return spell_info->HasAura(static_cast(aura));
     }
-    
+
     /**
      * 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)
+    bool HasAreaAuraEffect(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->HasAreaAuraEffect());
-        return 1;
+        return spell_info->HasAreaAuraEffect();
     }
-    
-   
+
     /**
      * 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 
+     * 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)
+    bool IsExplicitDiscovery(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsExplicitDiscovery());
-        return 1;
+        return spell_info->IsExplicitDiscovery();
     }
 
     /**
@@ -278,10 +265,9 @@ namespace LuaSpellInfo
      *
      * @return [bool] is_loot_crafting
      */
-    int IsLootCrafting(lua_State* L, SpellInfo* spell_info)
+    bool IsLootCrafting(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsLootCrafting());
-        return 1;
+        return spell_info->IsLootCrafting();
     }
 
     /**
@@ -292,83 +278,76 @@ namespace LuaSpellInfo
      *
      * @return [bool] is_profression_or_riding
      */
-    int IsProfessionOrRiding(lua_State* L, SpellInfo* spell_info)
+    bool IsProfessionOrRiding(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsProfessionOrRiding());
-        return 1;
+        return spell_info->IsProfessionOrRiding();
     }
 
     /**
      * Checks if the [SpellInfo] is related to a profession skill.
      *
-     * Profession skills may refer to abilities related to a specific occupation or trade, 
+     * 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)
+    bool IsProfession(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsProfession());
-        return 1;
+        return spell_info->IsProfession();
     }
 
     /**
      * 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, 
+     * 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)
+    bool IsPrimaryProfession(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsPrimaryProfession());
-        return 1;
+        return spell_info->IsPrimaryProfession();
     }
 
     /**
      * 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. 
+     *
+     * 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)
+    bool IsPrimaryProfessionFirstRank(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsPrimaryProfessionFirstRank());
-        return 1;
+        return spell_info->IsPrimaryProfessionFirstRank();
     }
 
     /**
      * Checks if the [SpellInfo] represents an ability learned with a profession skill.
      *
-     * Certain abilities or skills (like crafting item or gathering materials) 
+     * 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)
+    bool IsAbilityLearnedWithProfession(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsAbilityLearnedWithProfession());
-        return 1;
+        return spell_info->IsAbilityLearnedWithProfession();
     }
 
     /**
      * 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), 
+     * 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)
+    bool IsAbilityOfSkillType(SpellInfo* spell_info, uint32 skillType)
     {
-        uint32 skillType = ALE::CHECKVAL(L, 2);
-        ALE::Push(L, spell_info->IsAbilityOfSkillType(skillType));
-        return 1;
+        return spell_info->IsAbilityOfSkillType(skillType);
     }
 
     /**
@@ -378,129 +357,119 @@ namespace LuaSpellInfo
      *
      * @return [bool] is_targeting_area
      */
-    int IsTargetingArea(lua_State* L, SpellInfo* spell_info)
+    bool IsTargetingArea(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsTargetingArea());
-        return 1;
+        return spell_info->IsTargetingArea();
     }
 
     /**
      * 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. 
+     * 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)
+    bool NeedsExplicitUnitTarget(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->NeedsExplicitUnitTarget());
-        return 1;
+        return spell_info->NeedsExplicitUnitTarget();
     }
 
     /**
      * 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 
+     * 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)
+    bool NeedsToBeTriggeredByCaster(SpellInfo* spell_info, SpellInfo const* triggeringSpell)
     {
-        const SpellInfo* triggeringSpell = ALE::CHECKOBJ(L, 2);
-        ALE::Push(L, spell_info->NeedsToBeTriggeredByCaster(triggeringSpell));
-        return 1;
+        return spell_info->NeedsToBeTriggeredByCaster(triggeringSpell);
     }
 
     /**
      * 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 
+     * 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)
+    bool IsSelfCast(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsSelfCast());
-        return 1;
+        return spell_info->IsSelfCast();
     }
 
     /**
      * 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 
+     * 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)
+    bool IsPassive(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsPassive());
-        return 1;
+        return spell_info->IsPassive();
     }
 
     /**
      * 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] 
+     * 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)
+    bool IsAutocastable(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsAutocastable());
-        return 1;
+        return spell_info->IsAutocastable();
     }
 
     /**
      * 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 
+     * 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)
+    bool IsStackableWithRanks(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsStackableWithRanks());
-        return 1;
+        return spell_info->IsStackableWithRanks();
     }
 
     /**
      * 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 
+     * 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)
+    bool IsPassiveStackableWithRanks(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsPassiveStackableWithRanks());
-        return 1;
+        return spell_info->IsPassiveStackableWithRanks();
     }
 
     /**
      * 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. 
+     * 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)
+    bool IsMultiSlotAura(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsMultiSlotAura());
-        return 1;
+        return spell_info->IsMultiSlotAura();
     }
 
     /**
@@ -508,10 +477,9 @@ namespace LuaSpellInfo
      *
      * @return [bool] is_cooldown_started_on_event
      */
-    int IsCooldownStartedOnEvent(lua_State* L, SpellInfo* spell_info)
+    bool IsCooldownStartedOnEvent(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsCooldownStartedOnEvent());
-        return 1;
+        return spell_info->IsCooldownStartedOnEvent();
     }
 
     /**
@@ -519,10 +487,9 @@ namespace LuaSpellInfo
      *
      * @return [bool] is_death_persistant
      */
-    int IsDeathPersistent(lua_State* L, SpellInfo* spell_info)
+    bool IsDeathPersistent(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsDeathPersistent());
-        return 1;
+        return spell_info->IsDeathPersistent();
     }
 
     /**
@@ -530,10 +497,9 @@ namespace LuaSpellInfo
      *
      * @return [bool] : true if the [SpellInfo] requires a dead target; false otherwise
      */
-    int IsRequiringDeadTarget(lua_State* L, SpellInfo* spell_info)
+    bool IsRequiringDeadTarget(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsRequiringDeadTarget());
-        return 1;
+        return spell_info->IsRequiringDeadTarget();
     }
 
     /**
@@ -541,10 +507,9 @@ namespace LuaSpellInfo
      *
      * @return bool allowsDeadTarget
      */
-    int IsAllowingDeadTarget(lua_State* L, SpellInfo* spell_info)
+    bool IsAllowingDeadTarget(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsAllowingDeadTarget());
-        return 1;
+        return spell_info->IsAllowingDeadTarget();
     }
 
     /**
@@ -552,10 +517,9 @@ namespace LuaSpellInfo
      *
      * @return bool usableInCombat
      */
-    int CanBeUsedInCombat(lua_State* L, SpellInfo* spell_info)
+    bool CanBeUsedInCombat(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->CanBeUsedInCombat());
-        return 1;
+        return spell_info->CanBeUsedInCombat();
     }
 
     /**
@@ -563,10 +527,9 @@ namespace LuaSpellInfo
      *
      * @return bool isPositive
      */
-    int IsPositive(lua_State* L, SpellInfo* spell_info)
+    bool IsPositive(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsPositive());
-        return 1;
+        return spell_info->IsPositive();
     }
 
     /**
@@ -575,11 +538,9 @@ namespace LuaSpellInfo
      * @param uint8 effIndex
      * @return bool isPositiveEffect
      */
-    int IsPositiveEffect(lua_State* L, SpellInfo* spell_info)
+    bool IsPositiveEffect(SpellInfo* spell_info, uint8 effIndex)
     {
-        uint8 effIndex = ALE::CHECKVAL(L, 2);
-        ALE::Push(L, spell_info->IsPositiveEffect(effIndex));
-        return 1;
+        return spell_info->IsPositiveEffect(effIndex);
     }
 
     /**
@@ -587,10 +548,9 @@ namespace LuaSpellInfo
      *
      * @return bool isChanneled
      */
-    int IsChanneled(lua_State* L, SpellInfo* spell_info)
+    bool IsChanneled(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsChanneled());
-        return 1;
+        return spell_info->IsChanneled();
     }
 
     /**
@@ -598,10 +558,9 @@ namespace LuaSpellInfo
      *
      * @return bool needsComboPoints
      */
-    int NeedsComboPoints(lua_State* L, SpellInfo* spell_info)
+    bool NeedsComboPoints(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->NeedsComboPoints());
-        return 1;
+        return spell_info->NeedsComboPoints();
     }
 
     /**
@@ -609,10 +568,9 @@ namespace LuaSpellInfo
      *
      * @return bool breaksStealth
      */
-    int IsBreakingStealth(lua_State* L, SpellInfo* spell_info)
+    bool IsBreakingStealth(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsBreakingStealth());
-        return 1;
+        return spell_info->IsBreakingStealth();
     }
 
     /**
@@ -620,10 +578,9 @@ namespace LuaSpellInfo
      *
      * @return bool isRangedWeaponSpell
      */
-    int IsRangedWeaponSpell(lua_State* L, SpellInfo* spell_info)
+    bool IsRangedWeaponSpell(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsRangedWeaponSpell());
-        return 1;
+        return spell_info->IsRangedWeaponSpell();
     }
 
     /**
@@ -631,107 +588,92 @@ namespace LuaSpellInfo
      *
      * @return bool isAutoRepeat
      */
-    int IsAutoRepeatRangedSpell(lua_State* L, SpellInfo* spell_info)
+    bool IsAutoRepeatRangedSpell(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsAutoRepeatRangedSpell());
-        return 1;
-    }  
+        return spell_info->IsAutoRepeatRangedSpell();
+    }
 
     /**
      * 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)
+    bool IsAffectedBySpellMods(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsAffectedBySpellMods());
-        return 1;
+        return spell_info->IsAffectedBySpellMods();
     }
-    
-    /*  int IsAffectedBySpellMod(lua_State* L, SpellInfo* spell_info)
+
+    /*  bool IsAffectedBySpellMod(SpellInfo* spell_info, SpellInfo const* auraSpellInfo)
         {
-            const SpellInfo* auraSpellInfo = ALE::CHECKOBJ(L, 2);
-            ALE::Push(L, spell_info->IsAffectedBySpellMod(auraSpellInfo));
-            return 1;
+            return spell_info->IsAffectedBySpellMod(auraSpellInfo);
         }
     */
-    
+
     /**
      * 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)
+    bool CanPierceImmuneAura(SpellInfo* spell_info, SpellInfo const* auraSpellInfo)
     {
-        const SpellInfo* auraSpellInfo = ALE::CHECKOBJ(L, 2);
-        ALE::Push(L, spell_info->CanPierceImmuneAura(auraSpellInfo));
-        return 1;
+        return spell_info->CanPierceImmuneAura(auraSpellInfo);
     }
-    
+
     /**
      * 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)
+    bool CanDispelAura(SpellInfo* spell_info, SpellInfo const* auraSpellInfo)
     {
-        const SpellInfo* auraSpellInfo = ALE::CHECKOBJ(L, 2);
-        ALE::Push(L, spell_info->CanDispelAura(auraSpellInfo));
-        return 1;
+        return spell_info->CanDispelAura(auraSpellInfo);
     }
-    
+
     /**
      * 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)
+    bool IsSingleTarget(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->IsSingleTarget());
-        return 1;
+        return spell_info->IsSingleTarget();
     }
-    
+
     /**
      * 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)
+    bool IsAuraExclusiveBySpecificWith(SpellInfo* spell_info, SpellInfo const* spellInfo)
     {
-        const SpellInfo* spellInfo = ALE::CHECKOBJ(L, 2);
-        ALE::Push(L, spell_info->IsAuraExclusiveBySpecificWith(spellInfo));
-        return 1;
+        return spell_info->IsAuraExclusiveBySpecificWith(spellInfo);
     }
-    
+
     /**
      * 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)
+    bool IsAuraExclusiveBySpecificPerCasterWith(SpellInfo* spell_info, SpellInfo const* spellInfo)
     {
-        const SpellInfo* spellInfo = ALE::CHECKOBJ(L, 2);
-        ALE::Push(L, spell_info->IsAuraExclusiveBySpecificPerCasterWith(spellInfo));
-        return 1;
+        return spell_info->IsAuraExclusiveBySpecificPerCasterWith(spellInfo);
     }
-    
+
     /**
      * 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)
+    SpellCastResult CheckShapeshift(SpellInfo* spell_info, uint32 form)
     {
-        uint32 form = ALE::CHECKVAL(L, 2);
-        ALE::Push(L, spell_info->CheckShapeshift(form));
-        return 1;
+        return spell_info->CheckShapeshift(form);
     }
-    
+
     /**
      * Returns `true` if the [SpellInfo] can be cast in the specified location.
      *
@@ -742,18 +684,11 @@ namespace LuaSpellInfo
      * @param bool strict = false : whether all conditions must strictly match
      * @return bool isAllowed
      */
-    int CheckLocation(lua_State* L, SpellInfo* spell_info)
+    SpellCastResult CheckLocation(SpellInfo* spell_info, uint32 map_id, uint32 zone_id, uint32 area_id, Player* player, sol::optional strict)
     {
-        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;
+        return spell_info->CheckLocation(map_id, zone_id, area_id, player, strict.value_or(false));
     }
-    
+
     /**
      * Returns `true` if the target is valid for the [SpellInfo].
      *
@@ -762,16 +697,11 @@ namespace LuaSpellInfo
      * @param bool implicit = true : whether implicit target checks should apply
      * @return bool isValid
      */
-    int CheckTarget(lua_State* L, SpellInfo* spell_info)
+    SpellCastResult CheckTarget(SpellInfo* spell_info, Unit const* caster, WorldObject const* target, sol::optional implicit)
     {
-        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;
+        return spell_info->CheckTarget(caster, target, implicit.value_or(true));
     }
-    
+
     /**
      * Returns `true` if the [SpellInfo] can be explicitly cast on the given [target] with the optional [Item].
      *
@@ -780,30 +710,22 @@ namespace LuaSpellInfo
      * @param [Item] item : optional item used in the cast
      * @return bool isValid
      */
-    int CheckExplicitTarget(lua_State* L, SpellInfo* spell_info)
+    SpellCastResult CheckExplicitTarget(SpellInfo* spell_info, Unit const* caster, WorldObject const* target, Item const* item)
     {
-        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;
+        return spell_info->CheckExplicitTarget(caster, target, item);
     }
-    
+
     /**
      * 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)
+    bool CheckTargetCreatureType(SpellInfo* spell_info, Unit const* target)
     {
-        const Unit* target = ALE::CHECKOBJ(L, 2);
-
-        ALE::Push(L, spell_info->CheckTargetCreatureType(target));
-        return 1;
+        return spell_info->CheckTargetCreatureType(target);
     }
-    
+
     /**
      * Returns the school mask of the [SpellInfo].
      *
@@ -811,12 +733,11 @@ namespace LuaSpellInfo
      *
      * @return uint32 schoolMask
      */
-    int GetSchoolMask(lua_State* L, SpellInfo* spell_info)
+    SpellSchoolMask GetSchoolMask(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->GetSchoolMask());
-        return 1;
+        return spell_info->GetSchoolMask();
     }
-    
+
     /**
      * Returns a combined mechanic mask of all effects for the [SpellInfo].
      *
@@ -824,54 +745,44 @@ namespace LuaSpellInfo
      *
      * @return uint32 mechanicMask
      */
-    int GetAllEffectsMechanicMask(lua_State* L, SpellInfo* spell_info)
+    uint64 GetAllEffectsMechanicMask(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->GetAllEffectsMechanicMask());
-        return 1;
+        return spell_info->GetAllEffectsMechanicMask();
     }
-    
+
     /**
      * 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)
+    uint64 GetEffectMechanicMask(SpellInfo* spell_info, uint32 effIndex)
     {
-        uint32 effIndex = ALE::CHECKVAL(L, 2);
-        
-        ALE::Push(L, spell_info->GetEffectMechanicMask(static_cast(effIndex)));
-        return 1;
+        return spell_info->GetEffectMechanicMask(static_cast(effIndex));
     }
-    
+
     /**
      * 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)
+    uint64 GetSpellMechanicMaskByEffectMask(SpellInfo* spell_info, uint32 effectmask)
     {
-        uint32 effectmask = ALE::CHECKVAL(L, 2);
-
-        ALE::Push(L, spell_info->GetSpellMechanicMaskByEffectMask(effectmask));
-        return 1;
+        return spell_info->GetSpellMechanicMaskByEffectMask(effectmask);
     }
-    
+
     /**
      * 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)
+    Mechanics GetEffectMechanic(SpellInfo* spell_info, uint32 effIndex)
     {
-        uint32 effIndex = ALE::CHECKVAL(L, 2);
-
-        ALE::Push(L, spell_info->GetEffectMechanic(static_cast(effIndex)));
-        return 1;
+        return spell_info->GetEffectMechanic(static_cast(effIndex));
     }
-    
+
     /**
      * Returns the dispel mask for the [SpellInfo].
      *
@@ -880,14 +791,12 @@ namespace LuaSpellInfo
      * @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 GetDispelMask(SpellInfo* spell_info, sol::optional type)
     {
-        uint32 type = ALE::CHECKVAL(L, 2, false);
-
-        ALE::Push(L, type != 0 ? spell_info->GetDispelMask(static_cast(type)) : spell_info->GetDispelMask());
-        return 1;
+        uint32 dispelType = type.value_or(0);
+        return dispelType != 0 ? spell_info->GetDispelMask(static_cast(dispelType)) : spell_info->GetDispelMask();
     }
-    
+
     /**
      * Returns the explicit target mask of the [SpellInfo].
      *
@@ -895,12 +804,11 @@ namespace LuaSpellInfo
      *
      * @return uint32 targetMask
      */
-    int GetExplicitTargetMask(lua_State* L, SpellInfo* spell_info)
+    uint32 GetExplicitTargetMask(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->GetExplicitTargetMask());
-        return 1;
+        return spell_info->GetExplicitTargetMask();
     }
-    
+
     /**
      * Returns the aura state requirement for the [SpellInfo].
      *
@@ -908,12 +816,11 @@ namespace LuaSpellInfo
      *
      * @return uint32 auraState
      */
-    int GetAuraState(lua_State* L, SpellInfo* spell_info)
+    AuraStateType GetAuraState(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->GetAuraState());
-        return 1;
+        return spell_info->GetAuraState();
     }
-    
+
     /**
      * Returns the spell specific type of the [SpellInfo].
      *
@@ -921,10 +828,9 @@ namespace LuaSpellInfo
      *
      * @return uint32 spellSpecific
      */
-    int GetSpellSpecific(lua_State* L, SpellInfo* spell_info)
+    SpellSpecificType GetSpellSpecific(SpellInfo* spell_info)
     {
-        ALE::Push(L, spell_info->GetSpellSpecific());
-        return 1;
+        return spell_info->GetSpellSpecific();
     }
 
     /**
@@ -939,24 +845,15 @@ namespace LuaSpellInfo
     * @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)
+    int32 GetEffectMiscValueA(SpellInfo* spell_info, uint8 effectIndex)
     {
-        uint8 effectIndex = ALE::CHECKVAL(L, 2);
-        
         if (effectIndex >= MAX_SPELL_EFFECTS)
-        {
-            ALE::Push(L, 0);
-            return 1;
-        }
-        
+            return 0;
+
         if (spell_info->Effects[effectIndex].Effect == 0)
-        {
-            ALE::Push(L, 0);
-            return 1;
-        }
-        
-        ALE::Push(L, spell_info->Effects[effectIndex].MiscValue);
-        return 1;
+            return 0;
+
+        return spell_info->Effects[effectIndex].MiscValue;
     }
 
     /**
@@ -967,24 +864,79 @@ namespace LuaSpellInfo
     * @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)
+    int32 GetEffectMiscValueB(SpellInfo* spell_info, uint8 effectIndex)
     {
-        uint8 effectIndex = ALE::CHECKVAL(L, 2);
-        
         if (effectIndex >= MAX_SPELL_EFFECTS)
-        {
-            ALE::Push(L, 0);
-            return 1;
-        }
-        
+            return 0;
+
         if (spell_info->Effects[effectIndex].Effect == 0)
-        {
-            ALE::Push(L, 0);
-            return 1;
-        }
-        
-        ALE::Push(L, spell_info->Effects[effectIndex].MiscValueB);
-        return 1;
+            return 0;
+
+        return spell_info->Effects[effectIndex].MiscValueB;
     }
 }
-#endif
+
+void RegisterSpellInfoMethods(sol::state& lua)
+{
+    sol::usertype type = lua.new_usertype("SpellInfo", sol::no_constructor);
+
+    type["GetName"]                                = &LuaSpellInfo::GetName;
+    type["HasAttribute"]                           = &LuaSpellInfo::HasAttribute;
+    type["GetAttributes"]                          = &LuaSpellInfo::GetAttributes;
+    type["IsAffectingArea"]                        = &LuaSpellInfo::IsAffectingArea;
+    type["GetCategory"]                            = &LuaSpellInfo::GetCategory;
+    type["HasEffect"]                              = &LuaSpellInfo::HasEffect;
+    type["HasAura"]                                = &LuaSpellInfo::HasAura;
+    type["HasAreaAuraEffect"]                      = &LuaSpellInfo::HasAreaAuraEffect;
+    type["IsExplicitDiscovery"]                    = &LuaSpellInfo::IsExplicitDiscovery;
+    type["IsLootCrafting"]                         = &LuaSpellInfo::IsLootCrafting;
+    type["IsProfessionOrRiding"]                   = &LuaSpellInfo::IsProfessionOrRiding;
+    type["IsProfession"]                           = &LuaSpellInfo::IsProfession;
+    type["IsPrimaryProfession"]                    = &LuaSpellInfo::IsPrimaryProfession;
+    type["IsPrimaryProfessionFirstRank"]           = &LuaSpellInfo::IsPrimaryProfessionFirstRank;
+    type["IsAbilityLearnedWithProfession"]         = &LuaSpellInfo::IsAbilityLearnedWithProfession;
+    type["IsAbilityOfSkillType"]                   = &LuaSpellInfo::IsAbilityOfSkillType;
+    type["IsTargetingArea"]                        = &LuaSpellInfo::IsTargetingArea;
+    type["NeedsExplicitUnitTarget"]                = &LuaSpellInfo::NeedsExplicitUnitTarget;
+    type["NeedsToBeTriggeredByCaster"]             = &LuaSpellInfo::NeedsToBeTriggeredByCaster;
+    type["IsSelfCast"]                             = &LuaSpellInfo::IsSelfCast;
+    type["IsPassive"]                              = &LuaSpellInfo::IsPassive;
+    type["IsAutocastable"]                         = &LuaSpellInfo::IsAutocastable;
+    type["IsStackableWithRanks"]                   = &LuaSpellInfo::IsStackableWithRanks;
+    type["IsPassiveStackableWithRanks"]            = &LuaSpellInfo::IsPassiveStackableWithRanks;
+    type["IsMultiSlotAura"]                        = &LuaSpellInfo::IsMultiSlotAura;
+    type["IsCooldownStartedOnEvent"]               = &LuaSpellInfo::IsCooldownStartedOnEvent;
+    type["IsDeathPersistent"]                      = &LuaSpellInfo::IsDeathPersistent;
+    type["IsRequiringDeadTarget"]                  = &LuaSpellInfo::IsRequiringDeadTarget;
+    type["IsAllowingDeadTarget"]                   = &LuaSpellInfo::IsAllowingDeadTarget;
+    type["CanBeUsedInCombat"]                      = &LuaSpellInfo::CanBeUsedInCombat;
+    type["IsPositive"]                             = &LuaSpellInfo::IsPositive;
+    type["IsPositiveEffect"]                       = &LuaSpellInfo::IsPositiveEffect;
+    type["IsChanneled"]                            = &LuaSpellInfo::IsChanneled;
+    type["NeedsComboPoints"]                       = &LuaSpellInfo::NeedsComboPoints;
+    type["IsBreakingStealth"]                      = &LuaSpellInfo::IsBreakingStealth;
+    type["IsRangedWeaponSpell"]                    = &LuaSpellInfo::IsRangedWeaponSpell;
+    type["IsAutoRepeatRangedSpell"]                = &LuaSpellInfo::IsAutoRepeatRangedSpell;
+    type["IsAffectedBySpellMods"]                  = &LuaSpellInfo::IsAffectedBySpellMods;
+    type["CanPierceImmuneAura"]                    = &LuaSpellInfo::CanPierceImmuneAura;
+    type["CanDispelAura"]                          = &LuaSpellInfo::CanDispelAura;
+    type["IsSingleTarget"]                         = &LuaSpellInfo::IsSingleTarget;
+    type["IsAuraExclusiveBySpecificWith"]          = &LuaSpellInfo::IsAuraExclusiveBySpecificWith;
+    type["IsAuraExclusiveBySpecificPerCasterWith"] = &LuaSpellInfo::IsAuraExclusiveBySpecificPerCasterWith;
+    type["CheckShapeshift"]                        = &LuaSpellInfo::CheckShapeshift;
+    type["CheckLocation"]                          = ALEBind::Function(&LuaSpellInfo::CheckLocation);
+    type["CheckTarget"]                            = ALEBind::Function(&LuaSpellInfo::CheckTarget);
+    type["CheckExplicitTarget"]                    = ALEBind::Function(&LuaSpellInfo::CheckExplicitTarget);
+    type["CheckTargetCreatureType"]                = ALEBind::Function(&LuaSpellInfo::CheckTargetCreatureType);
+    type["GetSchoolMask"]                          = &LuaSpellInfo::GetSchoolMask;
+    type["GetAllEffectsMechanicMask"]              = &LuaSpellInfo::GetAllEffectsMechanicMask;
+    type["GetEffectMechanicMask"]                  = &LuaSpellInfo::GetEffectMechanicMask;
+    type["GetSpellMechanicMaskByEffectMask"]       = &LuaSpellInfo::GetSpellMechanicMaskByEffectMask;
+    type["GetEffectMechanic"]                      = &LuaSpellInfo::GetEffectMechanic;
+    type["GetDispelMask"]                          = &LuaSpellInfo::GetDispelMask;
+    type["GetExplicitTargetMask"]                  = &LuaSpellInfo::GetExplicitTargetMask;
+    type["GetAuraState"]                           = &LuaSpellInfo::GetAuraState;
+    type["GetSpellSpecific"]                       = &LuaSpellInfo::GetSpellSpecific;
+    type["GetEffectMiscValueA"]                    = &LuaSpellInfo::GetEffectMiscValueA;
+    type["GetEffectMiscValueB"]                    = &LuaSpellInfo::GetEffectMiscValueB;
+}
diff --git a/src/LuaEngine/methods/SpellMethods.h b/src/LuaEngine/methods/SpellMethods.cpp
similarity index 54%
rename from src/LuaEngine/methods/SpellMethods.h
rename to src/LuaEngine/methods/SpellMethods.cpp
index 52c14ef79a..9a80bb7fed 100644
--- a/src/LuaEngine/methods/SpellMethods.h
+++ b/src/LuaEngine/methods/SpellMethods.cpp
@@ -4,8 +4,11 @@
 * Please see the included DOCS/LICENSE.md for more information
 */
 
-#ifndef SPELLMETHODS_H
-#define SPELLMETHODS_H
+#include "ALEBind.h"
+
+#include "ObjectMgr.h"
+#include "Spell.h"
+#include "SpellInfo.h"
 
 /***
  * An instance of a spell, created when the spell is cast by a [Unit].
@@ -19,10 +22,9 @@ namespace LuaSpell
      *
      * @return bool isAutoRepeating
      */
-    int IsAutoRepeat(lua_State* L, Spell* spell)
+    bool IsAutoRepeat(Spell* spell)
     {
-        ALE::Push(L, spell->IsAutoRepeat());
-        return 1;
+        return spell->IsAutoRepeat();
     }
 
     /**
@@ -30,10 +32,9 @@ namespace LuaSpell
      *
      * @return [Unit] caster
      */
-    int GetCaster(lua_State* L, Spell* spell)
+    Unit* GetCaster(Spell* spell)
     {
-        ALE::Push(L, spell->GetCaster());
-        return 1;
+        return spell->GetCaster();
     }
 
     /**
@@ -41,10 +42,9 @@ namespace LuaSpell
      *
      * @return int32 castTime
      */
-    int GetCastTime(lua_State* L, Spell* spell)
+    int32 GetCastTime(Spell* spell)
     {
-        ALE::Push(L, spell->GetCastTime());
-        return 1;
+        return spell->GetCastTime();
     }
 
     /**
@@ -52,10 +52,9 @@ namespace LuaSpell
      *
      * @return uint32 entryId
      */
-    int GetEntry(lua_State* L, Spell* spell)
+    uint32 GetEntry(Spell* spell)
     {
-        ALE::Push(L, spell->m_spellInfo->Id);
-        return 1;
+        return spell->m_spellInfo->Id;
     }
 
     /**
@@ -63,10 +62,9 @@ namespace LuaSpell
      *
      * @return uint32 powerCost
      */
-    int GetPowerCost(lua_State* L, Spell* spell)
+    uint32 GetPowerCost(Spell* spell)
     {
-        ALE::Push(L, spell->GetPowerCost());
-        return 1;
+        return spell->GetPowerCost();
     }
 
     /**
@@ -74,23 +72,21 @@ namespace LuaSpell
      *
      * @return table reagents : a table containing the [ItemTemplate]s and amount of reagents needed for the [Spell]
     */
-    int GetReagentCost(lua_State* L, Spell* spell)
+    sol::table GetReagentCost(Spell* spell, sol::this_state s)
     {
         auto spellInfo = spell->GetSpellInfo();
         auto reagents = spellInfo->Reagent;
         auto reagentCounts = spellInfo->ReagentCount;
-        lua_newtable(L);
+        sol::table tbl = sol::state_view(s).create_table();
         for (auto i = 0; i < MAX_SPELL_REAGENTS; ++i)
         {
             if (reagents[i] <= 0)
                 continue;
-            auto reagent = eObjectMgr->GetItemTemplate(reagents[i]);
+            auto reagent = sObjectMgr->GetItemTemplate(reagents[i]);
             auto count = reagentCounts[i];
-            ALE::Push(L, reagent);
-            ALE::Push(L, count);
-            lua_settable(L, -3);
+            tbl[reagent] = count;
         }
-        return 1;
+        return tbl;
     }
 
     /**
@@ -98,10 +94,9 @@ namespace LuaSpell
      *
      * @return int32 duration
      */
-    int GetDuration(lua_State* L, Spell* spell)
+    int32 GetDuration(Spell* spell)
     {
-        ALE::Push(L, spell->GetSpellInfo()->GetDuration());
-        return 1;
+        return spell->GetSpellInfo()->GetDuration();
     }
 
     /**
@@ -111,17 +106,14 @@ namespace LuaSpell
      * @return float y : y coordinate of the [Spell]
      * @return float z : z coordinate of the [Spell]
      */
-    int GetTargetDest(lua_State* L, Spell* spell)
+    std::tuple, sol::optional, sol::optional> GetTargetDest(Spell* spell)
     {
         if (!spell->m_targets.HasDst())
-            return 3;
+            return { sol::nullopt, sol::nullopt, sol::nullopt };
         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;
+        return { x, y, z };
     }
 
     /**
@@ -136,19 +128,20 @@ namespace LuaSpell
      *
      * @return [Object] target
      */
-    int GetTarget(lua_State* L, Spell* spell)
+    sol::object GetTarget(Spell* spell, sol::this_state s)
     {
+        sol::state_view lua(s);
         if (GameObject* target = spell->m_targets.GetGOTarget())
-            ALE::Push(L, target);
+            return sol::make_object(lua, GameObjectRef(target));
         else if (Item* target = spell->m_targets.GetItemTarget())
-            ALE::Push(L, target);
+            return sol::make_object(lua, ItemRef(target));
         else if (Corpse* target = spell->m_targets.GetCorpseTarget())
-            ALE::Push(L, target);
+            return sol::make_object(lua, CorpseRef(target));
         else if (Unit* target = spell->m_targets.GetUnitTarget())
-            ALE::Push(L, target);
+            return ALEBind::ToLuaDynamic(lua, target);
         else if (WorldObject* target = spell->m_targets.GetObjectTarget())
-            ALE::Push(L, target);
-        return 1;
+            return ALEBind::ToLuaDynamic(lua, target);
+        return sol::make_object(lua, sol::lua_nil);
     }
 
     /**
@@ -156,11 +149,9 @@ namespace LuaSpell
      *
      * @param bool repeat : set variable to 'true' for spell to automatically repeat
      */
-    int SetAutoRepeat(lua_State* L, Spell* spell)
+    void SetAutoRepeat(Spell* spell, bool repeat)
     {
-        bool repeat = ALE::CHECKVAL(L, 2);
         spell->SetAutoRepeat(repeat);
-        return 0;
     }
 
     /**
@@ -168,29 +159,43 @@ namespace LuaSpell
      *
      * @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)
+    void Cast(Spell* spell, sol::optional skipCheck)
     {
-        bool skipCheck = ALE::CHECKVAL(L, 2, false);
-        spell->cast(skipCheck);
-        return 0;
+        spell->cast(skipCheck.value_or(false));
     }
 
     /**
      * Cancels the [Spell].
      */
-    int Cancel(lua_State* /*L*/, Spell* spell)
+    void Cancel(Spell* spell)
     {
         spell->cancel();
-        return 0;
     }
 
     /**
      * Finishes the [Spell].
      */
-    int Finish(lua_State* /*L*/, Spell* spell)
+    void Finish(Spell* spell)
     {
         spell->finish();
-        return 0;
     }
-};
-#endif
+}
+
+void RegisterSpellMethods(sol::state& lua)
+{
+    sol::usertype> type = ALEBind::NewHandleType>(lua, "Spell");
+
+    type["IsAutoRepeat"]   = ALEBind::Method(&LuaSpell::IsAutoRepeat);
+    type["GetCaster"]      = ALEBind::Method(&LuaSpell::GetCaster);
+    type["GetCastTime"]    = ALEBind::Method(&LuaSpell::GetCastTime);
+    type["GetEntry"]       = ALEBind::Method(&LuaSpell::GetEntry);
+    type["GetPowerCost"]   = ALEBind::Method(&LuaSpell::GetPowerCost);
+    type["GetReagentCost"] = ALEBind::Method(&LuaSpell::GetReagentCost);
+    type["GetDuration"]    = ALEBind::Method(&LuaSpell::GetDuration);
+    type["GetTargetDest"]  = ALEBind::Method(&LuaSpell::GetTargetDest);
+    type["GetTarget"]      = ALEBind::Method(&LuaSpell::GetTarget);
+    type["SetAutoRepeat"]  = ALEBind::Method(&LuaSpell::SetAutoRepeat);
+    type["Cast"]           = ALEBind::Method(&LuaSpell::Cast);
+    type["Cancel"]         = ALEBind::Method(&LuaSpell::Cancel);
+    type["Finish"]         = ALEBind::Method(&LuaSpell::Finish);
+}
diff --git a/src/LuaEngine/methods/TicketMethods.cpp b/src/LuaEngine/methods/TicketMethods.cpp
new file mode 100644
index 0000000000..4d24da5ac5
--- /dev/null
+++ b/src/LuaEngine/methods/TicketMethods.cpp
@@ -0,0 +1,308 @@
+/*
+* 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 "ALEBind.h"
+
+#include "TicketMgr.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
+     */
+    bool IsClosed(GmTicket* ticket)
+    {
+        return ticket->IsClosed();
+    }
+
+    /**
+     * Returns true if the [Ticket] is completed or false.
+     *
+     * @return bool isCompleted
+     */
+    bool IsCompleted(GmTicket* ticket)
+    {
+        return ticket->IsCompleted();
+    }
+
+    /**
+     * Return true if this GUID is the same as the [Player] who created the [Ticket] or false.
+     *
+     * @param ObjectGuid playerGuid
+     *
+     * @return bool isSamePlayer
+     */
+    bool IsFromPlayer(GmTicket* ticket, ObjectGuid guid)
+    {
+        return ticket->IsFromPlayer(guid);
+    }
+
+    /**
+     * Return true if the [Ticket] is assigned or false.
+     *
+     * @return bool isAssigned
+     */
+    bool IsAssigned(GmTicket* ticket)
+    {
+        return ticket->IsAssigned();
+    }
+
+    /**
+     * Return true if the [Ticket] is assigned to the [Player] or false.
+     *
+     * @param ObjectGuid playerGuid
+     *
+     * @return bool isAssignedTo
+     */
+    bool IsAssignedTo(GmTicket* ticket, ObjectGuid guid)
+    {
+        return ticket->IsAssignedTo(guid);
+    }
+
+    /**
+     * Return true if the [Ticket] is not assigned to the [Player] or false.
+     *
+     * @param ObjectGuid playerGuid
+     *
+     * @return bool isAssignedNotTo
+     */
+    bool IsAssignedNotTo(GmTicket* ticket, ObjectGuid guid)
+    {
+        return ticket->IsAssignedNotTo(guid);
+    }
+
+    /**
+     * Return the [Ticket] id.
+     *
+     * @return uint32 ticketId
+     */
+    uint32 GetId(GmTicket* ticket)
+    {
+        return ticket->GetId();
+    }
+
+    /**
+     * Return the [Player] from the [Ticket].
+     *
+     * @return [Player] player
+     */
+    Player* GetPlayer(GmTicket* ticket)
+    {
+        return ticket->GetPlayer();
+    }
+
+    /**
+     * Return the [Player] name from the [Ticket].
+     *
+     * @return string playerName
+     */
+    std::string GetPlayerName(GmTicket* ticket)
+    {
+        return ticket->GetPlayerName();
+    }
+
+    /**
+     * Returns the message sent in the [Ticket].
+     *
+     * @return string message
+     */
+    std::string GetMessage(GmTicket* ticket)
+    {
+        return ticket->GetMessage();
+    }
+
+    /**
+     * Returns the assigned [Player].
+     *
+     * @return [Player] assignedPlayer
+     */
+    Player* GetAssignedPlayer(GmTicket* ticket)
+    {
+        return ticket->GetAssignedPlayer();
+    }
+
+    /**
+     * Returns the assigned guid.
+     *
+     * @return uint32 assignedGuid
+     */
+    ObjectGuid GetAssignedToGUID(GmTicket* ticket)
+    {
+        return ticket->GetAssignedToGUID();
+    }
+
+    /**
+     * Returns the last modified time from the [Ticket].
+     *
+     * @return uint64 lastModifiedTime
+     */
+    uint64 GetLastModifiedTime(GmTicket* ticket)
+    {
+        return ticket->GetLastModifiedTime();
+    }
+
+    /**
+     * 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)
+     */
+    void SetAssignedTo(GmTicket* ticket, ObjectGuid guid, sol::optional isAdmin)
+    {
+        ticket->SetAssignedTo(guid, isAdmin.value_or(false));
+    }
+
+    /**
+     * Set [Ticket] resolved by player via his GUID.
+     *
+     * @param ObjectGuid playerGuid
+     */
+    void SetResolvedBy(GmTicket* ticket, ObjectGuid guid)
+    {
+        ticket->SetResolvedBy(guid);
+    }
+
+    /**
+     * Set [Ticket] completed.
+     *
+     */
+    void SetCompleted(GmTicket* ticket)
+    {
+        ticket->SetCompleted();
+    }
+
+    /**
+     * Set [Ticket] message.
+     *
+     * @param string message: desired message
+     *
+     */
+    void SetMessage(GmTicket* ticket, std::string message)
+    {
+        ticket->SetMessage(message);
+    }
+
+    /**
+     * Set [Ticket] comment.
+     *
+     * @param string comment: desired comment
+     *
+     */
+    void SetComment(GmTicket* ticket, std::string comment)
+    {
+        ticket->SetComment(comment);
+    }
+
+    /**
+     * Set [Ticket] as viewed.
+     *
+     */
+    void SetViewed(GmTicket* ticket)
+    {
+        ticket->SetViewed();
+    }
+
+    /**
+     * Set [Ticket] as unassigned.
+     *
+     */
+    void SetUnassigned(GmTicket* ticket)
+    {
+        ticket->SetUnassigned();
+    }
+
+    /**
+     * Set the new [Ticket] creation position.
+     *
+     * @param uint32 mapId
+     * @param float x
+     * @param float y
+     * @param float z
+     *
+     */
+    void SetPosition(GmTicket* ticket, uint32 mapId, float x, float y, float z)
+    {
+        ticket->SetPosition(mapId, x, y, z);
+    }
+
+    /**
+     * Adds a response to the [Ticket].
+     *
+     * @param string response: desired response
+     *
+     */
+    void AppendResponse(GmTicket* ticket, std::string response)
+    {
+        ticket->AppendResponse(response);
+    }
+
+    /**
+     * Return the [Ticket] response.
+     *
+     * @return string response
+     */
+    std::string GetResponse(GmTicket* ticket)
+    {
+        return ticket->GetResponse();
+    }
+
+    /**
+     * Delete the [Ticket] response.
+     *
+     */
+    void DeleteResponse(GmTicket* ticket)
+    {
+        ticket->DeleteResponse();
+    }
+
+    /**
+     * Return the [Ticket] chatlog.
+     *
+     * @return string chatlog
+     */
+    std::string GetChatLog(GmTicket* ticket)
+    {
+        return ticket->GetChatLog();
+    }
+}
+
+void RegisterTicketMethods(sol::state& lua)
+{
+    sol::usertype> type = ALEBind::NewHandleType>(lua, "Ticket");
+
+    type["IsClosed"]            = ALEBind::Method(&LuaTicket::IsClosed);
+    type["IsCompleted"]         = ALEBind::Method(&LuaTicket::IsCompleted);
+    type["IsFromPlayer"]        = ALEBind::Method(&LuaTicket::IsFromPlayer);
+    type["IsAssigned"]          = ALEBind::Method(&LuaTicket::IsAssigned);
+    type["IsAssignedTo"]        = ALEBind::Method(&LuaTicket::IsAssignedTo);
+    type["IsAssignedNotTo"]     = ALEBind::Method(&LuaTicket::IsAssignedNotTo);
+    type["GetId"]               = ALEBind::Method(&LuaTicket::GetId);
+    type["GetPlayer"]           = ALEBind::Method(&LuaTicket::GetPlayer);
+    type["GetPlayerName"]       = ALEBind::Method(&LuaTicket::GetPlayerName);
+    type["GetMessage"]          = ALEBind::Method(&LuaTicket::GetMessage);
+    type["GetAssignedPlayer"]   = ALEBind::Method(&LuaTicket::GetAssignedPlayer);
+    type["GetAssignedToGUID"]   = ALEBind::Method(&LuaTicket::GetAssignedToGUID);
+    type["GetLastModifiedTime"] = ALEBind::Method(&LuaTicket::GetLastModifiedTime);
+    type["SetAssignedTo"]       = ALEBind::Method(&LuaTicket::SetAssignedTo);
+    type["SetResolvedBy"]       = ALEBind::Method(&LuaTicket::SetResolvedBy);
+    type["SetCompleted"]        = ALEBind::Method(&LuaTicket::SetCompleted);
+    type["SetMessage"]          = ALEBind::Method(&LuaTicket::SetMessage);
+    type["SetComment"]          = ALEBind::Method(&LuaTicket::SetComment);
+    type["SetViewed"]           = ALEBind::Method(&LuaTicket::SetViewed);
+    type["SetUnassigned"]       = ALEBind::Method(&LuaTicket::SetUnassigned);
+    type["SetPosition"]         = ALEBind::Method(&LuaTicket::SetPosition);
+    type["AppendResponse"]      = ALEBind::Method(&LuaTicket::AppendResponse);
+    type["GetResponse"]         = ALEBind::Method(&LuaTicket::GetResponse);
+    type["DeleteResponse"]      = ALEBind::Method(&LuaTicket::DeleteResponse);
+    type["GetChatLog"]          = ALEBind::Method(&LuaTicket::GetChatLog);
+}
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/TransportMethods.h b/src/LuaEngine/methods/TransportMethods.cpp
similarity index 56%
rename from src/LuaEngine/methods/TransportMethods.h
rename to src/LuaEngine/methods/TransportMethods.cpp
index 941ce6732a..429eab72e4 100644
--- a/src/LuaEngine/methods/TransportMethods.h
+++ b/src/LuaEngine/methods/TransportMethods.cpp
@@ -4,8 +4,7 @@
 * Please see the included DOCS/LICENSE.md for more information
 */
 
-#ifndef TRANSPORTMETHODS_H
-#define TRANSPORTMETHODS_H
+#include "ALEBind.h"
 
 #include "Transport.h"
 
@@ -21,17 +20,17 @@ namespace LuaTransport
      *
      * @return table passengers
      */
-    int GetPassengers(lua_State* L, Transport* transport)
+    sol::table GetPassengers(Transport* transport, sol::this_state s)
     {
+        sol::state_view lua(s);
+        sol::table tbl = lua.create_table();
+
         Transport::PassengerSet const& passengers = transport->GetPassengers();
-        lua_createtable(L, static_cast(passengers.size()), 0);
         int i = 1;
         for (WorldObject* passenger : passengers)
-        {
-            ALE::Push(L, passenger);
-            lua_rawseti(L, -2, i++);
-        }
-        return 1;
+            tbl[i++] = ALEBind::ToLuaDynamic(lua, passenger);
+
+        return tbl;
     }
 
     /**
@@ -39,10 +38,9 @@ namespace LuaTransport
      *
      * @return bool isMotionTransport
      */
-    int IsMotionTransport(lua_State* L, Transport* transport)
+    bool IsMotionTransport(Transport* transport)
     {
-        ALE::Push(L, dynamic_cast(transport) != nullptr);
-        return 1;
+        return dynamic_cast(transport) != nullptr;
     }
 
     /**
@@ -51,12 +49,9 @@ namespace LuaTransport
      * @param [WorldObject] passenger : the object to add as a passenger
      * @param bool withAll = true : if true, also sets transport movement info on the passenger
      */
-    int AddPassenger(lua_State* L, Transport* transport)
+    void AddPassenger(Transport* transport, WorldObject* passenger, sol::optional withAll)
     {
-        WorldObject* passenger = ALE::CHECKOBJ(L, 2);
-        bool withAll = ALE::CHECKVAL(L, 3, true);
-        transport->AddPassenger(passenger, withAll);
-        return 0;
+        transport->AddPassenger(passenger, withAll.value_or(true));
     }
 
     /**
@@ -65,12 +60,9 @@ namespace LuaTransport
      * @param [WorldObject] passenger : the object to remove
      * @param bool withAll = true : if true, also clears transport movement info from the passenger
      */
-    int RemovePassenger(lua_State* L, Transport* transport)
+    void RemovePassenger(Transport* transport, WorldObject* passenger, sol::optional withAll)
     {
-        WorldObject* passenger = ALE::CHECKOBJ(L, 2);
-        bool withAll = ALE::CHECKVAL(L, 3, true);
-        transport->RemovePassenger(passenger, withAll);
-        return 0;
+        transport->RemovePassenger(passenger, withAll.value_or(true));
     }
 
     /**
@@ -80,14 +72,21 @@ namespace LuaTransport
      *
      * @param bool enabled : true to enable movement, false to stop
      */
-    int EnableMovement(lua_State* L, Transport* transport)
+    void EnableMovement(Transport* transport, bool enabled)
     {
-        bool enabled = ALE::CHECKVAL(L, 2);
         MotionTransport* mt = dynamic_cast(transport);
         if (mt)
             mt->EnableMovement(enabled);
-        return 0;
     }
 }
 
-#endif
+void RegisterTransportMethods(sol::state& lua)
+{
+    sol::usertype type = ALEBind::NewHandleType(lua, "Transport");
+
+    type["GetPassengers"]     = ALEBind::Method(&LuaTransport::GetPassengers);
+    type["IsMotionTransport"] = ALEBind::Method(&LuaTransport::IsMotionTransport);
+    type["AddPassenger"]      = ALEBind::Method(&LuaTransport::AddPassenger);
+    type["RemovePassenger"]   = ALEBind::Method(&LuaTransport::RemovePassenger);
+    type["EnableMovement"]    = ALEBind::Method(&LuaTransport::EnableMovement);
+}
diff --git a/src/LuaEngine/methods/UnitMethods.h b/src/LuaEngine/methods/UnitMethods.cpp
similarity index 58%
rename from src/LuaEngine/methods/UnitMethods.h
rename to src/LuaEngine/methods/UnitMethods.cpp
index 1ded5af420..2806b7526c 100644
--- a/src/LuaEngine/methods/UnitMethods.h
+++ b/src/LuaEngine/methods/UnitMethods.cpp
@@ -4,8 +4,21 @@
 * Please see the included DOCS/LICENSE.md for more information
 */
 
-#ifndef UNITMETHODS_H
-#define UNITMETHODS_H
+#include "ALEBind.h"
+#include "ALEUtility.h"
+
+#include "CellImpl.h"
+#include "Chat.h"
+#include "DBCStores.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
+#include "MotionMaster.h"
+#include "Player.h"
+#include "SpellInfo.h"
+#include "SpellMgr.h"
+#include "Unit.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
 
 /***
  * Represents a non-[Player] controlled [Unit] (i.e. NPCs).
@@ -55,15 +68,13 @@ namespace LuaUnit
     * @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)
+    void SetImmuneTo(Unit* unit, int32 immunity, sol::optional applyArg)
     {
-        int32 immunity = ALE::CHECKVAL(L, 2);
-        bool apply = ALE::CHECKVAL(L, 3, true);
+        bool apply = applyArg.value_or(true);
 
         unit->ApplySpellImmune(0, 5, immunity, apply);
-        return 0;
     }
-    
+
     /**
      * The [Unit] modifies a specific stat
      *
@@ -73,16 +84,11 @@ namespace LuaUnit
      * @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)
+    bool HandleStatFlatModifier(Unit* unit, int32 stat, int8 type, float value, sol::optional applyArg)
     {
-        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);
+        bool apply = applyArg.value_or(false);
 
-        ALE::Push(L, unit->HandleStatFlatModifier(UnitMods(UNIT_MOD_STAT_START + stat), (UnitModifierFlatType)type, value, apply));
-        return 1;
+        return unit->HandleStatFlatModifier(UnitMods(UNIT_MOD_STAT_START + stat), (UnitModifierFlatType)type, value, apply);
     }
 
     /**
@@ -92,13 +98,11 @@ namespace LuaUnit
      * @param bool meleeAttack = false: attack with melee or not
      * @return didAttack : if the [Unit] did not attack
      */
-    int Attack(lua_State* L, Unit* unit)
+    bool Attack(Unit* unit, Unit* who, sol::optional meleeAttackArg)
     {
-        Unit* who = ALE::CHECKOBJ(L, 2);
-        bool meleeAttack = ALE::CHECKVAL(L, 3, false);
+        bool meleeAttack = meleeAttackArg.value_or(false);
 
-        ALE::Push(L, unit->Attack(who, meleeAttack));
-        return 1;
+        return unit->Attack(who, meleeAttack);
     }
 
     /**
@@ -106,10 +110,9 @@ namespace LuaUnit
      *
      * @return bool isAttacking : if the [Unit] wasn't attacking already
      */
-    int AttackStop(lua_State* L, Unit* unit)
+    bool AttackStop(Unit* unit)
     {
-        ALE::Push(L, unit->AttackStop());
-        return 1;
+        return unit->AttackStop();
     }
 
     /**
@@ -117,10 +120,9 @@ namespace LuaUnit
      *
      * @return bool isStanding
      */
-    int IsStandState(lua_State* L, Unit* unit)
+    bool IsStandState(Unit* unit)
     {
-        ALE::Push(L, unit->IsStandState());
-        return 1;
+        return unit->IsStandState();
     }
 
     /**
@@ -128,10 +130,9 @@ namespace LuaUnit
      *
      * @return bool isMounted
      */
-    int IsMounted(lua_State* L, Unit* unit)
+    bool IsMounted(Unit* unit)
     {
-        ALE::Push(L, unit->IsMounted());
-        return 1;
+        return unit->IsMounted();
     }
 
     /**
@@ -139,11 +140,9 @@ namespace LuaUnit
      *
      * @return bool isRooted
      */
-    int IsRooted(lua_State* L, Unit* unit)
+    bool IsRooted(Unit* unit)
     {
-        ALE::Push(L, unit->HasRootAura() || unit->HasUnitMovementFlag(MOVEMENTFLAG_ROOT));
-
-        return 1;
+        return unit->HasRootAura() || unit->HasUnitMovementFlag(MOVEMENTFLAG_ROOT);
     }
 
     /**
@@ -151,10 +150,9 @@ namespace LuaUnit
      *
      * @return bool hasFullHealth
      */
-    int IsFullHealth(lua_State* L, Unit* unit)
+    bool IsFullHealth(Unit* unit)
     {
-        ALE::Push(L, unit->IsFullHealth());
-        return 1;
+        return unit->IsFullHealth();
     }
 
     /**
@@ -164,13 +162,9 @@ namespace LuaUnit
      * @param float radius
      * @return bool isAccessible
      */
-    int IsInAccessiblePlaceFor(lua_State* L, Unit* unit)
+    bool IsInAccessiblePlaceFor(Unit* unit, Creature* creature)
     {
-        Creature* creature = ALE::CHECKOBJ(L, 2);
-
-        ALE::Push(L, unit->isInAccessiblePlaceFor(creature));
-
-        return 1;
+        return unit->isInAccessiblePlaceFor(creature);
     }
 
     /**
@@ -178,11 +172,9 @@ namespace LuaUnit
      *
      * @return bool isAuctioneer
      */
-    int IsAuctioneer(lua_State* L, Unit* unit)
+    bool IsAuctioneer(Unit* unit)
     {
-        ALE::Push(L, unit->IsAuctioner());
-
-        return 1;
+        return unit->IsAuctioner();
     }
 
     /**
@@ -190,10 +182,9 @@ namespace LuaUnit
      *
      * @return bool isGuildMaster
      */
-    int IsGuildMaster(lua_State* L, Unit* unit)
+    bool IsGuildMaster(Unit* unit)
     {
-        ALE::Push(L, unit->IsGuildMaster());
-        return 1;
+        return unit->IsGuildMaster();
     }
 
     /**
@@ -201,10 +192,9 @@ namespace LuaUnit
      *
      * @return bool isInnkeeper
      */
-    int IsInnkeeper(lua_State* L, Unit* unit)
+    bool IsInnkeeper(Unit* unit)
     {
-        ALE::Push(L, unit->IsInnkeeper());
-        return 1;
+        return unit->IsInnkeeper();
     }
 
     /**
@@ -212,10 +202,9 @@ namespace LuaUnit
      *
      * @return bool isTrainer
      */
-    int IsTrainer(lua_State* L, Unit* unit)
+    bool IsTrainer(Unit* unit)
     {
-        ALE::Push(L, unit->IsTrainer());
-        return 1;
+        return unit->IsTrainer();
     }
 
     /**
@@ -223,10 +212,9 @@ namespace LuaUnit
      *
      * @return bool hasGossip
      */
-    int IsGossip(lua_State* L, Unit* unit)
+    bool IsGossip(Unit* unit)
     {
-        ALE::Push(L, unit->IsGossip());
-        return 1;
+        return unit->IsGossip();
     }
 
     /**
@@ -234,10 +222,9 @@ namespace LuaUnit
      *
      * @return bool isTaxi
      */
-    int IsTaxi(lua_State* L, Unit* unit)
+    bool IsTaxi(Unit* unit)
     {
-        ALE::Push(L, unit->IsTaxi());
-        return 1;
+        return unit->IsTaxi();
     }
 
     /**
@@ -245,10 +232,9 @@ namespace LuaUnit
      *
      * @return bool isSpiritHealer
      */
-    int IsSpiritHealer(lua_State* L, Unit* unit)
+    bool IsSpiritHealer(Unit* unit)
     {
-        ALE::Push(L, unit->IsSpiritHealer());
-        return 1;
+        return unit->IsSpiritHealer();
     }
 
     /**
@@ -256,10 +242,9 @@ namespace LuaUnit
      *
      * @return bool isSpiritGuide
      */
-    int IsSpiritGuide(lua_State* L, Unit* unit)
+    bool IsSpiritGuide(Unit* unit)
     {
-        ALE::Push(L, unit->IsSpiritGuide());
-        return 1;
+        return unit->IsSpiritGuide();
     }
 
     /**
@@ -267,10 +252,9 @@ namespace LuaUnit
      *
      * @return bool isTabardDesigner
      */
-    int IsTabardDesigner(lua_State* L, Unit* unit)
+    bool IsTabardDesigner(Unit* unit)
     {
-        ALE::Push(L, unit->IsTabardDesigner());
-        return 1;
+        return unit->IsTabardDesigner();
     }
 
     /**
@@ -278,10 +262,9 @@ namespace LuaUnit
      *
      * @return bool isTabardDesigner
      */
-    int IsServiceProvider(lua_State* L, Unit* unit)
+    bool IsServiceProvider(Unit* unit)
     {
-        ALE::Push(L, unit->IsServiceProvider());
-        return 1;
+        return unit->IsServiceProvider();
     }
 
     /**
@@ -289,10 +272,9 @@ namespace LuaUnit
      *
      * @return bool isSpiritService
      */
-    int IsSpiritService(lua_State* L, Unit* unit)
+    bool IsSpiritService(Unit* unit)
     {
-        ALE::Push(L, unit->IsSpiritService());
-        return 1;
+        return unit->IsSpiritService();
     }
 
     /**
@@ -300,10 +282,9 @@ namespace LuaUnit
      *
      * @return bool isAlive
      */
-    int IsAlive(lua_State* L, Unit* unit)
+    bool IsAlive(Unit* unit)
     {
-        ALE::Push(L, unit->IsAlive());
-        return 1;
+        return unit->IsAlive();
     }
 
     /**
@@ -311,10 +292,9 @@ namespace LuaUnit
      *
      * @return bool isDead
      */
-    int IsDead(lua_State* L, Unit* unit)
+    bool IsDead(Unit* unit)
     {
-        ALE::Push(L, unit->isDead());
-        return 1;
+        return unit->isDead();
     }
 
     /**
@@ -322,10 +302,9 @@ namespace LuaUnit
      *
      * @return bool isDying
      */
-    int IsDying(lua_State* L, Unit* unit)
+    bool IsDying(Unit* unit)
     {
-        ALE::Push(L, unit->isDying());
-        return 1;
+        return unit->isDying();
     }
 
     /**
@@ -333,10 +312,9 @@ namespace LuaUnit
      *
      * @return bool isBanker
      */
-    int IsBanker(lua_State* L, Unit* unit)
+    bool IsBanker(Unit* unit)
     {
-        ALE::Push(L, unit->IsBanker());
-        return 1;
+        return unit->IsBanker();
     }
 
     /**
@@ -344,10 +322,9 @@ namespace LuaUnit
      *
      * @return bool isVendor
      */
-    int IsVendor(lua_State* L, Unit* unit)
+    bool IsVendor(Unit* unit)
     {
-        ALE::Push(L, unit->IsVendor());
-        return 1;
+        return unit->IsVendor();
     }
 
     /**
@@ -355,10 +332,9 @@ namespace LuaUnit
      *
      * @return bool isBattleMaster
      */
-    int IsBattleMaster(lua_State* L, Unit* unit)
+    bool IsBattleMaster(Unit* unit)
     {
-        ALE::Push(L, unit->IsBattleMaster());
-        return 1;
+        return unit->IsBattleMaster();
     }
 
     /**
@@ -366,10 +342,9 @@ namespace LuaUnit
      *
      * @return bool isCharmed
      */
-    int IsCharmed(lua_State* L, Unit* unit)
+    bool IsCharmed(Unit* unit)
     {
-        ALE::Push(L, unit->IsCharmed());
-        return 1;
+        return unit->IsCharmed();
     }
 
     /**
@@ -377,10 +352,9 @@ namespace LuaUnit
      *
      * @return bool isArmorer
      */
-    int IsArmorer(lua_State* L, Unit* unit)
+    bool IsArmorer(Unit* unit)
     {
-        ALE::Push(L, unit->IsArmorer());
-        return 1;
+        return unit->IsArmorer();
     }
 
     /**
@@ -388,10 +362,9 @@ namespace LuaUnit
      *
      * @return bool isAttackingPlayer
      */
-    int IsAttackingPlayer(lua_State* L, Unit* unit)
+    bool IsAttackingPlayer(Unit* unit)
     {
-        ALE::Push(L, unit->isAttackingPlayer());
-        return 1;
+        return unit->isAttackingPlayer();
     }
 
     /**
@@ -399,10 +372,9 @@ namespace LuaUnit
      *
      * @return bool isPvP
      */
-    int IsPvPFlagged(lua_State* L, Unit* unit)
+    bool IsPvPFlagged(Unit* unit)
     {
-        ALE::Push(L, unit->IsPvP());
-        return 1;
+        return unit->IsPvP();
     }
 
     /**
@@ -410,10 +382,9 @@ namespace LuaUnit
      *
      * @return bool isOnVehicle
      */
-    int IsOnVehicle(lua_State* L, Unit* unit)
+    Vehicle* IsOnVehicle(Unit* unit)
     {
-        ALE::Push(L, unit->GetVehicle());
-        return 1;
+        return unit->GetVehicle();
     }
 
     /**
@@ -421,10 +392,9 @@ namespace LuaUnit
      *
      * @return bool inCombat
      */
-    int IsInCombat(lua_State* L, Unit* unit)
+    bool IsInCombat(Unit* unit)
     {
-        ALE::Push(L, unit->IsInCombat());
-        return 1;
+        return unit->IsInCombat();
     }
 
     /**
@@ -432,10 +402,9 @@ namespace LuaUnit
      *
      * @return bool underWater
      */
-    int IsUnderWater(lua_State* L, Unit* unit)
+    bool IsUnderWater(Unit* unit)
     {
-        ALE::Push(L, unit->IsUnderWater());
-        return 1;
+        return unit->IsUnderWater();
     }
 
     /**
@@ -443,10 +412,9 @@ namespace LuaUnit
      *
      * @return bool inWater
      */
-    int IsInWater(lua_State* L, Unit* unit)
+    bool IsInWater(Unit* unit)
     {
-        ALE::Push(L, unit->IsInWater());
-        return 1;
+        return unit->IsInWater();
     }
 
     /**
@@ -454,10 +422,9 @@ namespace LuaUnit
      *
      * @return bool notMoving
      */
-    int IsStopped(lua_State* L, Unit* unit)
+    bool IsStopped(Unit* unit)
     {
-        ALE::Push(L, unit->IsStopped());
-        return 1;
+        return unit->IsStopped();
     }
 
     /**
@@ -465,10 +432,9 @@ namespace LuaUnit
      *
      * @return bool questGiver
      */
-    int IsQuestGiver(lua_State* L, Unit* unit)
+    bool IsQuestGiver(Unit* unit)
     {
-        ALE::Push(L, unit->IsQuestGiver());
-        return 1;
+        return unit->IsQuestGiver();
     }
 
     /**
@@ -477,10 +443,9 @@ namespace LuaUnit
      * @param int32 healthpct : percentage in integer from
      * @return bool isBelow
      */
-    int HealthBelowPct(lua_State* L, Unit* unit)
+    bool HealthBelowPct(Unit* unit, int32 pct)
     {
-        ALE::Push(L, unit->HealthBelowPct(ALE::CHECKVAL(L, 2)));
-        return 1;
+        return unit->HealthBelowPct(pct);
     }
 
     /**
@@ -489,10 +454,9 @@ namespace LuaUnit
      * @param int32 healthpct : percentage in integer from
      * @return bool isAbove
      */
-    int HealthAbovePct(lua_State* L, Unit* unit)
+    bool HealthAbovePct(Unit* unit, int32 pct)
     {
-        ALE::Push(L, unit->HealthAbovePct(ALE::CHECKVAL(L, 2)));
-        return 1;
+        return unit->HealthAbovePct(pct);
     }
 
     /**
@@ -501,12 +465,9 @@ namespace LuaUnit
      * @param uint32 spell : entry of the aura spell
      * @return bool hasAura
      */
-    int HasAura(lua_State* L, Unit* unit)
+    bool HasAura(Unit* unit, uint32 spell)
     {
-        uint32 spell = ALE::CHECKVAL(L, 2);
-
-        ALE::Push(L, unit->HasAura(spell));
-        return 1;
+        return unit->HasAura(spell);
     }
 
     /**
@@ -514,10 +475,9 @@ namespace LuaUnit
      *
      * @return bool isCasting
      */
-    int IsCasting(lua_State* L, Unit* unit)
+    bool IsCasting(Unit* unit)
     {
-        ALE::Push(L, unit->HasUnitState(UNIT_STATE_CASTING));
-        return 1;
+        return unit->HasUnitState(UNIT_STATE_CASTING);
     }
 
     /**
@@ -526,40 +486,19 @@ namespace LuaUnit
      * @param [UnitState] state : an unit state
      * @return bool hasState
      */
-    int HasUnitState(lua_State* L, Unit* unit)
+    bool HasUnitState(Unit* unit, uint32 state)
     {
-        uint32 state = ALE::CHECKVAL(L, 2);
-        ALE::Push(L, unit->HasUnitState(state));
-        return 1;
+        return unit->HasUnitState(state);
     }
 
-    /*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)
+    Unit* GetOwner(Unit* unit)
     {
-        ALE::Push(L, unit->GetOwner());
-        return 1;
+        return unit->GetOwner();
     }
 
     /**
@@ -567,10 +506,9 @@ namespace LuaUnit
      *
      * @return ObjectGuid ownerGUID
      */
-    int GetOwnerGUID(lua_State* L, Unit* unit)
+    ObjectGuid GetOwnerGUID(Unit* unit)
     {
-        ALE::Push(L, unit->GetOwnerGUID());
-        return 1;
+        return unit->GetOwnerGUID();
     }
 
     /**
@@ -578,10 +516,9 @@ namespace LuaUnit
      *
      * @return uint32 mountId : displayId of the mount
      */
-    int GetMountId(lua_State* L, Unit* unit)
+    uint32 GetMountId(Unit* unit)
     {
-        ALE::Push(L, unit->GetMountID());
-        return 1;
+        return unit->GetMountID();
     }
 
     /**
@@ -589,10 +526,9 @@ namespace LuaUnit
      *
      * @return ObjectGuid creatorGUID
      */
-    int GetCreatorGUID(lua_State* L, Unit* unit)
+    ObjectGuid GetCreatorGUID(Unit* unit)
     {
-        ALE::Push(L, unit->GetCreatorGUID());
-        return 1;
+        return unit->GetCreatorGUID();
     }
 
     /**
@@ -600,10 +536,9 @@ namespace LuaUnit
      *
      * @return ObjectGuid charmerGUID
      */
-    int GetCharmerGUID(lua_State* L, Unit* unit)
+    ObjectGuid GetCharmerGUID(Unit* unit)
     {
-        ALE::Push(L, unit->GetCharmerGUID());
-        return 1;
+        return unit->GetCharmerGUID();
     }
 
     /**
@@ -611,10 +546,9 @@ namespace LuaUnit
      *
      * @return ObjectGuid charmedGUID
      */
-    int GetCharmGUID(lua_State* L, Unit* unit)
+    ObjectGuid GetCharmGUID(Unit* unit)
     {
-        ALE::Push(L, unit->GetCharmGUID());
-        return 1;
+        return unit->GetCharmGUID();
     }
 
     /**
@@ -622,10 +556,9 @@ namespace LuaUnit
      *
      * @return ObjectGuid petGUID
      */
-    int GetPetGUID(lua_State* L, Unit* unit)
+    ObjectGuid GetPetGUID(Unit* unit)
     {
-        ALE::Push(L, unit->GetPetGUID());
-        return 1;
+        return unit->GetPetGUID();
     }
 
     /**
@@ -633,10 +566,9 @@ namespace LuaUnit
      *
      * @return ObjectGuid controllerGUID
      */
-    int GetControllerGUID(lua_State* L, Unit* unit)
+    ObjectGuid GetControllerGUID(Unit* unit)
     {
-        ALE::Push(L, unit->GetCharmerOrOwnerGUID());
-        return 1;
+        return unit->GetCharmerOrOwnerGUID();
     }
 
     /**
@@ -644,10 +576,9 @@ namespace LuaUnit
      *
      * @return ObjectGuid controllerGUID
      */
-    int GetControllerGUIDS(lua_State* L, Unit* unit)
+    ObjectGuid GetControllerGUIDS(Unit* unit)
     {
-        ALE::Push(L, unit->GetCharmerOrOwnerOrOwnGUID());
-        return 1;
+        return unit->GetCharmerOrOwnerOrOwnGUID();
     }
 
     /**
@@ -656,15 +587,12 @@ namespace LuaUnit
      * @param uint32 statType
      * @return float stat
      */
-    int GetStat(lua_State* L, Unit* unit)
+    sol::optional GetStat(Unit* unit, uint32 stat)
     {
-        uint32 stat = ALE::CHECKVAL(L, 2);
-
         if (stat >= MAX_STATS)
-            return 1;
+            return sol::nullopt;
 
-        ALE::Push(L, unit->GetStat((Stats)stat));
-        return 1;
+        return unit->GetStat((Stats)stat);
     }
 
     /**
@@ -673,15 +601,12 @@ namespace LuaUnit
      * @param uint32 spellSchool
      * @return uint32 spellPower
      */
-    int GetBaseSpellPower(lua_State* L, Unit* unit)
+    sol::optional GetBaseSpellPower(Unit* unit, uint32 spellschool)
     {
-        uint32 spellschool = ALE::CHECKVAL(L, 2);
-
         if (spellschool >= MAX_SPELL_SCHOOL)
-            return 1;
+            return sol::nullopt;
 
-        ALE::Push(L, unit->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + spellschool));
-        return 1;
+        return unit->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + spellschool);
     }
 
     /**
@@ -689,10 +614,9 @@ namespace LuaUnit
      *
      * @return [Unit] victim
      */
-    int GetVictim(lua_State* L, Unit* unit)
+    Unit* GetVictim(Unit* unit)
     {
-        ALE::Push(L, unit->GetVictim());
-        return 1;
+        return unit->GetVictim();
     }
 
     /**
@@ -711,14 +635,12 @@ namespace LuaUnit
      * @param [CurrentSpellTypes] spellType
      * @return [Spell] castedSpell
      */
-    int GetCurrentSpell(lua_State* L, Unit* unit)
+    Spell* GetCurrentSpell(Unit* unit, uint32 type)
     {
-        uint32 type = ALE::CHECKVAL(L, 2);
         if (type >= CURRENT_MAX_SPELL)
-            return luaL_argerror(L, 2, "valid CurrentSpellTypes expected");
+            throw std::invalid_argument("valid CurrentSpellTypes expected");
 
-        ALE::Push(L, unit->GetCurrentSpell(type));
-        return 1;
+        return unit->GetCurrentSpell(type);
     }
 
     /**
@@ -726,10 +648,9 @@ namespace LuaUnit
      *
      * @return uint8 standState
      */
-    int GetStandState(lua_State* L, Unit* unit)
+    uint8 GetStandState(Unit* unit)
     {
-        ALE::Push(L, unit->getStandState());
-        return 1;
+        return unit->getStandState();
     }
 
     /**
@@ -737,10 +658,9 @@ namespace LuaUnit
      *
      * @return uint32 displayId
      */
-    int GetDisplayId(lua_State* L, Unit* unit)
+    uint32 GetDisplayId(Unit* unit)
     {
-        ALE::Push(L, unit->GetDisplayId());
-        return 1;
+        return unit->GetDisplayId();
     }
 
     /**
@@ -748,10 +668,9 @@ namespace LuaUnit
      *
      * @return uint32 displayId
      */
-    int GetNativeDisplayId(lua_State* L, Unit* unit)
+    uint32 GetNativeDisplayId(Unit* unit)
     {
-        ALE::Push(L, unit->GetNativeDisplayId());
-        return 1;
+        return unit->GetNativeDisplayId();
     }
 
     /**
@@ -759,10 +678,9 @@ namespace LuaUnit
      *
      * @return uint8 level
      */
-    int GetLevel(lua_State* L, Unit* unit)
+    uint8 GetLevel(Unit* unit)
     {
-        ALE::Push(L, unit->GetLevel());
-        return 1;
+        return unit->GetLevel();
     }
 
     /**
@@ -770,19 +688,18 @@ namespace LuaUnit
      *
      * @return uint32 healthAmount
      */
-    int GetHealth(lua_State* L, Unit* unit)
+    uint32 GetHealth(Unit* unit)
     {
-        ALE::Push(L, unit->GetHealth());
-        return 1;
+        return unit->GetHealth();
     }
 
-    Powers PowerSelectorHelper(lua_State* L, Unit* unit, int powerType = -1)
+    Powers PowerSelectorHelper(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");
+            throw std::invalid_argument("valid Powers expected");
 
         return (Powers)powerType;
     }
@@ -807,13 +724,12 @@ namespace LuaUnit
      * @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)
+    uint32 GetPower(Unit* unit, sol::optional typeArg)
     {
-        int type = ALE::CHECKVAL(L, 2, -1);
-        Powers power = PowerSelectorHelper(L, unit, type);
+        int type = typeArg.value_or(-1);
+        Powers power = PowerSelectorHelper(unit, type);
 
-        ALE::Push(L, unit->GetPower(power));
-        return 1;
+        return unit->GetPower(power);
     }
 
     /**
@@ -836,13 +752,12 @@ namespace LuaUnit
      * @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)
+    uint32 GetMaxPower(Unit* unit, sol::optional typeArg)
     {
-        int type = ALE::CHECKVAL(L, 2, -1);
-        Powers power = PowerSelectorHelper(L, unit, type);
+        int type = typeArg.value_or(-1);
+        Powers power = PowerSelectorHelper(unit, type);
 
-        ALE::Push(L, unit->GetMaxPower(power));
-        return 1;
+        return unit->GetMaxPower(power);
     }
 
     /**
@@ -865,15 +780,14 @@ namespace LuaUnit
      * @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)
+    float GetPowerPct(Unit* unit, sol::optional typeArg)
     {
-        int type = ALE::CHECKVAL(L, 2, -1);
-        Powers power = PowerSelectorHelper(L, unit, type);
+        int type = typeArg.value_or(-1);
+        Powers power = PowerSelectorHelper(unit, type);
 
         float percent = ((float)unit->GetPower(power) / (float)unit->GetMaxPower(power)) * 100.0f;
 
-        ALE::Push(L, percent);
-        return 1;
+        return percent;
     }
 
     /**
@@ -895,10 +809,9 @@ namespace LuaUnit
      *
      * @return [Powers] powerType
      */
-    int GetPowerType(lua_State* L, Unit* unit)
+    Powers GetPowerType(Unit* unit)
     {
-        ALE::Push(L, unit->getPowerType());
-        return 1;
+        return unit->getPowerType();
     }
 
     /**
@@ -906,10 +819,9 @@ namespace LuaUnit
      *
      * @return uint32 maxHealth
      */
-    int GetMaxHealth(lua_State* L, Unit* unit)
+    uint32 GetMaxHealth(Unit* unit)
     {
-        ALE::Push(L, unit->GetMaxHealth());
-        return 1;
+        return unit->GetMaxHealth();
     }
 
     /**
@@ -917,10 +829,9 @@ namespace LuaUnit
      *
      * @return float healthPct
      */
-    int GetHealthPct(lua_State* L, Unit* unit)
+    float GetHealthPct(Unit* unit)
     {
-        ALE::Push(L, unit->GetHealthPct());
-        return 1;
+        return unit->GetHealthPct();
     }
 
     /**
@@ -928,10 +839,9 @@ namespace LuaUnit
      *
      * @return uint8 gender : 0 for male, 1 for female and 2 for none
      */
-    int GetGender(lua_State* L, Unit* unit)
+    uint8 GetGender(Unit* unit)
     {
-        ALE::Push(L, unit->getGender());
-        return 1;
+        return unit->getGender();
     }
 
     /**
@@ -939,10 +849,9 @@ namespace LuaUnit
      *
      * @return [Races] race
      */
-    int GetRace(lua_State* L, Unit* unit)
+    uint8 GetRace(Unit* unit)
     {
-        ALE::Push(L, unit->getRace());
-        return 1;
+        return unit->getRace();
     }
 
     /**
@@ -950,10 +859,9 @@ namespace LuaUnit
      *
      * @return [Classes] class
      */
-    int GetClass(lua_State* L, Unit* unit)
+    uint8 GetClass(Unit* unit)
     {
-        ALE::Push(L, unit->getClass());
-        return 1;
+        return unit->getClass();
     }
 
     /**
@@ -961,10 +869,9 @@ namespace LuaUnit
     *
     * @return uint32 racemask
     */
-    int GetRaceMask(lua_State* L, Unit* unit)
+    uint32 GetRaceMask(Unit* unit)
     {
-        ALE::Push(L, unit->getRaceMask());
-        return 1;
+        return unit->getRaceMask();
     }
 
     /**
@@ -972,10 +879,9 @@ namespace LuaUnit
     *
     * @return uint32 classmask
     */
-    int GetClassMask(lua_State* L, Unit* unit)
+    uint32 GetClassMask(Unit* unit)
     {
-        ALE::Push(L, unit->getClassMask());
-        return 1;
+        return unit->getClassMask();
     }
 
     /**
@@ -1002,10 +908,9 @@ namespace LuaUnit
      *
      * @return [CreatureType] creatureType
      */
-    int GetCreatureType(lua_State* L, Unit* unit)
+    uint32 GetCreatureType(Unit* unit)
     {
-        ALE::Push(L, unit->GetCreatureType());
-        return 1;
+        return unit->GetCreatureType();
     }
 
     /**
@@ -1029,18 +934,17 @@ namespace LuaUnit
      * @param [LocaleConstant] locale = DEFAULT_LOCALE
      * @return string className : class name or nil
      */
-    int GetClassAsString(lua_State* L, Unit* unit)
+    sol::optional GetClassAsString(Unit* unit, sol::optional localeArg)
     {
-        uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE);
+        uint8 locale = localeArg.value_or(DEFAULT_LOCALE);
         if (locale >= TOTAL_LOCALES)
-            return luaL_argerror(L, 2, "valid LocaleConstant expected");
+            throw std::invalid_argument("valid LocaleConstant expected");
 
-        const ChrClassesEntry* entry = sChrClassesStore.LookupEntry(unit->getClass());
+        ChrClassesEntry const* entry = sChrClassesStore.LookupEntry(unit->getClass());
         if (!entry)
-            return 1;
+            return sol::nullopt;
 
-        ALE::Push(L, entry->name[locale]);
-        return 1;
+        return std::string(entry->name[locale]);
     }
 
     /**
@@ -1064,18 +968,17 @@ namespace LuaUnit
      * @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)
+    sol::optional GetRaceAsString(Unit* unit, sol::optional localeArg)
     {
-        uint8 locale = ALE::CHECKVAL(L, 2, DEFAULT_LOCALE);
+        uint8 locale = localeArg.value_or(DEFAULT_LOCALE);
         if (locale >= TOTAL_LOCALES)
-            return luaL_argerror(L, 2, "valid LocaleConstant expected");
+            throw std::invalid_argument("valid LocaleConstant expected");
 
-        const ChrRacesEntry* entry = sChrRacesStore.LookupEntry(unit->getRace());
+        ChrRacesEntry const* entry = sChrRacesStore.LookupEntry(unit->getRace());
         if (!entry)
-            return 1;
+            return sol::nullopt;
 
-        ALE::Push(L, entry->name[locale]);
-        return 1;
+        return std::string(entry->name[locale]);
     }
 
     /**
@@ -1083,10 +986,9 @@ namespace LuaUnit
      *
      * @return uint32 faction
      */
-    int GetFaction(lua_State* L, Unit* unit)
+    uint32 GetFaction(Unit* unit)
     {
-        ALE::Push(L, unit->GetFaction());
-        return 1;
+        return unit->GetFaction();
     }
 
     /**
@@ -1095,11 +997,9 @@ namespace LuaUnit
      * @param uint32 spellID : entry of the aura spell
      * @return [Aura] aura : aura object or nil
      */
-    int GetAura(lua_State* L, Unit* unit)
+    Aura* GetAura(Unit* unit, uint32 spellID)
     {
-        uint32 spellID = ALE::CHECKVAL(L, 2);
-        ALE::Push(L, unit->GetAura(spellID));
-        return 1;
+        return unit->GetAura(spellID);
     }
 
     /**
@@ -1108,9 +1008,9 @@ namespace LuaUnit
      * @param float range = 533.333 : search radius
      * @return table friendyUnits : table filled with friendly units
      */
-    int GetFriendlyUnitsInRange(lua_State* L, Unit* unit)
+    sol::table GetFriendlyUnitsInRange(Unit* unit, sol::optional rangeArg, sol::this_state s)
     {
-        float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS);
+        float range = rangeArg.value_or(SIZE_OF_GRIDS);
 
         std::list list;
 
@@ -1118,21 +1018,17 @@ namespace LuaUnit
         Acore::UnitListSearcher searcher(unit, list, checker);
         Cell::VisitObjects(unit, searcher, range);
 
-        ALEUtil::ObjectGUIDCheck guidCheck(unit->GET_GUID());
+        ALEUtil::ObjectGUIDCheck guidCheck(unit->GetGUID());
         list.remove_if(guidCheck);
 
-        lua_createtable(L, list.size(), 0);
-        int tbl = lua_gettop(L);
+        sol::state_view lua(s);
+        sol::table tbl = lua.create_table();
         uint32 i = 0;
 
         for (std::list::const_iterator it = list.begin(); it != list.end(); ++it)
-        {
-            ALE::Push(L, *it);
-            lua_rawseti(L, tbl, ++i);
-        }
+            tbl[++i] = ALEBind::ToLuaDynamic(lua, *it);
 
-        lua_settop(L, tbl);
-        return 1;
+        return tbl;
     }
 
     /**
@@ -1141,29 +1037,25 @@ namespace LuaUnit
      * @param float range = 533.333 : search radius
      * @return table unfriendyUnits : table filled with unfriendly units
      */
-    int GetUnfriendlyUnitsInRange(lua_State* L, Unit* unit)
+    sol::table GetUnfriendlyUnitsInRange(Unit* unit, sol::optional rangeArg, sol::this_state s)
     {
-        float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS);
+        float range = rangeArg.value_or(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());
+        ALEUtil::ObjectGUIDCheck guidCheck(unit->GetGUID());
         list.remove_if(guidCheck);
 
-        lua_createtable(L, list.size(), 0);
-        int tbl = lua_gettop(L);
+        sol::state_view lua(s);
+        sol::table tbl = lua.create_table();
         uint32 i = 0;
 
         for (std::list::const_iterator it = list.begin(); it != list.end(); ++it)
-        {
-            ALE::Push(L, *it);
-            lua_rawseti(L, tbl, ++i);
-        }
+            tbl[++i] = ALEBind::ToLuaDynamic(lua, *it);
 
-        lua_settop(L, tbl);
-        return 1;
+        return tbl;
     }
 
     /**
@@ -1171,27 +1063,19 @@ namespace LuaUnit
      *
      * @return [Vehicle] vehicle
      */
-    int GetVehicleKit(lua_State* L, Unit* unit)
+    Vehicle* GetVehicleKit(Unit* unit)
     {
-        ALE::Push(L, unit->GetVehicleKit());
-        return 1;
+        return unit->GetVehicleKit();
     }
 
-    /*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)
+    ObjectGuid GetCritterGUID(Unit* unit)
     {
-        ALE::Push(L, unit->GetCritterGUID());
-        return 1;
+        return unit->GetCritterGUID();
     }
 
     /**
@@ -1215,15 +1099,12 @@ namespace LuaUnit
      * @param [UnitMoveType] type
      * @return float speed
      */
-    int GetSpeed(lua_State* L, Unit* unit)
+    float GetSpeed(Unit* unit, uint32 type)
     {
-        uint32 type = ALE::CHECKVAL(L, 2);
         if (type >= MAX_MOVE_TYPE)
-            return luaL_argerror(L, 2, "valid UnitMoveType expected");
+            throw std::invalid_argument("valid UnitMoveType expected");
 
-        ALE::Push(L, unit->GetSpeed((UnitMoveType)type));
-
-        return 1;
+        return unit->GetSpeed((UnitMoveType)type);
     }
 
     /**
@@ -1247,17 +1128,12 @@ namespace LuaUnit
     * @param [UnitMoveType] type
     * @return float speed
     */
-    int GetSpeedRate(lua_State* L, Unit* unit)
+    float GetSpeedRate(Unit* unit, uint32 type)
     {
-        uint32 type = ALE::CHECKVAL(L, 2);
         if (type >= MAX_MOVE_TYPE)
-        {
-            return luaL_argerror(L, 2, "valid UnitMoveType expected");
-        }
+            throw std::invalid_argument("valid UnitMoveType expected");
 
-        ALE::Push(L, unit->GetSpeedRate((UnitMoveType)type));
-
-        return 1;
+        return unit->GetSpeedRate((UnitMoveType)type);
     }
 
     /**
@@ -1292,10 +1168,9 @@ namespace LuaUnit
      *
      * @return [MovementGeneratorType] movementType
      */
-    int GetMovementType(lua_State* L, Unit* unit)
+    MovementGeneratorType GetMovementType(Unit* unit)
     {
-        ALE::Push(L, unit->GetMotionMaster()->GetCurrentMovementGeneratorType());
-        return 1;
+        return unit->GetMotionMaster()->GetCurrentMovementGeneratorType();
     }
 
     /**
@@ -1303,27 +1178,23 @@ namespace LuaUnit
      *
      * @return table attackers : table of [Unit]s attacking the unit
      */
-    int GetAttackers(lua_State* L, Unit* unit)
+    sol::table GetAttackers(Unit* unit, sol::this_state s)
     {
-        const Unit::AttackerSet& attackers = unit->getAttackers();
+        Unit::AttackerSet const& attackers = unit->getAttackers();
+
+        sol::state_view lua(s);
+        sol::table tbl = lua.create_table();
+        uint32 i = 0;
 
-        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;
+            tbl[++i] = ALEBind::ToLuaDynamic(lua, attacker);
         }
 
-        lua_settop(L, table); // push table to top of stack
-        return 1;
+        return tbl;
     }
 
     /**
@@ -1331,12 +1202,9 @@ namespace LuaUnit
      *
      * @param ObjectGuid guid : new owner guid
      */
-    int SetOwnerGUID(lua_State* L, Unit* unit)
+    void SetOwnerGUID(Unit* unit, ObjectGuid guid)
     {
-        ObjectGuid guid = ALE::CHECKVAL(L, 2);
-
         unit->SetOwnerGUID(guid);
-        return 0;
     }
 
     /**
@@ -1344,12 +1212,11 @@ namespace LuaUnit
      *
      * @param bool apply = true : true if set on, false if off
      */
-    int SetPvP(lua_State* L, Unit* unit)
+    void SetPvP(Unit* unit, sol::optional applyArg)
     {
-        bool apply = ALE::CHECKVAL(L, 2, true);
+        bool apply = applyArg.value_or(true);
 
         unit->SetPvP(apply);
-        return 0;
     }
 
     /**
@@ -1364,14 +1231,12 @@ namespace LuaUnit
      *
      * @param [SheathState] sheathState : valid SheathState
      */
-    int SetSheath(lua_State* L, Unit* unit)
+    void SetSheath(Unit* unit, uint32 sheathed)
     {
-        uint32 sheathed = ALE::CHECKVAL(L, 2);
         if (sheathed >= MAX_SHEATH_STATE)
-            return luaL_argerror(L, 2, "valid SheathState expected");
+            throw std::invalid_argument("valid SheathState expected");
 
         unit->SetSheath((SheathState)sheathed);
-        return 0;
     }
 
     /**
@@ -1379,12 +1244,10 @@ namespace LuaUnit
      *
      * @param string name : new name
      */
-    int SetName(lua_State* L, Unit* unit)
+    void SetName(Unit* unit, std::string const& name)
     {
-        const char* name = ALE::CHECKVAL(L, 2);
-        if (std::string(name).length() > 0)
+        if (name.length() > 0)
             unit->SetName(name);
-        return 0;
     }
 
     /**
@@ -1410,17 +1273,13 @@ namespace LuaUnit
      * @param float rate
      * @param bool forced = false
      */
-    int SetSpeed(lua_State* L, Unit* unit)
+    void SetSpeed(Unit* unit, uint32 type, float rate, sol::optional forcedArg)
     {
-        uint32 type = ALE::CHECKVAL(L, 2);
-        float rate = ALE::CHECKVAL(L, 3);
-        bool forced = ALE::CHECKVAL(L, 4, false);
+        bool forced = forcedArg.value_or(false);
         if (type >= MAX_MOVE_TYPE)
-            return luaL_argerror(L, 2, "valid UnitMoveType expected");
+            throw std::invalid_argument("valid UnitMoveType expected");
 
         unit->SetSpeed((UnitMoveType)type, rate, forced);
-
-        return 0;
     }
 
     /**
@@ -1446,16 +1305,12 @@ namespace LuaUnit
      * @param float rate
      * @param bool forced = false
      */
-    int SetSpeedRate(lua_State* L, Unit* unit)
+    void SetSpeedRate(Unit* unit, uint32 type, float rate)
     {
-        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");
+            throw std::invalid_argument("valid UnitMoveType expected");
 
         unit->SetSpeedRate((UnitMoveType)type, rate);
-
-        return 0;
     }
 
     /**
@@ -1463,13 +1318,9 @@ namespace LuaUnit
      *
      * @param uint32 faction : new faction ID
      */
-    int SetFaction(lua_State* L, Unit* unit)
+    void SetFaction(Unit* unit, uint32 factionId)
     {
-        uint32 factionId = ALE::CHECKVAL(L, 2);
-
         unit->SetFaction(factionId);
-
-        return 0;
     }
 
     /**
@@ -1477,12 +1328,10 @@ namespace LuaUnit
      *
      * @param uint8 level : new level
      */
-    int SetLevel(lua_State* L, Unit* unit)
+    void SetLevel(Unit* unit, uint8 newlevel)
     {
-        uint8 newlevel = ALE::CHECKVAL(L, 2);
-
         if (newlevel < 1)
-            return luaL_argerror(L, 2, "level cannot be below 1");
+            throw std::invalid_argument("level cannot be below 1");
 
         if (Player* player = unit->ToPlayer())
         {
@@ -1492,8 +1341,6 @@ namespace LuaUnit
         }
         else
             unit->SetLevel(newlevel);
-
-        return 0;
     }
 
     /**
@@ -1501,11 +1348,9 @@ namespace LuaUnit
      *
      * @param uint32 health : new health
      */
-    int SetHealth(lua_State* L, Unit* unit)
+    void SetHealth(Unit* unit, uint32 amt)
     {
-        uint32 amt = ALE::CHECKVAL(L, 2);
         unit->SetHealth(amt);
-        return 0;
     }
 
     /**
@@ -1513,11 +1358,9 @@ namespace LuaUnit
      *
      * @param uint32 maxHealth : new max health
      */
-    int SetMaxHealth(lua_State* L, Unit* unit)
+    void SetMaxHealth(Unit* unit, uint32 amt)
     {
-        uint32 amt = ALE::CHECKVAL(L, 2);
         unit->SetMaxHealth(amt);
-        return 0;
     }
 
     /**
@@ -1540,14 +1383,12 @@ namespace LuaUnit
      * @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)
+    void SetPower(Unit* unit, uint32 amt, sol::optional typeArg)
     {
-        uint32 amt = ALE::CHECKVAL(L, 2);
-        int type = ALE::CHECKVAL(L, 3, -1);
-        Powers power = PowerSelectorHelper(L, unit, type);
+        int type = typeArg.value_or(-1);
+        Powers power = PowerSelectorHelper(unit, type);
 
         unit->SetPower(power, amt);
-        return 0;
     }
 
     /**
@@ -1570,14 +1411,12 @@ namespace LuaUnit
      * @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)
+    void ModifyPower(Unit* unit, int32 amt, sol::optional typeArg)
     {
-        int32 amt = ALE::CHECKVAL(L, 2);
-        int type = ALE::CHECKVAL(L, 3, -1);
-        Powers power = PowerSelectorHelper(L, unit, type);
+        int type = typeArg.value_or(-1);
+        Powers power = PowerSelectorHelper(unit, type);
 
         unit->ModifyPower(power, amt);
-        return 0;
     }
 
     /**
@@ -1600,14 +1439,12 @@ namespace LuaUnit
      * @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)
+    void SetMaxPower(Unit* unit, sol::optional typeArg, uint32 amt)
     {
-        int type = ALE::CHECKVAL(L, 2, -1);
-        uint32 amt = ALE::CHECKVAL(L, 3);
-        Powers power = PowerSelectorHelper(L, unit, type);
+        int type = typeArg.value_or(-1);
+        Powers power = PowerSelectorHelper(unit, type);
 
         unit->SetMaxPower(power, amt);
-        return 0;
     }
 
     /**
@@ -1629,14 +1466,12 @@ namespace LuaUnit
      *
      * @param [Powers] type : a valid power type
      */
-    int SetPowerType(lua_State* L, Unit* unit)
+    void SetPowerType(Unit* unit, uint32 type)
     {
-        uint32 type = ALE::CHECKVAL(L, 2);
         if (type >= int(MAX_POWERS))
-            return luaL_argerror(L, 2, "valid Powers expected");
+            throw std::invalid_argument("valid Powers expected");
 
         unit->setPowerType((Powers)type);
-        return 0;
     }
 
     /**
@@ -1644,11 +1479,9 @@ namespace LuaUnit
      *
      * @param uint32 displayId
      */
-    int SetDisplayId(lua_State* L, Unit* unit)
+    void SetDisplayId(Unit* unit, uint32 model)
     {
-        uint32 model = ALE::CHECKVAL(L, 2);
         unit->SetDisplayId(model);
-        return 0;
     }
 
     /**
@@ -1656,11 +1489,9 @@ namespace LuaUnit
      *
      * @param uint32 displayId
      */
-    int SetNativeDisplayId(lua_State* L, Unit* unit)
+    void SetNativeDisplayId(Unit* unit, uint32 model)
     {
-        uint32 model = ALE::CHECKVAL(L, 2);
         unit->SetNativeDisplayId(model);
-        return 0;
     }
 
     /**
@@ -1668,11 +1499,9 @@ namespace LuaUnit
      *
      * @param uint32 orientation
      */
-    int SetFacing(lua_State* L, Unit* unit)
+    void SetFacing(Unit* unit, float o)
     {
-        float o = ALE::CHECKVAL(L, 2);
         unit->SetFacingTo(o);
-        return 0;
     }
 
     /**
@@ -1680,11 +1509,9 @@ namespace LuaUnit
      *
      * @param [WorldObject] target
      */
-    int SetFacingToObject(lua_State* L, Unit* unit)
+    void SetFacingToObject(Unit* unit, WorldObject* obj)
     {
-        WorldObject* obj = ALE::CHECKOBJ(L, 2);
         unit->SetFacingToObject(obj);
-        return 0;
     }
 
     /**
@@ -1692,11 +1519,9 @@ namespace LuaUnit
      *
      * @param ObjectGuid guid
      */
-    int SetCreatorGUID(lua_State* L, Unit* unit)
+    void SetCreatorGUID(Unit* unit, ObjectGuid guid)
     {
-        ObjectGuid guid = ALE::CHECKVAL(L, 2);
         unit->SetCreatorGUID(guid);
-        return 0;
     }
 
     /**
@@ -1704,11 +1529,9 @@ namespace LuaUnit
      *
      * @param ObjectGuid guid
      */
-    int SetPetGUID(lua_State* L, Unit* unit)
+    void SetPetGUID(Unit* unit, ObjectGuid guid)
     {
-        ObjectGuid guid = ALE::CHECKVAL(L, 2);
         unit->SetPetGUID(guid);
-        return 0;
     }
 
     /**
@@ -1716,11 +1539,10 @@ namespace LuaUnit
      *
      * @param bool enable = true
      */
-    int SetWaterWalk(lua_State* L, Unit* unit)
+    void SetWaterWalk(Unit* unit, sol::optional enableArg)
     {
-        bool enable = ALE::CHECKVAL(L, 2, true);
+        bool enable = enableArg.value_or(true);
         unit->SetWaterWalking(enable);
-        return 0;
     }
 
     /**
@@ -1728,11 +1550,9 @@ namespace LuaUnit
      *
      * @param uint8 state : stand state
      */
-    int SetStandState(lua_State* L, Unit* unit)
+    void SetStandState(Unit* unit, uint8 state)
     {
-        uint8 state = ALE::CHECKVAL(L, 2);
         unit->SetStandState(state);
-        return 0;
     }
 
     /**
@@ -1740,11 +1560,9 @@ namespace LuaUnit
      *
      * @param [Unit] enemy : the [Unit] to start combat with
      */
-    int SetInCombatWith(lua_State* L, Unit* unit)
+    void SetInCombatWith(Unit* unit, Unit* enemy)
     {
-        Unit* enemy = ALE::CHECKOBJ(L, 2);
         unit->SetInCombatWith(enemy);
-        return 0;
     }
 
     /**
@@ -1752,9 +1570,9 @@ namespace LuaUnit
      *
      * @param bool apply = true
      */
-    int SetFFA(lua_State* L, Unit* unit)
+    void SetFFA(Unit* unit, sol::optional applyArg)
     {
-        bool apply = ALE::CHECKVAL(L, 2, true);
+        bool apply = applyArg.value_or(true);
 
         if (apply)
         {
@@ -1768,7 +1586,6 @@ namespace LuaUnit
             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;
     }
 
     /**
@@ -1776,9 +1593,9 @@ namespace LuaUnit
      *
      * @param bool apply = true
      */
-    int SetSanctuary(lua_State* L, Unit* unit)
+    void SetSanctuary(Unit* unit, sol::optional applyArg)
     {
-        bool apply = ALE::CHECKVAL(L, 2, true);
+        bool apply = applyArg.value_or(true);
 
         if (apply)
         {
@@ -1788,8 +1605,6 @@ namespace LuaUnit
         }
         else
             unit->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
-
-        return 0;
     }
 
     /**
@@ -1799,30 +1614,20 @@ namespace LuaUnit
      *
      * @param [ObjectGuid] guid : The GUID of the critter to set
      */
-    int SetCritterGUID(lua_State* L, Unit* unit)
+    void SetCritterGUID(Unit* unit, ObjectGuid guid)
     {
-        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)
+    void SetRooted(Unit* unit, sol::optional applyArg)
     {
-        bool apply = ALE::CHECKVAL(L, 2, true);
+        bool apply = applyArg.value_or(true);
         unit->SetControlled(apply, UNIT_STATE_ROOT);
-        return 0;
     }
 
     /**
@@ -1830,11 +1635,10 @@ namespace LuaUnit
      *
      * @param bool apply = true
      */
-    int SetConfused(lua_State* L, Unit* unit)
+    void SetConfused(Unit* unit, sol::optional applyArg)
     {
-        bool apply = ALE::CHECKVAL(L, 2, true);
+        bool apply = applyArg.value_or(true);
         unit->SetControlled(apply, UNIT_STATE_CONFUSED);
-        return 0;
     }
 
     /**
@@ -1842,34 +1646,18 @@ namespace LuaUnit
      *
      * @param bool apply = true
      */
-    int SetFeared(lua_State* L, Unit* unit)
+    void SetFeared(Unit* unit, sol::optional applyArg)
     {
-        bool apply = ALE::CHECKVAL(L, 2, true);
+        bool apply = applyArg.value_or(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)
+    void ClearThreatList(Unit* unit)
     {
         unit->GetThreatMgr().ClearAllThreat();
-        return 0;
     }
 
     /**
@@ -1877,32 +1665,26 @@ namespace LuaUnit
      *
      * @return table threatList : table of [Unit]s in the threat list
      */
-    int GetThreatList(lua_State* L, Unit* unit)
+    sol::object GetThreatList(Unit* unit, sol::this_state s)
     {
+        sol::state_view lua(s);
+
         if (!unit->CanHaveThreatList())
-        {
-            ALE::Push(L);
-            return 1;
-        }
+            return sol::make_object(lua, sol::lua_nil);
+
+        sol::table tbl = lua.create_table();
+        uint32 i = 0;
 
-        lua_newtable(L);
-        int table = lua_gettop(L);
-        uint32 i = 1;
         for (ThreatReference const* item : unit->GetThreatMgr().GetSortedThreatList())
         {
             Unit* victim = item->GetVictim();
             if (!victim)
-            {
                 continue;
-            }
 
-            ALE::Push(L, victim);
-            lua_rawseti(L, table, i);
-            ++i;
+            tbl[++i] = ALEBind::ToLuaDynamic(lua, victim);
         }
 
-        lua_settop(L, table); // push table to top of stack
-        return 1;
+        return sol::make_object(lua, tbl);
     }
 
     /**
@@ -1910,26 +1692,21 @@ namespace LuaUnit
      *
      * @param uint32 displayId
      */
-    int Mount(lua_State* L, Unit* unit)
+    void Mount(Unit* unit, uint32 displayId)
     {
-        uint32 displayId = ALE::CHECKVAL(L, 2);
-
         unit->Mount(displayId);
-        return 0;
     }
 
     /**
      * Dismounts the [Unit].
      */
-    int Dismount(lua_State* /*L*/, Unit* unit)
+    void Dismount(Unit* unit)
     {
         if (unit->IsMounted())
         {
             unit->Dismount();
             unit->RemoveAurasByType(SPELL_AURA_MOUNTED);
         }
-
-        return 0;
     }
 
     /**
@@ -1937,10 +1714,9 @@ namespace LuaUnit
      *
      * @param uint32 emoteId
      */
-    int PerformEmote(lua_State* L, Unit* unit)
+    void PerformEmote(Unit* unit, uint32 emoteId)
     {
-        unit->HandleEmoteCommand(ALE::CHECKVAL(L, 2));
-        return 0;
+        unit->HandleEmoteCommand(emoteId);
     }
 
     /**
@@ -1948,12 +1724,9 @@ namespace LuaUnit
      *
      * @param uint32 emoteId
      */
-    int EmoteState(lua_State* L, Unit* unit)
+    void EmoteState(Unit* unit, uint32 emoteId)
     {
-        uint32 emoteId = ALE::CHECKVAL(L, 2);
-
         unit->SetUInt32Value(UNIT_NPC_EMOTESTATE, emoteId);
-        return 0;
     }
 
     /**
@@ -1961,10 +1734,9 @@ namespace LuaUnit
      *
      * @return int32 percentage
      */
-    int CountPctFromCurHealth(lua_State* L, Unit* unit)
+    uint32 CountPctFromCurHealth(Unit* unit, int32 pct)
     {
-        ALE::Push(L, unit->CountPctFromCurHealth(ALE::CHECKVAL(L, 2)));
-        return 1;
+        return unit->CountPctFromCurHealth(pct);
     }
 
     /**
@@ -1972,10 +1744,9 @@ namespace LuaUnit
      *
      * @return int32 percentage
      */
-    int CountPctFromMaxHealth(lua_State* L, Unit* unit)
+    uint32 CountPctFromMaxHealth(Unit* unit, int32 pct)
     {
-        ALE::Push(L, unit->CountPctFromMaxHealth(ALE::CHECKVAL(L, 2)));
-        return 1;
+        return unit->CountPctFromMaxHealth(pct);
     }
 
     /**
@@ -1986,38 +1757,24 @@ namespace LuaUnit
      * @param string msg
      * @param [Player] target
      */
-    int SendChatMessageToPlayer(lua_State* L, Unit* unit)
+    void SendChatMessageToPlayer(Unit* unit, uint8 type, uint32 lang, std::string const& msg, Player* target)
     {
-        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");
+            throw std::invalid_argument("valid ChatMsg expected");
         if (lang >= LANGUAGES_COUNT)
-            return luaL_argerror(L, 3, "valid Language expected");
+            throw std::invalid_argument("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)
+    void MoveStop(Unit* unit)
     {
         unit->StopMoving();
-        return 0;
     }
 
     /**
@@ -2025,11 +1782,10 @@ namespace LuaUnit
      *
      * @param bool reset = true : cleans movement
      */
-    int MoveExpire(lua_State* L, Unit* unit)
+    void MoveExpire(Unit* unit, sol::optional resetArg)
     {
-        bool reset = ALE::CHECKVAL(L, 2, true);
+        bool reset = resetArg.value_or(true);
         unit->GetMotionMaster()->MovementExpired(reset);
-        return 0;
     }
 
     /**
@@ -2037,20 +1793,18 @@ namespace LuaUnit
      *
      * @param bool reset = true : clean movement
      */
-    int MoveClear(lua_State* L, Unit* unit)
+    void MoveClear(Unit* unit, sol::optional resetArg)
     {
-        bool reset = ALE::CHECKVAL(L, 2, true);
+        bool reset = resetArg.value_or(true);
         unit->GetMotionMaster()->Clear(reset);
-        return 0;
     }
 
     /**
      * The [Unit] will be idle
      */
-    int MoveIdle(lua_State* /*L*/, Unit* unit)
+    void MoveIdle(Unit* unit)
     {
         unit->GetMotionMaster()->MoveIdle();
-        return 0;
     }
 
     /**
@@ -2058,22 +1812,19 @@ namespace LuaUnit
      *
      * @param float radius : limit on how far the [Unit] will move at random
      */
-    int MoveRandom(lua_State* L, Unit* unit)
+    void MoveRandom(Unit* unit, float radius)
     {
-        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)
+    void MoveHome(Unit* unit)
     {
         unit->GetMotionMaster()->MoveTargetedHome();
-        return 0;
     }
 
     /**
@@ -2083,13 +1834,11 @@ namespace LuaUnit
      * @param float dist = 0 : distance to start following
      * @param float angle = 0
      */
-    int MoveFollow(lua_State* L, Unit* unit)
+    void MoveFollow(Unit* unit, Unit* target, sol::optional distArg, sol::optional angleArg)
     {
-        Unit* target = ALE::CHECKOBJ(L, 2);
-        float dist = ALE::CHECKVAL(L, 3, 0.0f);
-        float angle = ALE::CHECKVAL(L, 4, 0.0f);
+        float dist = distArg.value_or(0.0f);
+        float angle = angleArg.value_or(0.0f);
         unit->GetMotionMaster()->MoveFollow(target, dist, angle);
-        return 0;
     }
 
     /**
@@ -2099,22 +1848,19 @@ namespace LuaUnit
      * @param float dist = 0 : distance start chasing
      * @param float angle = 0
      */
-    int MoveChase(lua_State* L, Unit* unit)
+    void MoveChase(Unit* unit, Unit* target, sol::optional distArg, sol::optional angleArg)
     {
-        Unit* target = ALE::CHECKOBJ(L, 2);
-        float dist = ALE::CHECKVAL(L, 3, 0.0f);
-        float angle = ALE::CHECKVAL(L, 4, 0.0f);
+        float dist = distArg.value_or(0.0f);
+        float angle = angleArg.value_or(0.0f);
         unit->GetMotionMaster()->MoveChase(target, dist, angle);
-        return 0;
     }
 
     /**
      * The [Unit] will move confused
      */
-    int MoveConfused(lua_State* /*L*/, Unit* unit)
+    void MoveConfused(Unit* unit)
     {
         unit->GetMotionMaster()->MoveConfused();
-        return 0;
     }
 
     /**
@@ -2123,12 +1869,10 @@ namespace LuaUnit
      * @param [Unit] target
      * @param uint32 time = 0 : flee delay
      */
-    int MoveFleeing(lua_State* L, Unit* unit)
+    void MoveFleeing(Unit* unit, Unit* target, sol::optional timeArg)
     {
-        Unit* target = ALE::CHECKOBJ(L, 2);
-        uint32 time = ALE::CHECKVAL(L, 3, 0);
+        uint32 time = timeArg.value_or(0);
         unit->GetMotionMaster()->MoveFleeing(target, time);
-        return 0;
     }
 
     /**
@@ -2140,15 +1884,10 @@ namespace LuaUnit
      * @param float z
      * @param bool genPath = true : if true, generates path
      */
-    int MoveTo(lua_State* L, Unit* unit)
+    void MoveTo(Unit* unit, uint32 id, float x, float y, float z, sol::optional genPathArg)
     {
-        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);
+        bool genPath = genPathArg.value_or(true);
         unit->GetMotionMaster()->MovePoint(id, x, y, z, FORCED_MOVEMENT_NONE, 0.f, 0.f, genPath);
-        return 0;
     }
 
     /**
@@ -2161,17 +1900,11 @@ namespace LuaUnit
      * @param float maxHeight : maximum height
      * @param uint32 id = 0 : unique movement Id
      */
-    int MoveJump(lua_State* L, Unit* unit)
+    void MoveJump(Unit* unit, float x, float y, float z, float zSpeed, float maxHeight, sol::optional idArg)
     {
-        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);
+        uint32 id = idArg.value_or(0);
         Position pos(x, y, z);
         unit->GetMotionMaster()->MoveJump(pos, zSpeed, maxHeight, id);
-        return 0;
     }
 
     /**
@@ -2182,16 +1915,11 @@ namespace LuaUnit
      * @param [Player] receiver : specific [Unit] to receive the message
      * @param bool bossWhisper = false : is a boss whisper
      */
-    int SendUnitWhisper(lua_State* L, Unit* unit)
+    void SendUnitWhisper(Unit* unit, std::string const& msg, uint32 lang, Player* receiver, sol::optional bossWhisperArg)
     {
-        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)
+        bool bossWhisper = bossWhisperArg.value_or(false);
+        if (msg.length() > 0)
             unit->Whisper(msg, (Language)lang, receiver, bossWhisper);
-        return 0;
     }
 
     /**
@@ -2201,14 +1929,12 @@ namespace LuaUnit
      * @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)
+    void SendUnitEmote(Unit* unit, std::string const& msg, sol::optional receiverArg, sol::optional bossEmoteArg)
     {
-        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* receiver = receiverArg ? receiverArg->Resolve() : nullptr;
+        bool bossEmote = bossEmoteArg.value_or(false);
+        if (msg.length() > 0)
             unit->TextEmote(msg, receiver, bossEmote);
-        return 0;
     }
 
     /**
@@ -2217,13 +1943,10 @@ namespace LuaUnit
      * @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)
+    void SendUnitSay(Unit* unit, std::string const& msg, uint32 language)
     {
-        const char* msg = ALE::CHECKVAL(L, 2);
-        uint32 language = ALE::CHECKVAL(L, 3);
-        if (std::string(msg).length() > 0)
+        if (msg.length() > 0)
             unit->Say(msg, (Language)language, unit);
-        return 0;
     }
 
     /**
@@ -2232,22 +1955,18 @@ namespace LuaUnit
      * @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)
+    void SendUnitYell(Unit* unit, std::string const& msg, uint32 language)
     {
-        const char* msg = ALE::CHECKVAL(L, 2);
-        uint32 language = ALE::CHECKVAL(L, 3);
-        if (std::string(msg).length() > 0)
+        if (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)
+    void DeMorph(Unit* unit)
     {
         unit->DeMorph();
-        return 0;
     }
 
     /**
@@ -2257,17 +1976,15 @@ namespace LuaUnit
      * @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)
+    void CastSpell(Unit* unit, sol::optional targetArg, uint32 spell, sol::optional triggeredArg)
     {
-        Unit* target = ALE::CHECKOBJ(L, 2, false);
-        uint32 spell = ALE::CHECKVAL(L, 3);
-        bool triggered = ALE::CHECKVAL(L, 4, false);
+        Unit* target = targetArg ? targetArg->Resolve() : nullptr;
+        bool triggered = triggeredArg.value_or(false);
         SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(spell);
         if (!spellEntry)
-            return 0;
+            return;
 
         unit->CastSpell(target, spell, triggered);
-        return 0;
     }
 
     /**
@@ -2283,22 +2000,20 @@ namespace LuaUnit
      * @param [Item] castItem = nil
      * @param ObjectGuid originalCaster = ObjectGuid()
      */
-    int CastCustomSpell(lua_State* L, Unit* unit)
+    void CastCustomSpell(Unit* unit, sol::optional targetArg, uint32 spell, sol::optional triggeredArg, sol::optional bp0Arg, sol::optional bp1Arg, sol::optional bp2Arg, sol::optional castItemArg, sol::optional originalCasterArg)
     {
-        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* target = targetArg ? targetArg->Resolve() : nullptr;
+        bool triggered = triggeredArg.value_or(false);
+        bool has_bp0 = bp0Arg.has_value();
+        int32 bp0 = bp0Arg.value_or(0);
+        bool has_bp1 = bp1Arg.has_value();
+        int32 bp1 = bp1Arg.value_or(0);
+        bool has_bp2 = bp2Arg.has_value();
+        int32 bp2 = bp2Arg.value_or(0);
+        Item* castItem = castItemArg ? castItemArg->Resolve() : nullptr;
+        ObjectGuid originalCaster = originalCasterArg.value_or(ObjectGuid());
 
-        unit->CastCustomSpell(target, spell, has_bp0 ? &bp0 : NULL, has_bp1 ? &bp1 : NULL, has_bp2 ? &bp2 : NULL, triggered, castItem, NULL, ObjectGuid(originalCaster));
-        return 0;
+        unit->CastCustomSpell(target, spell, has_bp0 ? &bp0 : nullptr, has_bp1 ? &bp1 : nullptr, has_bp2 ? &bp2 : nullptr, triggered, castItem, nullptr, ObjectGuid(originalCaster));
     }
 
     /**
@@ -2310,24 +2025,18 @@ namespace LuaUnit
      * @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)
+    void CastSpellAoF(Unit* unit, float _x, float _y, float _z, uint32 spell, sol::optional triggeredArg)
     {
-        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);
+        bool triggered = triggeredArg.value_or(true);
         unit->CastSpell(_x, _y, _z, spell, triggered);
-        return 0;
     }
 
     /**
      * Clears the [Unit]'s combat
      */
-    int ClearInCombat(lua_State* /*L*/, Unit* unit)
+    void ClearInCombat(Unit* unit)
     {
         unit->ClearInCombat();
-        return 0;
     }
 
     /**
@@ -2335,11 +2044,10 @@ namespace LuaUnit
      *
      * @param uint32 spell = 0 : entry of a spell
      */
-    int StopSpellCast(lua_State* L, Unit* unit)
+    void StopSpellCast(Unit* unit, sol::optional spellIdArg)
     {
-        uint32 spellId = ALE::CHECKVAL(L, 2, 0);
+        uint32 spellId = spellIdArg.value_or(0);
         unit->CastStop(spellId);
-        return 0;
     }
 
     /**
@@ -2350,10 +2058,9 @@ namespace LuaUnit
      * @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)
+    void InterruptSpell(Unit* unit, int spellType, sol::optional delayedArg)
     {
-        int spellType = ALE::CHECKVAL(L, 2);
-        bool delayed = ALE::CHECKVAL(L, 3, true);
+        bool delayed = delayedArg.value_or(true);
         switch (spellType)
         {
         case 0:
@@ -2369,11 +2076,10 @@ namespace LuaUnit
             spellType = CURRENT_AUTOREPEAT_SPELL;
             break;
         default:
-            return luaL_argerror(L, 2, "valid CurrentSpellTypes expected");
+            throw std::invalid_argument("valid CurrentSpellTypes expected");
         }
 
         unit->InterruptSpell((CurrentSpellTypes)spellType, delayed);
-        return 0;
     }
 
     /**
@@ -2383,16 +2089,13 @@ namespace LuaUnit
      * @param [Unit] target : aura will be applied on the target
      * @return [Aura] aura
      */
-    int AddAura(lua_State* L, Unit* unit)
+    Aura* AddAura(Unit* unit, uint32 spell, Unit* target)
     {
-        uint32 spell = ALE::CHECKVAL(L, 2);
-        Unit* target = ALE::CHECKOBJ(L, 3);
         SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(spell);
         if (!spellEntry)
-            return 1;
+            return nullptr;
 
-        ALE::Push(L, unit->AddAura(spell, target));
-        return 1;
+        return unit->AddAura(spell, target);
     }
 
     /**
@@ -2400,11 +2103,9 @@ namespace LuaUnit
      *
      * @param uint32 spell : entry of a spell
      */
-    int RemoveAura(lua_State* L, Unit* unit)
+    void RemoveAura(Unit* unit, uint32 spellId)
     {
-        uint32 spellId = ALE::CHECKVAL(L, 2);
         unit->RemoveAurasDueToSpell(spellId);
-        return 0;
     }
 
     /**
@@ -2412,19 +2113,17 @@ namespace LuaUnit
      *
      *     Note: talents and racials are also auras, use with caution
      */
-    int RemoveAllAuras(lua_State* /*L*/, Unit* unit)
+    void RemoveAllAuras(Unit* unit)
     {
         unit->RemoveAllAuras();
-        return 0;
     }
 
     /**
      * Removes all positive visible [Aura]'s from the [Unit].
      */
-    int RemoveArenaAuras(lua_State* /*L*/, Unit* unit)
+    void RemoveArenaAuras(Unit* unit)
     {
         unit->RemoveArenaAuras();
-        return 0;
     }
 
     /**
@@ -2432,12 +2131,9 @@ namespace LuaUnit
      *
      * @param [UnitState] state
      */
-    int AddUnitState(lua_State* L, Unit* unit)
+    void AddUnitState(Unit* unit, uint32 state)
     {
-        uint32 state = ALE::CHECKVAL(L, 2);
-
         unit->AddUnitState(state);
-        return 0;
     }
 
     /**
@@ -2445,12 +2141,9 @@ namespace LuaUnit
      *
      * @param [UnitState] state
      */
-    int ClearUnitState(lua_State* L, Unit* unit)
+    void ClearUnitState(Unit* unit, uint32 state)
     {
-        uint32 state = ALE::CHECKVAL(L, 2);
-
         unit->ClearUnitState(state);
-        return 0;
     }
 
     /**
@@ -2461,15 +2154,9 @@ namespace LuaUnit
      * @param float z
      * @param float o : orientation
      */
-    int NearTeleport(lua_State* L, Unit* unit)
+    void NearTeleport(Unit* unit, float x, float y, float z, float o)
     {
-        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;
     }
 
     /**
@@ -2495,28 +2182,26 @@ namespace LuaUnit
      * @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)
+    void DealDamage(Unit* unit, Unit* target, uint32 damage, sol::optional durabilitylossArg, sol::optional schoolArg, sol::optional spellArg)
     {
-        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);
+        bool durabilityloss = durabilitylossArg.value_or(true);
+        uint32 school = schoolArg.value_or(MAX_SPELL_SCHOOL);
+        uint32 spell = spellArg.value_or(0);
         if (school > MAX_SPELL_SCHOOL)
-            return luaL_argerror(L, 6, "valid SpellSchool expected");
+            throw std::invalid_argument("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::DealDamage(unit, target, damage, nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, durabilityloss);
             unit->SendAttackStateUpdate(HITINFO_AFFECTS_VICTIM, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_HIT, 0);
-            return 0;
+            return;
         }
 
         SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
 
         if (Unit::IsDamageReducedByArmor(schoolmask))
-            damage = Unit::CalcArmorReducedDamage(unit, target, damage, NULL, BASE_ATTACK);
+            damage = Unit::CalcArmorReducedDamage(unit, target, damage, nullptr, BASE_ATTACK);
 
         if (!spell)
         {
@@ -2531,23 +2216,22 @@ namespace LuaUnit
             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::DealDamage(unit, target, damage, nullptr, DIRECT_DAMAGE, schoolmask, nullptr, false);
             unit->SendAttackStateUpdate(HITINFO_AFFECTS_VICTIM, target, 0, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0);
-            return 0;
+            return;
         }
 
         if (!spell)
-            return 0;
+            return;
 
         SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
         if (!spellInfo)
-            return 0;
+            return;
 
         SpellNonMeleeDamage dmgInfo(unit, target, spellInfo, spellInfo->GetSchoolMask());
         Unit::DealDamageMods(dmgInfo.target, dmgInfo.damage, &dmgInfo.absorb);
         unit->SendSpellNonMeleeDamageLog(&dmgInfo);
         unit->DealSpellDamage(&dmgInfo, true);
-        return 0;
     }
 
     /**
@@ -2558,19 +2242,15 @@ namespace LuaUnit
      * @param uint32 amount : amount to heal
      * @param bool critical = false : if true, heal is logged as critical
      */
-    int DealHeal(lua_State* L, Unit* unit)
+    void DealHeal(Unit* unit, Unit* target, uint32 spell, uint32 amount, sol::optional criticalArg)
     {
-        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);
+        bool critical = criticalArg.value_or(false);
 
-        if (const SpellInfo* info = sSpellMgr->GetSpellInfo(spell))
+        if (SpellInfo const* info = sSpellMgr->GetSpellInfo(spell))
         {
             HealInfo healInfo(unit, target, amount, info, info->GetSchoolMask());
             unit->HealBySpell(healInfo, critical);
         }
-        return 0;
     }
 
     /**
@@ -2579,13 +2259,11 @@ namespace LuaUnit
      * @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)
+    void Kill(Unit* unit, Unit* target, sol::optional durLossArg)
     {
-        Unit* target = ALE::CHECKOBJ(L, 2);
-        bool durLoss = ALE::CHECKVAL(L, 3, true);
+        bool durLoss = durLossArg.value_or(true);
 
         Unit::Kill(unit, target, durLoss);
-        return 0;
     }
 
     /**
@@ -2610,19 +2288,16 @@ namespace LuaUnit
      * @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)
+    void AddThreat(Unit* unit, Unit* victim, sol::optional threatArg, sol::optional spellArg, sol::optional schoolMaskArg)
     {
-        Unit* victim = ALE::CHECKOBJ(L, 2);
-        float threat = ALE::CHECKVAL(L, 3, true);
-        uint32 spell = ALE::CHECKVAL(L, 4, 0);
+        float threat = threatArg.value_or(1.0f);
+        uint32 spell = spellArg.value_or(0);
 
-        uint32 schoolMask = ALE::CHECKVAL(L, 5, 0);
+        uint32 schoolMask = schoolMaskArg.value_or(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;
+            throw std::invalid_argument("valid SpellSchoolMask expected");
+
+        unit->AddThreat(victim, threat, (SpellSchoolMask)schoolMask, spell ? sSpellMgr->GetSpellInfo(spell) : nullptr);
     }
 
     /**
@@ -2631,110 +2306,29 @@ namespace LuaUnit
      * @param [Unit] victim : [Unit] that caused the threat
      * @param int32 percent : threat amount in pct
      */
-    int ModifyThreatPct(lua_State* L, Unit* unit)
+    void ModifyThreatPct(Unit* unit, Unit* victim, sol::optional threatPctArg)
     {
-        Unit* victim = ALE::CHECKOBJ(L, 2);
-        int32 threatPct = ALE::CHECKVAL(L, 3, true);
+        int32 threatPct = threatPctArg.value_or(1);
 
         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)
+    void ClearThreat(Unit* unit, Unit* target)
     {
-        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)
+    void ResetAllThreat(Unit* unit)
     {
         unit->GetThreatMgr().ResetAllThreat();
-        return 0;
     }
 
     /**
@@ -2743,12 +2337,173 @@ namespace LuaUnit
      * @param [Unit] target
      * @return float threat
      */
-    int GetThreat(lua_State* L, Unit* unit)
+    float GetThreat(Unit* unit, Unit* target)
     {
-        Unit* target = ALE::CHECKOBJ(L, 2);
-
-        ALE::Push(L, unit->GetThreatMgr().GetThreat(target));
-        return 1;
+        return unit->GetThreatMgr().GetThreat(target);
     }
-};
-#endif
+}
+
+void RegisterUnitMethods(sol::state& lua)
+{
+    sol::usertype type = ALEBind::NewHandleType(lua, "Unit");
+
+    type["SetImmuneTo"]              = ALEBind::Method(&LuaUnit::SetImmuneTo);
+    type["HandleStatFlatModifier"]   = ALEBind::Method(&LuaUnit::HandleStatFlatModifier);
+    type["Attack"]                   = ALEBind::Method(&LuaUnit::Attack);
+    type["AttackStop"]               = ALEBind::Method(&LuaUnit::AttackStop);
+    type["IsStandState"]             = ALEBind::Method(&LuaUnit::IsStandState);
+    type["IsMounted"]                = ALEBind::Method(&LuaUnit::IsMounted);
+    type["IsRooted"]                 = ALEBind::Method(&LuaUnit::IsRooted);
+    type["IsFullHealth"]             = ALEBind::Method(&LuaUnit::IsFullHealth);
+    type["IsInAccessiblePlaceFor"]   = ALEBind::Method(&LuaUnit::IsInAccessiblePlaceFor);
+    type["IsAuctioneer"]             = ALEBind::Method(&LuaUnit::IsAuctioneer);
+    type["IsGuildMaster"]            = ALEBind::Method(&LuaUnit::IsGuildMaster);
+    type["IsInnkeeper"]              = ALEBind::Method(&LuaUnit::IsInnkeeper);
+    type["IsTrainer"]                = ALEBind::Method(&LuaUnit::IsTrainer);
+    type["IsGossip"]                 = ALEBind::Method(&LuaUnit::IsGossip);
+    type["IsTaxi"]                   = ALEBind::Method(&LuaUnit::IsTaxi);
+    type["IsSpiritHealer"]           = ALEBind::Method(&LuaUnit::IsSpiritHealer);
+    type["IsSpiritGuide"]            = ALEBind::Method(&LuaUnit::IsSpiritGuide);
+    type["IsTabardDesigner"]         = ALEBind::Method(&LuaUnit::IsTabardDesigner);
+    type["IsServiceProvider"]        = ALEBind::Method(&LuaUnit::IsServiceProvider);
+    type["IsSpiritService"]          = ALEBind::Method(&LuaUnit::IsSpiritService);
+    type["IsAlive"]                  = ALEBind::Method(&LuaUnit::IsAlive);
+    type["IsDead"]                   = ALEBind::Method(&LuaUnit::IsDead);
+    type["IsDying"]                  = ALEBind::Method(&LuaUnit::IsDying);
+    type["IsBanker"]                 = ALEBind::Method(&LuaUnit::IsBanker);
+    type["IsVendor"]                 = ALEBind::Method(&LuaUnit::IsVendor);
+    type["IsBattleMaster"]           = ALEBind::Method(&LuaUnit::IsBattleMaster);
+    type["IsCharmed"]                = ALEBind::Method(&LuaUnit::IsCharmed);
+    type["IsArmorer"]                = ALEBind::Method(&LuaUnit::IsArmorer);
+    type["IsAttackingPlayer"]        = ALEBind::Method(&LuaUnit::IsAttackingPlayer);
+    type["IsPvPFlagged"]             = ALEBind::Method(&LuaUnit::IsPvPFlagged);
+    type["IsOnVehicle"]              = ALEBind::Method(&LuaUnit::IsOnVehicle);
+    type["IsInCombat"]               = ALEBind::Method(&LuaUnit::IsInCombat);
+    type["IsUnderWater"]             = ALEBind::Method(&LuaUnit::IsUnderWater);
+    type["IsInWater"]                = ALEBind::Method(&LuaUnit::IsInWater);
+    type["IsStopped"]                = ALEBind::Method(&LuaUnit::IsStopped);
+    type["IsQuestGiver"]             = ALEBind::Method(&LuaUnit::IsQuestGiver);
+    type["HealthBelowPct"]           = ALEBind::Method(&LuaUnit::HealthBelowPct);
+    type["HealthAbovePct"]           = ALEBind::Method(&LuaUnit::HealthAbovePct);
+    type["HasAura"]                  = ALEBind::Method(&LuaUnit::HasAura);
+    type["IsCasting"]                = ALEBind::Method(&LuaUnit::IsCasting);
+    type["HasUnitState"]             = ALEBind::Method(&LuaUnit::HasUnitState);
+    type["GetOwner"]                 = ALEBind::Method(&LuaUnit::GetOwner);
+    type["GetOwnerGUID"]             = ALEBind::Method(&LuaUnit::GetOwnerGUID);
+    type["GetMountId"]               = ALEBind::Method(&LuaUnit::GetMountId);
+    type["GetCreatorGUID"]           = ALEBind::Method(&LuaUnit::GetCreatorGUID);
+    type["GetCharmerGUID"]           = ALEBind::Method(&LuaUnit::GetCharmerGUID);
+    type["GetCharmGUID"]             = ALEBind::Method(&LuaUnit::GetCharmGUID);
+    type["GetPetGUID"]               = ALEBind::Method(&LuaUnit::GetPetGUID);
+    type["GetControllerGUID"]        = ALEBind::Method(&LuaUnit::GetControllerGUID);
+    type["GetControllerGUIDS"]       = ALEBind::Method(&LuaUnit::GetControllerGUIDS);
+    type["GetStat"]                  = ALEBind::Method(&LuaUnit::GetStat);
+    type["GetBaseSpellPower"]        = ALEBind::Method(&LuaUnit::GetBaseSpellPower);
+    type["GetVictim"]                = ALEBind::Method(&LuaUnit::GetVictim);
+    type["GetCurrentSpell"]          = ALEBind::Method(&LuaUnit::GetCurrentSpell);
+    type["GetStandState"]            = ALEBind::Method(&LuaUnit::GetStandState);
+    type["GetDisplayId"]             = ALEBind::Method(&LuaUnit::GetDisplayId);
+    type["GetNativeDisplayId"]       = ALEBind::Method(&LuaUnit::GetNativeDisplayId);
+    type["GetLevel"]                 = ALEBind::Method(&LuaUnit::GetLevel);
+    type["GetHealth"]                = ALEBind::Method(&LuaUnit::GetHealth);
+    type["GetPower"]                 = ALEBind::Method(&LuaUnit::GetPower);
+    type["GetMaxPower"]              = ALEBind::Method(&LuaUnit::GetMaxPower);
+    type["GetPowerPct"]              = ALEBind::Method(&LuaUnit::GetPowerPct);
+    type["GetPowerType"]             = ALEBind::Method(&LuaUnit::GetPowerType);
+    type["GetMaxHealth"]             = ALEBind::Method(&LuaUnit::GetMaxHealth);
+    type["GetHealthPct"]             = ALEBind::Method(&LuaUnit::GetHealthPct);
+    type["GetGender"]                = ALEBind::Method(&LuaUnit::GetGender);
+    type["GetRace"]                  = ALEBind::Method(&LuaUnit::GetRace);
+    type["GetClass"]                 = ALEBind::Method(&LuaUnit::GetClass);
+    type["GetRaceMask"]              = ALEBind::Method(&LuaUnit::GetRaceMask);
+    type["GetClassMask"]             = ALEBind::Method(&LuaUnit::GetClassMask);
+    type["GetCreatureType"]          = ALEBind::Method(&LuaUnit::GetCreatureType);
+    type["GetClassAsString"]         = ALEBind::Method(&LuaUnit::GetClassAsString);
+    type["GetRaceAsString"]          = ALEBind::Method(&LuaUnit::GetRaceAsString);
+    type["GetFaction"]               = ALEBind::Method(&LuaUnit::GetFaction);
+    type["GetAura"]                  = ALEBind::Method(&LuaUnit::GetAura);
+    type["GetFriendlyUnitsInRange"]  = ALEBind::Method(&LuaUnit::GetFriendlyUnitsInRange);
+    type["GetUnfriendlyUnitsInRange"] = ALEBind::Method(&LuaUnit::GetUnfriendlyUnitsInRange);
+    type["GetVehicleKit"]            = ALEBind::Method(&LuaUnit::GetVehicleKit);
+    type["GetCritterGUID"]           = ALEBind::Method(&LuaUnit::GetCritterGUID);
+    type["GetSpeed"]                 = ALEBind::Method(&LuaUnit::GetSpeed);
+    type["GetSpeedRate"]             = ALEBind::Method(&LuaUnit::GetSpeedRate);
+    type["GetMovementType"]          = ALEBind::Method(&LuaUnit::GetMovementType);
+    type["GetAttackers"]             = ALEBind::Method(&LuaUnit::GetAttackers);
+    type["SetOwnerGUID"]             = ALEBind::Method(&LuaUnit::SetOwnerGUID);
+    type["SetPvP"]                   = ALEBind::Method(&LuaUnit::SetPvP);
+    type["SetSheath"]                = ALEBind::Method(&LuaUnit::SetSheath);
+    type["SetName"]                  = ALEBind::Method(&LuaUnit::SetName);
+    type["SetSpeed"]                 = ALEBind::Method(&LuaUnit::SetSpeed);
+    type["SetSpeedRate"]             = ALEBind::Method(&LuaUnit::SetSpeedRate);
+    type["SetFaction"]               = ALEBind::Method(&LuaUnit::SetFaction);
+    type["SetLevel"]                 = ALEBind::Method(&LuaUnit::SetLevel);
+    type["SetHealth"]                = ALEBind::Method(&LuaUnit::SetHealth);
+    type["SetMaxHealth"]             = ALEBind::Method(&LuaUnit::SetMaxHealth);
+    type["SetPower"]                 = ALEBind::Method(&LuaUnit::SetPower);
+    type["ModifyPower"]              = ALEBind::Method(&LuaUnit::ModifyPower);
+    type["SetMaxPower"]              = ALEBind::Method(&LuaUnit::SetMaxPower);
+    type["SetPowerType"]             = ALEBind::Method(&LuaUnit::SetPowerType);
+    type["SetDisplayId"]             = ALEBind::Method(&LuaUnit::SetDisplayId);
+    type["SetNativeDisplayId"]       = ALEBind::Method(&LuaUnit::SetNativeDisplayId);
+    type["SetFacing"]                = ALEBind::Method(&LuaUnit::SetFacing);
+    type["SetFacingToObject"]        = ALEBind::Method(&LuaUnit::SetFacingToObject);
+    type["SetCreatorGUID"]           = ALEBind::Method(&LuaUnit::SetCreatorGUID);
+    type["SetPetGUID"]               = ALEBind::Method(&LuaUnit::SetPetGUID);
+    type["SetWaterWalk"]             = ALEBind::Method(&LuaUnit::SetWaterWalk);
+    type["SetStandState"]            = ALEBind::Method(&LuaUnit::SetStandState);
+    type["SetInCombatWith"]          = ALEBind::Method(&LuaUnit::SetInCombatWith);
+    type["SetFFA"]                   = ALEBind::Method(&LuaUnit::SetFFA);
+    type["SetSanctuary"]             = ALEBind::Method(&LuaUnit::SetSanctuary);
+    type["SetCritterGUID"]           = ALEBind::Method(&LuaUnit::SetCritterGUID);
+    type["SetRooted"]                = ALEBind::Method(&LuaUnit::SetRooted);
+    type["SetConfused"]              = ALEBind::Method(&LuaUnit::SetConfused);
+    type["SetFeared"]                = ALEBind::Method(&LuaUnit::SetFeared);
+    type["ClearThreatList"]          = ALEBind::Method(&LuaUnit::ClearThreatList);
+    type["GetThreatList"]            = ALEBind::Method(&LuaUnit::GetThreatList);
+    type["Mount"]                    = ALEBind::Method(&LuaUnit::Mount);
+    type["Dismount"]                 = ALEBind::Method(&LuaUnit::Dismount);
+    type["PerformEmote"]             = ALEBind::Method(&LuaUnit::PerformEmote);
+    type["EmoteState"]               = ALEBind::Method(&LuaUnit::EmoteState);
+    type["CountPctFromCurHealth"]    = ALEBind::Method(&LuaUnit::CountPctFromCurHealth);
+    type["CountPctFromMaxHealth"]    = ALEBind::Method(&LuaUnit::CountPctFromMaxHealth);
+    type["SendChatMessageToPlayer"]  = ALEBind::Method(&LuaUnit::SendChatMessageToPlayer);
+    type["MoveStop"]                 = ALEBind::Method(&LuaUnit::MoveStop);
+    type["MoveExpire"]               = ALEBind::Method(&LuaUnit::MoveExpire);
+    type["MoveClear"]                = ALEBind::Method(&LuaUnit::MoveClear);
+    type["MoveIdle"]                 = ALEBind::Method(&LuaUnit::MoveIdle);
+    type["MoveRandom"]               = ALEBind::Method(&LuaUnit::MoveRandom);
+    type["MoveHome"]                 = ALEBind::Method(&LuaUnit::MoveHome);
+    type["MoveFollow"]               = ALEBind::Method(&LuaUnit::MoveFollow);
+    type["MoveChase"]                = ALEBind::Method(&LuaUnit::MoveChase);
+    type["MoveConfused"]             = ALEBind::Method(&LuaUnit::MoveConfused);
+    type["MoveFleeing"]              = ALEBind::Method(&LuaUnit::MoveFleeing);
+    type["MoveTo"]                   = ALEBind::Method(&LuaUnit::MoveTo);
+    type["MoveJump"]                 = ALEBind::Method(&LuaUnit::MoveJump);
+    type["SendUnitWhisper"]          = ALEBind::Method(&LuaUnit::SendUnitWhisper);
+    type["SendUnitEmote"]            = ALEBind::Method(&LuaUnit::SendUnitEmote);
+    type["SendUnitSay"]              = ALEBind::Method(&LuaUnit::SendUnitSay);
+    type["SendUnitYell"]             = ALEBind::Method(&LuaUnit::SendUnitYell);
+    type["DeMorph"]                  = ALEBind::Method(&LuaUnit::DeMorph);
+    type["CastSpell"]                = ALEBind::Method(&LuaUnit::CastSpell);
+    type["CastCustomSpell"]          = ALEBind::Method(&LuaUnit::CastCustomSpell);
+    type["CastSpellAoF"]             = ALEBind::Method(&LuaUnit::CastSpellAoF);
+    type["ClearInCombat"]            = ALEBind::Method(&LuaUnit::ClearInCombat);
+    type["StopSpellCast"]            = ALEBind::Method(&LuaUnit::StopSpellCast);
+    type["InterruptSpell"]           = ALEBind::Method(&LuaUnit::InterruptSpell);
+    type["AddAura"]                  = ALEBind::Method(&LuaUnit::AddAura);
+    type["RemoveAura"]               = ALEBind::Method(&LuaUnit::RemoveAura);
+    type["RemoveAllAuras"]           = ALEBind::Method(&LuaUnit::RemoveAllAuras);
+    type["RemoveArenaAuras"]         = ALEBind::Method(&LuaUnit::RemoveArenaAuras);
+    type["AddUnitState"]             = ALEBind::Method(&LuaUnit::AddUnitState);
+    type["ClearUnitState"]           = ALEBind::Method(&LuaUnit::ClearUnitState);
+    type["NearTeleport"]             = ALEBind::Method(&LuaUnit::NearTeleport);
+    type["DealDamage"]               = ALEBind::Method(&LuaUnit::DealDamage);
+    type["DealHeal"]                 = ALEBind::Method(&LuaUnit::DealHeal);
+    type["Kill"]                     = ALEBind::Method(&LuaUnit::Kill);
+    type["AddThreat"]                = ALEBind::Method(&LuaUnit::AddThreat);
+    type["ModifyThreatPct"]          = ALEBind::Method(&LuaUnit::ModifyThreatPct);
+    type["ClearThreat"]              = ALEBind::Method(&LuaUnit::ClearThreat);
+    type["ResetAllThreat"]           = ALEBind::Method(&LuaUnit::ResetAllThreat);
+    type["GetThreat"]                = ALEBind::Method(&LuaUnit::GetThreat);
+}
diff --git a/src/LuaEngine/methods/VehicleMethods.h b/src/LuaEngine/methods/VehicleMethods.cpp
similarity index 52%
rename from src/LuaEngine/methods/VehicleMethods.h
rename to src/LuaEngine/methods/VehicleMethods.cpp
index bb0a40c558..9c01896f56 100644
--- a/src/LuaEngine/methods/VehicleMethods.h
+++ b/src/LuaEngine/methods/VehicleMethods.cpp
@@ -4,8 +4,10 @@
 * Please see the included DOCS/LICENSE.md for more information
 */
 
-#ifndef VEHICLEMETHODS_H
-#define VEHICLEMETHODS_H
+#include "ALEBind.h"
+
+#include "Unit.h"
+#include "Vehicle.h"
 
 /***
  * Represents a vehicle in the game, which can carry passengers and provide special abilities or movement.
@@ -20,11 +22,9 @@ namespace LuaVehicle
      * @param [Unit] passenger
      * @return bool isOnBoard
      */
-    int IsOnBoard(lua_State* L, Vehicle* vehicle)
+    bool IsOnBoard(Vehicle* vehicle, Unit* passenger)
     {
-        Unit* passenger = ALE::CHECKOBJ(L, 2);
-        ALE::Push(L, passenger->IsOnVehicle(vehicle->GetBase()));
-        return 1;
+        return passenger->IsOnVehicle(vehicle->GetBase());
     }
 
     /**
@@ -32,10 +32,9 @@ namespace LuaVehicle
      *
      * @return [Unit] owner
      */
-    int GetOwner(lua_State* L, Vehicle* vehicle)
+    Unit* GetOwner(Vehicle* vehicle)
     {
-        ALE::Push(L, vehicle->GetBase());
-        return 1;
+        return vehicle->GetBase();
     }
 
     /**
@@ -43,10 +42,9 @@ namespace LuaVehicle
      *
      * @return uint32 entry
      */
-    int GetEntry(lua_State* L, Vehicle* vehicle)
+    uint32 GetEntry(Vehicle* vehicle)
     {
-        ALE::Push(L, vehicle->GetVehicleInfo()->m_ID);
-        return 1;
+        return vehicle->GetVehicleInfo()->m_ID;
     }
 
     /**
@@ -55,11 +53,9 @@ namespace LuaVehicle
      * @param int8 seat
      * @return [Unit] passenger
      */
-    int GetPassenger(lua_State* L, Vehicle* vehicle)
+    Unit* GetPassenger(Vehicle* vehicle, int8 seatId)
     {
-        int8 seatId = ALE::CHECKVAL(L, 2);
-        ALE::Push(L, vehicle->GetPassenger(seatId));
-        return 1;
+        return vehicle->GetPassenger(seatId);
     }
 
     /**
@@ -68,13 +64,9 @@ namespace LuaVehicle
      * @param [Unit] passenger
      * @param int8 seat
      */
-    int AddPassenger(lua_State* L, Vehicle* vehicle)
+    void AddPassenger(Vehicle* vehicle, Unit* passenger, int8 seatId)
     {
-        Unit* passenger = ALE::CHECKOBJ(L, 2);
-        int8 seatId = ALE::CHECKVAL(L, 3);
-
         vehicle->AddPassenger(passenger, seatId);
-        return 0;
     }
 
     /**
@@ -82,12 +74,20 @@ namespace LuaVehicle
      *
      * @param [Unit] passenger
      */
-    int RemovePassenger(lua_State* L, Vehicle* vehicle)
+    void RemovePassenger(Vehicle* vehicle, Unit* passenger)
     {
-        Unit* passenger = ALE::CHECKOBJ(L, 2);
         vehicle->RemovePassenger(passenger);
-        return 0;
     }
 }
 
-#endif // VEHICLEMETHODS_H
+void RegisterVehicleMethods(sol::state& lua)
+{
+    sol::usertype> type = ALEBind::NewHandleType>(lua, "Vehicle");
+
+    type["IsOnBoard"]       = ALEBind::Method(&LuaVehicle::IsOnBoard);
+    type["GetOwner"]        = ALEBind::Method(&LuaVehicle::GetOwner);
+    type["GetEntry"]        = ALEBind::Method(&LuaVehicle::GetEntry);
+    type["GetPassenger"]    = ALEBind::Method(&LuaVehicle::GetPassenger);
+    type["AddPassenger"]    = ALEBind::Method(&LuaVehicle::AddPassenger);
+    type["RemovePassenger"] = ALEBind::Method(&LuaVehicle::RemovePassenger);
+}
diff --git a/src/LuaEngine/methods/WorldObjectMethods.h b/src/LuaEngine/methods/WorldObjectMethods.cpp
similarity index 52%
rename from src/LuaEngine/methods/WorldObjectMethods.h
rename to src/LuaEngine/methods/WorldObjectMethods.cpp
index a92a435b01..d6b5c6e4cc 100644
--- a/src/LuaEngine/methods/WorldObjectMethods.h
+++ b/src/LuaEngine/methods/WorldObjectMethods.cpp
@@ -4,8 +4,20 @@
 * Please see the included DOCS/LICENSE.md for more information
 */
 
-#ifndef WORLDOBJECTMETHODS_H
-#define WORLDOBJECTMETHODS_H
+#include "ALEBind.h"
+#include "ALEEventMgr.h"
+#include "ALEUtility.h"
+
+#include "CellImpl.h"
+#include "DBCStores.h"
+#include "GameObject.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
+#include "Object.h"
+#include "Opcodes.h"
+#include "Player.h"
+#include "TemporarySummon.h"
+#include "WorldPacket.h"
 
 /***
  * Represents a [WorldObject] in the game world.
@@ -19,10 +31,9 @@ namespace LuaWorldObject
      *
      * @return string name
      */
-    int GetName(lua_State* L, WorldObject* obj)
+    std::string GetName(WorldObject* worldobject)
     {
-        ALE::Push(L, obj->GetName());
-        return 1;
+        return worldobject->GetName();
     }
 
     /**
@@ -30,10 +41,9 @@ namespace LuaWorldObject
      *
      * @return [Map] mapObject
      */
-    int GetMap(lua_State* L, WorldObject* obj)
+    Map* GetMap(WorldObject* worldobject)
     {
-        ALE::Push(L, obj->GetMap());
-        return 1;
+        return worldobject->GetMap();
     }
 
     /**
@@ -41,10 +51,9 @@ namespace LuaWorldObject
      *
      * @return uint32 phase
      */
-    int GetPhaseMask(lua_State* L, WorldObject* obj)
+    uint32 GetPhaseMask(WorldObject* worldobject)
     {
-        ALE::Push(L, obj->GetPhaseMask());
-        return 1;
+        return worldobject->GetPhaseMask();
     }
 
     /**
@@ -53,12 +62,10 @@ namespace LuaWorldObject
     * @param uint32 phaseMask
     * @param bool update = true : update visibility to nearby objects
     */
-    int SetPhaseMask(lua_State* L, WorldObject* obj)
+    void SetPhaseMask(WorldObject* worldobject, uint32 phaseMask, sol::optional updateArg)
     {
-        uint32 phaseMask = ALE::CHECKVAL(L, 2);
-        bool update = ALE::CHECKVAL(L, 3, true);
-        obj->SetPhaseMask(phaseMask, update);
-        return 0;
+        bool update = updateArg.value_or(true);
+        worldobject->SetPhaseMask(phaseMask, update);
     }
 
     /**
@@ -66,10 +73,9 @@ namespace LuaWorldObject
      *
      * @return uint32 instanceId
      */
-    int GetInstanceId(lua_State* L, WorldObject* obj)
+    uint32 GetInstanceId(WorldObject* worldobject)
     {
-        ALE::Push(L, obj->GetInstanceId());
-        return 1;
+        return worldobject->GetInstanceId();
     }
 
     /**
@@ -77,10 +83,9 @@ namespace LuaWorldObject
      *
      * @return uint32 areaId
      */
-    int GetAreaId(lua_State* L, WorldObject* obj)
+    uint32 GetAreaId(WorldObject* worldobject)
     {
-        ALE::Push(L, obj->GetAreaId());
-        return 1;
+        return worldobject->GetAreaId();
     }
 
     /**
@@ -88,10 +93,9 @@ namespace LuaWorldObject
      *
      * @return uint32 zoneId
      */
-    int GetZoneId(lua_State* L, WorldObject* obj)
+    uint32 GetZoneId(WorldObject* worldobject)
     {
-        ALE::Push(L, obj->GetZoneId());
-        return 1;
+        return worldobject->GetZoneId();
     }
 
     /**
@@ -99,10 +103,9 @@ namespace LuaWorldObject
      *
      * @return uint32 mapId
      */
-    int GetMapId(lua_State* L, WorldObject* obj)
+    uint32 GetMapId(WorldObject* worldobject)
     {
-        ALE::Push(L, obj->GetMapId());
-        return 1;
+        return worldobject->GetMapId();
     }
 
     /**
@@ -110,10 +113,9 @@ namespace LuaWorldObject
      *
      * @return float x
      */
-    int GetX(lua_State* L, WorldObject* obj)
+    float GetX(WorldObject* worldobject)
     {
-        ALE::Push(L, obj->GetPositionX());
-        return 1;
+        return worldobject->GetPositionX();
     }
 
     /**
@@ -121,10 +123,9 @@ namespace LuaWorldObject
      *
      * @return float y
      */
-    int GetY(lua_State* L, WorldObject* obj)
+    float GetY(WorldObject* worldobject)
     {
-        ALE::Push(L, obj->GetPositionY());
-        return 1;
+        return worldobject->GetPositionY();
     }
 
     /**
@@ -132,10 +133,9 @@ namespace LuaWorldObject
      *
      * @return float z
      */
-    int GetZ(lua_State* L, WorldObject* obj)
+    float GetZ(WorldObject* worldobject)
     {
-        ALE::Push(L, obj->GetPositionZ());
-        return 1;
+        return worldobject->GetPositionZ();
     }
 
     /**
@@ -143,10 +143,9 @@ namespace LuaWorldObject
      *
      * @return float orientation / facing
      */
-    int GetO(lua_State* L, WorldObject* obj)
+    float GetO(WorldObject* worldobject)
     {
-        ALE::Push(L, obj->GetOrientation());
-        return 1;
+        return worldobject->GetOrientation();
     }
 
     /**
@@ -157,13 +156,9 @@ namespace LuaWorldObject
      * @return float z : z coordinate (height) of the [WorldObject]
      * @return float o : facing / orientation of  the [WorldObject]
      */
-    int GetLocation(lua_State* L, WorldObject* obj)
+    std::tuple GetLocation(WorldObject* worldobject)
     {
-        ALE::Push(L, obj->GetPositionX());
-        ALE::Push(L, obj->GetPositionY());
-        ALE::Push(L, obj->GetPositionZ());
-        ALE::Push(L, obj->GetOrientation());
-        return 4;
+        return std::tuple(worldobject->GetPositionX(), worldobject->GetPositionY(), worldobject->GetPositionZ(), worldobject->GetOrientation());
     }
 
     /**
@@ -175,20 +170,19 @@ namespace LuaWorldObject
      *
      * @return [Player] nearestPlayer
      */
-    int GetNearestPlayer(lua_State* L, WorldObject* obj)
+    Unit* GetNearestPlayer(WorldObject* worldobject, sol::optional rangeArg, sol::optional hostileArg, sol::optional deadArg)
     {
-        float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS);
-        uint32 hostile = ALE::CHECKVAL(L, 3, 0);
-        uint32 dead = ALE::CHECKVAL(L, 4, 1);
+        float range = rangeArg.value_or(SIZE_OF_GRIDS);
+        uint32 hostile = hostileArg.value_or(0);
+        uint32 dead = deadArg.value_or(1);
 
-        Unit* target = NULL;
-        ALEUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_PLAYER, 0, hostile, dead);
+        Unit* target = nullptr;
+        ALEUtil::WorldObjectInRangeCheck checker(true, worldobject, range, TYPEMASK_PLAYER, 0, hostile, dead);
 
-        Acore::UnitLastSearcher searcher(obj, target, checker);
-        Cell::VisitObjects(obj, searcher, range);
+        Acore::UnitLastSearcher searcher(worldobject, target, checker);
+        Cell::VisitObjects(worldobject, searcher, range);
 
-        ALE::Push(L, target);
-        return 1;
+        return target;
     }
 
     /**
@@ -200,20 +194,19 @@ namespace LuaWorldObject
      *
      * @return [GameObject] nearestGameObject
      */
-    int GetNearestGameObject(lua_State* L, WorldObject* obj)
+    GameObject* GetNearestGameObject(WorldObject* worldobject, sol::optional rangeArg, sol::optional entryArg, sol::optional hostileArg)
     {
-        float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS);
-        uint32 entry = ALE::CHECKVAL(L, 3, 0);
-        uint32 hostile = ALE::CHECKVAL(L, 4, 0);
+        float range = rangeArg.value_or(SIZE_OF_GRIDS);
+        uint32 entry = entryArg.value_or(0);
+        uint32 hostile = hostileArg.value_or(0);
 
-        GameObject* target = NULL;
-        ALEUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_GAMEOBJECT, entry, hostile);
+        GameObject* target = nullptr;
+        ALEUtil::WorldObjectInRangeCheck checker(true, worldobject, range, TYPEMASK_GAMEOBJECT, entry, hostile);
 
-        Acore::GameObjectLastSearcher searcher(obj, target, checker);
-        Cell::VisitObjects(obj, searcher, range);
+        Acore::GameObjectLastSearcher searcher(worldobject, target, checker);
+        Cell::VisitObjects(worldobject, searcher, range);
 
-        ALE::Push(L, target);
-        return 1;
+        return target;
     }
 
     /**
@@ -226,21 +219,20 @@ namespace LuaWorldObject
      *
      * @return [Creature] nearestCreature
      */
-    int GetNearestCreature(lua_State* L, WorldObject* obj)
+    Creature* GetNearestCreature(WorldObject* worldobject, sol::optional rangeArg, sol::optional entryArg, sol::optional hostileArg, sol::optional deadArg)
     {
-        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);
+        float range = rangeArg.value_or(SIZE_OF_GRIDS);
+        uint32 entry = entryArg.value_or(0);
+        uint32 hostile = hostileArg.value_or(0);
+        uint32 dead = deadArg.value_or(1);
 
-        Creature* target = NULL;
-        ALEUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_UNIT, entry, hostile, dead);
+        Creature* target = nullptr;
+        ALEUtil::WorldObjectInRangeCheck checker(true, worldobject, range, TYPEMASK_UNIT, entry, hostile, dead);
 
-        Acore::CreatureLastSearcher searcher(obj, target, checker);
-        Cell::VisitObjects(obj, searcher, range);
+        Acore::CreatureLastSearcher searcher(worldobject, target, checker);
+        Cell::VisitObjects(worldobject, searcher, range);
 
-        ALE::Push(L, target);
-        return 1;
+        return target;
     }
 
     /**
@@ -252,30 +244,25 @@ namespace LuaWorldObject
      *
      * @return table playersInRange : table of [Player]s
      */
-    int GetPlayersInRange(lua_State* L, WorldObject* obj)
+    sol::table GetPlayersInRange(WorldObject* worldobject, sol::optional rangeArg, sol::optional hostileArg, sol::optional deadArg, sol::this_state s)
     {
-        float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS);
-        uint32 hostile = ALE::CHECKVAL(L, 3, 0);
-        uint32 dead = ALE::CHECKVAL(L, 4, 1);
+        float range = rangeArg.value_or(SIZE_OF_GRIDS);
+        uint32 hostile = hostileArg.value_or(0);
+        uint32 dead = deadArg.value_or(1);
 
         std::list list;
-        ALEUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_PLAYER, 0, hostile, dead);
+        ALEUtil::WorldObjectInRangeCheck checker(false, worldobject, range, TYPEMASK_PLAYER, 0, hostile, dead);
 
-        Acore::PlayerListSearcher searcher(obj, list, checker);
-        Cell::VisitObjects(obj, searcher, range);
+        Acore::PlayerListSearcher searcher(worldobject, list, checker);
+        Cell::VisitObjects(worldobject, searcher, range);
 
-        lua_createtable(L, list.size(), 0);
-        int tbl = lua_gettop(L);
+        sol::table tbl = sol::state_view(s).create_table();
         uint32 i = 0;
 
         for (std::list::const_iterator it = list.begin(); it != list.end(); ++it)
-        {
-            ALE::Push(L, *it);
-            lua_rawseti(L, tbl, ++i);
-        }
+            tbl[++i] = PlayerRef(*it);
 
-        lua_settop(L, tbl);
-        return 1;
+        return tbl;
     }
 
     /**
@@ -288,31 +275,26 @@ namespace LuaWorldObject
      *
      * @return table creaturesInRange : table of [Creature]s
      */
-    int GetCreaturesInRange(lua_State* L, WorldObject* obj)
+    sol::table GetCreaturesInRange(WorldObject* worldobject, sol::optional rangeArg, sol::optional entryArg, sol::optional hostileArg, sol::optional deadArg, sol::this_state s)
     {
-        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);
+        float range = rangeArg.value_or(SIZE_OF_GRIDS);
+        uint32 entry = entryArg.value_or(0);
+        uint32 hostile = hostileArg.value_or(0);
+        uint32 dead = deadArg.value_or(1);
 
         std::list list;
-        ALEUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_UNIT, entry, hostile, dead);
+        ALEUtil::WorldObjectInRangeCheck checker(false, worldobject, range, TYPEMASK_UNIT, entry, hostile, dead);
 
-        Acore::CreatureListSearcher searcher(obj, list, checker);
-        Cell::VisitObjects(obj, searcher, range);
+        Acore::CreatureListSearcher searcher(worldobject, list, checker);
+        Cell::VisitObjects(worldobject, searcher, range);
 
-        lua_createtable(L, list.size(), 0);
-        int tbl = lua_gettop(L);
+        sol::table tbl = sol::state_view(s).create_table();
         uint32 i = 0;
 
         for (std::list::const_iterator it = list.begin(); it != list.end(); ++it)
-        {
-            ALE::Push(L, *it);
-            lua_rawseti(L, tbl, ++i);
-        }
+            tbl[++i] = CreatureRef(*it);
 
-        lua_settop(L, tbl);
-        return 1;
+        return tbl;
     }
 
     /**
@@ -324,30 +306,25 @@ namespace LuaWorldObject
      *
      * @return table gameObjectsInRange : table of [GameObject]s
      */
-    int GetGameObjectsInRange(lua_State* L, WorldObject* obj)
+    sol::table GetGameObjectsInRange(WorldObject* worldobject, sol::optional rangeArg, sol::optional entryArg, sol::optional hostileArg, sol::this_state s)
     {
-        float range = ALE::CHECKVAL(L, 2, SIZE_OF_GRIDS);
-        uint32 entry = ALE::CHECKVAL(L, 3, 0);
-        uint32 hostile = ALE::CHECKVAL(L, 4, 0);
+        float range = rangeArg.value_or(SIZE_OF_GRIDS);
+        uint32 entry = entryArg.value_or(0);
+        uint32 hostile = hostileArg.value_or(0);
 
         std::list list;
-        ALEUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_GAMEOBJECT, entry, hostile);
+        ALEUtil::WorldObjectInRangeCheck checker(false, worldobject, range, TYPEMASK_GAMEOBJECT, entry, hostile);
 
-        Acore::GameObjectListSearcher searcher(obj, list, checker);
-        Cell::VisitObjects(obj, searcher, range);
+        Acore::GameObjectListSearcher searcher(worldobject, list, checker);
+        Cell::VisitObjects(worldobject, searcher, range);
 
-        lua_createtable(L, list.size(), 0);
-        int tbl = lua_gettop(L);
+        sol::table tbl = sol::state_view(s).create_table();
         uint32 i = 0;
 
         for (std::list::const_iterator it = list.begin(); it != list.end(); ++it)
-        {
-            ALE::Push(L, *it);
-            lua_rawseti(L, tbl, ++i);
-        }
+            tbl[++i] = GameObjectRef(*it);
 
-        lua_settop(L, tbl);
-        return 1;
+        return tbl;
     }
 
     /**
@@ -362,25 +339,24 @@ namespace LuaWorldObject
      *
      * @return [WorldObject] worldObject
      */
-    int GetNearObject(lua_State* L, WorldObject* obj)
+    WorldObject* GetNearObject(WorldObject* worldobject, sol::optional rangeArg, sol::optional typeArg, sol::optional entryArg, sol::optional hostileArg, sol::optional deadArg)
     {
-        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 range = rangeArg.value_or(SIZE_OF_GRIDS);
+        uint16 type = typeArg.value_or(0); // TypeMask
+        uint32 entry = entryArg.value_or(0);
+        uint32 hostile = hostileArg.value_or(0); // 0 none, 1 hostile, 2 friendly
+        uint32 dead = deadArg.value_or(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->GetPosition(x, y, z);
+        ALEUtil::WorldObjectInRangeCheck checker(true, worldobject, range, type, entry, hostile, dead);
 
-        WorldObject* target = NULL;
+        WorldObject* target = nullptr;
 
-        Acore::WorldObjectLastSearcher searcher(obj, target, checker);
-        Cell::VisitObjects(obj, searcher, range);
+        Acore::WorldObjectLastSearcher searcher(worldobject, target, checker);
+        Cell::VisitObjects(worldobject, searcher, range);
 
-        ALE::Push(L, target);
-        return 1;
+        return target;
     }
 
     /**
@@ -395,35 +371,31 @@ namespace LuaWorldObject
      *
      * @return table worldObjectList : table of [WorldObject]s
      */
-    int GetNearObjects(lua_State* L, WorldObject* obj)
+    sol::table GetNearObjects(WorldObject* worldobject, sol::optional rangeArg, sol::optional typeArg, sol::optional entryArg, sol::optional hostileArg, sol::optional deadArg, sol::this_state s)
     {
-        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 range = rangeArg.value_or(SIZE_OF_GRIDS);
+        uint16 type = typeArg.value_or(0); // TypeMask
+        uint32 entry = entryArg.value_or(0);
+        uint32 hostile = hostileArg.value_or(0); // 0 none, 1 hostile, 2 friendly
+        uint32 dead = deadArg.value_or(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);
+        worldobject->GetPosition(x, y, z);
+        ALEUtil::WorldObjectInRangeCheck checker(false, worldobject, range, type, entry, hostile, dead);
 
         std::list list;
 
-        Acore::WorldObjectListSearcher searcher(obj, list, checker);
-        Cell::VisitObjects(obj, searcher, range);
+        Acore::WorldObjectListSearcher searcher(worldobject, list, checker);
+        Cell::VisitObjects(worldobject, searcher, range);
 
-        lua_createtable(L, list.size(), 0);
-        int tbl = lua_gettop(L);
+        sol::state_view lua(s);
+        sol::table tbl = lua.create_table();
         uint32 i = 0;
 
         for (std::list::const_iterator it = list.begin(); it != list.end(); ++it)
-        {
-            ALE::Push(L, *it);
-            lua_rawseti(L, tbl, ++i);
-        }
+            tbl[++i] = ALEBind::ToLuaDynamic(lua, *it);
 
-        lua_settop(L, tbl);
-        return 1;
+        return tbl;
     }
 
     /**
@@ -441,19 +413,19 @@ namespace LuaWorldObject
      *
      * @return float dist : the distance in yards
      */
-    int GetDistance(lua_State* L, WorldObject* obj)
+    float GetDistance(WorldObject* worldobject, sol::object first, sol::optional yArg, sol::optional zArg)
     {
-        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;
+        if (first.is())
+            if (WorldObject* target = first.as().Resolve())
+                return worldobject->GetDistance(target);
+
+        if (!first.is() || !yArg || !zArg)
+            throw std::invalid_argument("WorldObject or coordinates (x, y, z) expected");
+
+        float X = first.as();
+        float Y = *yArg;
+        float Z = *zArg;
+        return worldobject->GetDistance(X, Y, Z);
     }
 
     /**
@@ -471,11 +443,12 @@ namespace LuaWorldObject
      *
      * @return float dist : the distance in yards
      */
-    int GetExactDistance(lua_State* L, WorldObject* obj)
+    float GetExactDistance(WorldObject* worldobject, sol::object first, sol::optional yArg, sol::optional zArg)
     {
         float x, y, z;
-        obj->GetPosition(x, y, z);
-        WorldObject* target = ALE::CHECKOBJ(L, 2, false);
+        worldobject->GetPosition(x, y, z);
+
+        WorldObject* target = first.is() ? first.as().Resolve() : nullptr;
         if (target)
         {
             float x2, y2, z2;
@@ -486,13 +459,15 @@ namespace LuaWorldObject
         }
         else
         {
-            x -= ALE::CHECKVAL(L, 2);
-            y -= ALE::CHECKVAL(L, 3);
-            z -= ALE::CHECKVAL(L, 4);
+            if (!first.is() || !yArg || !zArg)
+                throw std::invalid_argument("WorldObject or coordinates (x, y, z) expected");
+
+            x -= first.as();
+            y -= *yArg;
+            z -= *zArg;
         }
 
-        ALE::Push(L, std::sqrt(x*x + y*y + z*z));
-        return 1;
+        return std::sqrt(x*x + y*y + z*z);
     }
 
     /**
@@ -509,18 +484,18 @@ namespace LuaWorldObject
      *
      * @return float dist : the distance in yards
      */
-    int GetDistance2d(lua_State* L, WorldObject* obj)
+    float GetDistance2d(WorldObject* worldobject, sol::object first, sol::optional yArg)
     {
-        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;
+        if (first.is())
+            if (WorldObject* target = first.as().Resolve())
+                return worldobject->GetDistance2d(target);
+
+        if (!first.is() || !yArg)
+            throw std::invalid_argument("WorldObject or coordinates (x, y) expected");
+
+        float X = first.as();
+        float Y = *yArg;
+        return worldobject->GetDistance2d(X, Y);
     }
 
     /**
@@ -537,11 +512,12 @@ namespace LuaWorldObject
      *
      * @return float dist : the distance in yards
      */
-    int GetExactDistance2d(lua_State* L, WorldObject* obj)
+    float GetExactDistance2d(WorldObject* worldobject, sol::object first, sol::optional yArg)
     {
         float x, y, z;
-        obj->GetPosition(x, y, z);
-        WorldObject* target = ALE::CHECKOBJ(L, 2, false);
+        worldobject->GetPosition(x, y, z);
+
+        WorldObject* target = first.is() ? first.as().Resolve() : nullptr;
         if (target)
         {
             float x2, y2, z2;
@@ -551,12 +527,14 @@ namespace LuaWorldObject
         }
         else
         {
-            x -= ALE::CHECKVAL(L, 2);
-            y -= ALE::CHECKVAL(L, 3);
+            if (!first.is() || !yArg)
+                throw std::invalid_argument("WorldObject or coordinates (x, y) expected");
+
+            x -= first.as();
+            y -= *yArg;
         }
 
-        ALE::Push(L, std::sqrt(x*x + y*y));
-        return 1;
+        return std::sqrt(x*x + y*y);
     }
 
     /**
@@ -569,18 +547,12 @@ namespace LuaWorldObject
      * @return float y
      * @return float z
      */
-    int GetRelativePoint(lua_State* L, WorldObject* obj)
+    std::tuple GetRelativePoint(WorldObject* worldobject, float dist, float rad)
     {
-        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);
+        worldobject->GetClosePoint(x, y, z, 0.0f, dist, rad);
 
-        ALE::Push(L, x);
-        ALE::Push(L, y);
-        ALE::Push(L, z);
-        return 3;
+        return std::tuple(x, y, z);
     }
 
     /**
@@ -597,19 +569,18 @@ namespace LuaWorldObject
      *
      * @return float angle : angle in radians in range 0..2*pi
      */
-    int GetAngle(lua_State* L, WorldObject* obj)
+    float GetAngle(WorldObject* worldobject, sol::object first, sol::optional yArg)
     {
-        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));
-        }
+        if (first.is())
+            if (WorldObject* target = first.as().Resolve())
+                return worldobject->GetAbsoluteAngle(target);
+
+        if (!first.is() || !yArg)
+            throw std::invalid_argument("WorldObject or coordinates (x, y) expected");
 
-        return 1;
+        float x = first.as();
+        float y = *yArg;
+        return worldobject->GetAbsoluteAngle(x, y);
     }
 
     /**
@@ -617,10 +588,9 @@ namespace LuaWorldObject
      *
      * @return [Transport] transport
      */
-    int GetTransport(lua_State* L, WorldObject* obj)
+    Transport* GetTransport(WorldObject* worldobject)
     {
-        ALE::Push(L, static_cast(obj->GetTransport()));
-        return 1;
+        return static_cast(worldobject->GetTransport());
     }
 
     /**
@@ -628,11 +598,9 @@ namespace LuaWorldObject
      *
      * @param [WorldPacket] packet
      */
-    int SendPacket(lua_State* L, WorldObject* obj)
+    void SendPacket(WorldObject* worldobject, WorldPacket* data)
     {
-        WorldPacket* data = ALE::CHECKOBJ(L, 2);
-        obj->SendMessageToSet(data, true);
-        return 0;
+        worldobject->SendMessageToSet(data, true);
     }
 
     /**
@@ -646,17 +614,11 @@ namespace LuaWorldObject
      * @param uint32 respawnDelay = 30 : respawn time in seconds
      * @return [GameObject] gameObject
      */
-    int SummonGameObject(lua_State* L, WorldObject* obj)
+    GameObject* SummonGameObject(WorldObject* worldobject, uint32 entry, float x, float y, float z, float o, sol::optional respawnDelayArg)
     {
-        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;
+        uint32 respawnDelay = respawnDelayArg.value_or(30);
+
+        return worldobject->SummonGameObject(entry, x, y, z, o, 0, 0, 0, 0, respawnDelay);
     }
 
     /**
@@ -685,15 +647,10 @@ namespace LuaWorldObject
      * @param uint32 despawnTimer = 0 : despawn time in milliseconds
      * @return [Creature] spawnedCreature
      */
-    int SpawnCreature(lua_State* L, WorldObject* obj)
+    Creature* SpawnCreature(WorldObject* worldobject, uint32 entry, float x, float y, float z, float o, sol::optional spawnTypeArg, sol::optional despawnTimerArg)
     {
-        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);
+        uint32 spawnType = spawnTypeArg.value_or(8);
+        uint32 despawnTimer = despawnTimerArg.value_or(0);
 
         TempSummonType type;
         switch (spawnType)
@@ -723,11 +680,10 @@ namespace LuaWorldObject
                 type = TEMPSUMMON_MANUAL_DESPAWN;
                 break;
             default:
-                return luaL_argerror(L, 7, "valid SpawnType expected");
+                throw std::invalid_argument("valid SpawnType expected");
         }
 
-        ALE::Push(L, obj->SummonCreature(entry, x, y, z, o, type, despawnTimer));
-        return 1;
+        return worldobject->SummonCreature(entry, x, y, z, o, type, despawnTimer);
     }
 
     /**
@@ -755,35 +711,29 @@ namespace LuaWorldObject
      * @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)
+    uint64 RegisterEvent(WorldObject* worldobject, sol::protected_function function, sol::object delay, sol::optional repeatsArg)
     {
-        luaL_checktype(L, 2, LUA_TFUNCTION);
         uint32 min, max;
-        if (lua_istable(L, 3))
+        if (delay.is())
         {
-            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);
+            sol::table delayTable = delay.as();
+            min = delayTable.get(1);
+            max = delayTable.get(2);
         }
         else
-            min = max = ALE::CHECKVAL(L, 3);
-        uint32 repeats = ALE::CHECKVAL(L, 4, 1);
+        {
+            sol::optional delayValue = delay.as>();
+            if (!delayValue)
+                throw std::invalid_argument("number or table expected");
+
+            min = max = *delayValue;
+        }
+        uint32 repeats = repeatsArg.value_or(1);
 
         if (min > max)
-            return luaL_argerror(L, 3, "min is bigger than max delay");
+            throw std::invalid_argument("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;
+        return worldobject->ALEEvents->AddEvent(function, min, max, repeats);
     }
 
     /**
@@ -791,21 +741,18 @@ namespace LuaWorldObject
      *
      * @param int eventId : event Id to remove
      */
-    int RemoveEventById(lua_State* L, WorldObject* obj)
+    void RemoveEventById(WorldObject* worldobject, uint64 eventId)
     {
-        int eventId = ALE::CHECKVAL(L, 2);
-        obj->ALEEvents->SetState(eventId, LUAEVENT_STATE_ABORT);
-        return 0;
+        worldobject->ALEEvents->SetState(eventId, LUAEVENT_STATE_ABORT);
     }
 
     /**
      * Removes all timed events from a [WorldObject]
      *
      */
-    int RemoveEvents(lua_State* /*L*/, WorldObject* obj)
+    void RemoveEvents(WorldObject* worldobject)
     {
-        obj->ALEEvents->SetStates(LUAEVENT_STATE_ABORT);
-        return 0;
+        worldobject->ALEEvents->SetStates(LUAEVENT_STATE_ABORT);
     }
 
     /**
@@ -820,21 +767,19 @@ namespace LuaWorldObject
      * @param float z
      * @return bool isInLoS
      */
-    int IsWithinLoS(lua_State* L, WorldObject* obj)
+    bool IsWithinLoS(WorldObject* worldobject, sol::object first, sol::optional yArg, sol::optional zArg)
     {
-        WorldObject* target = ALE::CHECKOBJ(L, 2, false);
+        if (first.is())
+            if (WorldObject* target = first.as().Resolve())
+                return worldobject->IsWithinLOSInMap(target);
 
-        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));
-        }
+        if (!first.is() || !yArg || !zArg)
+            throw std::invalid_argument("WorldObject or coordinates (x, y, z) expected");
 
-        return 1;
+        float x = first.as();
+        float y = *yArg;
+        float z = *zArg;
+        return worldobject->IsWithinLOS(x, y, z);
     }
 
     /**
@@ -843,11 +788,9 @@ namespace LuaWorldObject
      * @param [WorldObject] worldobject
      * @return bool isInMap
      */
-    int IsInMap(lua_State* L, WorldObject* obj)
+    bool IsInMap(WorldObject* worldobject, WorldObject* target)
     {
-        WorldObject* target = ALE::CHECKOBJ(L, 2, true);
-        ALE::Push(L, obj->IsInMap(target));
-        return 1;
+        return worldobject->IsInMap(target);
     }
 
     /**
@@ -861,14 +804,9 @@ namespace LuaWorldObject
      * @param float distance
      * @return bool isInDistance
      */
-    int IsWithinDist3d(lua_State* L, WorldObject* obj)
+    bool IsWithinDist3d(WorldObject* worldobject, float x, float y, float z, float dist)
     {
-        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;
+        return worldobject->IsWithinDist3d(x, y, z, dist);
     }
 
     /**
@@ -882,13 +820,9 @@ namespace LuaWorldObject
      * @param float distance
      * @return bool isInDistance
      */
-    int IsWithinDist2d(lua_State* L, WorldObject* obj)
+    bool IsWithinDist2d(WorldObject* worldobject, float x, float y, float dist)
     {
-        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;
+        return worldobject->IsWithinDist2d(x, y, dist);
     }
 
     /**
@@ -901,13 +835,10 @@ namespace LuaWorldObject
      * @param bool is3D = true : if false, only x,y coordinates used for checking
      * @return bool isInDistance
      */
-    int IsWithinDist(lua_State* L, WorldObject* obj)
+    bool IsWithinDist(WorldObject* worldobject, WorldObject* target, float distance, sol::optional is3DArg)
     {
-        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;
+        bool is3D = is3DArg.value_or(true);
+        return worldobject->IsWithinDist(target, distance, is3D);
     }
 
     /**
@@ -920,14 +851,11 @@ namespace LuaWorldObject
      * @param bool is3D = true : if false, only x,y coordinates used for checking
      * @return bool isInDistance
      */
-    int IsWithinDistInMap(lua_State* L, WorldObject* obj)
+    bool IsWithinDistInMap(WorldObject* worldobject, WorldObject* target, float distance, sol::optional is3DArg)
     {
-        WorldObject* target = ALE::CHECKOBJ(L, 2);
-        float distance = ALE::CHECKVAL(L, 3);
-        bool is3D = ALE::CHECKVAL(L, 4, true);
+        bool is3D = is3DArg.value_or(true);
 
-        ALE::Push(L, obj->IsWithinDistInMap(target, distance, is3D));
-        return 1;
+        return worldobject->IsWithinDistInMap(target, distance, is3D);
     }
 
     /**
@@ -941,15 +869,11 @@ namespace LuaWorldObject
      * @param bool is3D = true : if false, only x,y coordinates used for checking
      * @return bool isInDistance
      */
-    int IsInRange(lua_State* L, WorldObject* obj)
+    bool IsInRange(WorldObject* worldobject, WorldObject* target, float minrange, float maxrange, sol::optional is3DArg)
     {
-        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);
+        bool is3D = is3DArg.value_or(true);
 
-        ALE::Push(L, obj->IsInRange(target, minrange, maxrange, is3D));
-        return 1;
+        return worldobject->IsInRange(target, minrange, maxrange, is3D);
     }
 
     /**
@@ -963,15 +887,9 @@ namespace LuaWorldObject
      * @param float maxrange
      * @return bool isInDistance
      */
-    int IsInRange2d(lua_State* L, WorldObject* obj)
+    bool IsInRange2d(WorldObject* worldobject, float x, float y, float minrange, float maxrange)
     {
-        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;
+        return worldobject->IsInRange2d(x, y, minrange, maxrange);
     }
 
     /**
@@ -986,16 +904,9 @@ namespace LuaWorldObject
      * @param float maxrange
      * @return bool isInDistance
      */
-    int IsInRange3d(lua_State* L, WorldObject* obj)
+    bool IsInRange3d(WorldObject* worldobject, float x, float y, float z, float minrange, float maxrange)
     {
-        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;
+        return worldobject->IsInRange3d(x, y, z, minrange, maxrange);
     }
 
     /**
@@ -1005,13 +916,11 @@ namespace LuaWorldObject
      * @param float arc = pi
      * @return bool isInFront
      */
-    int IsInFront(lua_State* L, WorldObject* obj)
+    bool IsInFront(WorldObject* worldobject, WorldObject* target, sol::optional arcArg)
     {
-        WorldObject* target = ALE::CHECKOBJ(L, 2);
-        float arc = ALE::CHECKVAL(L, 3, static_cast(M_PI));
+        float arc = arcArg.value_or(static_cast(M_PI));
 
-        ALE::Push(L, obj->isInFront(target, arc));
-        return 1;
+        return worldobject->isInFront(target, arc);
     }
 
     /**
@@ -1021,13 +930,11 @@ namespace LuaWorldObject
      * @param float arc = pi
      * @return bool isInBack
      */
-    int IsInBack(lua_State* L, WorldObject* obj)
+    bool IsInBack(WorldObject* worldobject, WorldObject* target, sol::optional arcArg)
     {
-        WorldObject* target = ALE::CHECKOBJ(L, 2);
-        float arc = ALE::CHECKVAL(L, 3, static_cast(M_PI));
+        float arc = arcArg.value_or(static_cast(M_PI));
 
-        ALE::Push(L, obj->isInBack(target, arc));
-        return 1;
+        return worldobject->isInBack(target, arc);
     }
 
     /**
@@ -1041,18 +948,16 @@ namespace LuaWorldObject
      * @param uint32 music : entry of a music
      * @param [Player] player = nil : [Player] to play the music to
      */
-    int PlayMusic(lua_State* L, WorldObject* obj)
+    void PlayMusic(WorldObject* worldobject, uint32 musicid, sol::optional playerArg)
     {
-        uint32 musicid = ALE::CHECKVAL(L, 2);
-        Player* player = ALE::CHECKOBJ(L, 3, false);
+        Player* player = playerArg ? playerArg->Resolve() : nullptr;
 
         WorldPacket data(SMSG_PLAY_MUSIC, 4);
         data << uint32(musicid);
         if (player)
             player->SendDirectMessage(&data);
         else
-            obj->SendMessageToSet(&data, true);
-        return 0;
+            worldobject->SendMessageToSet(&data, true);
     }
 
     /**
@@ -1066,18 +971,16 @@ namespace LuaWorldObject
      * @param uint32 sound : entry of a sound
      * @param [Player] player = nil : [Player] to play the sound to
      */
-    int PlayDirectSound(lua_State* L, WorldObject* obj)
+    void PlayDirectSound(WorldObject* worldobject, uint32 soundId, sol::optional playerArg)
     {
-        uint32 soundId = ALE::CHECKVAL(L, 2);
-        Player* player = ALE::CHECKOBJ(L, 3, false);
+        Player* player = playerArg ? playerArg->Resolve() : nullptr;
         if (!sSoundEntriesStore.LookupEntry(soundId))
-            return 0;
+            return;
 
         if (player)
-            obj->PlayDirectSound(soundId, player);
+            worldobject->PlayDirectSound(soundId, player);
         else
-            obj->PlayDirectSound(soundId);
-        return 0;
+            worldobject->PlayDirectSound(soundId);
     }
 
     /**
@@ -1092,18 +995,69 @@ namespace LuaWorldObject
      * @param uint32 sound : entry of a sound
      * @param [Player] player = nil : [Player] to play the sound to
      */
-    int PlayDistanceSound(lua_State* L, WorldObject* obj)
+    void PlayDistanceSound(WorldObject* worldobject, uint32 soundId, sol::optional playerArg)
     {
-        uint32 soundId = ALE::CHECKVAL(L, 2);
-        Player* player = ALE::CHECKOBJ(L, 3, false);
+        Player* player = playerArg ? playerArg->Resolve() : nullptr;
         if (!sSoundEntriesStore.LookupEntry(soundId))
-            return 0;
+            return;
 
         if (player)
-            obj->PlayDistanceSound(soundId, player);
+            worldobject->PlayDistanceSound(soundId, player);
         else
-            obj->PlayDistanceSound(soundId);
-        return 0;
+            worldobject->PlayDistanceSound(soundId);
     }
-};
-#endif
+}
+
+void RegisterWorldObjectMethods(sol::state& lua)
+{
+    sol::usertype type = ALEBind::NewHandleType(lua, "WorldObject");
+
+    type["GetName"]               = ALEBind::Method(&LuaWorldObject::GetName);
+    type["GetMap"]                = ALEBind::Method(&LuaWorldObject::GetMap);
+    type["GetPhaseMask"]          = ALEBind::Method(&LuaWorldObject::GetPhaseMask);
+    type["SetPhaseMask"]          = ALEBind::Method(&LuaWorldObject::SetPhaseMask);
+    type["GetInstanceId"]         = ALEBind::Method(&LuaWorldObject::GetInstanceId);
+    type["GetAreaId"]             = ALEBind::Method(&LuaWorldObject::GetAreaId);
+    type["GetZoneId"]             = ALEBind::Method(&LuaWorldObject::GetZoneId);
+    type["GetMapId"]              = ALEBind::Method(&LuaWorldObject::GetMapId);
+    type["GetX"]                  = ALEBind::Method(&LuaWorldObject::GetX);
+    type["GetY"]                  = ALEBind::Method(&LuaWorldObject::GetY);
+    type["GetZ"]                  = ALEBind::Method(&LuaWorldObject::GetZ);
+    type["GetO"]                  = ALEBind::Method(&LuaWorldObject::GetO);
+    type["GetLocation"]           = ALEBind::Method(&LuaWorldObject::GetLocation);
+    type["GetNearestPlayer"]      = ALEBind::Method(&LuaWorldObject::GetNearestPlayer);
+    type["GetNearestGameObject"]  = ALEBind::Method(&LuaWorldObject::GetNearestGameObject);
+    type["GetNearestCreature"]    = ALEBind::Method(&LuaWorldObject::GetNearestCreature);
+    type["GetPlayersInRange"]     = ALEBind::Method(&LuaWorldObject::GetPlayersInRange);
+    type["GetCreaturesInRange"]   = ALEBind::Method(&LuaWorldObject::GetCreaturesInRange);
+    type["GetGameObjectsInRange"] = ALEBind::Method(&LuaWorldObject::GetGameObjectsInRange);
+    type["GetNearObject"]         = ALEBind::Method(&LuaWorldObject::GetNearObject);
+    type["GetNearObjects"]        = ALEBind::Method(&LuaWorldObject::GetNearObjects);
+    type["GetDistance"]           = ALEBind::Method(&LuaWorldObject::GetDistance);
+    type["GetExactDistance"]      = ALEBind::Method(&LuaWorldObject::GetExactDistance);
+    type["GetDistance2d"]         = ALEBind::Method(&LuaWorldObject::GetDistance2d);
+    type["GetExactDistance2d"]    = ALEBind::Method(&LuaWorldObject::GetExactDistance2d);
+    type["GetRelativePoint"]      = ALEBind::Method(&LuaWorldObject::GetRelativePoint);
+    type["GetAngle"]              = ALEBind::Method(&LuaWorldObject::GetAngle);
+    type["GetTransport"]          = ALEBind::Method(&LuaWorldObject::GetTransport);
+    type["SendPacket"]            = ALEBind::Method(&LuaWorldObject::SendPacket);
+    type["SummonGameObject"]      = ALEBind::Method(&LuaWorldObject::SummonGameObject);
+    type["SpawnCreature"]         = ALEBind::Method(&LuaWorldObject::SpawnCreature);
+    type["RegisterEvent"]         = ALEBind::Method(&LuaWorldObject::RegisterEvent);
+    type["RemoveEventById"]       = ALEBind::Method(&LuaWorldObject::RemoveEventById);
+    type["RemoveEvents"]          = ALEBind::Method(&LuaWorldObject::RemoveEvents);
+    type["IsWithinLoS"]           = ALEBind::Method(&LuaWorldObject::IsWithinLoS);
+    type["IsInMap"]               = ALEBind::Method(&LuaWorldObject::IsInMap);
+    type["IsWithinDist3d"]        = ALEBind::Method(&LuaWorldObject::IsWithinDist3d);
+    type["IsWithinDist2d"]        = ALEBind::Method(&LuaWorldObject::IsWithinDist2d);
+    type["IsWithinDist"]          = ALEBind::Method(&LuaWorldObject::IsWithinDist);
+    type["IsWithinDistInMap"]     = ALEBind::Method(&LuaWorldObject::IsWithinDistInMap);
+    type["IsInRange"]             = ALEBind::Method(&LuaWorldObject::IsInRange);
+    type["IsInRange2d"]           = ALEBind::Method(&LuaWorldObject::IsInRange2d);
+    type["IsInRange3d"]           = ALEBind::Method(&LuaWorldObject::IsInRange3d);
+    type["IsInFront"]             = ALEBind::Method(&LuaWorldObject::IsInFront);
+    type["IsInBack"]              = ALEBind::Method(&LuaWorldObject::IsInBack);
+    type["PlayMusic"]             = ALEBind::Method(&LuaWorldObject::PlayMusic);
+    type["PlayDirectSound"]       = ALEBind::Method(&LuaWorldObject::PlayDirectSound);
+    type["PlayDistanceSound"]     = ALEBind::Method(&LuaWorldObject::PlayDistanceSound);
+}
diff --git a/src/LuaEngine/methods/WorldPacketMethods.h b/src/LuaEngine/methods/WorldPacketMethods.cpp
similarity index 62%
rename from src/LuaEngine/methods/WorldPacketMethods.h
rename to src/LuaEngine/methods/WorldPacketMethods.cpp
index 3972eee316..1667c6ed7e 100644
--- a/src/LuaEngine/methods/WorldPacketMethods.h
+++ b/src/LuaEngine/methods/WorldPacketMethods.cpp
@@ -4,8 +4,10 @@
 * Please see the included DOCS/LICENSE.md for more information
 */
 
-#ifndef WORLDPACKETMETHODS_H
-#define WORLDPACKETMETHODS_H
+#include "ALEBind.h"
+
+#include "Opcodes.h"
+#include "WorldPacket.h"
 
 /***
  * A packet used to pass messages between the server and a client.
@@ -18,17 +20,16 @@
  *
  * Inherits all methods from: none
  */
-namespace LuaPacket
+namespace LuaWorldPacket
 {
     /**
      * Returns the opcode of the [WorldPacket].
      *
      * @return uint16 opcode
      */
-    int GetOpcode(lua_State* L, WorldPacket* packet)
+    uint16 GetOpcode(WorldPacket* packet)
     {
-        ALE::Push(L, packet->GetOpcode());
-        return 1;
+        return packet->GetOpcode();
     }
 
     /**
@@ -36,10 +37,9 @@ namespace LuaPacket
      *
      * @return uint32 size
      */
-    int GetSize(lua_State* L, WorldPacket* packet)
+    uint32 GetSize(WorldPacket* packet)
     {
-        ALE::Push(L, packet->size());
-        return 1;
+        return packet->size();
     }
 
     /**
@@ -47,13 +47,11 @@ namespace LuaPacket
      *
      * @param [Opcodes] opcode : see Opcodes.h for all known opcodes
      */
-    int SetOpcode(lua_State* L, WorldPacket* packet)
+    void SetOpcode(WorldPacket* packet, uint32 opcode)
     {
-        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;
+            throw std::invalid_argument("valid opcode expected");
+        packet->SetOpcode(static_cast(opcode));
     }
 
     /**
@@ -61,12 +59,11 @@ namespace LuaPacket
      *
      * @return int8 value
      */
-    int ReadByte(lua_State* L, WorldPacket* packet)
+    int8 ReadByte(WorldPacket* packet)
     {
         int8 _byte;
         (*packet) >> _byte;
-        ALE::Push(L, _byte);
-        return 1;
+        return _byte;
     }
 
     /**
@@ -74,12 +71,11 @@ namespace LuaPacket
      *
      * @return uint8 value
      */
-    int ReadUByte(lua_State* L, WorldPacket* packet)
+    uint8 ReadUByte(WorldPacket* packet)
     {
         uint8 _ubyte;
         (*packet) >> _ubyte;
-        ALE::Push(L, _ubyte);
-        return 1;
+        return _ubyte;
     }
 
     /**
@@ -87,12 +83,11 @@ namespace LuaPacket
      *
      * @return int16 value
      */
-    int ReadShort(lua_State* L, WorldPacket* packet)
+    int16 ReadShort(WorldPacket* packet)
     {
         int16 _short;
         (*packet) >> _short;
-        ALE::Push(L, _short);
-        return 1;
+        return _short;
     }
 
     /**
@@ -100,12 +95,11 @@ namespace LuaPacket
      *
      * @return uint16 value
      */
-    int ReadUShort(lua_State* L, WorldPacket* packet)
+    uint16 ReadUShort(WorldPacket* packet)
     {
         uint16 _ushort;
         (*packet) >> _ushort;
-        ALE::Push(L, _ushort);
-        return 1;
+        return _ushort;
     }
 
     /**
@@ -113,12 +107,11 @@ namespace LuaPacket
      *
      * @return int32 value
      */
-    int ReadLong(lua_State* L, WorldPacket* packet)
+    int32 ReadLong(WorldPacket* packet)
     {
         int32 _long;
         (*packet) >> _long;
-        ALE::Push(L, _long);
-        return 1;
+        return _long;
     }
 
     /**
@@ -126,12 +119,11 @@ namespace LuaPacket
      *
      * @return uint32 value
      */
-    int ReadULong(lua_State* L, WorldPacket* packet)
+    uint32 ReadULong(WorldPacket* packet)
     {
         uint32 _ulong;
         (*packet) >> _ulong;
-        ALE::Push(L, _ulong);
-        return 1;
+        return _ulong;
     }
 
     /**
@@ -139,12 +131,11 @@ namespace LuaPacket
      *
      * @return float value
      */
-    int ReadFloat(lua_State* L, WorldPacket* packet)
+    float ReadFloat(WorldPacket* packet)
     {
         float _val;
         (*packet) >> _val;
-        ALE::Push(L, _val);
-        return 1;
+        return _val;
     }
 
     /**
@@ -152,12 +143,11 @@ namespace LuaPacket
      *
      * @return double value
      */
-    int ReadDouble(lua_State* L, WorldPacket* packet)
+    double ReadDouble(WorldPacket* packet)
     {
         double _val;
         (*packet) >> _val;
-        ALE::Push(L, _val);
-        return 1;
+        return _val;
     }
 
     /**
@@ -165,12 +155,11 @@ namespace LuaPacket
      *
      * @return ObjectGuid value : value returned as string
      */
-    int ReadGUID(lua_State* L, WorldPacket* packet)
+    ObjectGuid ReadGUID(WorldPacket* packet)
     {
         ObjectGuid guid;
         (*packet) >> guid;
-        ALE::Push(L, guid);
-        return 1;
+        return guid;
     }
 
     /**
@@ -179,25 +168,23 @@ namespace LuaPacket
      *
      * @return uint64 value : value returned as string
      */
-    int ReadPackedGUID(lua_State* L, WorldPacket* packet)
+    uint64 ReadPackedGUID(WorldPacket* packet)
     {
         uint64 guid;
         packet->readPackGUID(guid);
-        ALE::Push(L, guid);
-        return 1;
+        return guid;
     }
-	
+
     /**
      * Reads and returns a string value from the [WorldPacket].
      *
      * @return string value
      */
-    int ReadString(lua_State* L, WorldPacket* packet)
+    std::string ReadString(WorldPacket* packet)
     {
         std::string _val;
         (*packet) >> _val;
-        ALE::Push(L, _val);
-        return 1;
+        return _val;
     }
 
     /**
@@ -205,11 +192,9 @@ namespace LuaPacket
      *
      * @param ObjectGuid value : the value to be written to the [WorldPacket]
      */
-    int WriteGUID(lua_State* L, WorldPacket* packet)
+    void WriteGUID(WorldPacket* packet, ObjectGuid guid)
     {
-        ObjectGuid guid = ALE::CHECKVAL(L, 2);
         (*packet) << guid;
-        return 0;
     }
 
     /**
@@ -217,12 +202,10 @@ namespace LuaPacket
      *
      * @param ObjectGuid value : the ObjectGuid to be packed to the [WorldPacket]
      */
-    int WritePackedGUID(lua_State* L, WorldPacket* packet)
+    void WritePackedGUID(WorldPacket* packet, ObjectGuid guid)
     {
-        ObjectGuid guid = ALE::CHECKVAL(L, 2);
         PackedGuid packedGuid(guid);
         (*packet) << packedGuid;
-        return 0;
     }
 
     /**
@@ -230,11 +213,9 @@ namespace LuaPacket
      *
      * @param string value : the string to be written to the [WorldPacket]
      */
-    int WriteString(lua_State* L, WorldPacket* packet)
+    void WriteString(WorldPacket* packet, std::string _val)
     {
-        std::string _val = ALE::CHECKVAL(L, 2);
         (*packet) << _val;
-        return 0;
     }
 
     /**
@@ -242,11 +223,9 @@ namespace LuaPacket
      *
      * @param int8 value : the int8 value to be written to the [WorldPacket]
      */
-    int WriteByte(lua_State* L, WorldPacket* packet)
+    void WriteByte(WorldPacket* packet, int8 byte)
     {
-        int8 byte = ALE::CHECKVAL(L, 2);
         (*packet) << byte;
-        return 0;
     }
 
     /**
@@ -254,11 +233,9 @@ namespace LuaPacket
      *
      * @param uint8 value : the uint8 value to be written to the [WorldPacket]
      */
-    int WriteUByte(lua_State* L, WorldPacket* packet)
+    void WriteUByte(WorldPacket* packet, uint8 byte)
     {
-        uint8 byte = ALE::CHECKVAL(L, 2);
         (*packet) << byte;
-        return 0;
     }
 
     /**
@@ -266,11 +243,9 @@ namespace LuaPacket
      *
      * @param int16 value : the int16 value to be written to the [WorldPacket]
      */
-    int WriteShort(lua_State* L, WorldPacket* packet)
+    void WriteShort(WorldPacket* packet, int16 _short)
     {
-        int16 _short = ALE::CHECKVAL(L, 2);
         (*packet) << _short;
-        return 0;
     }
 
     /**
@@ -278,11 +253,9 @@ namespace LuaPacket
      *
      * @param uint16 value : the uint16 value to be written to the [WorldPacket]
      */
-    int WriteUShort(lua_State* L, WorldPacket* packet)
+    void WriteUShort(WorldPacket* packet, uint16 _ushort)
     {
-        uint16 _ushort = ALE::CHECKVAL(L, 2);
         (*packet) << _ushort;
-        return 0;
     }
 
     /**
@@ -290,11 +263,9 @@ namespace LuaPacket
      *
      * @param int32 value : the int32 value to be written to the [WorldPacket]
      */
-    int WriteLong(lua_State* L, WorldPacket* packet)
+    void WriteLong(WorldPacket* packet, int32 _long)
     {
-        int32 _long = ALE::CHECKVAL(L, 2);
         (*packet) << _long;
-        return 0;
     }
 
     /**
@@ -302,11 +273,9 @@ namespace LuaPacket
      *
      * @param uint32 value : the uint32 value to be written to the [WorldPacket]
      */
-    int WriteULong(lua_State* L, WorldPacket* packet)
+    void WriteULong(WorldPacket* packet, uint32 _ulong)
     {
-        uint32 _ulong = ALE::CHECKVAL(L, 2);
         (*packet) << _ulong;
-        return 0;
     }
 
     /**
@@ -314,11 +283,9 @@ namespace LuaPacket
      *
      * @param float value : the float value to be written to the [WorldPacket]
      */
-    int WriteFloat(lua_State* L, WorldPacket* packet)
+    void WriteFloat(WorldPacket* packet, float _val)
     {
-        float _val = ALE::CHECKVAL(L, 2);
         (*packet) << _val;
-        return 0;
     }
 
     /**
@@ -326,12 +293,39 @@ namespace LuaPacket
      *
      * @param double value : the double value to be written to the [WorldPacket]
      */
-    int WriteDouble(lua_State* L, WorldPacket* packet)
+    void WriteDouble(WorldPacket* packet, double _val)
     {
-        double _val = ALE::CHECKVAL(L, 2);
         (*packet) << _val;
-        return 0;
     }
-};
+}
+
+void RegisterWorldPacketMethods(sol::state& lua)
+{
+    sol::usertype type = lua.new_usertype("WorldPacket", sol::no_constructor);
 
-#endif
+    type["GetOpcode"]       = &LuaWorldPacket::GetOpcode;
+    type["GetSize"]         = &LuaWorldPacket::GetSize;
+    type["SetOpcode"]       = &LuaWorldPacket::SetOpcode;
+    type["ReadByte"]        = &LuaWorldPacket::ReadByte;
+    type["ReadUByte"]       = &LuaWorldPacket::ReadUByte;
+    type["ReadShort"]       = &LuaWorldPacket::ReadShort;
+    type["ReadUShort"]      = &LuaWorldPacket::ReadUShort;
+    type["ReadLong"]        = &LuaWorldPacket::ReadLong;
+    type["ReadULong"]       = &LuaWorldPacket::ReadULong;
+    type["ReadFloat"]       = &LuaWorldPacket::ReadFloat;
+    type["ReadDouble"]      = &LuaWorldPacket::ReadDouble;
+    type["ReadGUID"]        = &LuaWorldPacket::ReadGUID;
+    type["ReadPackedGUID"]  = &LuaWorldPacket::ReadPackedGUID;
+    type["ReadString"]      = &LuaWorldPacket::ReadString;
+    type["WriteGUID"]       = &LuaWorldPacket::WriteGUID;
+    type["WritePackedGUID"] = &LuaWorldPacket::WritePackedGUID;
+    type["WriteString"]     = &LuaWorldPacket::WriteString;
+    type["WriteByte"]       = &LuaWorldPacket::WriteByte;
+    type["WriteUByte"]      = &LuaWorldPacket::WriteUByte;
+    type["WriteShort"]      = &LuaWorldPacket::WriteShort;
+    type["WriteUShort"]     = &LuaWorldPacket::WriteUShort;
+    type["WriteLong"]       = &LuaWorldPacket::WriteLong;
+    type["WriteULong"]      = &LuaWorldPacket::WriteULong;
+    type["WriteFloat"]      = &LuaWorldPacket::WriteFloat;
+    type["WriteDouble"]     = &LuaWorldPacket::WriteDouble;
+}
diff --git a/src/lualib/lua/CMakeLists.txt b/src/lualib/lua/CMakeLists.txt
index 3f36675640..de87fb327b 100644
--- a/src/lualib/lua/CMakeLists.txt
+++ b/src/lualib/lua/CMakeLists.txt
@@ -129,7 +129,11 @@ else()
   install(TARGETS lua_interpreter DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
 endif()
 
-add_executable(lua_compiler ${LUA_SOURCE_FOLDER}/luac.c)
+if (LUA_STATIC)
+  add_executable(lua_compiler ${LUA_SOURCE_FOLDER}/luac.c)
+else()
+  add_executable(lua_compiler ${LUA_SOURCE_FOLDER}/luac.c ${LOCAL_SOURCES_C})
+endif()
 target_link_libraries(lua_compiler lualib)
 target_compile_definitions(lua_compiler PRIVATE _CRT_SECURE_NO_WARNINGS)
 if (NOT WIN32)
diff --git a/src/lualib/luajit/CMakeLists.txt b/src/lualib/luajit/CMakeLists.txt
index 64c0cf4791..839b95daba 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"
     )
 
@@ -99,7 +99,7 @@ if (WIN32)
     PROPERTIES
     IMPORTED_LOCATION ${LUA_BIN_FOLDER}/src/lua51.dll
     IMPORTED_IMPLIB ${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})
diff --git a/src/lualib/sol/LICENSE.txt b/src/lualib/sol/LICENSE.txt
new file mode 100644
index 0000000000..5813440548
--- /dev/null
+++ b/src/lualib/sol/LICENSE.txt
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013-2022 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.
diff --git a/src/lualib/sol/README.md b/src/lualib/sol/README.md
new file mode 100644
index 0000000000..cf0e9e616e
--- /dev/null
+++ b/src/lualib/sol/README.md
@@ -0,0 +1,161 @@
+# sol2
+
+[![Documentation Status](https://readthedocs.org/projects/sol2/badge/?version=latest)](http://sol2.readthedocs.io/en/latest/?badge=latest)
+
+
+
+sol2 is a C++ library binding to Lua. It currently supports all Lua versions 5.1+ (LuaJIT 2.0+ and MoonJIT included). sol2 aims to be easy to use and easy to add to a project. The library is header-only for easy integration with projects, and a single header can be used for drag-and-drop start up.
+
+
+
+## Sneak Peek
+
+```cpp
+#include 
+#include 
+
+int main() {
+    sol::state lua;
+    int x = 0;
+    lua.set_function("beep", [&x]{ ++x; });
+    lua.script("beep()");
+    assert(x == 1);
+}
+```
+
+```cpp
+#include 
+#include 
+
+struct vars {
+    int boop = 0;
+};
+
+int main() {
+    sol::state lua;
+    lua.new_usertype("vars", "boop", &vars::boop);
+    lua.script("beep = vars.new()\n"
+               "beep.boop = 1");
+    assert(lua.get("beep").boop == 1);
+}
+```
+
+More examples are given in the examples directory [here](https://github.com/ThePhD/sol2/tree/develop/examples). 
+
+
+## Documentation
+
+Find it [here](http://sol2.rtfd.io/). A run-through kind of tutorial is [here](http://sol2.readthedocs.io/en/latest/tutorial/all-the-things.html)! The API documentation goes over most cases (particularly, the "api/usertype" and "api/table_proxy" and "api/function" sections) that should still get you off your feet and going, and there's an examples directory [here](https://github.com/ThePhD/sol2/tree/develop/examples) as well.
+
+
+
+
+# "I need X Feature or Fix, Right Nowâ„¢"
+
+Find the support option that's right for you, [here](https://github.com/ThePhD/.github/blob/main/SUPPORT.md)! If you're happy to wait, you can just file a boring issue and we'll get to it Whenever There Is Timeâ„¢.
+
+
+
+## I want to donate to help!
+
+You can find [donation and sponorship options here](https://github.com/ThePhD/.github/blob/main/SUPPORT.md#support-in-general) and from the little heart button near the top of this repository that will take you to a bevy of links in which you can donate and show support for this project and others!
+
+
+
+
+# Features
+
+- [Fastest in the land](http://sol2.readthedocs.io/en/latest/benchmarks.html) (see: sol2 bar in graph).
+- Supports retrieval and setting of multiple types including: 
+  * `std::string`, `std::wstring`, `std::u16string` and `std::u32string` support (and for views).
+  * understands and works with containers such as `std::map/unordered_map`, c-style arrays, vectors, non-standard custom containers and more.
+  * user-defined types, with or **without** registering that type 
+  * `std::unique_ptr`, `std::shared_ptr`, and optional support of other pointer types like `boost::shared_ptr`.
+  * custom `optional` that works with references, and support for the inferior `std::optional`.
+  * C++17 support for variants and similar new types.
+- Lambda, function, and member function bindings are supported.
+- Intermediate type for checking if a variable exists.
+- Simple API that completely abstracts away the C stack API, including `protected_function` with the ability to use an error-handling function.
+- `operator[]`-style manipulation of tables
+- C++ type representations in Lua userdata as `usertype`s with guaranteed cleanup.
+- Customization points to allow your C++ objects to be pushed and retrieved from Lua as multiple consecutive objects, or anything else you desire!
+- Overloaded function calls: `my_function(1); my_function("Hello")` in the same Lua script route to different function calls based on parameters
+- Support for tables, nested tables, table iteration with `table.for_each` / `begin()` and `end()` iterators.
+- Zero string overhead for usertype function lookup.
+
+
+
+## Supported Compilers
+
+sol2 makes use of C++17 features. GCC 7.x.x and Clang 3.9.x (with `-std=c++1z` and appropriate standard library) or higher should be able to compile without problems. However, the officially supported and CI-tested compilers are:
+
+- GCC 7.x.x+ (MinGW 7.x.x+)
+- Clang 3.9.x+
+- Visual Studio 2017 Community (Visual C++ 15.0)+
+
+Please make sure you use the `-std=c++2a`, `-std=c++1z`, `-std=c++17` or better standard flags 
+(some of these flags are the defaults in later versions of GCC, such as 7+ and better).
+
+If you would like support for an older compiler (at the cost of some features), use the latest tagged sol2 branch. If you would like support for an even older compiler, feel free to contact me for a Custom Solution.
+
+sol2 is checked by-hand for other platforms as well, including Android-based builds with GCC and iOS-based builds out of XCode with Apple-clang. It should work on both of these platforms, so long as you have the proper standards flags. If something doesn't work or you need special options, you may need to look into the different ways to support the project to have it done for you!
+
+
+
+## Creating a single header
+
+You can grab a single header (and the single forward header) out of the library [here](https://github.com/ThePhD/sol2/tree/develop/single). For stable version, check the releases tab on GitHub for a provided single header file for maximum ease of use. A script called [`single.py`](https://github.com/ThePhD/sol2/blob/develop/single/single.py) is provided in the repository if there's some bleeding edge change that hasn't been published on the releases page. You can run this script to create a single file version of the library so you can only include that part of it. Check `single.py --help` for more info.
+
+If you use CMake, you can also configure and generate a project that will generate the `sol2_single_header` for you. You can also include the project using CMake. Run CMake for more details. Thanks @Nava2, @alkino, @mrgreywater and others for help with making the CMake build a reality.
+
+
+
+
+# Testing
+
+Testing turns on certain CI-only variables in the CMake to test a myriad of configuration options. You can generate the tests by running CMake and configuring `SOL2_TESTS`, `SOL2_TESTS_SINGLE`, `SOL2_TESTS_EXAMPLES`, and `SOL2_EXAMPLES` to be on. Make sure `SOL2_SINGLE` is also on.
+
+You will need any flavor of python3 and an available compiler. The testing suite will build its own version of Lua and LuaJIT, so you do not have to provide one (you may provide one with the `LUA_LOCAL_DIR` variable).
+
+
+
+# Presentations
+
+"A Sun For the Moon - A Zero-Overhead Lua Abstraction using C++"  
+ThePhD
+Lua Workshop 2016 - Mashape, San Francisco, CA  
+[Deck](https://github.com/ThePhD/sol2/blob/develop/documentation/presentation/2016.10.14%20-%20ThePhD%20-%20No%20Overhead%20C%20Abstraction.pdf)
+
+"Wrapping Lua C in C++ - Efficiently, Nicely, and with a Touch of Magic"  
+ThePhD
+Boston C++ Meetup November 2017 - CiC (Milk Street), Boston, MA  
+[Deck](https://github.com/ThePhD/sol2/blob/develop/documentation/presentation/2017.11.08%20-%20ThePhD%20-%20Wrapping%20Lua%20C%20in%20C%2B%2B.pdf)
+
+"Biting the CMake Bullet"  
+ThePhD
+Boston C++ Meetup February 2018 - CiC (Main Street), Cambridge, MA  
+[Deck](https://github.com/ThePhD/sol2/blob/develop/documentation/presentation/2018.02.06%20-%20ThePhD%20-%20Biting%20the%20CMake%20Bullet.pdf)
+
+"Compile Fast, Run Faster, Scale Forever: A look into the sol2 Library"  
+ThePhD
+C++Now 2018 - Hudson Commons, Aspen Physics Center, Aspen, Colorado  
+[Deck](https://github.com/ThePhD/sol2/blob/develop/documentation/presentation/2018.05.10%20-%20ThePhD%20-%20Compile%20Fast%2C%20Run%20Faster%2C%20Scale%20Forever.pdf)
+
+"Scripting at the Speed of Thought: Using Lua in C++ with sol2"  
+ThePhD
+CppCon 2018 - 404 Keystone, Meydenbauer Center, Aspen, Colorado  
+[Deck](https://github.com/ThePhD/sol2/blob/develop/documentation/presentation/2018.09.28%20-%20ThePhD%20-%20Scripting%20at%20the%20Speed%20of%20Thought.pdf)
+
+"The Plan for Tomorrow: Compile-Time Extension Points in C++"
+ThePhD
+C++Now 2019 - Flug Auditorium, Aspen Physics Center, Aspen, Colorado
+[Deck](https://github.com/ThePhD/sol2/blob/develop/documentation/presentation/2019.05.10%20-%20ThePhD%20-%20The%20Plan%20for%20Tomorrow%20-%20Compile-Time%20Extension%20Points%20in%20C%2b%2b.pdf)
+
+
+
+
+# License
+
+sol2 is distributed with an MIT License. You can see LICENSE.txt for more info.
+
+If you need a custom solution, [feel free to reach out](https://soasis.org/contact/opensource/).
diff --git a/src/lualib/sol/config.hpp b/src/lualib/sol/config.hpp
new file mode 100644
index 0000000000..3b7ef023f5
--- /dev/null
+++ b/src/lualib/sol/config.hpp
@@ -0,0 +1,53 @@
+// 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
+
+/* Base, empty configuration file!
+
+     To override, place a file in your include paths of the form:
+
+. (your include path here)
+| sol (directory, or equivalent)
+  | config.hpp (your config.hpp file)
+
+     So that when sol2 includes the file
+
+#include 
+
+     it gives you the configuration values you desire. Configuration values can be
+seen in the safety.rst of the doc/src, or at
+https://sol2.readthedocs.io/en/latest/safety.html ! You can also pass them through
+the build system, or the command line options of your compiler.
+
+*/
+
+// end of sol/config.hpp
+
+#endif // SOL_SINGLE_CONFIG_HPP
diff --git a/src/lualib/sol/forward.hpp b/src/lualib/sol/forward.hpp
new file mode 100644
index 0000000000..8690690871
--- /dev/null
+++ b/src/lualib/sol/forward.hpp
@@ -0,0 +1,1321 @@
+// 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.328625 UTC
+// This header was generated with sol v3.3.0 (revision eba86625)
+// https://github.com/ThePhD/sol2
+
+#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
+#define SOL_SINGLE_INCLUDE_FORWARD_HPP
+
+// beginning of sol/forward.hpp
+
+#ifndef SOL_FORWARD_HPP
+#define SOL_FORWARD_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
+
+#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
+
+#endif // SOL_SINGLE_INCLUDE_FORWARD_HPP
diff --git a/src/lualib/sol/sol.hpp b/src/lualib/sol/sol.hpp
new file mode 100644
index 0000000000..8b0b7d36ea
--- /dev/null
+++ b/src/lualib/sol/sol.hpp
@@ -0,0 +1,28907 @@
+// 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