summaryrefslogtreecommitdiffstats
path: root/src/Bindings
diff options
context:
space:
mode:
Diffstat (limited to 'src/Bindings')
-rw-r--r--src/Bindings/LuaState.cpp54
-rw-r--r--src/Bindings/LuaState.h6
-rw-r--r--src/Bindings/ManualBindings.cpp63
3 files changed, 113 insertions, 10 deletions
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index ed31e678f..9c1e2865c 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -1133,6 +1133,23 @@ void cLuaState::GetStackValue(int a_StackPos, pWorld & a_ReturnedVal)
+void cLuaState::GetStackValue(int a_StackPos, pClientHandle & a_ReturnedVal)
+{
+ if (lua_isnil(m_LuaState, a_StackPos))
+ {
+ a_ReturnedVal = nullptr;
+ return;
+ }
+ tolua_Error err;
+ if (tolua_isusertype(m_LuaState, a_StackPos, "cClientHandle", false, &err))
+ {
+ a_ReturnedVal = *(reinterpret_cast<cClientHandle **>(lua_touserdata(m_LuaState, a_StackPos)));
+ }
+}
+
+
+
+
bool cLuaState::CallFunction(int a_NumResults)
{
ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first
@@ -1415,6 +1432,30 @@ bool cLuaState::CheckParamEnd(int a_Param)
+bool cLuaState::IsParamUserType(int a_Param, AString a_UserType)
+{
+ ASSERT(IsValid());
+
+ tolua_Error tolua_err;
+ return tolua_isusertype(m_LuaState, a_Param, a_UserType.c_str(), 0, &tolua_err);
+}
+
+
+
+
+
+bool cLuaState::IsParamNumber(int a_Param)
+{
+ ASSERT(IsValid());
+
+ tolua_Error tolua_err;
+ return tolua_isnumber(m_LuaState, a_Param, 0, &tolua_err);
+}
+
+
+
+
+
bool cLuaState::ReportErrors(int a_Status)
{
return ReportErrors(m_LuaState, a_Status);
@@ -1494,7 +1535,7 @@ int cLuaState::CallFunctionWithForeignParams(
if (!PushFunction(a_FunctionName.c_str()))
{
LOGWARNING("Function '%s' not found", a_FunctionName.c_str());
- lua_pop(m_LuaState, 2);
+ lua_settop(m_LuaState, OldTop);
return -1;
}
@@ -1502,7 +1543,7 @@ int cLuaState::CallFunctionWithForeignParams(
if (CopyStackFrom(a_SrcLuaState, a_SrcParamStart, a_SrcParamEnd) < 0)
{
// Something went wrong, fix the stack and exit
- lua_pop(m_LuaState, 2);
+ lua_settop(m_LuaState, OldTop);
m_NumCurrentFunctionArgs = -1;
m_CurrentFunctionName.clear();
return -1;
@@ -1513,13 +1554,8 @@ int cLuaState::CallFunctionWithForeignParams(
if (ReportErrors(s))
{
LOGWARN("Error while calling function '%s' in '%s'", a_FunctionName.c_str(), m_SubsystemName.c_str());
- // Fix the stack.
- // We don't know how many values have been pushed, so just get rid of any that weren't there initially
- int CurTop = lua_gettop(m_LuaState);
- if (CurTop > OldTop)
- {
- lua_pop(m_LuaState, CurTop - OldTop);
- }
+ // Reset the stack:
+ lua_settop(m_LuaState, OldTop);
// Reset the internal checking mechanisms:
m_NumCurrentFunctionArgs = -1;
diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h
index 6bedbf5ec..3f2e828f3 100644
--- a/src/Bindings/LuaState.h
+++ b/src/Bindings/LuaState.h
@@ -76,6 +76,7 @@ typedef cPluginManager * pPluginManager;
typedef cRoot * pRoot;
typedef cScoreboard * pScoreboard;
typedef cWorld * pWorld;
+typedef cClientHandle * pClientHandle;
@@ -254,6 +255,7 @@ public:
void GetStackValue(int a_StackPos, int & a_Value);
void GetStackValue(int a_StackPos, pBlockArea & a_Value);
void GetStackValue(int a_StackPos, pBoundingBox & a_Value);
+ void GetStackValue(int a_StackPos, pClientHandle & a_Value);
void GetStackValue(int a_StackPos, pMapManager & a_Value);
void GetStackValue(int a_StackPos, pPluginManager & a_Value);
void GetStackValue(int a_StackPos, pRoot & a_Value);
@@ -307,6 +309,10 @@ public:
/** Returns true if the specified parameter on the stack is nil (indicating an end-of-parameters) */
bool CheckParamEnd(int a_Param);
+ bool IsParamUserType(int a_Param, AString a_UserType);
+
+ bool IsParamNumber(int a_Param);
+
/** If the status is nonzero, prints the text on the top of Lua stack and returns true */
bool ReportErrors(int status);
diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp
index f25800d5f..20042a780 100644
--- a/src/Bindings/ManualBindings.cpp
+++ b/src/Bindings/ManualBindings.cpp
@@ -32,9 +32,10 @@
#include "../WorldStorage/SchematicFileSerializer.h"
#include "../CompositeChat.h"
#include "../StringCompression.h"
+#include "../Broadcaster.h"
-
+#include <array>
// Better error reporting for Lua
@@ -1987,6 +1988,11 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S)
{
return 0;
}
+ if (Callback.m_NumReturns < 0)
+ {
+ // The call has failed, there are zero return values. Do NOT return negative number (Lua considers that a "yield")
+ return 0;
+ }
return Callback.m_NumReturns;
}
@@ -2009,6 +2015,60 @@ static int tolua_cPluginManager_FindPlugins(lua_State * tolua_S)
+static int tolua_cWorld_BroadcastParticleEffect(lua_State * tolua_S)
+{
+ cLuaState L(tolua_S);
+ if (
+ !L.CheckParamUserType(1, "cWorld") ||
+ !L.CheckParamString (2) ||
+ !L.CheckParamNumber (3, 10)
+ )
+ {
+ return 0;
+ }
+
+ cPluginLua * Plugin = GetLuaPlugin(tolua_S);
+ if (Plugin == nullptr)
+ {
+ return 0;
+ }
+
+ // Read the params:
+ cWorld * World = nullptr;
+ AString Name;
+ double PosX, PosY, PosZ, OffX, OffY, OffZ;
+ double ParticleData;
+ int ParticleAmmount;
+ L.GetStackValues(1, World, Name, PosX, PosY, PosZ, OffX, OffY, OffZ, ParticleData, ParticleAmmount);
+ if (World == nullptr)
+ {
+ LOGWARNING("World:BroadcastParticleEffect(): invalid world parameter");
+ L.LogStackTrace();
+ return 0;
+ }
+
+ std::array<int, 2> data;
+
+ for (int i = 0; (i < 2) && L.IsParamNumber(11 + i); i++)
+ {
+ L.GetStackValue(11 + i, data[i]);
+ }
+
+ cClientHandle * Exclude = nullptr;
+
+ if (L.IsParamUserType(11, "cClientHandle"))
+ {
+ L.GetStackValue(11, Exclude);
+ }
+ World->GetBroadcaster().BroadcastParticleEffect(Name, Vector3f(PosX, PosY, PosZ), Vector3f(OffX, OffY, OffZ), ParticleData, ParticleAmmount, Exclude);
+
+ return 0;
+}
+
+
+
+
+
static int tolua_cWorld_ChunkStay(lua_State * tolua_S)
{
/* Function signature:
@@ -3792,6 +3852,7 @@ void ManualBindings::Bind(lua_State * tolua_S)
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cWorld");
+ tolua_function(tolua_S, "BroadcastParticleEffect", tolua_cWorld_BroadcastParticleEffect);
tolua_function(tolua_S, "ChunkStay", tolua_cWorld_ChunkStay);
tolua_function(tolua_S, "DoWithBlockEntityAt", tolua_DoWithXYZ<cWorld, cBlockEntity, &cWorld::DoWithBlockEntityAt>);
tolua_function(tolua_S, "DoWithBeaconAt", tolua_DoWithXYZ<cWorld, cBeaconEntity, &cWorld::DoWithBeaconAt>);