Player attrs: permits to remove an attribute by setting value to nil (#5716)
authorLoïc Blot <nerzhul@users.noreply.github.com>
Sun, 7 May 2017 10:13:15 +0000 (12:13 +0200)
committerGitHub <noreply@github.com>
Sun, 7 May 2017 10:13:15 +0000 (12:13 +0200)
* Player attrs: permits to remove an attribute by setting value to nil

When doing player:set_attribute("attr", nil) remove attribute

Also remove a useless check on C++ API part (already done by checkplayer)

Fix #5709

doc/lua_api.txt
games/minimal/mods/default/init.lua
src/content_sao.h
src/script/lua_api/l_object.cpp

index 607a13fdd1334fb5a7579589959789c899a1fb63..d8e297f4c659fb1e019a1ec585cffa9369d32f5c 100644 (file)
@@ -3028,7 +3028,9 @@ This is basically a reference to a C++ `ServerActiveObject`
         * `0`: player is drowning,
         * `1`-`10`: remaining number of bubbles
         * `11`: bubbles bar is not shown
-* `set_attribute(attribute, value)`: sets an extra attribute with value on player
+* `set_attribute(attribute, value)`:
+    * Sets an extra attribute with value on player.
+    * If value is nil, remove attribute from player.
 * `get_attribute(attribute)`: returns value for extra attribute. Returns nil if no attribute found.
 * `set_inventory_formspec(formspec)`
     * Redefine player's inventory form
index d36e225a32c5091126456e6505ca077ac5333d63..64970f922bdc56cfb8f900d3e058f61d26996d85 100644 (file)
@@ -18,6 +18,8 @@ dofile(minetest.get_modpath("default").."/mapgen.lua")
 minetest.register_on_joinplayer(function(player)
        local cb = function(player)
                minetest.chat_send_player(player:get_player_name(), "This is the [minimal] \"Minimal Development Test\" game. Use [minetest_game] for the real thing.")
+               player:set_attribute("test_attribute", "test_me")
+               player:set_attribute("remove_this", nil)
        end
        minetest.after(2.0, cb, player)
 end)
@@ -1387,13 +1389,13 @@ minetest.register_abm({
 
                local srclist = inv:get_list("src")
                local cooked = nil
-               
+
                if srclist then
                        cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
                end
-               
+
                local was_active = false
-               
+
                if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
                        was_active = true
                        meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
@@ -1413,7 +1415,7 @@ minetest.register_abm({
                                meta:set_string("src_time", 0)
                        end
                end
-               
+
                if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
                        local percent = math.floor(meta:get_float("fuel_time") /
                                        meta:get_float("fuel_totaltime") * 100)
@@ -1438,7 +1440,7 @@ minetest.register_abm({
                local cooked = nil
                local fuellist = inv:get_list("fuel")
                local srclist = inv:get_list("src")
-               
+
                if srclist then
                        cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
                end
@@ -1464,7 +1466,7 @@ minetest.register_abm({
 
                meta:set_string("fuel_totaltime", fuel.time)
                meta:set_string("fuel_time", 0)
-               
+
                local stack = inv:get_stack("fuel", 1)
                stack:take_item()
                inv:set_stack("fuel", 1, stack)
@@ -1571,7 +1573,7 @@ function default.grow_tree(data, a, pos, is_apple_tree, seed)
        y = y+th-1 -- (x, y, z) is now last piece of trunk
        local leaves_a = VoxelArea:new{MinEdge={x=-2, y=-1, z=-2}, MaxEdge={x=2, y=2, z=2}}
        local leaves_buffer = {}
-       
+
        -- Force leaves near the trunk
        local d = 1
        for xi = -d, d do
@@ -1581,14 +1583,14 @@ function default.grow_tree(data, a, pos, is_apple_tree, seed)
        end
        end
        end
-       
+
        -- Add leaves randomly
        for iii = 1, 8 do
                local d = 1
                local xx = pr:next(leaves_a.MinEdge.x, leaves_a.MaxEdge.x - d)
                local yy = pr:next(leaves_a.MinEdge.y, leaves_a.MaxEdge.y - d)
                local zz = pr:next(leaves_a.MinEdge.z, leaves_a.MaxEdge.z - d)
-               
+
                for xi = 0, d do
                for yi = 0, d do
                for zi = 0, d do
@@ -1597,7 +1599,7 @@ function default.grow_tree(data, a, pos, is_apple_tree, seed)
                end
                end
        end
-       
+
        -- Add the leaves
        for xi = leaves_a.MinEdge.x, leaves_a.MaxEdge.x do
        for yi = leaves_a.MinEdge.y, leaves_a.MaxEdge.y do
index e0879557941507e77de18c859872dcb0032c410e..0dad548057c284b097a4be4eb849e21e8445ffbe 100644 (file)
@@ -277,6 +277,16 @@ public:
                return true;
        }
 
+       inline void removeExtendedAttribute(const std::string &attr)
+       {
+               PlayerAttributes::iterator it = m_extra_attributes.find(attr);
+               if (it == m_extra_attributes.end())
+                       return;
+
+               m_extra_attributes.erase(it);
+               m_extended_attributes_modified = true;
+       }
+
        inline const PlayerAttributes &getExtendedAttributes()
        {
                return m_extra_attributes;
index 6f61ab55cc50e3b8c9159c4d3c7a6be6a9fe78c5..c7a31d0487d2d30e0f9e223a88012a3ecc62e484 100644 (file)
@@ -1202,9 +1202,10 @@ int ObjectRef::l_set_attribute(lua_State *L)
        }
 
        std::string attr = luaL_checkstring(L, 2);
-       std::string value = luaL_checkstring(L, 3);
-
-       if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
+       if (lua_isnil(L, 3)) {
+               co->removeExtendedAttribute(attr);
+       } else {
+               std::string value = luaL_checkstring(L, 3);
                co->setExtendedAttribute(attr, value);
        }
        return 1;