diff --git a/src/LuaEngine/ElunaIncludes.h b/src/LuaEngine/ElunaIncludes.h
index 7692680e10..d35a825ae5 100644
--- a/src/LuaEngine/ElunaIncludes.h
+++ b/src/LuaEngine/ElunaIncludes.h
@@ -56,7 +56,7 @@ 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.
+ * please update LuaGlobal::GetCoreName or LuaGlobal::GetCoreVersion documentation example string.
*/
#define CORE_NAME "AzerothCore"
diff --git a/src/LuaEngine/ElunaTemplate.cpp b/src/LuaEngine/ElunaTemplate.cpp
new file mode 100644
index 0000000000..eb09935f4d
--- /dev/null
+++ b/src/LuaEngine/ElunaTemplate.cpp
@@ -0,0 +1,51 @@
+/*
+* Copyright (C) 2010 - 2024 Eluna Lua Engine
+* This program is free software licensed under GPL version 3
+* Please see the included DOCS/LICENSE.md for more information
+*/
+
+// Eluna
+#include "LuaEngine.h"
+#include "ElunaIncludes.h"
+#include "ElunaTemplate.h"
+#include "ElunaUtility.h"
+
+// fix compile error about accessing vehicle destructor
+template<> int ElunaTemplate::CollectGarbage(lua_State* L)
+{
+ ASSERT(!manageMemory);
+
+ // Get object pointer (and check type, no error)
+ ElunaObject* obj = Eluna::CHECKOBJ(L, 1, false);
+ delete obj;
+ return 0;
+}
+
+template<> inline int ElunaTemplate::Add(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::plus()); }
+template<> inline int ElunaTemplate::Subtract(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::minus()); }
+template<> inline int ElunaTemplate::Multiply(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::multiplies()); }
+template<> inline int ElunaTemplate::Divide(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::divides()); }
+template<> inline int ElunaTemplate::Mod(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::modulus()); }
+template<> inline int ElunaTemplate::Equal(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::equal_to()); }
+template<> inline int ElunaTemplate::Less(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::less()); }
+template<> inline int ElunaTemplate::LessOrEqual(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::less_equal()); }
+template<> inline int ElunaTemplate::ToString(lua_State* L) { return ElunaTemplateHelper::ToString(L); }
+template<> inline int ElunaTemplate::Pow(lua_State* L) { return ElunaTemplateHelper::Pow(L); }
+
+template<> inline int ElunaTemplate::Add(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::plus()); }
+template<> inline int ElunaTemplate::Subtract(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::minus()); }
+template<> inline int ElunaTemplate::Multiply(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::multiplies()); }
+template<> inline int ElunaTemplate::Divide(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::divides()); }
+template<> inline int ElunaTemplate::Mod(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::modulus()); }
+template<> inline int ElunaTemplate::UnaryMinus(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::negate()); }
+template<> inline int ElunaTemplate::Equal(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::equal_to()); }
+template<> inline int ElunaTemplate::Less(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::less()); }
+template<> inline int ElunaTemplate::LessOrEqual(lua_State* L) { return ElunaTemplateHelper::PerformOp(L, std::less_equal()); }
+template<> inline int ElunaTemplate::ToString(lua_State* L) { return ElunaTemplateHelper::ToString(L); }
+template<> inline int ElunaTemplate::Pow(lua_State* L) { return ElunaTemplateHelper::Pow(L); }
+
+template<> inline int ElunaTemplate::Equal(lua_State* L) { Eluna::Push(L, Eluna::CHECKVAL(L, 1) == Eluna::CHECKVAL(L, 2)); return 1; }
+template<> inline int ElunaTemplate::ToString(lua_State* L)
+{
+ Eluna::Push(L, Eluna::CHECKVAL(L, 1).ToString());
+}
diff --git a/src/LuaEngine/ElunaTemplate.h b/src/LuaEngine/ElunaTemplate.h
index 30c9f7d573..df55396394 100644
--- a/src/LuaEngine/ElunaTemplate.h
+++ b/src/LuaEngine/ElunaTemplate.h
@@ -112,14 +112,14 @@ class ElunaObject
const char* type_name;
};
-template
+template
struct ElunaRegister
{
const char* name;
int(*mfunc)(lua_State*, T*);
};
-template
+template
class ElunaTemplate
{
public:
@@ -170,7 +170,7 @@ class ElunaTemplate
lua_setfield(E->L, metatable, "__add");
// make new indexes saved to methods
- lua_pushcfunction(E->L, Substract);
+ lua_pushcfunction(E->L, Subtract);
lua_setfield(E->L, metatable, "__sub");
// make new indexes saved to methods
@@ -347,9 +347,8 @@ class ElunaTemplate
{
// Get object pointer (and check type, no error)
ElunaObject* obj = Eluna::CHECKOBJ(L, 1, false);
- if (obj && manageMemory)
- delete static_cast(obj->GetObj());
- delete obj;
+ obj->~ElunaObject();
+
return 0;
}
@@ -363,7 +362,7 @@ class ElunaTemplate
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 Subtract(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); }
@@ -375,6 +374,9 @@ class ElunaTemplate
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); }
+
+ static int MethodWrongState(lua_State* L) { luaL_error(L, "attempt to call method '%s' that does not exist for state: %d", lua_tostring(L, lua_upvalueindex(1)), lua_tointeger(L, lua_upvalueindex(2))); return 0; }
+ static int MethodUnimpl(lua_State* L) { luaL_error(L, "attempt to call method '%s' that is not implemented for this emulator", lua_tostring(L, lua_upvalueindex(1))); return 0; }
};
template
@@ -386,4 +388,38 @@ ElunaObject::ElunaObject(T * obj, bool manageMemory) : callstackid(1), _invalida
template const char* ElunaTemplate::tname = NULL;
template bool ElunaTemplate::manageMemory = false;
+template
+class ElunaTemplateHelper
+{
+public:
+ static int PerformOp(lua_State* L, std::function op)
+ {
+ T val1 = Eluna::CHECKVAL(L, 1);
+ T val2 = Eluna::CHECKVAL(L, 2);
+ Eluna::Push(L, op(val1, val2));
+ return 1;
+ }
+ static int PerformOp(lua_State* L, std::function op)
+ {
+ T val = Eluna::CHECKVAL(L, 1);
+ Eluna::Push(L, op(val));
+ return 1;
+ }
+ static int ToString(lua_State* L)
+ {
+ T val = Eluna::CHECKVAL(L, 1);
+ std::ostringstream ss;
+ ss << val;
+ Eluna::Push(L, ss.str());
+ return 1;
+ }
+ static int Pow(lua_State* L)
+ {
+ T val1 = Eluna::CHECKVAL(L, 1);
+ T val2 = Eluna::CHECKVAL(L, 2);
+ Eluna::Push(L, static_cast(powl(static_cast(val1), static_cast(val2))));
+ return 1;
+ }
+};
+
#endif
diff --git a/src/LuaEngine/LuaEngine.cpp b/src/LuaEngine/LuaEngine.cpp
index 40cb155b3b..1760228a17 100644
--- a/src/LuaEngine/LuaEngine.cpp
+++ b/src/LuaEngine/LuaEngine.cpp
@@ -45,7 +45,7 @@ bool Eluna::reload = false;
bool Eluna::initialized = false;
Eluna::LockType Eluna::lock;
-extern void RegisterFunctions(Eluna* E);
+extern void RegisterMethods(Eluna* E);
void Eluna::Initialize()
{
@@ -221,7 +221,7 @@ void Eluna::OpenLua()
// open additional lua libraries
// Register methods and functions
- RegisterFunctions(this);
+ RegisterMethods(this);
// Set lua require folder paths (scripts folder structure)
lua_getglobal(L, "package");
diff --git a/src/LuaEngine/LuaFunctions.cpp b/src/LuaEngine/LuaFunctions.cpp
deleted file mode 100644
index 9868b756fe..0000000000
--- a/src/LuaEngine/LuaFunctions.cpp
+++ /dev/null
@@ -1,1441 +0,0 @@
-/*
-* Copyright (C) 2010 - 2016 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"
-};
-
-// Eluna
-#include "LuaEngine.h"
-#include "ElunaEventMgr.h"
-#include "ElunaIncludes.h"
-#include "ElunaTemplate.h"
-#include "ElunaUtility.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 "ElunaQueryMethods.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"
-
-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 },
-
- { "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 },
-
- // Getters
- { "GetLuaEngine", &LuaGlobalFunctions::GetLuaEngine },
- { "GetCoreName", &LuaGlobalFunctions::GetCoreName },
- { "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 },
- { "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 },
-
- // Boolean
- { "IsCompatibilityMode", &LuaGlobalFunctions::IsCompatibilityMode },
- { "IsInventoryPos", &LuaGlobalFunctions::IsInventoryPos },
- { "IsEquipmentPos", &LuaGlobalFunctions::IsEquipmentPos },
- { "IsBankPos", &LuaGlobalFunctions::IsBankPos },
- { "IsBagPos", &LuaGlobalFunctions::IsBagPos },
- { "IsGameEventActive", &LuaGlobalFunctions::IsGameEventActive },
-
- // Other
- { "ReloadEluna", &LuaGlobalFunctions::ReloadEluna },
- { "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 },
-
- { NULL, NULL }
-};
-
-ElunaRegister