SAPI: Accept either ARGB8 table or ColorString to specify colors
authorkwolekr <kwolekr@minetest.net>
Sat, 16 May 2015 16:26:57 +0000 (12:26 -0400)
committerkwolekr <kwolekr@minetest.net>
Sun, 17 May 2015 00:15:03 +0000 (20:15 -0400)
doc/lua_api.txt
src/script/common/c_content.cpp
src/script/common/c_converter.cpp
src/script/common/c_converter.h
src/script/lua_api/l_object.cpp

index e1ee42b947b96272dd61c061ddec8c00b99ccf50..9249703f6c23b2819c251e34734e19a1b666d2b7 100644 (file)
@@ -1607,6 +1607,16 @@ To specify the value of the alpha channel, append `#AA` to the end of the color
 (e.g. `colorname#08`). For named colors the hexadecimal string representing the alpha
 value must (always) be two hexadecimal digits.
 
+`ColorSpec`
+-----------
+A ColorSpec specifies a 32-bit color.  It can be written in either:
+table form, each element ranging from 0..255 (a, if absent, defaults to 255):
+    `colorspec = {a=255, r=0, g=255, b=0}`
+numerical form, the raw integer value of an ARGB8 quad:
+    `colorspec = 0xFF00FF00`
+or string form, a ColorString (defined above):
+    `colorspec = "green"`
+
 Vector helpers
 --------------
 
@@ -2481,7 +2491,7 @@ This is basically a reference to a C++ `ServerActiveObject`
     * `name`: `"breath"` or `"health"`
     * `hud_definition`: definition to replace builtin definition
 * `set_sky(bgcolor, type, {texture names})`
-    * `bgcolor`: `{r=0...255, g=0...255, b=0...255}` or `nil`, defaults to white
+    * `bgcolor`: ColorSpec, defaults to white
     * Available types:
         * `"regular"`: Uses 0 textures, `bgcolor` ignored
         * `"skybox"`: Uses 6 textures, `bgcolor` used
@@ -2507,13 +2517,13 @@ This is basically a reference to a C++ `ServerActiveObject`
 * `get_nametag_attributes()`
     * returns a table with the attributes of the nametag of the player
     * {
-        color = { a = 0...255, r = 0...255, g = 0...255, b = 0...255 }
+        color = {a=0..255, r=0..255, g=0..255, b=0..255},
       }
 * `set_nametag_attributes(attributes)`
     * sets the attributes of the nametag of the player
     * `attributes`:
       {
-        color = { a = 0...255, r = 0...255, g = 0...255, b = 0...255 }
+        color = ColorSpec,
       }
 
 ### `InvRef`
@@ -3023,7 +3033,7 @@ Definition tables
         ^ List can be shortened to needed length ]]
         alpha = 255,
         use_texture_alpha = false, -- Use texture's alpha channel
-        post_effect_color = {a=0, r=0, g=0, b=0}, -- If player is inside node
+        post_effect_color = "green#0F", -- If player is inside node, see "ColorSpec"
         paramtype = "none", -- See "Nodes" --[[
         ^ paramtype = "light" allows light to propagate from or through the node with light value
         ^ falling by 1 per node. This line is essential for a light source node to spread its light. ]]
index 8f82b692a689fd81561b3d9188d210488258fa94..c0728177fda0ad9ba90b530b06155172d52e57f4 100644 (file)
@@ -162,18 +162,13 @@ void read_object_properties(lua_State *L, int index,
        lua_pop(L, 1);
 
        lua_getfield(L, -1, "colors");
-       if(lua_istable(L, -1)){
-               prop->colors.clear();
+       if (lua_istable(L, -1)) {
                int table = lua_gettop(L);
-               lua_pushnil(L);
-               while(lua_next(L, table) != 0){
-                       // key at index -2 and value at index -1
-                       if(lua_isstring(L, -1))
-                               prop->colors.push_back(readARGB8(L, -1));
-                       else
-                               prop->colors.push_back(video::SColor(255, 255, 255, 255));
-                       // removes value, keeps key for next iteration
-                       lua_pop(L, 1);
+               prop->colors.clear();
+               for (lua_pushnil(L); lua_next(L, table); lua_pop(L, 1)) {
+                       video::SColor color(255, 255, 255, 255);
+                       read_color(L, -1, &color);
+                       prop->colors.push_back(color);
                }
        }
        lua_pop(L, 1);
@@ -357,8 +352,7 @@ ContentFeatures read_content_features(lua_State *L, int index)
        /* Other stuff */
 
        lua_getfield(L, index, "post_effect_color");
-       if(!lua_isnil(L, -1))
-               f.post_effect_color = readARGB8(L, -1);
+       read_color(L, -1, &f.post_effect_color);
        lua_pop(L, 1);
 
        f.param_type = (ContentParamType)getenumfield(L, index, "paramtype",
index 9d68298155cf08672011abfcbf8a9c428e5546fb..6fb6f623a66d361a3b930ae8eff88d0c6771f83f 100644 (file)
@@ -23,35 +23,23 @@ extern "C" {
 }
 
 #include "util/numeric.h"
+#include "util/string.h"
 #include "common/c_converter.h"
 #include "constants.h"
 
 
 #define CHECK_TYPE(index, name, type) do { \
-       int t = lua_type(L, (index)); \
-       if (t != (type)) { \
-               throw LuaError(std::string("Invalid ") + (name) + \
-                       " (expected " + lua_typename(L, (type)) + \
-                       " got " + lua_typename(L, t) + ")."); \
-       } \
-} while(0)
+               int t = lua_type(L, (index)); \
+               if (t != (type)) { \
+                       throw LuaError(std::string("Invalid ") + (name) + \
+                               " (expected " + lua_typename(L, (type)) + \
+                               " got " + lua_typename(L, t) + ")."); \
+               } \
+       } while(0)
 #define CHECK_POS_COORD(name) CHECK_TYPE(-1, "position coordinate '" name "'", LUA_TNUMBER)
 #define CHECK_POS_TAB(index) CHECK_TYPE(index, "position", LUA_TTABLE)
 
 
-void push_ARGB8(lua_State *L, video::SColor color)
-{
-       lua_newtable(L);
-       lua_pushnumber(L, color.getAlpha());
-       lua_setfield(L, -2, "a");
-       lua_pushnumber(L, color.getRed());
-       lua_setfield(L, -2, "r");
-       lua_pushnumber(L, color.getGreen());
-       lua_setfield(L, -2, "g");
-       lua_pushnumber(L, color.getBlue());
-       lua_setfield(L, -2, "b");
-}
-
 void push_v3f(lua_State *L, v3f p)
 {
        lua_newtable(L);
@@ -176,6 +164,19 @@ v3f check_v3f(lua_State *L, int index)
        return pos;
 }
 
+void push_ARGB8(lua_State *L, video::SColor color)
+{
+       lua_newtable(L);
+       lua_pushnumber(L, color.getAlpha());
+       lua_setfield(L, -2, "a");
+       lua_pushnumber(L, color.getRed());
+       lua_setfield(L, -2, "r");
+       lua_pushnumber(L, color.getGreen());
+       lua_setfield(L, -2, "g");
+       lua_pushnumber(L, color.getBlue());
+       lua_setfield(L, -2, "b");
+}
+
 void pushFloatPos(lua_State *L, v3f p)
 {
        p /= BS;
@@ -212,13 +213,31 @@ v3s16 check_v3s16(lua_State *L, int index)
        return floatToInt(pf, 1.0);
 }
 
-video::SColor readARGB8(lua_State *L, int index)
+bool read_color(lua_State *L, int index, video::SColor *color)
+{
+       if (lua_istable(L, index)) {
+               *color = read_ARGB8(L, index);
+       } else if (lua_isnumber(L, index)) {
+               color->set(lua_tonumber(L, index));
+       } else if (lua_isstring(L, index)) {
+               video::SColor parsed_color;
+               if (!parseColorString(lua_tostring(L, index), parsed_color, true))
+                       return false;
+
+               *color = parsed_color;
+       } else {
+               return false;
+       }
+
+       return true;
+}
+
+video::SColor read_ARGB8(lua_State *L, int index)
 {
        video::SColor color(0);
        CHECK_TYPE(index, "ARGB color", LUA_TTABLE);
        lua_getfield(L, index, "a");
-       if(lua_isnumber(L, -1))
-               color.setAlpha(lua_tonumber(L, -1));
+       color.setAlpha(lua_isnumber(L, -1) ? lua_tonumber(L, -1) : 0xFF);
        lua_pop(L, 1);
        lua_getfield(L, index, "r");
        color.setRed(lua_tonumber(L, -1));
index ff1fcaadfc9eb3aaed7dbc35d467aa8afbdc6645..e99826404f058527ad603c185c72ca7f3fe357e7 100644 (file)
@@ -76,7 +76,6 @@ void               setfloatfield(lua_State *L, int table,
 void               setboolfield(lua_State *L, int table,
                              const char *fieldname, bool value);
 
-
 v3f                 checkFloatPos       (lua_State *L, int index);
 v2f                 check_v2f           (lua_State *L, int index);
 v2s16               check_v2s16         (lua_State *L, int index);
@@ -87,7 +86,10 @@ v3f                 read_v3f            (lua_State *L, int index);
 v2f                 read_v2f            (lua_State *L, int index);
 v2s16               read_v2s16          (lua_State *L, int index);
 v2s32               read_v2s32          (lua_State *L, int index);
-video::SColor       readARGB8           (lua_State *L, int index);
+video::SColor       read_ARGB8          (lua_State *L, int index);
+bool                read_color          (lua_State *L, int index,
+                                         video::SColor *color);
+
 aabb3f              read_aabb3f         (lua_State *L, int index, f32 scale);
 v3s16               read_v3s16          (lua_State *L, int index);
 std::vector<aabb3f> read_aabb3f_vector  (lua_State *L, int index, f32 scale);
@@ -100,11 +102,8 @@ void                pushFloatPos        (lua_State *L, v3f p);
 void                push_v3f            (lua_State *L, v3f p);
 void                push_v2f            (lua_State *L, v2f p);
 
-
-
-void                warn_if_field_exists      (lua_State *L,
-                                              int table,
-                                              const char *fieldname,
-                                              const std::string &message);
+void                warn_if_field_exists(lua_State *L, int table,
+                                         const char *fieldname,
+                                         const std::string &message);
 
 #endif /* C_CONVERTER_H_ */
index 74903df5fa4d9533d93b5bf267fbf21e71d1ff12..c83c8c7475f7f525ac7be285f7ea9b4d732fa657 100644 (file)
@@ -1222,8 +1222,7 @@ int ObjectRef::l_set_sky(lua_State *L)
                return 0;
 
        video::SColor bgcolor(255,255,255,255);
-       if (!lua_isnil(L, 2))
-               bgcolor = readARGB8(L, 2);
+       read_color(L, 2, &bgcolor);
 
        std::string type = luaL_checkstring(L, 3);
 
@@ -1283,11 +1282,13 @@ int ObjectRef::l_set_nametag_attributes(lua_State *L)
        if (playersao == NULL)
                return 0;
 
-       video::SColor color = playersao->getNametagColor();
        lua_getfield(L, 2, "color");
-       if (!lua_isnil(L, -1))
-               color = readARGB8(L, -1);
-       playersao->setNametagColor(color);
+       if (!lua_isnil(L, -1)) {
+               video::SColor color = playersao->getNametagColor();
+               if (!read_color(L, -1, &color))
+                       return 0;
+               playersao->setNametagColor(color);
+       }
 
        lua_pushboolean(L, true);
        return 1;