#include "util/serialize.h"
#include "util/string.h"
#include "common/c_converter.h"
+#include "common/c_internal.h"
#include "constants.h"
-#define CHECK_TYPE(index, name, type) do { \
+#define CHECK_TYPE(index, name, type) { \
int t = lua_type(L, (index)); \
if (t != (type)) { \
+ std::string traceback = script_get_backtrace(L); \
throw LuaError(std::string("Invalid ") + (name) + \
" (expected " + lua_typename(L, (type)) + \
- " got " + lua_typename(L, t) + ")."); \
+ " got " + lua_typename(L, t) + ").\n" + traceback); \
} \
- } while(0)
+ }
#define CHECK_POS_COORD(name) CHECK_TYPE(-1, "position coordinate '" name "'", LUA_TNUMBER)
#define CHECK_FLOAT_RANGE(value, name) \
if (value < F1000_MIN || value > F1000_MAX) { \
#define CHECK_POS_TAB(index) CHECK_TYPE(index, "position", LUA_TTABLE)
+void push_float_string(lua_State *L, float value)
+{
+ std::stringstream ss;
+ std::string str;
+ ss << value;
+ str = ss.str();
+ lua_pushstring(L, str.c_str());
+}
+
void push_v3f(lua_State *L, v3f p)
{
lua_newtable(L);
lua_setfield(L, -2, "y");
}
-v2s16 read_v2s16(lua_State *L, int index)
+void push_v3_float_string(lua_State *L, v3f p)
{
- v2s16 p;
- CHECK_POS_TAB(index);
- lua_getfield(L, index, "x");
- p.X = lua_tonumber(L, -1);
- lua_pop(L, 1);
- lua_getfield(L, index, "y");
- p.Y = lua_tonumber(L, -1);
- lua_pop(L, 1);
- return p;
+ lua_newtable(L);
+ push_float_string(L, p.X);
+ lua_setfield(L, -2, "x");
+ push_float_string(L, p.Y);
+ lua_setfield(L, -2, "y");
+ push_float_string(L, p.Z);
+ lua_setfield(L, -2, "z");
}
-v2s16 check_v2s16(lua_State *L, int index)
+void push_v2_float_string(lua_State *L, v2f p)
+{
+ lua_newtable(L);
+ push_float_string(L, p.X);
+ lua_setfield(L, -2, "x");
+ push_float_string(L, p.Y);
+ lua_setfield(L, -2, "y");
+}
+
+v2s16 read_v2s16(lua_State *L, int index)
{
v2s16 p;
CHECK_POS_TAB(index);
lua_getfield(L, index, "x");
- CHECK_POS_COORD("x");
p.X = lua_tonumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, index, "y");
- CHECK_POS_COORD("y");
p.Y = lua_tonumber(L, -1);
lua_pop(L, 1);
return p;
return pos;
}
+v3d read_v3d(lua_State *L, int index)
+{
+ v3d pos;
+ CHECK_POS_TAB(index);
+ lua_getfield(L, index, "x");
+ pos.X = lua_tonumber(L, -1);
+ lua_pop(L, 1);
+ lua_getfield(L, index, "y");
+ pos.Y = lua_tonumber(L, -1);
+ lua_pop(L, 1);
+ lua_getfield(L, index, "z");
+ pos.Z = lua_tonumber(L, -1);
+ lua_pop(L, 1);
+ return pos;
+}
+
+v3d check_v3d(lua_State *L, int index)
+{
+ v3d pos;
+ CHECK_POS_TAB(index);
+ lua_getfield(L, index, "x");
+ CHECK_POS_COORD("x");
+ pos.X = lua_tonumber(L, -1);
+ CHECK_FLOAT_RANGE(pos.X, "x")
+ lua_pop(L, 1);
+ lua_getfield(L, index, "y");
+ CHECK_POS_COORD("y");
+ pos.Y = lua_tonumber(L, -1);
+ CHECK_FLOAT_RANGE(pos.Y, "y")
+ lua_pop(L, 1);
+ lua_getfield(L, index, "z");
+ CHECK_POS_COORD("z");
+ pos.Z = lua_tonumber(L, -1);
+ CHECK_FLOAT_RANGE(pos.Z, "z")
+ lua_pop(L, 1);
+ return pos;
+}
+
void push_ARGB8(lua_State *L, video::SColor color)
{
lua_newtable(L);
v3s16 read_v3s16(lua_State *L, int index)
{
// Correct rounding at <0
- v3f pf = read_v3f(L, index);
- return floatToInt(pf, 1.0);
+ v3d pf = read_v3d(L, index);
+ return doubleToInt(pf, 1.0);
}
v3s16 check_v3s16(lua_State *L, int index)
{
// Correct rounding at <0
- v3f pf = check_v3f(L, index);
- return floatToInt(pf, 1.0);
+ v3d pf = check_v3d(L, index);
+ return doubleToInt(pf, 1.0);
}
bool read_color(lua_State *L, int index, video::SColor *color)
return color;
}
+bool is_color_table(lua_State *L, int index)
+{
+ // Check whole table in case of missing ColorSpec keys:
+ // This check does not remove the checked value from the stack.
+ // Only update the value if we know we have a valid ColorSpec key pair.
+ if (!lua_istable(L, index))
+ return false;
+
+ bool is_color_table = false;
+ lua_getfield(L, index, "r");
+ if (!is_color_table)
+ is_color_table = lua_isnumber(L, -1);
+ lua_getfield(L, index, "g");
+ if (!is_color_table)
+ is_color_table = lua_isnumber(L, -1);
+ lua_getfield(L, index, "b");
+ if (!is_color_table)
+ is_color_table = lua_isnumber(L, -1);
+ lua_pop(L, 3); // b, g, r values
+ return is_color_table;
+}
+
aabb3f read_aabb3f(lua_State *L, int index, f32 scale)
{
aabb3f box;
box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
lua_pop(L, 1);
}
+ box.repair();
return box;
}
return got;
}
-bool getintfield(lua_State *L, int table,
- const char *fieldname, int &result)
-{
- lua_getfield(L, table, fieldname);
- bool got = false;
- if(lua_isnumber(L, -1)){
- result = lua_tointeger(L, -1);
- got = true;
- }
- lua_pop(L, 1);
- return got;
-}
-
-bool getintfield(lua_State *L, int table,
- const char *fieldname, u8 &result)
-{
- lua_getfield(L, table, fieldname);
- bool got = false;
- if(lua_isnumber(L, -1)){
- result = lua_tointeger(L, -1);
- got = true;
- }
- lua_pop(L, 1);
- return got;
-}
-
-bool getintfield(lua_State *L, int table,
- const char *fieldname, u16 &result)
-{
- lua_getfield(L, table, fieldname);
- bool got = false;
- if(lua_isnumber(L, -1)){
- result = lua_tointeger(L, -1);
- got = true;
- }
- lua_pop(L, 1);
- return got;
-}
-
-bool getintfield(lua_State *L, int table,
- const char *fieldname, u32 &result)
-{
- lua_getfield(L, table, fieldname);
- bool got = false;
- if(lua_isnumber(L, -1)){
- result = lua_tointeger(L, -1);
- got = true;
- }
- lua_pop(L, 1);
- return got;
-}
-
bool getfloatfield(lua_State *L, int table,
const char *fieldname, float &result)
{
return result;
}
-int check_material_type_param(lua_State *L, int table,
- const char *fieldname, int default_)
-{
- int material_type_param =
- getintfield_default(L, table, fieldname, default_);
- u32 alphaSource = (material_type_param & 0x0000F000) >> 12;
- u32 modulo = (material_type_param & 0x00000F00) >> 8;
- u32 srcFact = (material_type_param & 0x000000F0) >> 4;
- u32 dstFact = material_type_param & 0x0000000F;
- if (alphaSource <= 3 && modulo <= 4 && srcFact <= 10 && dstFact <= 10) {
- return material_type_param;
- } else {
- std::ostringstream error_text;
- error_text << "Incorrect material_type_param value ";
- error_text << "for particle or particle spawner.";
- error_text << std::endl;
- throw LuaError(error_text.str());
- return 0;
- }
-}
-
-
float getfloatfield_default(lua_State *L, int table,
const char *fieldname, float default_)
{
return result;
}
+v3s16 getv3s16field_default(lua_State *L, int table,
+ const char *fieldname, v3s16 default_)
+{
+ getv3intfield(L, table, fieldname, default_);
+ return default_;
+}
+
void setstringfield(lua_State *L, int table,
- const char *fieldname, const char *value)
+ const char *fieldname, const std::string &value)
{
- lua_pushstring(L, value);
+ lua_pushlstring(L, value.c_str(), value.length());
if(table < 0)
table -= 1;
lua_setfield(L, table, fieldname);