]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/script/common/c_converter.cpp
set_sky improvements, set_sun, set_moon and set_stars
[dragonfireclient.git] / src / script / common / c_converter.cpp
index f1d3cc421d4dc1d21feecb5fb4cf566f844ae2db..3c2f7564133d067524b5e2bd2daef7b65749f987 100644 (file)
@@ -23,23 +23,43 @@ extern "C" {
 }
 
 #include "util/numeric.h"
+#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) { \
+       std::ostringstream error_text; \
+       error_text << "Invalid float vector dimension range '" name "' " << \
+       "(expected " << F1000_MIN << " < " name " < " << F1000_MAX << \
+       " got " << value << ")." << std::endl; \
+       throw LuaError(error_text.str()); \
+}
 #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);
@@ -60,29 +80,34 @@ void push_v2f(lua_State *L, v2f p)
        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;
@@ -170,14 +195,55 @@ v3f check_v3f(lua_State *L, int 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;
+}
+
+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;
 }
@@ -220,15 +286,15 @@ void push_v3s16(lua_State *L, v3s16 p)
 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)
@@ -269,6 +335,28 @@ video::SColor read_ARGB8(lua_State *L, int index)
        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;
@@ -292,6 +380,7 @@ aabb3f read_aabb3f(lua_State *L, int index, f32 scale)
                box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
                lua_pop(L, 1);
        }
+       box.repair();
        return box;
 }
 
@@ -385,58 +474,6 @@ bool getstringfield(lua_State *L, int table,
        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_tonumber(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_tonumber(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_tonumber(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_tonumber(L, -1);
-               got = true;
-       }
-       lua_pop(L, 1);
-       return got;
-}
-
 bool getfloatfield(lua_State *L, int table,
                const char *fieldname, float &result)
 {
@@ -517,6 +554,22 @@ bool getboolfield_default(lua_State *L, int table,
        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 std::string &value)
+{
+       lua_pushlstring(L, value.c_str(), value.length());
+       if(table < 0)
+               table -= 1;
+       lua_setfield(L, table, fieldname);
+}
+
 void setintfield(lua_State *L, int table,
                const char *fieldname, int value)
 {