From c1b3ed4180dea16e2fa77663a7d2bf155595dd60 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Lo=C3=AFc=20Blot?= Date: Sun, 7 May 2017 12:13:15 +0200 Subject: [PATCH] Player attrs: permits to remove an attribute by setting value to nil (#5716) * 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 | 4 +++- games/minimal/mods/default/init.lua | 22 ++++++++++++---------- src/content_sao.h | 10 ++++++++++ src/script/lua_api/l_object.cpp | 7 ++++--- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 607a13fdd..d8e297f4c 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -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 diff --git a/games/minimal/mods/default/init.lua b/games/minimal/mods/default/init.lua index d36e225a3..64970f922 100644 --- a/games/minimal/mods/default/init.lua +++ b/games/minimal/mods/default/init.lua @@ -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 diff --git a/src/content_sao.h b/src/content_sao.h index e08795579..0dad54805 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -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; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 6f61ab55c..c7a31d048 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -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; -- 2.25.1