1
0
Fork 0

Bindings: Allow coercion between Vector3 subtypes. (#4646)

In manually bound functions, allows one to use any Vector3<T> value, as well as a {x, y, z} table, in Lua as any Vector3<T> parameter.
Has example in Debuggers' /vector command.
Unfortunately doesn't work in auto-bindings.
This commit is contained in:
Mattes D 2020-04-14 16:43:21 +02:00 committed by GitHub
parent 35299b8509
commit c9a9b3c9d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 204 additions and 166 deletions

View File

@ -1727,6 +1727,26 @@ end
function HandleVectorCmd(a_Split, a_Player)
a_Player:SendMessage("Testing the Vector3 APIs...")
-- Test the Vector3 coercion in ManualBindings - any Vector3 type should be accepted for any Vector3 parameter:
local pos = a_Player:GetPosition()
local c = cCuboid:new()
c:Assign(pos - Vector3d(2, 2, 2), pos + Vector3d(2, 2, 2))
assert(c:IsInside(Vector3d(pos)))
assert(c:IsInside(Vector3f(pos)))
assert(c:IsInside(Vector3i(pos)))
assert(c:IsInside({pos.x, pos.y, pos.z}))
a_Player:SendMessage("Test successful.")
return true
end
function HandleWESel(a_Split, a_Player) function HandleWESel(a_Split, a_Player)
-- Check if the selection is a cuboid: -- Check if the selection is a cuboid:
local IsCuboid = cPluginManager:CallPlugin("WorldEdit", "IsPlayerSelectionCuboid") local IsCuboid = cPluginManager:CallPlugin("WorldEdit", "IsPlayerSelectionCuboid")

View File

@ -260,6 +260,14 @@ g_PluginInfo =
Handler = HandleTestWndCmd, Handler = HandleTestWndCmd,
HelpString = "Opens up a window using plugin API" HelpString = "Opens up a window using plugin API"
}, },
["/vector"] =
{
Permission = "debuggers",
Handler = HandleVectorCmd,
HelpString = "Tests the Vector3 API",
},
["/wesel"] = ["/wesel"] =
{ {
Permission = "debuggers", Permission = "debuggers",

View File

@ -74,7 +74,20 @@ local access =
-- Map of classname -> true -- Map of classname -> true
local g_HasCustomPushImplementation = local g_HasCustomPushImplementation =
{ {
cEntity = true cEntity = true,
}
--- Defines classes that have a custom manual GetStackValue() implementation and should not generate the automatic one
-- Map of classname -> true
local g_HasCustomGetImplementation =
{
Vector3d = true,
Vector3f = true,
Vector3i = true,
} }
@ -209,13 +222,15 @@ local function OutputLuaStateHelpers(a_Package)
f:write("// This file expects to be included form inside the cLuaState class definition\n") f:write("// This file expects to be included form inside the cLuaState class definition\n")
f:write("\n\n\n\n\n") f:write("\n\n\n\n\n")
for _, item in ipairs(types) do for _, item in ipairs(types) do
if not(g_HasCustomPushImplementation[item.name]) then if not(g_HasCustomPushImplementation[item.lname]) then
f:write("void Push(" .. item.name .. " * a_Value);\n") f:write("void Push(" .. item.name .. " * a_Value);\n")
end end
end end
for _, item in ipairs(types) do for _, item in ipairs(types) do
f:write("bool GetStackValue(int a_StackPos, Ptr" .. item.lname .. " & a_ReturnedVal);\n") if not(g_HasCustomGetImplementation[item.lname]) then
f:write("bool GetStackValue(int a_StackPos, ConstPtr" .. item.lname .. " & a_ReturnedVal);\n") f:write("bool GetStackValue(int a_StackPos, Ptr" .. item.lname .. " & a_ReturnedVal);\n")
f:write("bool GetStackValue(int a_StackPos, ConstPtr" .. item.lname .. " & a_ReturnedVal);\n")
end
end end
f:write("\n\n\n\n\n") f:write("\n\n\n\n\n")
f:close() f:close()
@ -231,38 +246,40 @@ local function OutputLuaStateHelpers(a_Package)
f:write("#include \"Globals.h\"\n#include \"LuaState.h\"\n#include \"tolua++/include/tolua++.h\"\n") f:write("#include \"Globals.h\"\n#include \"LuaState.h\"\n#include \"tolua++/include/tolua++.h\"\n")
f:write("\n\n\n\n\n") f:write("\n\n\n\n\n")
for _, item in ipairs(types) do for _, item in ipairs(types) do
if not(g_HasCustomPushImplementation[item.name]) then if not(g_HasCustomPushImplementation[item.lname]) then
f:write("void cLuaState::Push(" .. item.name .. " * a_Value)\n{\n\tASSERT(IsValid());\n") f:write("void cLuaState::Push(" .. item.name .. " * a_Value)\n{\n\tASSERT(IsValid());\n")
f:write("\ttolua_pushusertype(m_LuaState, a_Value, \"" .. item.name .. "\");\n"); f:write("\ttolua_pushusertype(m_LuaState, a_Value, \"" .. item.name .. "\");\n");
f:write("}\n\n\n\n\n\n") f:write("}\n\n\n\n\n\n")
end end
end end
for _, item in ipairs(types) do for _, item in ipairs(types) do
f:write("bool cLuaState::GetStackValue(int a_StackPos, Ptr" .. item.lname .. " & a_ReturnedVal)\n{\n\tASSERT(IsValid());\n") if not(g_HasCustomGetImplementation[item.lname]) then
f:write("\tif (lua_isnil(m_LuaState, a_StackPos))\n\t{\n") f:write("bool cLuaState::GetStackValue(int a_StackPos, Ptr" .. item.lname .. " & a_ReturnedVal)\n{\n\tASSERT(IsValid());\n")
f:write("\t\ta_ReturnedVal = nullptr;\n") f:write("\tif (lua_isnil(m_LuaState, a_StackPos))\n\t{\n")
f:write("\t\treturn false;\n\t}\n") f:write("\t\ta_ReturnedVal = nullptr;\n")
f:write("\ttolua_Error err;\n") f:write("\t\treturn false;\n\t}\n")
f:write("\tif (tolua_isusertype(m_LuaState, a_StackPos, \"" .. item.name .. "\", false, &err))\n") f:write("\ttolua_Error err;\n")
f:write("\t{\n") f:write("\tif (tolua_isusertype(m_LuaState, a_StackPos, \"" .. item.name .. "\", false, &err))\n")
f:write("\t\ta_ReturnedVal = *(static_cast<" .. item.name .. " **>(lua_touserdata(m_LuaState, a_StackPos)));\n") f:write("\t{\n")
f:write("\t\treturn true;\n"); f:write("\t\ta_ReturnedVal = *(static_cast<" .. item.name .. " **>(lua_touserdata(m_LuaState, a_StackPos)));\n")
f:write("\t}\n") f:write("\t\treturn true;\n");
f:write("\treturn false;\n") f:write("\t}\n")
f:write("}\n\n\n\n\n\n") f:write("\treturn false;\n")
f:write("}\n\n\n\n\n\n")
f:write("bool cLuaState::GetStackValue(int a_StackPos, ConstPtr" .. item.lname .. " & a_ReturnedVal)\n{\n\tASSERT(IsValid());\n") f:write("bool cLuaState::GetStackValue(int a_StackPos, ConstPtr" .. item.lname .. " & a_ReturnedVal)\n{\n\tASSERT(IsValid());\n")
f:write("\tif (lua_isnil(m_LuaState, a_StackPos))\n\t{\n") f:write("\tif (lua_isnil(m_LuaState, a_StackPos))\n\t{\n")
f:write("\t\ta_ReturnedVal = nullptr;\n") f:write("\t\ta_ReturnedVal = nullptr;\n")
f:write("\t\treturn false;\n\t}\n") f:write("\t\treturn false;\n\t}\n")
f:write("\ttolua_Error err;\n") f:write("\ttolua_Error err;\n")
f:write("\tif (tolua_isusertype(m_LuaState, a_StackPos, \"const " .. item.name .. "\", false, &err))\n") f:write("\tif (tolua_isusertype(m_LuaState, a_StackPos, \"const " .. item.name .. "\", false, &err))\n")
f:write("\t{\n") f:write("\t{\n")
f:write("\t\ta_ReturnedVal = *(static_cast<const " .. item.name .. " **>(lua_touserdata(m_LuaState, a_StackPos)));\n") f:write("\t\ta_ReturnedVal = *(static_cast<const " .. item.name .. " **>(lua_touserdata(m_LuaState, a_StackPos)));\n")
f:write("\t\treturn true;\n"); f:write("\t\treturn true;\n");
f:write("\t}\n") f:write("\t}\n")
f:write("\treturn false;\n") f:write("\treturn false;\n")
f:write("}\n\n\n\n\n\n") f:write("}\n\n\n\n\n\n")
end
end end
f:close() f:close()
end end

View File

@ -518,49 +518,6 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S)
template <typename T>
int tolua_Vector3_Abs(lua_State * a_LuaState)
{
// Retrieve the params, including self:
cLuaState L(a_LuaState);
Vector3<T> * self;
if (!L.GetStackValues(1, self))
{
tolua_error(a_LuaState, "invalid 'self' in function 'Vector3<T>:Abs'", nullptr);
return 0;
}
// Absolutize the vector:
self->Abs();
return 0;
}
template <typename T>
int tolua_Vector3_Clamp(lua_State * a_LuaState)
{
// Retrieve the params, including self:
cLuaState L(a_LuaState);
Vector3<T> * self;
T min, max;
if (!L.GetStackValues(1, self, min, max))
{
tolua_error(a_LuaState, "invalid parameters for function 'Vector3<T>:Clamp', expected a Vector3 and two numbers", nullptr);
return 0;
}
// Clamp the vector:
self->Clamp(min, max);
return 0;
}
void DeprecatedBindings::Bind(lua_State * tolua_S) void DeprecatedBindings::Bind(lua_State * tolua_S)
{ {
tolua_beginmodule(tolua_S, nullptr); tolua_beginmodule(tolua_S, nullptr);
@ -604,21 +561,6 @@ void DeprecatedBindings::Bind(lua_State * tolua_S)
tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines); tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines);
tolua_endmodule(tolua_S); tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "Vector3i");
tolua_function(tolua_S,"abs", tolua_Vector3_Abs<int>);
tolua_function(tolua_S,"clamp", tolua_Vector3_Clamp<int>);
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "Vector3f");
tolua_function(tolua_S,"abs", tolua_Vector3_Abs<float>);
tolua_function(tolua_S,"clamp", tolua_Vector3_Clamp<float>);
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "Vector3d");
tolua_function(tolua_S,"abs", tolua_Vector3_Abs<double>);
tolua_function(tolua_S,"clamp", tolua_Vector3_Clamp<double>);
tolua_endmodule(tolua_S);
tolua_endmodule(tolua_S); tolua_endmodule(tolua_S);
} }

View File

@ -1451,6 +1451,57 @@ bool cLuaState::GetStackValue(int a_StackPos, cUUID & a_Value)
template <typename T>
bool cLuaState::GetStackValue(int a_StackPos, Vector3<T> & a_ReturnedVal)
{
tolua_Error err;
if (lua_isnil(m_LuaState, a_StackPos))
{
return false;
}
if (tolua_isusertype(m_LuaState, a_StackPos, "Vector3<double>", 0, &err))
{
a_ReturnedVal = **(static_cast<const Vector3d **>(lua_touserdata(m_LuaState, a_StackPos)));
return true;
}
if (tolua_isusertype(m_LuaState, a_StackPos, "Vector3<float>", 0, &err))
{
a_ReturnedVal = **(static_cast<const Vector3f **>(lua_touserdata(m_LuaState, a_StackPos)));
return true;
}
if (tolua_isusertype(m_LuaState, a_StackPos, "Vector3<int>", 0, &err))
{
a_ReturnedVal = **(static_cast<const Vector3i **>(lua_touserdata(m_LuaState, a_StackPos)));
return true;
}
// Bonus: Allow simple tables to work as Vector3:
if (lua_istable(m_LuaState, a_StackPos))
{
lua_rawgeti(m_LuaState, a_StackPos, 1);
lua_rawgeti(m_LuaState, a_StackPos, 2);
lua_rawgeti(m_LuaState, a_StackPos, 3);
T x, y, z;
if (!GetStackValues(-3, x, y, z))
{
return false;
}
a_ReturnedVal = Vector3<T>(x, y, z);
return true;
}
return false;
}
// Explicitly instantiate the previous function for all Vector3 types:
template bool cLuaState::GetStackValue(int a_StackPos, Vector3d & a_ReturnedVal);
template bool cLuaState::GetStackValue(int a_StackPos, Vector3f & a_ReturnedVal);
template bool cLuaState::GetStackValue(int a_StackPos, Vector3i & a_ReturnedVal);
cLuaState::cStackValue cLuaState::WalkToValue(const AString & a_Name) cLuaState::cStackValue cLuaState::WalkToValue(const AString & a_Name)
{ {
// There needs to be at least one value on the stack: // There needs to be at least one value on the stack:
@ -1937,24 +1988,40 @@ bool cLuaState::CheckParamStaticSelf(const char * a_SelfClassName)
bool cLuaState::IsParamUserType(int a_Param, AString a_UserType) bool cLuaState::IsParamUserType(int a_ParamIdx, AString a_UserType)
{ {
ASSERT(IsValid()); ASSERT(IsValid());
tolua_Error tolua_err; tolua_Error tolua_err;
return (tolua_isusertype(m_LuaState, a_Param, a_UserType.c_str(), 0, &tolua_err) == 1); return (tolua_isusertype(m_LuaState, a_ParamIdx, a_UserType.c_str(), 0, &tolua_err) == 1);
} }
bool cLuaState::IsParamNumber(int a_Param) bool cLuaState::IsParamNumber(int a_ParamIdx)
{ {
ASSERT(IsValid()); ASSERT(IsValid());
tolua_Error tolua_err; tolua_Error tolua_err;
return (tolua_isnumber(m_LuaState, a_Param, 0, &tolua_err) == 1); return (tolua_isnumber(m_LuaState, a_ParamIdx, 0, &tolua_err) == 1);
}
bool cLuaState::IsParamVector3(int a_ParamIdx)
{
ASSERT(IsValid());
return (
IsParamUserType(a_ParamIdx, "Vector3<double>") ||
IsParamUserType(a_ParamIdx, "Vector3<float>") ||
IsParamUserType(a_ParamIdx, "Vector3<int>") ||
lua_istable(m_LuaState, a_ParamIdx) // Assume any table is good enough
);
} }

View File

@ -696,6 +696,10 @@ public:
return GetStackValue(a_StackPos, a_ReturnedVal.GetDest()); return GetStackValue(a_StackPos, a_ReturnedVal.GetDest());
} }
/** Retrieves any Vector3 value and coerces it into a Vector3<T>. */
template <typename T>
bool GetStackValue(int a_StackPos, Vector3<T> & a_ReturnedVal);
/** Pushes the named value in the table at the top of the stack. /** Pushes the named value in the table at the top of the stack.
a_Name may be a path containing multiple table levels, such as "cChatColor.Blue". a_Name may be a path containing multiple table levels, such as "cChatColor.Blue".
If the value is found, it is pushed on top of the stack and the returned cStackValue is valid. If the value is found, it is pushed on top of the stack and the returned cStackValue is valid.
@ -805,9 +809,14 @@ public:
Returns false and logs a special warning ("wrong calling convention") if not. */ Returns false and logs a special warning ("wrong calling convention") if not. */
bool CheckParamStaticSelf(const char * a_SelfClassName); bool CheckParamStaticSelf(const char * a_SelfClassName);
bool IsParamUserType(int a_Param, AString a_UserType); /** Returns true if the specified parameter is of the specified class. */
bool IsParamUserType(int a_ParamIdx, AString a_UserType);
bool IsParamNumber(int a_Param); /** Returns true if the specified parameter is a number. */
bool IsParamNumber(int a_ParamIdx);
/** Returns true if the specified parameter is any of the Vector3 types. */
bool IsParamVector3(int a_ParamIdx);
/** If the status is nonzero, prints the text on the top of Lua stack and returns true */ /** If the status is nonzero, prints the text on the top of Lua stack and returns true */
bool ReportErrors(int status); bool ReportErrors(int status);
@ -1027,7 +1036,12 @@ protected:
/** Removes the specified reference from tracking. /** Removes the specified reference from tracking.
The reference will no longer be invalidated when this Lua state is about to be closed. */ The reference will no longer be invalidated when this Lua state is about to be closed. */
void UntrackRef(cTrackedRef & a_Ref); void UntrackRef(cTrackedRef & a_Ref);
} ; }; // cLuaState
// Instantiate the GetStackValue(Vector3<>) function for all Vector3 types:
extern template bool cLuaState::GetStackValue(int a_StackPos, Vector3d & a_ReturnedVal);
extern template bool cLuaState::GetStackValue(int a_StackPos, Vector3f & a_ReturnedVal);
extern template bool cLuaState::GetStackValue(int a_StackPos, Vector3i & a_ReturnedVal);

View File

@ -2963,9 +2963,9 @@ static int tolua_cLineBlockTracer_FirstSolidHitTrace(lua_State * tolua_S)
return 4; return 4;
} }
if (L.IsParamUserType(idx + 1, "Vector3<double>")) if (L.IsParamVector3(idx + 1))
{ {
// This is the Vector3d-based variant of the call: // This is the Vector3-based variant of the call:
if ( if (
!L.CheckParamUserType(idx + 1, "Vector3<double>", idx + 2) || !L.CheckParamUserType(idx + 1, "Vector3<double>", idx + 2) ||
!L.CheckParamEnd(idx + 3) !L.CheckParamEnd(idx + 3)
@ -2975,8 +2975,8 @@ static int tolua_cLineBlockTracer_FirstSolidHitTrace(lua_State * tolua_S)
} }
// Get the params: // Get the params:
cWorld * world; cWorld * world;
Vector3d * start; Vector3d start;
Vector3d * end; Vector3d end;
if (!L.GetStackValues(idx, world, start, end)) if (!L.GetStackValues(idx, world, start, end))
{ {
LOGWARNING("cLineBlockTracer:FirstSolidHitTrace(): Cannot read parameters, aborting the trace."); LOGWARNING("cLineBlockTracer:FirstSolidHitTrace(): Cannot read parameters, aborting the trace.");
@ -2987,7 +2987,7 @@ static int tolua_cLineBlockTracer_FirstSolidHitTrace(lua_State * tolua_S)
Vector3d hitCoords; Vector3d hitCoords;
Vector3i hitBlockCoords; Vector3i hitBlockCoords;
eBlockFace hitBlockFace; eBlockFace hitBlockFace;
auto isHit = cLineBlockTracer::FirstSolidHitTrace(*world, *start, *end, hitCoords, hitBlockCoords, hitBlockFace); auto isHit = cLineBlockTracer::FirstSolidHitTrace(*world, start, end, hitCoords, hitBlockCoords, hitBlockFace);
L.Push(isHit); L.Push(isHit);
if (!isHit) if (!isHit)
{ {
@ -2999,7 +2999,7 @@ static int tolua_cLineBlockTracer_FirstSolidHitTrace(lua_State * tolua_S)
return 4; return 4;
} }
tolua_error(L, "cLineBlockTracer:FirstSolidHitTrace(): Invalid parameters, expected either a set of coords, or two Vector3d's", nullptr); tolua_error(L, "cLineBlockTracer:FirstSolidHitTrace(): Invalid parameters, expected either a set of coords, or two Vector3's", nullptr);
return 0; return 0;
} }
@ -3074,8 +3074,8 @@ static int tolua_cLineBlockTracer_LineOfSightTrace(lua_State * tolua_S)
} }
// Get the params: // Get the params:
cWorld * world; cWorld * world;
Vector3d * start; Vector3d start;
Vector3d * end; Vector3d end;
if (!L.GetStackValues(idx, world, start, end)) if (!L.GetStackValues(idx, world, start, end))
{ {
LOGWARNING("cLineBlockTracer:LineOfSightTrace(): Cannot read parameters, aborting the trace."); LOGWARNING("cLineBlockTracer:LineOfSightTrace(): Cannot read parameters, aborting the trace.");
@ -3085,7 +3085,7 @@ static int tolua_cLineBlockTracer_LineOfSightTrace(lua_State * tolua_S)
} }
int lineOfSight = cLineBlockTracer::losAirWater; int lineOfSight = cLineBlockTracer::losAirWater;
L.GetStackValue(idx + 7, lineOfSight); L.GetStackValue(idx + 7, lineOfSight);
L.Push(cLineBlockTracer::LineOfSightTrace(*world, *start, *end, lineOfSight)); L.Push(cLineBlockTracer::LineOfSightTrace(*world, start, end, lineOfSight));
return 1; return 1;
} }
@ -3497,19 +3497,19 @@ static int tolua_cBoundingBox_CalcLineIntersection(lua_State * a_LuaState)
{ {
/* Function signatures: /* Function signatures:
bbox:CalcLineIntersection(pt1, pt2) -> bool, [number, blockface] bbox:CalcLineIntersection(pt1, pt2) -> bool, [number, blockface]
cBoundingBox:CalcLineIntersection(min, max, pt1, pt2) -> bool, [number, blockface] cBoundingBox:CalcLineIntersection(min, max, pt1, pt2) -> bool, [number, blockface] (static)
*/ */
cLuaState L(a_LuaState); cLuaState L(a_LuaState);
const Vector3d * min; Vector3d min;
const Vector3d * max; Vector3d max;
const Vector3d * pt1; Vector3d pt1;
const Vector3d * pt2; Vector3d pt2;
double lineCoeff; double lineCoeff;
eBlockFace blockFace; eBlockFace blockFace;
bool res; bool res;
if (L.GetStackValues(2, min, max, pt1, pt2)) // Try the static signature first if (L.GetStackValues(2, min, max, pt1, pt2)) // Try the static signature first
{ {
res = cBoundingBox::CalcLineIntersection(*min, *max, *pt1, *pt2, lineCoeff, blockFace); res = cBoundingBox::CalcLineIntersection(min, max, pt1, pt2, lineCoeff, blockFace);
} }
else else
{ {
@ -3520,7 +3520,7 @@ static int tolua_cBoundingBox_CalcLineIntersection(lua_State * a_LuaState)
tolua_error(a_LuaState, "Invalid function params. Expected either bbox:CalcLineIntersection(pt1, pt2) or cBoundingBox:CalcLineIntersection(min, max, pt1, pt2).", nullptr); tolua_error(a_LuaState, "Invalid function params. Expected either bbox:CalcLineIntersection(pt1, pt2) or cBoundingBox:CalcLineIntersection(min, max, pt1, pt2).", nullptr);
return 0; return 0;
} }
res = bbox->CalcLineIntersection(*pt1, *pt2, lineCoeff, blockFace); res = bbox->CalcLineIntersection(pt1, pt2, lineCoeff, blockFace);
} }
L.Push(res); L.Push(res);
if (res) if (res)
@ -3984,11 +3984,11 @@ static int tolua_cCuboid_Assign(lua_State * tolua_S)
} }
// Try the (Vector3i, Vector3i) param version: // Try the (Vector3i, Vector3i) param version:
Vector3i * pt1 = nullptr; Vector3i pt1;
Vector3i * pt2 = nullptr; Vector3i pt2;
if (L.GetStackValues(2, pt1, pt2) && (pt1 != nullptr) && (pt2 != nullptr)) if (L.GetStackValues(2, pt1, pt2))
{ {
self->Assign(*pt1, *pt2); self->Assign(pt1, pt2);
return 0; return 0;
} }
return L.ApiParamError("Invalid parameter, expected either a cCuboid or two Vector3i-s."); return L.ApiParamError("Invalid parameter, expected either a cCuboid or two Vector3i-s.");
@ -4014,32 +4014,20 @@ static int tolua_cCuboid_IsInside(lua_State * tolua_S)
int x, y, z; int x, y, z;
if (L.GetStackValues(2, x, y, z)) if (L.GetStackValues(2, x, y, z))
{ {
LOGWARNING("cCuboid:IsInside(x, y, z) is deprecated, use cCuboid:IsInside(Vector3d) instead."); LOGWARNING("cCuboid:IsInside(x, y, z) is deprecated, use cCuboid:IsInside(Vector3) instead.");
L.LogStackTrace(); L.LogStackTrace();
self->Move({x, y, z}); L.Push(self->IsInside(Vector3i{x, y, z}));
return 0; return 1;
} }
// Try the (Vector3i) param version: // Try the Vector3 param version:
Vector3d pt;
if (L.GetStackValue(2, pt))
{ {
Vector3i * pt = nullptr; L.Push(self->IsInside(pt));
if (L.GetStackValue(2, pt) && (pt != nullptr)) return 1;
{
L.Push(self->IsInside(*pt));
return 1;
}
} }
return L.ApiParamError("Invalid parameter #2, expected a Vector3.");
// Try the (Vector3d) param version:
{
Vector3d * pt = nullptr;
if (L.GetStackValue(2, pt) && (pt != nullptr))
{
L.Push(self->IsInside(*pt));
return 1;
}
}
return L.ApiParamError("Invalid parameter #2, expected a Vector3i or a Vector3d.");
} }
@ -4068,12 +4056,12 @@ static int tolua_cCuboid_Move(lua_State * tolua_S)
return 0; return 0;
} }
Vector3i * offset = nullptr; Vector3i offset;
if (!L.GetStackValue(2, offset) || (offset == nullptr)) if (!L.GetStackValue(2, offset))
{ {
return L.ApiParamError("Invalid parameter #2, expected a Vector3i."); return L.ApiParamError("Invalid parameter #2, expected a Vector3.");
} }
self->Move(*offset); self->Move(offset);
return 0; return 0;
} }

View File

@ -48,14 +48,10 @@ static int readCuboidOverloadParams(cLuaState & a_LuaState, int a_StartParam, cC
else else
{ {
// Assume the 2-Vector3i version: // Assume the 2-Vector3i version:
Vector3i * p1; if (!a_LuaState.GetStackValues(a_StartParam, a_Cuboid.p1, a_Cuboid.p2))
Vector3i * p2;
if (!a_LuaState.GetStackValues(a_StartParam, p1, p2))
{ {
return a_LuaState.ApiParamError("Cannot read the bounds parameter, expected two Vector3i instances"); return a_LuaState.ApiParamError("Cannot read the bounds parameter, expected two Vector3i instances");
} }
a_Cuboid.p1 = *p1;
a_Cuboid.p2 = *p2;
return a_StartParam + 2; return a_StartParam + 2;
} }
} }
@ -85,12 +81,10 @@ static int readVector3iOverloadParams(cLuaState & a_LuaState, int a_StartParam,
else else
{ {
// Assume the Vector3i version: // Assume the Vector3i version:
Vector3i * c; if (!a_LuaState.GetStackValues(a_StartParam, a_Coords))
if (!a_LuaState.GetStackValues(a_StartParam, c))
{ {
return a_LuaState.ApiParamError("Cannot read the %s, expected a Vector3i instance", a_ParamName); return a_LuaState.ApiParamError("Cannot read the %s, expected a Vector3i instance", a_ParamName);
} }
a_Coords = *c;
return a_StartParam + 1; return a_StartParam + 1;
} }
} }

View File

@ -39,10 +39,8 @@ static bool CheckParamVectorOr3Numbers(cLuaState & L, const char * a_VectorName,
template <typename T> template <typename T>
static bool GetStackVectorOr3Numbers(cLuaState & L, int a_Index, Vector3<T> & a_Return) static bool GetStackVectorOr3Numbers(cLuaState & L, int a_Index, Vector3<T> & a_Return)
{ {
Vector3<T> * UserType; if (L.GetStackValue(a_Index, a_Return))
if (L.GetStackValue(a_Index, UserType))
{ {
a_Return = *UserType;
return true; return true;
} }
return L.GetStackValues(a_Index, a_Return.x, a_Return.y, a_Return.z); return L.GetStackValues(a_Index, a_Return.x, a_Return.y, a_Return.z);
@ -367,10 +365,10 @@ static int tolua_cWorld_DoExplosionAt(lua_State * tolua_S)
case esBed: case esBed:
{ {
// esBed receives a Vector3i SourceData param: // esBed receives a Vector3i SourceData param:
Vector3i * pos = nullptr; Vector3i pos;
L.GetStackValue(8, pos); L.GetStackValue(8, pos);
SourceType = esBed; SourceType = esBed;
SourceData = pos; SourceData = &pos;
break; break;
} }
@ -481,24 +479,19 @@ static int tolua_cWorld_DoWithNearestPlayer(lua_State * tolua_S)
// Get parameters: // Get parameters:
cWorld * Self; cWorld * Self;
Vector3d * Position; Vector3d Position;
double RangeLimit; double RangeLimit;
cLuaState::cRef FnRef; cLuaState::cRef FnRef;
bool CheckLineOfSight = true, IgnoreSpectators = true; // Defaults for the optional params bool CheckLineOfSight = true, IgnoreSpectators = true; // Defaults for the optional params
L.GetStackValues(1, Self, Position, RangeLimit, FnRef, CheckLineOfSight, IgnoreSpectators); L.GetStackValues(1, Self, Position, RangeLimit, FnRef, CheckLineOfSight, IgnoreSpectators);
if (Position == nullptr)
{
return L.ApiParamError("Expected a non-nil Vector3d for parameter #2");
}
if (!FnRef.IsValid()) if (!FnRef.IsValid())
{ {
return L.ApiParamError("Expected a valid callback function for parameter #3"); return L.ApiParamError("Expected a valid callback function for parameter #3");
} }
// Call the function: // Call the function:
bool res = Self->DoWithNearestPlayer(*Position, RangeLimit, [&](cPlayer & a_Player) bool res = Self->DoWithNearestPlayer(Position, RangeLimit, [&](cPlayer & a_Player)
{ {
bool ret = false; bool ret = false;
L.Call(FnRef, &a_Player, cLuaState::Return, ret); L.Call(FnRef, &a_Player, cLuaState::Return, ret);
@ -895,7 +888,7 @@ static int tolua_cWorld_SpawnSplitExperienceOrbs(lua_State* tolua_S)
} }
cWorld * self = nullptr; cWorld * self = nullptr;
Vector3d * Position = nullptr; Vector3d Position;
int Reward; int Reward;
L.GetStackValues(1, self, Position, Reward); L.GetStackValues(1, self, Position, Reward);
if (self == nullptr) if (self == nullptr)
@ -903,14 +896,9 @@ static int tolua_cWorld_SpawnSplitExperienceOrbs(lua_State* tolua_S)
tolua_error(tolua_S, "Invalid 'self' in function 'SpawnSplitExperienceOrbs'", nullptr); tolua_error(tolua_S, "Invalid 'self' in function 'SpawnSplitExperienceOrbs'", nullptr);
return 0; return 0;
} }
if (Position == nullptr)
{
tolua_error(tolua_S, "Error in function 'SpawnSplitExperienceOrbs' arg #2. Value must not be nil.", nullptr);
return 0;
}
// Execute and push result: // Execute and push result:
L.Push(self->SpawnExperienceOrb(Position->x, Position->y, Position->z, Reward)); L.Push(self->SpawnExperienceOrb(Position, Reward));
return 1; return 1;
} }