From 55097e19850d175fe3c93a40ce7c6d50d2c60e8f Mon Sep 17 00:00:00 2001 From: PilzAdam Date: Sun, 3 Mar 2013 16:34:06 +0100 Subject: Fix pickup of dropped items when the player only takes a part of them --- builtin/item_entity.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'builtin') diff --git a/builtin/item_entity.lua b/builtin/item_entity.lua index 1699cb03c..50ce7eafe 100644 --- a/builtin/item_entity.lua +++ b/builtin/item_entity.lua @@ -111,6 +111,7 @@ minetest.register_entity("__builtin:item", { if self.itemstring ~= '' then local left = hitter:get_inventory():add_item("main", self.itemstring) if not left:is_empty() then + self.itemstring = left:to_string() return end end -- cgit v1.2.3 From ba78194636a9a498f6979cc21cd39399f23d658a Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sun, 24 Feb 2013 16:00:35 -0500 Subject: Allow any character in formspec strings with escape char --- builtin/misc.lua | 7 +++ doc/lua_api.txt | 3 ++ src/guiFormSpecMenu.cpp | 122 ++++++++++++++++++++++++++---------------------- src/strfnd.h | 37 +++++++++++++++ src/util/string.h | 16 +++++++ 5 files changed, 129 insertions(+), 56 deletions(-) (limited to 'builtin') diff --git a/builtin/misc.lua b/builtin/misc.lua index e018aff85..496435b33 100644 --- a/builtin/misc.lua +++ b/builtin/misc.lua @@ -99,3 +99,10 @@ function minetest.setting_get_pos(name) return minetest.string_to_pos(value) end +function minetest.formspec_escape(str) + str = string.gsub(str, "\\", "\\\\") + str = string.gsub(str, "%[", "\\[") + str = string.gsub(str, "%]", "\\]") + return str +end + diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 005d7c010..8246377e2 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -778,6 +778,9 @@ string:trim() minetest.pos_to_string({x=X,y=Y,z=Z}) -> "(X,Y,Z)" ^ Convert position to a printable string minetest.string_to_pos(string) -> position +^ Same but in reverse +minetest.formspec_escape(string) -> string +^ escapes characters like [, ], and \ that can not be used in formspecs minetest namespace reference ----------------------------- diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index 120d6629a..1754422d0 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -207,18 +207,18 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) Strfnd f(m_formspec_string); while(f.atend() == false) { - std::string type = trim(f.next("[")); + std::string type = trim(f.next_esc("[")); if(type == "invsize" || type == "size") { v2f invsize; - invsize.X = stof(f.next(",")); + invsize.X = stof(f.next_esc(",")); if(type == "size") { - invsize.Y = stof(f.next("]")); + invsize.Y = stof(f.next_esc("]")); } else{ - invsize.Y = stof(f.next(";")); - f.next("]"); + invsize.Y = stof(f.next_esc(";")); + f.next_esc("]"); } infostream<<"Form size ("<(pos.X, pos.Y+((imgsize.Y/2)-15), pos.X+300, pos.Y+((imgsize.Y/2)+15)); - std::string flabel = f.next("]"); + std::string flabel = f.next_esc("]"); if(bp_set != 2) errorstream<<"WARNING: invalid use of label without a size[] element"<(pos.X, pos.Y-15, pos.X+geom.X, pos.Y+15); - std::string fname = f.next(";"); - std::string flabel = f.next("]"); + std::string fname = f.next_esc(";"); + std::string flabel = f.next_esc("]"); if(bp_set != 2) errorstream<<"WARNING: invalid use of button without a size[] element"<(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y); - std::string fimage = f.next(";"); - std::string fname = f.next(";"); - std::string flabel = f.next("]"); + std::string fimage = f.next_esc(";"); + std::string fname = f.next_esc(";"); + std::string flabel = f.next_esc("]"); if(bp_set != 2) errorstream<<"WARNING: invalid use of image_button without a size[] element"<(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y); - std::string fimage = f.next(";"); - std::string fname = f.next(";"); - std::string flabel = f.next("]"); + std::string fimage = f.next_esc(";"); + std::string fname = f.next_esc(";"); + std::string flabel = f.next_esc("]"); if(bp_set != 2) errorstream<<"WARNING: invalid use of item_image_button without a size[] element"<idef(); @@ -535,6 +544,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) item.deSerialize(fimage, idef); video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef); std::string tooltip = item.getDefinition(idef).description; + flabel = unescape_string(flabel); FieldSpec spec = FieldSpec( narrow_to_wide(fname.c_str()), narrow_to_wide(flabel.c_str()), @@ -556,7 +566,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) else { // Ignore others - std::string ts = f.next("]"); + std::string ts = f.next_esc("]"); infostream<<"Unknown DrawSpec: type="<= tek.size()) + return ""; + + realp = p; + do { + n = tek.find(plop, p); + if (n == std::string::npos || plop == "") + n = tek.length(); + p = n + plop.length(); + } while (n > 0 && tek[n - 1] == '\\'); + + return tek.substr(realp, n - realp); + } + void skip_over(std::string chars){ while(p < tek.size()){ bool is = false; @@ -128,6 +147,24 @@ public: //std::cout<<"palautus=\""<= tek.size()) + return L""; + + realp = p; + do { + n = tek.find(plop, p); + if (n == std::wstring::npos || plop == L"") + n = tek.length(); + p = n + plop.length(); + } while (n > 0 && tek[n - 1] == '\\'); + + return tek.substr(realp, n - realp); + } + bool atend(){ if(p>=tek.size()) return true; return false; diff --git a/src/util/string.h b/src/util/string.h index 2f0264bd4..6c48adeb3 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -286,6 +286,22 @@ inline std::string wrap_rows(const std::string &from, u32 rowlen) return to; } +/* + Removes all \\ from a string that had been escaped (FormSpec strings) +*/ +inline std::string unescape_string(std::string &s) +{ + std::string res; + + for (size_t i = 0; i <= s.length(); i++) { + if (s[i] == '\\') + i++; + res += s[i]; + } + + return res; +} + std::string translatePassword(std::string playername, std::wstring password); size_t curl_write_data(char *ptr, size_t size, size_t nmemb, void *userdata); u32 readFlagString(std::string str, FlagDesc *flagdesc); -- cgit v1.2.3 From fc5d2074b99d22022d2bf8e693351274bc3f6d09 Mon Sep 17 00:00:00 2001 From: Jeija Date: Mon, 11 Feb 2013 09:58:58 +0100 Subject: Allow minetest.after to take a variable number of arguments --- builtin/misc.lua | 6 +++--- doc/lua_api.txt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'builtin') diff --git a/builtin/misc.lua b/builtin/misc.lua index 496435b33..2cc76e8ec 100644 --- a/builtin/misc.lua +++ b/builtin/misc.lua @@ -14,14 +14,14 @@ minetest.register_globalstep(function(dtime) for index, timer in ipairs(minetest.timers) do timer.time = timer.time - dtime if timer.time <= 0 then - timer.func(timer.param) + timer.func(unpack(timer.args)) table.remove(minetest.timers,index) end end end) -function minetest.after(time, func, param) - table.insert(minetest.timers_to_add, {time=time, func=func, param=param}) +function minetest.after(time, func, ...) + table.insert(minetest.timers_to_add, {time=time, func=func, args=arg}) end function minetest.check_player_privs(name, privs) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 809d3d9d0..eb05d117e 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -977,9 +977,9 @@ minetest.sound_play(spec, parameters) -> handle minetest.sound_stop(handle) Timing: -minetest.after(time, func, param) +minetest.after(time, func, ...) ^ Call function after time seconds -^ param is optional; to pass multiple parameters, pass a table. +^ Optional: Variable number of arguments that are passed to func Server: minetest.request_shutdown() -> request for server shutdown -- cgit v1.2.3 From d6026a5fee11722798ddcb1e4d0b5638f16ba9ce Mon Sep 17 00:00:00 2001 From: PilzAdam Date: Tue, 19 Mar 2013 00:13:00 +0100 Subject: Prevent passing nil to unpack() in minetest.after --- builtin/misc.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'builtin') diff --git a/builtin/misc.lua b/builtin/misc.lua index 2cc76e8ec..8308b3d6b 100644 --- a/builtin/misc.lua +++ b/builtin/misc.lua @@ -14,14 +14,14 @@ minetest.register_globalstep(function(dtime) for index, timer in ipairs(minetest.timers) do timer.time = timer.time - dtime if timer.time <= 0 then - timer.func(unpack(timer.args)) + timer.func(unpack(timer.args or {})) table.remove(minetest.timers,index) end end end) function minetest.after(time, func, ...) - table.insert(minetest.timers_to_add, {time=time, func=func, args=arg}) + table.insert(minetest.timers_to_add, {time=time, func=func, args={...}}) end function minetest.check_player_privs(name, privs) -- cgit v1.2.3 From 9b5bb5c7559953db40b52dead3c85e1a1245b4f1 Mon Sep 17 00:00:00 2001 From: Splizard Date: Thu, 20 Dec 2012 10:24:54 +1300 Subject: Allow falling nodes to pass through solid "buildable_to" nodes. --- builtin/falling.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'builtin') diff --git a/builtin/falling.lua b/builtin/falling.lua index d3af36f29..1c09f9856 100644 --- a/builtin/falling.lua +++ b/builtin/falling.lua @@ -57,6 +57,10 @@ minetest.register_entity("__builtin:falling_node", { -- Note: walkable is in the node definition, not in item groups if minetest.registered_nodes[bcn.name] and minetest.registered_nodes[bcn.name].walkable then + if minetest.registered_nodes[bcn.name].buildable_to then + minetest.env:remove_node(bcp) + return + end local np = {x=bcp.x, y=bcp.y+1, z=bcp.z} -- Check what's here local n2 = minetest.env:get_node(np) @@ -80,6 +84,7 @@ minetest.register_entity("__builtin:falling_node", { -- Create node and remove entity minetest.env:add_node(np, {name=self.nodename}) self.object:remove() + nodeupdate(np) else -- Do nothing end @@ -144,7 +149,8 @@ function nodeupdate_single(p) n_bottom = minetest.env:get_node(p_bottom) -- Note: walkable is in the node definition, not in item groups if minetest.registered_nodes[n_bottom.name] and - not minetest.registered_nodes[n_bottom.name].walkable then + (not minetest.registered_nodes[n_bottom.name].walkable or + minetest.registered_nodes[n_bottom.name].buildable_to) then minetest.env:remove_node(p) spawn_falling_node(p, n.name) nodeupdate(p) -- cgit v1.2.3 From 02cbb5810774ec0d8eb43b6cd5796a3d43878fe1 Mon Sep 17 00:00:00 2001 From: "0gb.us" <0gb.us@0gb.us> Date: Thu, 28 Mar 2013 01:24:48 -0700 Subject: Fix node replacement in not-quite-loaded chunks When first entering an area, sometimes placing nodes replaces other nodes that are not buildable_to. This seems to be caused by the fact that nodes in unloaded map blocks are treated as ignore, a node that is buildable_to. This fixes that, by using get_node_or_nil() instead of the previously-used get_node(), then checking to see if the nodes were actually loaded before replacing. --- builtin/item.lua | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'builtin') diff --git a/builtin/item.lua b/builtin/item.lua index 1349fdf63..8e2f75a1a 100644 --- a/builtin/item.lua +++ b/builtin/item.lua @@ -129,11 +129,18 @@ function minetest.item_place_node(itemstack, placer, pointed_thing) end local under = pointed_thing.under - local oldnode_under = minetest.env:get_node(under) + local oldnode_under = minetest.env:get_node_or_nil(under) + local above = pointed_thing.above + local oldnode_above = minetest.env:get_node_or_nil(above) + + if not oldnode_under or not oldnode_above then + minetest.log("info", placer:get_player_name() .. " tried to place" + .. " node in unloaded position " .. minetest.pos_to_string(above)) + return itemstack + end + local olddef_under = ItemStack({name=oldnode_under.name}):get_definition() olddef_under = olddef_under or minetest.nodedef_default - local above = pointed_thing.above - local oldnode_above = minetest.env:get_node(above) local olddef_above = ItemStack({name=oldnode_above.name}):get_definition() olddef_above = olddef_above or minetest.nodedef_default -- cgit v1.2.3