From 6fa1b8659716e7f3f469e70cef49d1f680bfc1a2 Mon Sep 17 00:00:00 2001 From: coil <51716565+coil0@users.noreply.github.com> Date: Wed, 18 Dec 2019 15:06:39 -0500 Subject: [PATCH 001/366] Limit number of nodes processed according to charge --- init.lua | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/init.lua b/init.lua index edf9e24..d45733c 100644 --- a/init.lua +++ b/init.lua @@ -554,6 +554,19 @@ function replacer.replace(itemstack, user, pt, right_clicked) return end + local meta = minetest.deserialize(itemstack:get_metadata()) + if not meta or not meta.charge + or meta.charge < replacer.charge_per_node then + inform(name, "Not enough charge to use this mode.") + return + end + + local max_charge_to_use = math.min(meta.charge, replacer.max_charge) + local max_nodes = math.floor(max_charge_to_use / replacer.charge_per_node) + if max_nodes > 3168 then + max_nodes = 3168 + end + local ps,num if mode == "field" then -- get connected positions for plane field replacing @@ -574,11 +587,11 @@ function replacer.replace(itemstack, user, pt, right_clicked) end right_clicked = right_clicked and true or false ps,num = get_ps(pos, {func=field_position, name=node_toreplace.name, - pname=name, above=pdif, right_clicked=right_clicked}, adps, 8799) + pname=name, above=pdif, right_clicked=right_clicked}, adps, max_nodes) elseif mode == "crust" then local nodename_clicked = get_node(pt.under).name local aps,n,aboves = get_ps(pt.above, {func=crust_above_position, - name=nodename_clicked, pname=name}, nil, 8799) + name=nodename_clicked, pname=name}, nil, max_nodes) if aps then if right_clicked then local data = {ps=aps, num=n, name=nodename_clicked, pname=name} @@ -587,7 +600,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) else ps,num = get_ps(pt.under, {func=crust_under_position, name=node_toreplace.name, pname=name, aboves=aboves}, - offsets_hollowcube, 8799) + offsets_hollowcube, max_nodes) if ps then local data = {aboves=aboves, ps=ps, num=num} reduce_crust_ps(data) @@ -597,7 +610,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) end elseif mode == "chunkborder" then ps,num = get_ps(pos, {func=mantle_position, name=node_toreplace.name, - pname=name}, nil, 8799) + pname=name}, nil, max_nodes) end -- reset known nodes table @@ -609,9 +622,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) end local charge_needed = replacer.charge_per_node * num - local meta = minetest.deserialize(itemstack:get_metadata()) - if not meta or not meta.charge - or meta.charge < charge_needed then + if meta.charge < charge_needed then inform(name, "Need " .. charge_needed .. " charge to replace " .. num .. " nodes.") return end From d21d8f31b93b67c835e26726bdd2fc6c30c2fd51 Mon Sep 17 00:00:00 2001 From: coil <51716565+coil0@users.noreply.github.com> Date: Wed, 18 Dec 2019 03:40:37 -0500 Subject: [PATCH 002/366] Increase charge per node --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index edf9e24..dc54579 100644 --- a/init.lua +++ b/init.lua @@ -56,7 +56,7 @@ replacer.blacklist[ "protector:protect"] = true; replacer.blacklist[ "protector:protect2"] = true; replacer.max_charge = 30000 -replacer.charge_per_node = 10 +replacer.charge_per_node = 15 -- adds a tool for inspecting nodes and entities dofile(path.."/inspect.lua") From eb9eb021c0c841d76c563d74448fa64ea1bcc2ad Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 19 Dec 2019 06:34:02 +0100 Subject: [PATCH 003/366] Update README.md reflect changed recipe --- README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0a9269d..81932bf 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,11 @@ It replaces nodes with a previously selected other type of node (i.e. places sai into a brick wall). **Crafting:** - chest - - - - stick - - - - chest +``` + | chest | | | + | | green energy crystal | | + | | | chest | +``` Or just use `/giveme replacer:replacer` **Usage:** Right-click on a node of that type you want to replace other nodes with. @@ -22,9 +24,12 @@ will be taken from your inventory. The second tool included in this mod is the inspector. -Crafting: torch - stick - +Crafting: +``` + | torch | | | + | stick | | | + | | | | +``` Just wield it and click on any node or entity you want to know more about. A limited craft-guide is included. From e13f4c7148d920b80e4a46251ad6b835588d72fe Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 19 Dec 2019 06:45:23 +0100 Subject: [PATCH 004/366] Update README.md more description --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 81932bf..8f74bf4 100644 --- a/README.md +++ b/README.md @@ -12,15 +12,16 @@ into a brick wall). ``` Or just use `/giveme replacer:replacer` -**Usage:** Right-click on a node of that type you want to replace other nodes with. - Left-click (normal usage) on any nodes you want to replace with the type you previously right-clicked on. - SHIFT-Right-click in order to store a new pattern. +**Usage:** Sneak-right-click on a node of which type you want to replace other nodes with. + Left-click (normal usage) on any nodes you want to replace with that type. Right-click to place a node of that type onto clicked node. When in creative mode, the node will just be replaced. Your inventory will not be changed. When *not* in creative mode, digging will be simulated and you will get what was there. In return, the replacement node will be taken from your inventory. +**Modes:** +Special-right-click to cycle through the modes. Single-mode does not need any charge. The other modes do. The second tool included in this mod is the inspector. From 1c35eecd45ac1dfa25754b0c20ab6e89fe9eb52a Mon Sep 17 00:00:00 2001 From: BuckarooBanzay Date: Thu, 9 Jan 2020 13:15:25 +0100 Subject: [PATCH 005/366] create "crafts" and "replacer" modules / add .luacheckrc / fix *some* issues (not all) --- .luacheckrc | 21 ++ check_owner.lua | 44 ---- crafts.lua | 19 ++ init.lua | 609 +----------------------------------------------- inspect.lua | 38 ++- replacer.lua | 593 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 651 insertions(+), 673 deletions(-) create mode 100644 .luacheckrc delete mode 100644 check_owner.lua create mode 100644 crafts.lua create mode 100644 replacer.lua diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..8c058c8 --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,21 @@ + +globals = { + "replacer", +} + +read_globals = { + -- Stdlib + string = {fields = {"split"}}, + table = {fields = {"copy", "getn"}}, + + -- Minetest + "vector", "ItemStack", + "dump", "VoxelArea", + + -- deps + "technic", + "default", + "minetest", + "creative", + "circular_saw" +} diff --git a/check_owner.lua b/check_owner.lua deleted file mode 100644 index 6a63f69..0000000 --- a/check_owner.lua +++ /dev/null @@ -1,44 +0,0 @@ --- taken from Vanessa Ezekowitz' homedecor mod --- see http://forum.minetest.net/viewtopic.php?pid=26061 or https://github.com/VanessaE/homedecor for details! -function replacer_homedecor_node_is_owned(pos, placer) - - if( not( placer ) or not(pos )) then - return true; - end - local pname = placer:get_player_name(); - if (type( minetest.is_protected ) == "function") then - local res = minetest.is_protected( pos, pname ); - if( res ) then - minetest.chat_send_player( pname, "Cannot replace node. It is protected." ); - end - return res; - end - - local ownername = false - if type(IsPlayerNodeOwner) == "function" then -- node_ownership mod - if HasOwner(pos, placer) then -- returns true if the node is owned - if not IsPlayerNodeOwner(pos, pname) then - if type(getLastOwner) == "function" then -- ...is an old version - ownername = getLastOwner(pos) - elseif type(GetNodeOwnerName) == "function" then -- ...is a recent version - ownername = GetNodeOwnerName(pos) - else - ownername = "someone" - end - end - end - - elseif type(isprotect)=="function" then -- glomie's protection mod - if not isprotect(5, pos, placer) then - ownername = "someone" - end - end - - if ownername ~= false then - minetest.chat_send_player( pname, "Sorry, "..ownername.." owns that spot." ) - return true - else - return false - end -end - diff --git a/crafts.lua b/crafts.lua new file mode 100644 index 0000000..891cc8e --- /dev/null +++ b/crafts.lua @@ -0,0 +1,19 @@ + + +minetest.register_craft({ + output = "replacer:replacer", + recipe = { + {'default:chest', '', ''}, + {'', 'technic:green_energy_crystal', ''}, + {'', '', 'default:chest'}, + } +}) + + +minetest.register_craft({ + output = 'replacer:inspect', + recipe = { + { 'default:torch'}, + { 'default:stick'}, + } +}) diff --git a/init.lua b/init.lua index acaa0bc..f8fadd5 100644 --- a/init.lua +++ b/init.lua @@ -37,9 +37,6 @@ local path = minetest.get_modpath("replacer") --- adds a function to check ownership of a node; taken from VanessaEs homedecor mod -dofile(path.."/check_owner.lua") - replacer = {} replacer.blacklist = {}; @@ -60,607 +57,5 @@ replacer.charge_per_node = 15 -- adds a tool for inspecting nodes and entities dofile(path.."/inspect.lua") - -local function inform(name, msg) - minetest.chat_send_player(name, msg) - minetest.log("info", "[replacer] "..name..": "..msg) -end - -local mode_infos = { - single = "Replace single node.", - field = "Left click: Replace field of nodes of a kind where a translucent node is in front of it. Right click: Replace field of air where no translucent node is behind the air.", - crust = "Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air. Right click: Replace air nodes which touch the crust", - chunkborder = "TODO", -} -local mode_colours = { - single = "#ffffff", - field = "#54FFAC", - crust = "#9F6200", - chunkborder = "#FF5457", -} -local modes = {"single", "field", "crust", "chunkborder"} -for n = 1,#modes do - modes[modes[n]] = n -end - -local function get_data(stack) - local daten = stack:get_meta():get_string"replacer":split" " or {} - return { - name = daten[1] or "default:dirt", - param1 = tonumber(daten[2]) or 0, - param2 = tonumber(daten[3]) or 0 - }, - modes[daten[4]] and daten[4] or modes[1] -end - -local function set_data(stack, node, mode) - mode = mode or modes[1] - local metadata = (node.name or "default:dirt") .. " " - .. (node.param1 or 0) .. " " - .. (node.param2 or 0) .." " - .. mode - local meta = stack:get_meta() - meta:set_string("replacer", metadata) - meta:set_string("color", mode_colours[mode]) - return metadata -end - -technic.register_power_tool("replacer:replacer", replacer.max_charge) - -minetest.register_tool("replacer:replacer", { - description = "Node replacement tool", - inventory_image = "replacer_replacer.png", - stack_max = 1, -- it has to store information - thus only one can be stacked - wear_represents = "technic_RE_charge", - on_refill = technic.refill_RE_charge, - liquids_pointable = true, -- it is ok to painit in/with water - --node_placement_prediction = nil, - metadata = "default:dirt", -- default replacement: common dirt - - on_place = function(itemstack, placer, pt) - if not placer - or not pt then - return - end - - local keys = placer:get_player_control() - local name = placer:get_player_name() - local creative_enabled = creative.is_enabled_for(name) - local has_give = minetest.check_player_privs(name, "give") - - if keys.aux1 then - -- Change Mode when holding the fast key - local node, mode = get_data(itemstack) - mode = modes[modes[mode]%#modes+1] - set_data(itemstack, node, mode) - inform(name, "Mode changed to: "..mode..": "..mode_infos[mode]) - return itemstack - end - - -- If not holding shift, place node(s) - if not keys.sneak then - return replacer.replace(itemstack, placer, pt, true) - end - - -- Select new node - if pt.type ~= "node" then - inform(name, "Error: No node selected.") - return - end - - local node, mode = get_data(itemstack) - node = minetest.get_node_or_nil(pt.under) or node - - local inv = placer:get_inventory() - if not (creative_enabled and has_give) - and not inv:contains_item("main", node.name) then - if creative_enabled then - if minetest.get_item_group(node.name, - "not_in_creative_inventory") > 0 then - -- search for a drop available in creative inventory - local found_item = false - local drops = minetest.get_node_drops(node.name) - for i = 1,#drops do - local name = drops[i] - if minetest.registered_nodes[name] - and minetest.get_item_group(name, - "not_in_creative_inventory") == 0 then - node.name = name - found_item = true - break - end - end - if not found_item then - inform(name, "Node not in creative invenotry: \"" .. - node.name .. "\".") - return - end - end - else - local found_item = false - -- search for a drop that the player has if possible - local drops = minetest.get_node_drops(node.name) - for i = 1,#drops do - local name = drops[i] - if minetest.registered_nodes[name] - and inv:contains_item("main", name) then - node.name = name - found_item = true - break - end - end - if not found_item then - -- search for a drop available in creative inventory - -- that first configuring the replacer, - -- then digging the nodes works - for i = 1,#drops do - local name = drops[i] - if minetest.registered_nodes[name] - and minetest.get_item_group(name, - "not_in_creative_inventory") == 0 then - node.name = name - found_item = true - break - end - end - end - if not found_item - and not has_give then - inform(name, "Item not in your inventory: '" .. node.name .. - "'.") - return - end - end - end - - local metadata = set_data(itemstack, node, mode) - - inform(name, "Node replacement tool set to: '" .. metadata .. "'.") - - return itemstack --data changed - end, - --- on_drop = func(itemstack, dropper, pos), - - on_use = function(...) - -- Replace nodes - return replacer.replace(...) - end, -}) - -local poshash = minetest.hash_node_position - --- cache results of minetest.get_node -local known_nodes = {} -local function get_node(pos) - local i = poshash(pos) - local node = known_nodes[i] - if node then - return node - end - node = minetest.get_node(pos) - known_nodes[i] = node - return node -end - --- tests if there's a node at pos which should be replaced -local function replaceable(pos, name, pname) - return get_node(pos).name == name - and not minetest.is_protected(pos, pname) -end - -local trans_nodes = {} -local function node_translucent(name) - if trans_nodes[name] ~= nil then - return trans_nodes[name] - end - local data = minetest.registered_nodes[name] - if data - and (not data.drawtype or data.drawtype == "normal") then - trans_nodes[name] = false - return false - end - trans_nodes[name] = true - return true -end - -local function field_position(pos, data) - return replaceable(pos, data.name, data.pname) - and node_translucent( - get_node(vector.add(data.above, pos)).name) ~= data.right_clicked -end - -local offsets_touch = { - {x=-1, y=0, z=0}, - {x=1, y=0, z=0}, - {x=0, y=-1, z=0}, - {x=0, y=1, z=0}, - {x=0, y=0, z=-1}, - {x=0, y=0, z=1}, -} - --- 3x3x3 hollow cube -local offsets_hollowcube = {} -for x = -1,1 do - for y = -1,1 do - for z = -1,1 do - local p = {x=x, y=y, z=z} - if x ~= 0 - or y ~= 0 - or z ~= 0 then - offsets_hollowcube[#offsets_hollowcube+1] = p - end - end - end -end - --- To get the crust, first nodes near it need to be collected -local function crust_above_position(pos, data) - -- test if the node at pos is a translucent node and not part of the crust - local nd = get_node(pos).name - if nd == data.name - or not node_translucent(nd) then - return false - end - -- test if a node of the crust is near pos - for i = 1,26 do - local p2 = offsets_hollowcube[i] - if replaceable(vector.add(pos, p2), data.name, data.pname) then - return true - end - end - return false -end - --- used to get nodes the crust belongs to -local function crust_under_position(pos, data) - if not replaceable(pos, data.name, data.pname) then - return false - end - for i = 1,26 do - local p2 = offsets_hollowcube[i] - if data.aboves[poshash(vector.add(pos, p2))] then - return true - end - end - return false -end - --- extract the crust from the nodes the crust belongs to -local function reduce_crust_ps(data) - local newps = {} - local n = 0 - for i = 1,data.num do - local p = data.ps[i] - for i = 1,6 do - local p2 = offsets_touch[i] - if data.aboves[poshash(vector.add(p, p2))] then - n = n+1 - newps[n] = p - break - end - end - end - data.ps = newps - data.num = n -end - --- gets the air nodes touching the crust -local function reduce_crust_above_ps(data) - local newps = {} - local n = 0 - for i = 1,data.num do - local p = data.ps[i] - if replaceable(p, "air", data.pname) then - for i = 1,6 do - local p2 = offsets_touch[i] - if replaceable(vector.add(p, p2), data.name, data.pname) then - n = n+1 - newps[n] = p - break - end - end - end - end - data.ps = newps - data.num = n -end - -local function mantle_position(pos, data) - if not replaceable(pos, data.name, data.pname) then - return false - end - for i = 1,6 do - if get_node(vector.add(pos, offsets_touch[i])).name ~= data.name then - return true - end - end - return false -end - --- finds out positions using depth first search -local function get_ps(pos, fdata, adps, max) - adps = adps or offsets_touch - - local tab = {} - local num = 0 - - local todo = {pos} - local ti = 1 - - local tab_avoid = {} - - while ti ~= 0 do - local p = todo[ti] - --~ todo[ti] = nil - ti = ti-1 - - for _,p2 in pairs(adps) do - p2 = vector.add(p, p2) - local i = poshash(p2) - if not tab_avoid[i] - and fdata.func(p2, fdata) then - - num = num+1 - tab[num] = p2 - - ti = ti+1 - todo[ti] = p2 - - tab_avoid[i] = true - - if max - and num >= max then - return false - end - end - end - end - return tab, num, tab_avoid -end - --- replaces one node with another one and returns if it was successful -local function replace_single_node(pos, node, nnd, player, name, inv, creative) - if minetest.is_protected(pos, name) then - return false, "Protected at "..minetest.pos_to_string(pos) - end - - if replacer.blacklist[node.name] then - return false, "Replacing blocks of the type '" .. - node.name .. - "' is not allowed on this server. Replacement failed." - end - - -- do not replace if there is nothing to be done - if node.name == nnd.name then - -- only the orientation was changed - if node.param1 ~= nnd.param1 - or node.param2 ~= nnd.param2 then - minetest.swap_node(pos, nnd) - end - return true - end - - -- does the player carry at least one of the desired nodes with him? - if not creative - and not inv:contains_item("main", nnd.name) then - return false, "You have no further '"..(nnd.name or "?").. - "'. Replacement failed." - end - - local ndef = minetest.registered_nodes[node.name] - if not ndef then - return false, "Unknown node: "..node.name - end - local new_ndef = minetest.registered_nodes[nnd.name] - if not new_ndef then - return false, "Unknown node should be placed: "..nnd.name - end - - -- dig the current node if needed - if not ndef.buildable_to then - -- give the player the item by simulating digging if possible - ndef.on_dig(pos, node, player) - -- test if digging worked - local dug_node = minetest.get_node_or_nil(pos) - if not dug_node - or not minetest.registered_nodes[dug_node.name].buildable_to then - return false, "Couldn't dig '".. node.name .."' properly." - end - end - - -- place the node similar to how a player does it - -- (other than the pointed_thing) - local newitem, succ = new_ndef.on_place(ItemStack(nnd.name), player, - {type = "node", under = vector.new(pos), above = vector.new(pos)}) - if succ == false then - return false, "Couldn't place '" .. nnd.name .. "'." - end - - -- update inventory in survival mode - if not creative then - -- consume the item - inv:remove_item("main", nnd.name.." 1") - -- if placing the node didn't result in empty stack… - if newitem:to_string() ~= "" then - inv:add_item("main", newitem) - end - end - - -- test whether the placed node differs from the supposed node - local placed_node = minetest.get_node(pos) - if placed_node.name ~= nnd.name then - -- Sometimes placing doesn't put the node but does something different - -- e.g. when placing snow on snow with the snow mod - return true - end - - -- fix orientation if needed - if placed_node.param1 ~= nnd.param1 - or placed_node.param2 ~= nnd.param2 then - minetest.swap_node(pos, nnd) - end - - return true -end - --- the function which happens when the replacer is used -function replacer.replace(itemstack, user, pt, right_clicked) - if not user - or not pt then - return - end - - local name = user:get_player_name() - local creative_enabled = creative.is_enabled_for(name) - - if pt.type ~= "node" then - inform(name, "Error: " .. pt.type .. " is not a node.") - return - end - - local pos = minetest.get_pointed_thing_position(pt, right_clicked) - local node_toreplace = minetest.get_node_or_nil(pos) - - if not node_toreplace then - inform(name, "Target node not yet loaded. Please wait a " .. - "moment for the server to catch up.") - return - end - - local nnd, mode = get_data(itemstack) - if node_toreplace.name == nnd.name - and node_toreplace.param1 == nnd.param1 - and node_toreplace.param2 == nnd.param2 then - inform(name, "Nothing to replace.") - return - end - - if replacer.blacklist[nnd.name] then - minetest.chat_send_player(name, "Placing blocks of the type '" .. - nnd.name .. - "' with the replacer is not allowed on this server. " .. - "Replacement failed.") - return - end - - if mode == "single" then - local succ,err = replace_single_node(pos, node_toreplace, nnd, user, - name, user:get_inventory(), creative_enabled) - - if not succ then - inform(name, err) - end - return - end - - local meta = minetest.deserialize(itemstack:get_metadata()) - if not meta or not meta.charge - or meta.charge < replacer.charge_per_node then - inform(name, "Not enough charge to use this mode.") - return - end - - local max_charge_to_use = math.min(meta.charge, replacer.max_charge) - local max_nodes = math.floor(max_charge_to_use / replacer.charge_per_node) - if max_nodes > 3168 then - max_nodes = 3168 - end - - local ps,num - if mode == "field" then - -- get connected positions for plane field replacing - local pdif = vector.subtract(pt.above, pt.under) - local adps,n = {},1 - for _,i in pairs{"x", "y", "z"} do - if pdif[i] == 0 then - for a = -1,1,2 do - local p = {x=0, y=0, z=0} - p[i] = a - adps[n] = p - n = n+1 - end - end - end - if right_clicked then - pdif = vector.multiply(pdif, -1) - end - right_clicked = right_clicked and true or false - ps,num = get_ps(pos, {func=field_position, name=node_toreplace.name, - pname=name, above=pdif, right_clicked=right_clicked}, adps, max_nodes) - elseif mode == "crust" then - local nodename_clicked = get_node(pt.under).name - local aps,n,aboves = get_ps(pt.above, {func=crust_above_position, - name=nodename_clicked, pname=name}, nil, max_nodes) - if aps then - if right_clicked then - local data = {ps=aps, num=n, name=nodename_clicked, pname=name} - reduce_crust_above_ps(data) - ps,num = data.ps, data.num - else - ps,num = get_ps(pt.under, {func=crust_under_position, - name=node_toreplace.name, pname=name, aboves=aboves}, - offsets_hollowcube, max_nodes) - if ps then - local data = {aboves=aboves, ps=ps, num=num} - reduce_crust_ps(data) - ps,num = data.ps, data.num - end - end - end - elseif mode == "chunkborder" then - ps,num = get_ps(pos, {func=mantle_position, name=node_toreplace.name, - pname=name}, nil, max_nodes) - end - - -- reset known nodes table - known_nodes = {} - - if not ps then - inform(name, "Aborted, too many nodes detected.") - return - end - - local charge_needed = replacer.charge_per_node * num - if meta.charge < charge_needed then - inform(name, "Need " .. charge_needed .. " charge to replace " .. num .. " nodes.") - return - end - - -- set nodes - local inv = user:get_inventory() - for i = 1,num do - local pos = ps[i] - local succ,err = replace_single_node(pos, minetest.get_node(pos), nnd, - user, name, inv, creative_enabled) - if not succ then - inform(name, err) - if not technic.creative_mode then - meta.charge = meta.charge - replacer.charge_per_node * i - technic.set_RE_wear(itemstack, meta.charge, replacer.max_charge) - itemstack:set_metadata(minetest.serialize(meta)) - return itemstack - end - return - end - end - - if not technic.creative_mode then - meta.charge = meta.charge - replacer.charge_per_node * num - technic.set_RE_wear(itemstack, meta.charge, replacer.max_charge) - itemstack:set_metadata(minetest.serialize(meta)) - return itemstack - end - inform(name, num.." nodes replaced.") -end - - -minetest.register_craft({ - output = "replacer:replacer", - recipe = { - {'default:chest', '', ''}, - {'', 'technic:green_energy_crystal', ''}, - {'', '', 'default:chest'}, - } -}) - +dofile(path.."/replacer.lua") +dofile(path.."/crafts.lua") diff --git a/inspect.lua b/inspect.lua index d0f0123..4648a74 100644 --- a/inspect.lua +++ b/inspect.lua @@ -21,7 +21,7 @@ end minetest.register_tool("replacer:inspect", { description = "Node inspection tool", - groups = {}, + groups = {}, inventory_image = "replacer_inspect.png", wield_image = "", wield_scale = {x=1,y=1,z=1}, @@ -37,7 +37,7 @@ minetest.register_tool("replacer:inspect", }) -replacer.inspect = function(itemstack, user, pointed_thing, mode, show_receipe) +replacer.inspect = function(_, user, pointed_thing, mode, show_receipe) if (user == nil or pointed_thing == nil) then return nil @@ -47,7 +47,7 @@ replacer.inspect = function(itemstack, user, pointed_thing, mode, show_receipe) if (keys["sneak"]) then show_receipe = true end - + if (pointed_thing.type == 'object') then local text = 'This is ' local ref = pointed_thing.ref @@ -66,7 +66,7 @@ replacer.inspect = function(itemstack, user, pointed_thing, mode, show_receipe) text = text..' ['..tostring(sdata.itemstring)..']' if (show_receipe) then -- the fields part is used here to provide additional information about the entity - replacer.inspect_show_crafting(name, sdata.itemstring, { pos=pos, luaob=luaob}) + replacer.inspect_show_crafting(name, sdata.itemstring, { luaob=luaob}) end end if (sdata.age) then @@ -82,23 +82,26 @@ replacer.inspect = function(itemstack, user, pointed_thing, mode, show_receipe) minetest.chat_send_player(name, text) return nil elseif (pointed_thing.type ~= 'node') then - minetest.chat_send_player(name, 'Sorry. This is an unkown something of type \"'..tostring(pointed_thing.type)..'\". No information available.') + minetest.chat_send_player(name, 'Sorry. This is an unkown something of type \"'.. + tostring(pointed_thing.type)..'\". No information available.') return nil end - + local pos = minetest.get_pointed_thing_position(pointed_thing, mode) local node = minetest.get_node_or_nil(pos) - + if (node == nil) then minetest.chat_send_player(name, "Error: Target node not yet loaded. Please wait a moment for the server to catch up.") return nil end - local text = ' ['..tostring(node.name)..'] with param2='..tostring(node.param2)..' at '..minetest.pos_to_string(pos)..'.' + local text = ' ['..tostring(node.name)..'] with param2='..tostring(node.param2).. + ' at '..minetest.pos_to_string(pos)..'.' if (not(minetest.registered_nodes[node.name])) then text = 'This node is an UNKOWN block'..text else - text = 'This is a \"'..tostring(minetest.registered_nodes[node.name].description or ' - no description provided -')..'\" block'..text + text = 'This is a \"'..tostring(minetest.registered_nodes[node.name].description or + ' - no description provided -')..'\" block'..text end local protected_info = "" if (minetest.is_protected( pos, name)) then @@ -109,7 +112,7 @@ replacer.inspect = function(itemstack, user, pointed_thing, mode, show_receipe) text = text..' '..protected_info -- no longer spam the chat; the craft guide is more informative -- minetest.chat_send_player(name, text) - + if (show_receipe) then -- get light of the node at the current time local light = minetest.get_node_light(pos, nil) @@ -148,7 +151,7 @@ if (minetest.get_modpath("dye") and dye and dye.basecolors) then replacer.group_placeholder['group:flower,color_'..color] = 'dye:'..color end end -end +end replacer.image_button_link = function(stack_string) local group = '' @@ -158,7 +161,7 @@ replacer.image_button_link = function(stack_string) if (replacer.group_placeholder[stack_string]) then stack_string = replacer.group_placeholder[stack_string] group = 'G' - end + end -- TODO: show information about other groups not handled above local stack = ItemStack(stack_string) local new_node_name = stack_string @@ -272,7 +275,7 @@ replacer.inspect_show_crafting = function(name, node_name, fields) if (not(desc) or desc=="") then desc = ' - no description provided - ' end - + local formspec = "size[6,6]".. "label[0,5.5;This is a "..minetest.formspec_escape(desc)..".]".. "button_exit[5.0,4.3;1,0.5;quit;Exit]".. @@ -389,12 +392,3 @@ end -- establish a callback so that input from the player-specific formspec gets handled minetest.register_on_player_receive_fields(replacer.form_input_handler) - - -minetest.register_craft({ - output = 'replacer:inspect', - recipe = { - { 'default:torch'}, - { 'default:stick'}, - } -}) diff --git a/replacer.lua b/replacer.lua new file mode 100644 index 0000000..f1d0b94 --- /dev/null +++ b/replacer.lua @@ -0,0 +1,593 @@ + +local function inform(name, msg) + minetest.chat_send_player(name, msg) + minetest.log("info", "[replacer] "..name..": "..msg) +end + +local mode_infos = { + single = "Replace single node.", + field = "Left click: Replace field of nodes of a kind where a translucent node is in front of it. Right click: Replace field of air where no translucent node is behind the air.", + crust = "Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air. Right click: Replace air nodes which touch the crust", + chunkborder = "TODO", +} +local mode_colours = { + single = "#ffffff", + field = "#54FFAC", + crust = "#9F6200", + chunkborder = "#FF5457", +} +local modes = {"single", "field", "crust", "chunkborder"} +for n = 1,#modes do + modes[modes[n]] = n +end + +local function get_data(stack) + local daten = stack:get_meta():get_string"replacer":split" " or {} + return { + name = daten[1] or "default:dirt", + param1 = tonumber(daten[2]) or 0, + param2 = tonumber(daten[3]) or 0 + }, + modes[daten[4]] and daten[4] or modes[1] +end + +local function set_data(stack, node, mode) + mode = mode or modes[1] + local metadata = (node.name or "default:dirt") .. " " + .. (node.param1 or 0) .. " " + .. (node.param2 or 0) .." " + .. mode + local meta = stack:get_meta() + meta:set_string("replacer", metadata) + meta:set_string("color", mode_colours[mode]) + return metadata +end + +technic.register_power_tool("replacer:replacer", replacer.max_charge) + +minetest.register_tool("replacer:replacer", { + description = "Node replacement tool", + inventory_image = "replacer_replacer.png", + stack_max = 1, -- it has to store information - thus only one can be stacked + wear_represents = "technic_RE_charge", + on_refill = technic.refill_RE_charge, + liquids_pointable = true, -- it is ok to painit in/with water + --node_placement_prediction = nil, + metadata = "default:dirt", -- default replacement: common dirt + + on_place = function(itemstack, placer, pt) + if not placer + or not pt then + return + end + + local keys = placer:get_player_control() + local name = placer:get_player_name() + local creative_enabled = creative.is_enabled_for(name) + local has_give = minetest.check_player_privs(name, "give") + + if keys.aux1 then + -- Change Mode when holding the fast key + local node, mode = get_data(itemstack) + mode = modes[modes[mode]%#modes+1] + set_data(itemstack, node, mode) + inform(name, "Mode changed to: "..mode..": "..mode_infos[mode]) + return itemstack + end + + -- If not holding shift, place node(s) + if not keys.sneak then + return replacer.replace(itemstack, placer, pt, true) + end + + -- Select new node + if pt.type ~= "node" then + inform(name, "Error: No node selected.") + return + end + + local node, mode = get_data(itemstack) + node = minetest.get_node_or_nil(pt.under) or node + + local inv = placer:get_inventory() + if not (creative_enabled and has_give) + and not inv:contains_item("main", node.name) then + if creative_enabled then + if minetest.get_item_group(node.name, + "not_in_creative_inventory") > 0 then + -- search for a drop available in creative inventory + local found_item = false + local drops = minetest.get_node_drops(node.name) + for i = 1,#drops do + local name = drops[i] + if minetest.registered_nodes[name] + and minetest.get_item_group(name, + "not_in_creative_inventory") == 0 then + node.name = name + found_item = true + break + end + end + if not found_item then + inform(name, "Node not in creative invenotry: \"" .. + node.name .. "\".") + return + end + end + else + local found_item = false + -- search for a drop that the player has if possible + local drops = minetest.get_node_drops(node.name) + for i = 1,#drops do + local name = drops[i] + if minetest.registered_nodes[name] + and inv:contains_item("main", name) then + node.name = name + found_item = true + break + end + end + if not found_item then + -- search for a drop available in creative inventory + -- that first configuring the replacer, + -- then digging the nodes works + for i = 1,#drops do + local name = drops[i] + if minetest.registered_nodes[name] + and minetest.get_item_group(name, + "not_in_creative_inventory") == 0 then + node.name = name + found_item = true + break + end + end + end + if not found_item + and not has_give then + inform(name, "Item not in your inventory: '" .. node.name .. + "'.") + return + end + end + end + + local metadata = set_data(itemstack, node, mode) + + inform(name, "Node replacement tool set to: '" .. metadata .. "'.") + + return itemstack --data changed + end, + +-- on_drop = func(itemstack, dropper, pos), + + on_use = function(...) + -- Replace nodes + return replacer.replace(...) + end, +}) + +local poshash = minetest.hash_node_position + +-- cache results of minetest.get_node +local known_nodes = {} +local function get_node(pos) + local i = poshash(pos) + local node = known_nodes[i] + if node then + return node + end + node = minetest.get_node(pos) + known_nodes[i] = node + return node +end + +-- tests if there's a node at pos which should be replaced +local function replaceable(pos, name, pname) + return get_node(pos).name == name + and not minetest.is_protected(pos, pname) +end + +local trans_nodes = {} +local function node_translucent(name) + if trans_nodes[name] ~= nil then + return trans_nodes[name] + end + local data = minetest.registered_nodes[name] + if data + and (not data.drawtype or data.drawtype == "normal") then + trans_nodes[name] = false + return false + end + trans_nodes[name] = true + return true +end + +local function field_position(pos, data) + return replaceable(pos, data.name, data.pname) + and node_translucent( + get_node(vector.add(data.above, pos)).name) ~= data.right_clicked +end + +local offsets_touch = { + {x=-1, y=0, z=0}, + {x=1, y=0, z=0}, + {x=0, y=-1, z=0}, + {x=0, y=1, z=0}, + {x=0, y=0, z=-1}, + {x=0, y=0, z=1}, +} + +-- 3x3x3 hollow cube +local offsets_hollowcube = {} +for x = -1,1 do + for y = -1,1 do + for z = -1,1 do + local p = {x=x, y=y, z=z} + if x ~= 0 + or y ~= 0 + or z ~= 0 then + offsets_hollowcube[#offsets_hollowcube+1] = p + end + end + end +end + +-- To get the crust, first nodes near it need to be collected +local function crust_above_position(pos, data) + -- test if the node at pos is a translucent node and not part of the crust + local nd = get_node(pos).name + if nd == data.name + or not node_translucent(nd) then + return false + end + -- test if a node of the crust is near pos + for i = 1,26 do + local p2 = offsets_hollowcube[i] + if replaceable(vector.add(pos, p2), data.name, data.pname) then + return true + end + end + return false +end + +-- used to get nodes the crust belongs to +local function crust_under_position(pos, data) + if not replaceable(pos, data.name, data.pname) then + return false + end + for i = 1,26 do + local p2 = offsets_hollowcube[i] + if data.aboves[poshash(vector.add(pos, p2))] then + return true + end + end + return false +end + +-- extract the crust from the nodes the crust belongs to +local function reduce_crust_ps(data) + local newps = {} + local n = 0 + for i = 1,data.num do + local p = data.ps[i] + for i = 1,6 do + local p2 = offsets_touch[i] + if data.aboves[poshash(vector.add(p, p2))] then + n = n+1 + newps[n] = p + break + end + end + end + data.ps = newps + data.num = n +end + +-- gets the air nodes touching the crust +local function reduce_crust_above_ps(data) + local newps = {} + local n = 0 + for i = 1,data.num do + local p = data.ps[i] + if replaceable(p, "air", data.pname) then + for i = 1,6 do + local p2 = offsets_touch[i] + if replaceable(vector.add(p, p2), data.name, data.pname) then + n = n+1 + newps[n] = p + break + end + end + end + end + data.ps = newps + data.num = n +end + +local function mantle_position(pos, data) + if not replaceable(pos, data.name, data.pname) then + return false + end + for i = 1,6 do + if get_node(vector.add(pos, offsets_touch[i])).name ~= data.name then + return true + end + end + return false +end + +-- finds out positions using depth first search +local function get_ps(pos, fdata, adps, max) + adps = adps or offsets_touch + + local tab = {} + local num = 0 + + local todo = {pos} + local ti = 1 + + local tab_avoid = {} + + while ti ~= 0 do + local p = todo[ti] + --~ todo[ti] = nil + ti = ti-1 + + for _,p2 in pairs(adps) do + p2 = vector.add(p, p2) + local i = poshash(p2) + if not tab_avoid[i] + and fdata.func(p2, fdata) then + + num = num+1 + tab[num] = p2 + + ti = ti+1 + todo[ti] = p2 + + tab_avoid[i] = true + + if max + and num >= max then + return false + end + end + end + end + return tab, num, tab_avoid +end + +-- replaces one node with another one and returns if it was successful +local function replace_single_node(pos, node, nnd, player, name, inv, creative) + if minetest.is_protected(pos, name) then + return false, "Protected at "..minetest.pos_to_string(pos) + end + + if replacer.blacklist[node.name] then + return false, "Replacing blocks of the type '" .. + node.name .. + "' is not allowed on this server. Replacement failed." + end + + -- do not replace if there is nothing to be done + if node.name == nnd.name then + -- only the orientation was changed + if node.param1 ~= nnd.param1 + or node.param2 ~= nnd.param2 then + minetest.swap_node(pos, nnd) + end + return true + end + + -- does the player carry at least one of the desired nodes with him? + if not creative + and not inv:contains_item("main", nnd.name) then + return false, "You have no further '"..(nnd.name or "?").. + "'. Replacement failed." + end + + local ndef = minetest.registered_nodes[node.name] + if not ndef then + return false, "Unknown node: "..node.name + end + local new_ndef = minetest.registered_nodes[nnd.name] + if not new_ndef then + return false, "Unknown node should be placed: "..nnd.name + end + + -- dig the current node if needed + if not ndef.buildable_to then + -- give the player the item by simulating digging if possible + ndef.on_dig(pos, node, player) + -- test if digging worked + local dug_node = minetest.get_node_or_nil(pos) + if not dug_node + or not minetest.registered_nodes[dug_node.name].buildable_to then + return false, "Couldn't dig '".. node.name .."' properly." + end + end + + -- place the node similar to how a player does it + -- (other than the pointed_thing) + local newitem, succ = new_ndef.on_place(ItemStack(nnd.name), player, + {type = "node", under = vector.new(pos), above = vector.new(pos)}) + if succ == false then + return false, "Couldn't place '" .. nnd.name .. "'." + end + + -- update inventory in survival mode + if not creative then + -- consume the item + inv:remove_item("main", nnd.name.." 1") + -- if placing the node didn't result in empty stack… + if newitem:to_string() ~= "" then + inv:add_item("main", newitem) + end + end + + -- test whether the placed node differs from the supposed node + local placed_node = minetest.get_node(pos) + if placed_node.name ~= nnd.name then + -- Sometimes placing doesn't put the node but does something different + -- e.g. when placing snow on snow with the snow mod + return true + end + + -- fix orientation if needed + if placed_node.param1 ~= nnd.param1 + or placed_node.param2 ~= nnd.param2 then + minetest.swap_node(pos, nnd) + end + + return true +end + +-- the function which happens when the replacer is used +function replacer.replace(itemstack, user, pt, right_clicked) + if not user + or not pt then + return + end + + local name = user:get_player_name() + local creative_enabled = creative.is_enabled_for(name) + + if pt.type ~= "node" then + inform(name, "Error: " .. pt.type .. " is not a node.") + return + end + + local pos = minetest.get_pointed_thing_position(pt, right_clicked) + local node_toreplace = minetest.get_node_or_nil(pos) + + if not node_toreplace then + inform(name, "Target node not yet loaded. Please wait a " .. + "moment for the server to catch up.") + return + end + + local nnd, mode = get_data(itemstack) + if node_toreplace.name == nnd.name + and node_toreplace.param1 == nnd.param1 + and node_toreplace.param2 == nnd.param2 then + inform(name, "Nothing to replace.") + return + end + + if replacer.blacklist[nnd.name] then + minetest.chat_send_player(name, "Placing blocks of the type '" .. + nnd.name .. + "' with the replacer is not allowed on this server. " .. + "Replacement failed.") + return + end + + if mode == "single" then + local succ,err = replace_single_node(pos, node_toreplace, nnd, user, + name, user:get_inventory(), creative_enabled) + + if not succ then + inform(name, err) + end + return + end + + local meta = minetest.deserialize(itemstack:get_metadata()) + if not meta or not meta.charge + or meta.charge < replacer.charge_per_node then + inform(name, "Not enough charge to use this mode.") + return + end + + local max_charge_to_use = math.min(meta.charge, replacer.max_charge) + local max_nodes = math.floor(max_charge_to_use / replacer.charge_per_node) + if max_nodes > 3168 then + max_nodes = 3168 + end + + local ps,num + if mode == "field" then + -- get connected positions for plane field replacing + local pdif = vector.subtract(pt.above, pt.under) + local adps,n = {},1 + for _,i in pairs{"x", "y", "z"} do + if pdif[i] == 0 then + for a = -1,1,2 do + local p = {x=0, y=0, z=0} + p[i] = a + adps[n] = p + n = n+1 + end + end + end + if right_clicked then + pdif = vector.multiply(pdif, -1) + end + right_clicked = right_clicked and true or false + ps,num = get_ps(pos, {func=field_position, name=node_toreplace.name, + pname=name, above=pdif, right_clicked=right_clicked}, adps, max_nodes) + elseif mode == "crust" then + local nodename_clicked = get_node(pt.under).name + local aps,n,aboves = get_ps(pt.above, {func=crust_above_position, + name=nodename_clicked, pname=name}, nil, max_nodes) + if aps then + if right_clicked then + local data = {ps=aps, num=n, name=nodename_clicked, pname=name} + reduce_crust_above_ps(data) + ps,num = data.ps, data.num + else + ps,num = get_ps(pt.under, {func=crust_under_position, + name=node_toreplace.name, pname=name, aboves=aboves}, + offsets_hollowcube, max_nodes) + if ps then + local data = {aboves=aboves, ps=ps, num=num} + reduce_crust_ps(data) + ps,num = data.ps, data.num + end + end + end + elseif mode == "chunkborder" then + ps,num = get_ps(pos, {func=mantle_position, name=node_toreplace.name, + pname=name}, nil, max_nodes) + end + + -- reset known nodes table + known_nodes = {} + + if not ps then + inform(name, "Aborted, too many nodes detected.") + return + end + + local charge_needed = replacer.charge_per_node * num + if meta.charge < charge_needed then + inform(name, "Need " .. charge_needed .. " charge to replace " .. num .. " nodes.") + return + end + + -- set nodes + local inv = user:get_inventory() + for i = 1,num do + local pos = ps[i] + local succ,err = replace_single_node(pos, minetest.get_node(pos), nnd, + user, name, inv, creative_enabled) + if not succ then + inform(name, err) + if not technic.creative_mode then + meta.charge = meta.charge - replacer.charge_per_node * i + technic.set_RE_wear(itemstack, meta.charge, replacer.max_charge) + itemstack:set_metadata(minetest.serialize(meta)) + return itemstack + end + return + end + end + + if not technic.creative_mode then + meta.charge = meta.charge - replacer.charge_per_node * num + technic.set_RE_wear(itemstack, meta.charge, replacer.max_charge) + itemstack:set_metadata(minetest.serialize(meta)) + return itemstack + end + inform(name, num.." nodes replaced.") +end From c1536836214fffb04ad355af9320411fca16c4fa Mon Sep 17 00:00:00 2001 From: BuckarooBanzay Date: Thu, 9 Jan 2020 13:17:57 +0100 Subject: [PATCH 006/366] add "replacer.max_nodes" settings with default of 3168 nodes --- init.lua | 1 + replacer.lua | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index f8fadd5..f4b41b0 100644 --- a/init.lua +++ b/init.lua @@ -54,6 +54,7 @@ replacer.blacklist[ "protector:protect2"] = true; replacer.max_charge = 30000 replacer.charge_per_node = 15 +replacer.max_nodes = tonumber( minetest.settings:get("replacer.max_nodes") or "3168") -- adds a tool for inspecting nodes and entities dofile(path.."/inspect.lua") diff --git a/replacer.lua b/replacer.lua index f1d0b94..0491071 100644 --- a/replacer.lua +++ b/replacer.lua @@ -501,8 +501,8 @@ function replacer.replace(itemstack, user, pt, right_clicked) local max_charge_to_use = math.min(meta.charge, replacer.max_charge) local max_nodes = math.floor(max_charge_to_use / replacer.charge_per_node) - if max_nodes > 3168 then - max_nodes = 3168 + if max_nodes > replacer.max_nodes then + max_nodes = replacer.max_nodes end local ps,num From 3cf927be860b8fc74183f6381667a98826c53bfd Mon Sep 17 00:00:00 2001 From: BuckarooBanzay Date: Thu, 9 Jan 2020 13:20:36 +0100 Subject: [PATCH 007/366] update readme, add contributors / settings --- README.md | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8f74bf4..ea3bac6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ This tool is helpful for creative purposes (i.e. build a wall and "paint" window It replaces nodes with a previously selected other type of node (i.e. places said windows into a brick wall). -**Crafting:** +# Crafting + ``` | chest | | | | | green energy crystal | | @@ -12,7 +13,9 @@ into a brick wall). ``` Or just use `/giveme replacer:replacer` -**Usage:** Sneak-right-click on a node of which type you want to replace other nodes with. +# Usage + +Sneak-right-click on a node of which type you want to replace other nodes with. Left-click (normal usage) on any nodes you want to replace with that type. Right-click to place a node of that type onto clicked node. When in creative mode, the node will just be replaced. Your inventory will not be changed. @@ -20,7 +23,8 @@ When in creative mode, the node will just be replaced. Your inventory will not b When *not* in creative mode, digging will be simulated and you will get what was there. In return, the replacement node will be taken from your inventory. -**Modes:** +# Modes + Special-right-click to cycle through the modes. Single-mode does not need any charge. The other modes do. The second tool included in this mod is the inspector. @@ -33,6 +37,19 @@ Crafting: ``` Just wield it and click on any node or entity you want to know more about. A limited craft-guide is included. +# Settings + +* **replacer.max_nodes** max allowed nodes to replace (default: 3168) + +# Contributors + +* Sokomine +* coil0 +* SwissalpS +* OgelGames +* BuckarooBanzay + +# License Copyright (C) 2013,2014,2015 Sokomine @@ -49,4 +66,3 @@ Just wield it and click on any node or entity you want to know more about. A lim You should have received a copy of the GNU General Public License along with this program. If not, see . - From 1356f7c395a7250634dc309ff7d72afc8b403a2a Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Sun, 12 Jan 2020 18:36:44 +0100 Subject: [PATCH 008/366] Let's not forget HybridDog's contributions --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ea3bac6..e65ccf8 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ Just wield it and click on any node or entity you want to know more about. A lim * Sokomine * coil0 +* HybridDog * SwissalpS * OgelGames * BuckarooBanzay From bb0dc6ede29b901d3f160b15caaba1d873a9007e Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Sun, 12 Jan 2020 19:03:41 +0100 Subject: [PATCH 009/366] comment cleanup --- replacer.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replacer.lua b/replacer.lua index 0491071..5151469 100644 --- a/replacer.lua +++ b/replacer.lua @@ -75,7 +75,7 @@ minetest.register_tool("replacer:replacer", { return itemstack end - -- If not holding shift, place node(s) + -- If not holding sneak key, place node(s) if not keys.sneak then return replacer.replace(itemstack, placer, pt, true) end From f2e97f9b406465104f792087bcefa01cf54932f6 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 31 Jan 2020 03:30:39 +0100 Subject: [PATCH 010/366] whitespace --- replacer.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replacer.lua b/replacer.lua index 5151469..4c5b7ee 100644 --- a/replacer.lua +++ b/replacer.lua @@ -35,7 +35,7 @@ local function set_data(stack, node, mode) mode = mode or modes[1] local metadata = (node.name or "default:dirt") .. " " .. (node.param1 or 0) .. " " - .. (node.param2 or 0) .." " + .. (node.param2 or 0) .. " " .. mode local meta = stack:get_meta() meta:set_string("replacer", metadata) From 07e286c379377fffc74c0f043ad5dd32ccfffdd2 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 31 Jan 2020 04:12:12 +0100 Subject: [PATCH 011/366] change mode via formspec --- replacer.lua | 59 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/replacer.lua b/replacer.lua index 4c5b7ee..c43dbe1 100644 --- a/replacer.lua +++ b/replacer.lua @@ -43,6 +43,32 @@ local function set_data(stack, node, mode) return metadata end +local replacer_form_name_modes = "replacer_replacer_mode_change" +local function get_form_modes(current_mode) + -- TODO: possibly add the info here instead of as + -- a chat message + -- TODO: add close button for mobile users who possibly can't esc + -- need feedback from mobile user to know if this is required + local formspec = "size[3.9,2]" + .. "label[0,0;Choose mode]" + if current_mode ~= modes[1] then + formspec = formspec .. "button_exit[0.0,0.6;2,0.5;mode;" .. modes[1] .. "]" + end + if current_mode ~= modes[2] then + formspec = formspec .. "button_exit[1.9,0.6;2,0.5;mode;" .. modes[2] .. "]" + end + if current_mode ~= modes[3] then + formspec = formspec .. "button_exit[0.0,1.4;2,0.5;mode;" .. modes[3] .. "]" + end + -- TODO: enable mode when it is available + --[[ + if current_mode ~= modes[4] then + formspec = formspec .. "button_exit[1.9,1.4;2,0.5;mode;" .. modes[] .. "]" + end + --]] + return formspec +end + technic.register_power_tool("replacer:replacer", replacer.max_charge) minetest.register_tool("replacer:replacer", { @@ -66,12 +92,13 @@ minetest.register_tool("replacer:replacer", { local creative_enabled = creative.is_enabled_for(name) local has_give = minetest.check_player_privs(name, "give") + -- is special-key held? (aka fast-key) if keys.aux1 then - -- Change Mode when holding the fast key - local node, mode = get_data(itemstack) - mode = modes[modes[mode]%#modes+1] - set_data(itemstack, node, mode) - inform(name, "Mode changed to: "..mode..": "..mode_infos[mode]) + -- fetch current mode + local _, mode = get_data(itemstack) + -- Show formspec to choose mode + minetest.show_formspec(name, replacer_form_name_modes, get_form_modes(mode)) + -- return unchanged tool return itemstack end @@ -166,6 +193,28 @@ minetest.register_tool("replacer:replacer", { end, }) +local function replacer_register_on_player_receive_fields(player, form_name, fields) + -- no need to process if it's not expected formspec that triggered call + if form_name ~= replacer_form_name_modes then return end + -- no need to process if user closed formspec without changing mode + if nil == fields.mode then return end + + -- collect some information + local itemstack = player:get_wielded_item() + local node, _ = get_data(itemstack) + local mode = fields.mode + local name = player:get_player_name() + + -- set metadata and itemstring + set_data(itemstack, node, mode) + -- update wielded item + player:set_wielded_item(itemstack) + -- spam players chat with information + inform(name, "Mode changed to: " .. mode .. ": " .. mode_infos[mode]) +end +-- listen to submitted fields +minetest.register_on_player_receive_fields(replacer_register_on_player_receive_fields) + local poshash = minetest.hash_node_position -- cache results of minetest.get_node From b89a261fae0b0ab39556c7a48cc5298f2b1599ba Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 31 Jan 2020 04:33:22 +0100 Subject: [PATCH 012/366] allow changing mode with special+left-click To help avoid confusion with drills which set mode with left-click For backward compatibility we keep right-click working too Nice side-effect: can now change mode without actually pointing at a node. --- replacer.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/replacer.lua b/replacer.lua index c43dbe1..391d64c 100644 --- a/replacer.lua +++ b/replacer.lua @@ -498,7 +498,19 @@ function replacer.replace(itemstack, user, pt, right_clicked) return end + local keys = user:get_player_control() local name = user:get_player_name() + + -- is special-key held? (aka fast-key) + if keys.aux1 then + -- fetch current mode + local _, mode = get_data(itemstack) + -- Show formspec to choose mode + minetest.show_formspec(name, replacer_form_name_modes, get_form_modes(mode)) + -- return unchanged tool + return itemstack + end + local creative_enabled = creative.is_enabled_for(name) if pt.type ~= "node" then From e2d47238f673c8626a9d50bac75303f27cc4f6ea Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 31 Jan 2020 05:04:44 +0100 Subject: [PATCH 013/366] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e65ccf8..3a3e1d4 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,8 @@ will be taken from your inventory. # Modes -Special-right-click to cycle through the modes. Single-mode does not need any charge. The other modes do. +Special-right-click on a node or special-left-click anywhere to change the mode. +Single-mode does not need any charge. The other modes do. The second tool included in this mod is the inspector. From de4cf4f2ef6892e1329ac04f8ac2d5fd31ab6595 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 31 Jan 2020 16:01:04 +0100 Subject: [PATCH 014/366] restore old behaviour for less user-friction --- replacer.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/replacer.lua b/replacer.lua index 391d64c..6be58bf 100644 --- a/replacer.lua +++ b/replacer.lua @@ -95,10 +95,14 @@ minetest.register_tool("replacer:replacer", { -- is special-key held? (aka fast-key) if keys.aux1 then -- fetch current mode - local _, mode = get_data(itemstack) - -- Show formspec to choose mode - minetest.show_formspec(name, replacer_form_name_modes, get_form_modes(mode)) - -- return unchanged tool + local node, mode = get_data(itemstack) + -- increment and roll-over mode + mode = modes[modes[mode]%#modes+1] + -- update tool + set_data(itemstack, node, mode) + -- spam chat + inform(name, "Mode changed to: " .. mode .. ": " .. mode_infos[mode]) + -- return changed tool return itemstack end From 93de871b3a2fb4c0179cbca249970bfefb8d59ab Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 31 Jan 2020 16:50:09 +0100 Subject: [PATCH 015/366] nicer formspec also worked using button instead of exit-buttons for current setting. This way is a little more elegant imo. --- replacer.lua | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/replacer.lua b/replacer.lua index 6be58bf..bf31c06 100644 --- a/replacer.lua +++ b/replacer.lua @@ -51,19 +51,31 @@ local function get_form_modes(current_mode) -- need feedback from mobile user to know if this is required local formspec = "size[3.9,2]" .. "label[0,0;Choose mode]" - if current_mode ~= modes[1] then - formspec = formspec .. "button_exit[0.0,0.6;2,0.5;mode;" .. modes[1] .. "]" - end - if current_mode ~= modes[2] then - formspec = formspec .. "button_exit[1.9,0.6;2,0.5;mode;" .. modes[2] .. "]" - end - if current_mode ~= modes[3] then - formspec = formspec .. "button_exit[0.0,1.4;2,0.5;mode;" .. modes[3] .. "]" + .. "button_exit[0.0,0.6;2,0.5;" + if current_mode == modes[1] then + formspec = formspec .. "_;< " .. modes[1] .. " >]" + else + formspec = formspec .. "mode;" .. modes[1] .. "]" + end + formspec = formspec .. "button_exit[1.9,0.6;2,0.5;" + if current_mode == modes[2] then + formspec = formspec .. "_;< " .. modes[2] .. " >]" + else + formspec = formspec .. "mode;" .. modes[2] .. "]" + end + formspec = formspec .. "button_exit[0.0,1.4;2,0.5;" + if current_mode == modes[3] then + formspec = formspec .. "_;< " .. modes[3] .. " >]" + else + formspec = formspec .. "mode;" .. modes[3] .. "]" end -- TODO: enable mode when it is available --[[ - if current_mode ~= modes[4] then - formspec = formspec .. "button_exit[1.9,1.4;2,0.5;mode;" .. modes[] .. "]" + formspec = formspec .. "button_exit[1.9,1.4;2,0.5;" + if current_mode == modes[4] then + formspec = formspec .. "_;< " .. modes[4] .. " >]" + else + formspec = formspec .. "mode;" .. modes[4] .. "]" end --]] return formspec From a243a0248b8829d0fbac85d57e30b89bae27d898 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 31 Jan 2020 17:00:27 +0100 Subject: [PATCH 016/366] no chat spam when using formspec --- replacer.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/replacer.lua b/replacer.lua index bf31c06..b0fac24 100644 --- a/replacer.lua +++ b/replacer.lua @@ -225,8 +225,11 @@ local function replacer_register_on_player_receive_fields(player, form_name, fie set_data(itemstack, node, mode) -- update wielded item player:set_wielded_item(itemstack) + --[[ NOTE: for now I leave this code here in case we later make this a setting in + some way that does not mute all messages of tool -- spam players chat with information inform(name, "Mode changed to: " .. mode .. ": " .. mode_infos[mode]) + --]] end -- listen to submitted fields minetest.register_on_player_receive_fields(replacer_register_on_player_receive_fields) From 7a41f0278a8f35ae65d5fcd8fa538072afe27aaa Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 31 Jan 2020 17:08:10 +0100 Subject: [PATCH 017/366] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3a3e1d4..d30cbdf 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Just wield it and click on any node or entity you want to know more about. A lim * SwissalpS * OgelGames * BuckarooBanzay +* S-S-X # License From 88ff420f582f605e6f6b0574fa4341f5f2765d24 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 31 Jan 2020 17:53:51 +0100 Subject: [PATCH 018/366] whitespace --- replacer.lua | 105 ++++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/replacer.lua b/replacer.lua index 5151469..7f2e9a0 100644 --- a/replacer.lua +++ b/replacer.lua @@ -209,24 +209,24 @@ local function field_position(pos, data) end local offsets_touch = { - {x=-1, y=0, z=0}, - {x=1, y=0, z=0}, - {x=0, y=-1, z=0}, - {x=0, y=1, z=0}, - {x=0, y=0, z=-1}, - {x=0, y=0, z=1}, + {x =-1, y = 0, z = 0}, + {x = 1, y = 0, z = 0}, + {x = 0, y =-1, z = 0}, + {x = 0, y = 1, z = 0}, + {x = 0, y = 0, z =-1}, + {x = 0, y = 0, z = 1}, } -- 3x3x3 hollow cube local offsets_hollowcube = {} -for x = -1,1 do - for y = -1,1 do - for z = -1,1 do - local p = {x=x, y=y, z=z} +for x = -1, 1 do + for y = -1, 1 do + for z = -1, 1 do + local p = {x = x, y = y, z = z} if x ~= 0 or y ~= 0 or z ~= 0 then - offsets_hollowcube[#offsets_hollowcube+1] = p + offsets_hollowcube[#offsets_hollowcube + 1] = p end end end @@ -241,7 +241,7 @@ local function crust_above_position(pos, data) return false end -- test if a node of the crust is near pos - for i = 1,26 do + for i = 1, 26 do local p2 = offsets_hollowcube[i] if replaceable(vector.add(pos, p2), data.name, data.pname) then return true @@ -255,7 +255,7 @@ local function crust_under_position(pos, data) if not replaceable(pos, data.name, data.pname) then return false end - for i = 1,26 do + for i = 1, 26 do local p2 = offsets_hollowcube[i] if data.aboves[poshash(vector.add(pos, p2))] then return true @@ -268,12 +268,12 @@ end local function reduce_crust_ps(data) local newps = {} local n = 0 - for i = 1,data.num do + for i = 1, data.num do local p = data.ps[i] for i = 1,6 do local p2 = offsets_touch[i] if data.aboves[poshash(vector.add(p, p2))] then - n = n+1 + n = n + 1 newps[n] = p break end @@ -287,13 +287,13 @@ end local function reduce_crust_above_ps(data) local newps = {} local n = 0 - for i = 1,data.num do + for i = 1, data.num do local p = data.ps[i] if replaceable(p, "air", data.pname) then - for i = 1,6 do + for i = 1, 6 do local p2 = offsets_touch[i] if replaceable(vector.add(p, p2), data.name, data.pname) then - n = n+1 + n = n + 1 newps[n] = p break end @@ -308,7 +308,7 @@ local function mantle_position(pos, data) if not replaceable(pos, data.name, data.pname) then return false end - for i = 1,6 do + for i = 1, 6 do if get_node(vector.add(pos, offsets_touch[i])).name ~= data.name then return true end @@ -331,18 +331,18 @@ local function get_ps(pos, fdata, adps, max) while ti ~= 0 do local p = todo[ti] --~ todo[ti] = nil - ti = ti-1 + ti = ti - 1 - for _,p2 in pairs(adps) do + for _, p2 in pairs(adps) do p2 = vector.add(p, p2) local i = poshash(p2) if not tab_avoid[i] and fdata.func(p2, fdata) then - num = num+1 + num = num + 1 tab[num] = p2 - ti = ti+1 + ti = ti + 1 todo[ti] = p2 tab_avoid[i] = true @@ -360,7 +360,7 @@ end -- replaces one node with another one and returns if it was successful local function replace_single_node(pos, node, nnd, player, name, inv, creative) if minetest.is_protected(pos, name) then - return false, "Protected at "..minetest.pos_to_string(pos) + return false, "Protected at " .. minetest.pos_to_string(pos) end if replacer.blacklist[node.name] then @@ -382,17 +382,17 @@ local function replace_single_node(pos, node, nnd, player, name, inv, creative) -- does the player carry at least one of the desired nodes with him? if not creative and not inv:contains_item("main", nnd.name) then - return false, "You have no further '"..(nnd.name or "?").. + return false, "You have no further '" .. (nnd.name or "?") .. "'. Replacement failed." end local ndef = minetest.registered_nodes[node.name] if not ndef then - return false, "Unknown node: "..node.name + return false, "Unknown node: " .. node.name end local new_ndef = minetest.registered_nodes[nnd.name] if not new_ndef then - return false, "Unknown node should be placed: "..nnd.name + return false, "Unknown node should be placed: " .. nnd.name end -- dig the current node if needed @@ -403,7 +403,7 @@ local function replace_single_node(pos, node, nnd, player, name, inv, creative) local dug_node = minetest.get_node_or_nil(pos) if not dug_node or not minetest.registered_nodes[dug_node.name].buildable_to then - return false, "Couldn't dig '".. node.name .."' properly." + return false, "Couldn't dig '" .. node.name .. "' properly." end end @@ -418,7 +418,7 @@ local function replace_single_node(pos, node, nnd, player, name, inv, creative) -- update inventory in survival mode if not creative then -- consume the item - inv:remove_item("main", nnd.name.." 1") + inv:remove_item("main", nnd.name .. " 1") -- if placing the node didn't result in empty stack… if newitem:to_string() ~= "" then inv:add_item("main", newitem) @@ -472,7 +472,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) and node_toreplace.param2 == nnd.param2 then inform(name, "Nothing to replace.") return - end + end if replacer.blacklist[nnd.name] then minetest.chat_send_player(name, "Placing blocks of the type '" .. @@ -483,7 +483,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) end if mode == "single" then - local succ,err = replace_single_node(pos, node_toreplace, nnd, user, + local succ, err = replace_single_node(pos, node_toreplace, nnd, user, name, user:get_inventory(), creative_enabled) if not succ then @@ -505,18 +505,18 @@ function replacer.replace(itemstack, user, pt, right_clicked) max_nodes = replacer.max_nodes end - local ps,num + local ps, num if mode == "field" then -- get connected positions for plane field replacing local pdif = vector.subtract(pt.above, pt.under) - local adps,n = {},1 - for _,i in pairs{"x", "y", "z"} do + local adps, n = {}, 1 + for _, i in pairs{"x", "y", "z"} do if pdif[i] == 0 then - for a = -1,1,2 do - local p = {x=0, y=0, z=0} + for a = -1, 1, 2 do + local p = {x = 0, y = 0, z = 0} p[i] = a adps[n] = p - n = n+1 + n = n + 1 end end end @@ -524,31 +524,31 @@ function replacer.replace(itemstack, user, pt, right_clicked) pdif = vector.multiply(pdif, -1) end right_clicked = right_clicked and true or false - ps,num = get_ps(pos, {func=field_position, name=node_toreplace.name, - pname=name, above=pdif, right_clicked=right_clicked}, adps, max_nodes) + ps, num = get_ps(pos, {func = field_position, name = node_toreplace.name, + pname = name, above = pdif, right_clicked = right_clicked}, adps, max_nodes) elseif mode == "crust" then local nodename_clicked = get_node(pt.under).name - local aps,n,aboves = get_ps(pt.above, {func=crust_above_position, - name=nodename_clicked, pname=name}, nil, max_nodes) + local aps, n, aboves = get_ps(pt.above, {func = crust_above_position, + name = nodename_clicked, pname = name}, nil, max_nodes) if aps then if right_clicked then - local data = {ps=aps, num=n, name=nodename_clicked, pname=name} + local data = {ps = aps, num = n, name = nodename_clicked, pname = name} reduce_crust_above_ps(data) - ps,num = data.ps, data.num + ps, num = data.ps, data.num else - ps,num = get_ps(pt.under, {func=crust_under_position, - name=node_toreplace.name, pname=name, aboves=aboves}, + ps, num = get_ps(pt.under, {func = crust_under_position, + name = node_toreplace.name, pname = name, aboves = aboves}, offsets_hollowcube, max_nodes) if ps then - local data = {aboves=aboves, ps=ps, num=num} + local data = {aboves = aboves, ps = ps, num = num} reduce_crust_ps(data) - ps,num = data.ps, data.num + ps, num = data.ps, data.num end end end elseif mode == "chunkborder" then - ps,num = get_ps(pos, {func=mantle_position, name=node_toreplace.name, - pname=name}, nil, max_nodes) + ps, num = get_ps(pos, {func = mantle_position, name = node_toreplace.name, + pname = name}, nil, max_nodes) end -- reset known nodes table @@ -567,9 +567,9 @@ function replacer.replace(itemstack, user, pt, right_clicked) -- set nodes local inv = user:get_inventory() - for i = 1,num do + for i = 1, num do local pos = ps[i] - local succ,err = replace_single_node(pos, minetest.get_node(pos), nnd, + local succ, err = replace_single_node(pos, minetest.get_node(pos), nnd, user, name, inv, creative_enabled) if not succ then inform(name, err) @@ -589,5 +589,6 @@ function replacer.replace(itemstack, user, pt, right_clicked) itemstack:set_metadata(minetest.serialize(meta)) return itemstack end - inform(name, num.." nodes replaced.") + inform(name, num .. " nodes replaced.") end + From f88546bf40b474a49f53d8e516f9eef049e3da2b Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 31 Jan 2020 18:47:49 +0100 Subject: [PATCH 019/366] replace a single node in multi-mode when only one node in field --- replacer.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/replacer.lua b/replacer.lua index 7f2e9a0..f32bcc8 100644 --- a/replacer.lua +++ b/replacer.lua @@ -559,6 +559,16 @@ function replacer.replace(itemstack, user, pt, right_clicked) return end + if 0 == num then + local succ, err = replace_single_node(pos, node_toreplace, nnd, user, + name, user:get_inventory(), creative_enabled) + + if not succ then + inform(name, err) + end + return + end + local charge_needed = replacer.charge_per_node * num if meta.charge < charge_needed then inform(name, "Need " .. charge_needed .. " charge to replace " .. num .. " nodes.") From b16099dbf9f01b81588a516110ec46e5915999a5 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Wed, 5 Feb 2020 20:08:11 +0100 Subject: [PATCH 020/366] move away from depends.txt --- depends.txt | 3 --- mod.conf | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) delete mode 100644 depends.txt create mode 100644 mod.conf diff --git a/depends.txt b/depends.txt deleted file mode 100644 index afef51e..0000000 --- a/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -default? -dye? -technic diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..6471d28 --- /dev/null +++ b/mod.conf @@ -0,0 +1,4 @@ +name = replacer +description = Replacement tool for creative building and tool to inspect nodes. +depends = default +optional_depends = dye, technic From 32611b0172768f87eadcfd41646486983d5a437c Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Wed, 5 Feb 2020 20:10:06 +0100 Subject: [PATCH 021/366] whitespace --- init.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/init.lua b/init.lua index f4b41b0..de147a9 100644 --- a/init.lua +++ b/init.lua @@ -43,20 +43,20 @@ replacer.blacklist = {}; -- playing with tnt and creative building are usually contradictory -- (except when doing large-scale landscaping in singleplayer) -replacer.blacklist[ "tnt:boom"] = true; -replacer.blacklist[ "tnt:gunpowder"] = true; -replacer.blacklist[ "tnt:gunpowder_burning"] = true; -replacer.blacklist[ "tnt:tnt"] = true; +replacer.blacklist["tnt:boom"] = true; +replacer.blacklist["tnt:gunpowder"] = true; +replacer.blacklist["tnt:gunpowder_burning"] = true; +replacer.blacklist["tnt:tnt"] = true; -- prevent accidental replacement of your protector -replacer.blacklist[ "protector:protect"] = true; -replacer.blacklist[ "protector:protect2"] = true; +replacer.blacklist["protector:protect"] = true; +replacer.blacklist["protector:protect2"] = true; replacer.max_charge = 30000 replacer.charge_per_node = 15 -replacer.max_nodes = tonumber( minetest.settings:get("replacer.max_nodes") or "3168") +replacer.max_nodes = tonumber(minetest.settings:get("replacer.max_nodes") or "3168") -- adds a tool for inspecting nodes and entities -dofile(path.."/inspect.lua") -dofile(path.."/replacer.lua") -dofile(path.."/crafts.lua") +dofile(path .. "/inspect.lua") +dofile(path .. "/replacer.lua") +dofile(path .. "/crafts.lua") From 70c7c6e93428ff2f8d669dad8ca5d3d9b36b1b88 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Wed, 5 Feb 2020 20:11:28 +0100 Subject: [PATCH 022/366] refactor moving strings and patterns into separate files --- init.lua | 10 + replacer.lua | 821 +++++++++++++++++------------------------- replacer_blabla.lua | 29 ++ replacer_patterns.lua | 193 ++++++++++ 4 files changed, 565 insertions(+), 488 deletions(-) create mode 100644 replacer_blabla.lua create mode 100644 replacer_patterns.lua diff --git a/init.lua b/init.lua index de147a9..0e674ec 100644 --- a/init.lua +++ b/init.lua @@ -52,11 +52,21 @@ replacer.blacklist["tnt:tnt"] = true; replacer.blacklist["protector:protect"] = true; replacer.blacklist["protector:protect2"] = true; +-- charge limits replacer.max_charge = 30000 replacer.charge_per_node = 15 +-- node count limit replacer.max_nodes = tonumber(minetest.settings:get("replacer.max_nodes") or "3168") +replacer.has_technic_mod = minetest.get_modpath('technic') + -- adds a tool for inspecting nodes and entities dofile(path .. "/inspect.lua") +dofile(path .. "/replacer_blabla.lua") +dofile(path .. "/replacer_patterns.lua") dofile(path .. "/replacer.lua") dofile(path .. "/crafts.lua") +-------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- +print('[replacer] loaded') + diff --git a/replacer.lua b/replacer.lua index 61151c3..6d397e3 100644 --- a/replacer.lua +++ b/replacer.lua @@ -1,466 +1,126 @@ +replacer.tool_name_basic = "replacer:replacer" +replacer.tool_name_technic = "replacer:replacer_technic" +replacer.tool_default_node = "default:dirt" -local function inform(name, msg) +local r = replacer +local rb = replacer.blabla +local rp = replacer.patterns + +function replacer.inform(name, msg) minetest.chat_send_player(name, msg) - minetest.log("info", "[replacer] "..name..": "..msg) + minetest.log("info", rb.log:format(name, msg)) end -local mode_infos = { - single = "Replace single node.", - field = "Left click: Replace field of nodes of a kind where a translucent node is in front of it. Right click: Replace field of air where no translucent node is behind the air.", - crust = "Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air. Right click: Replace air nodes which touch the crust", - chunkborder = "TODO", -} -local mode_colours = { - single = "#ffffff", - field = "#54FFAC", - crust = "#9F6200", - chunkborder = "#FF5457", -} -local modes = {"single", "field", "crust", "chunkborder"} -for n = 1,#modes do - modes[modes[n]] = n +replacer.modes = { "single", "field", "crust", "chunkborder" } +for n = 1, #r.modes do + r.modes[r.modes[n]] = n end -local function get_data(stack) - local daten = stack:get_meta():get_string"replacer":split" " or {} - return { - name = daten[1] or "default:dirt", - param1 = tonumber(daten[2]) or 0, - param2 = tonumber(daten[3]) or 0 - }, - modes[daten[4]] and daten[4] or modes[1] +replacer.mode_infos = {} +replacer.mode_infos[r.modes[1]] = rb.mode_single +replacer.mode_infos[r.modes[2]] = rb.mode_field +replacer.mode_infos[r.modes[3]] = rb.mode_crust +replacer.mode_infos[r.modes[4]] = rb.mode_chunkborder + +replacer.mode_colours = {} +replacer.mode_colours[r.modes[1]] = "#ffffff" +replacer.mode_colours[r.modes[2]] = "#54FFAC" +replacer.mode_colours[r.modes[3]] = "#9F6200" +replacer.mode_colours[r.modes[4]] = "#FF5457" + +function replacer.get_data(stack) + local data = stack:get_meta():get_string("replacer"):split(" ") or {} + local node = { + name = data[1] or r.tool_default_node, + param1 = tonumber(data[2]) or 0, + param2 = tonumber(data[3]) or 0 + } + local mode = r.modes[1] + if data[4] and r.modes[data[4]] then + mode = data[4] + end + return node, mode end -local function set_data(stack, node, mode) - mode = mode or modes[1] - local metadata = (node.name or "default:dirt") .. " " - .. (node.param1 or 0) .. " " - .. (node.param2 or 0) .. " " +function replacer.set_data(stack, node, mode) + mode = mode or r.modes[1] + local metadata = (node.name or replacer.tool_default_node) .. " " + .. tostring(node.param1 or 0) .. " " + .. tostring(node.param2 or 0) .. " " .. mode local meta = stack:get_meta() meta:set_string("replacer", metadata) - meta:set_string("color", mode_colours[mode]) + meta:set_string("color", r.mode_colours[mode]) return metadata end -local replacer_form_name_modes = "replacer_replacer_mode_change" -local function get_form_modes(current_mode) +replacer.form_name_modes = "replacer_replacer_mode_change" +function replacer.get_form_modes(current_mode) -- TODO: possibly add the info here instead of as -- a chat message - -- TODO: add close button for mobile users who possibly can't esc - -- need feedback from mobile user to know if this is required local formspec = "size[3.9,2]" .. "label[0,0;Choose mode]" .. "button_exit[0.0,0.6;2,0.5;" - if current_mode == modes[1] then - formspec = formspec .. "_;< " .. modes[1] .. " >]" + if r.modes[1] == current_mode then + formspec = formspec .. "_;< " .. r.modes[1] .. " >]" else - formspec = formspec .. "mode;" .. modes[1] .. "]" + formspec = formspec .. "mode;" .. r.modes[1] .. "]" end formspec = formspec .. "button_exit[1.9,0.6;2,0.5;" - if current_mode == modes[2] then - formspec = formspec .. "_;< " .. modes[2] .. " >]" + if r.modes[2] == current_mode then + formspec = formspec .. "_;< " .. r.modes[2] .. " >]" else - formspec = formspec .. "mode;" .. modes[2] .. "]" + formspec = formspec .. "mode;" .. r.modes[2] .. "]" end formspec = formspec .. "button_exit[0.0,1.4;2,0.5;" - if current_mode == modes[3] then - formspec = formspec .. "_;< " .. modes[3] .. " >]" + if r.modes[3] == current_mode then + formspec = formspec .. "_;< " .. r.modes[3] .. " >]" else - formspec = formspec .. "mode;" .. modes[3] .. "]" + formspec = formspec .. "mode;" .. r.modes[3] .. "]" end -- TODO: enable mode when it is available --[[ formspec = formspec .. "button_exit[1.9,1.4;2,0.5;" - if current_mode == modes[4] then - formspec = formspec .. "_;< " .. modes[4] .. " >]" + if r.modes[4] == current_mode then + formspec = formspec .. "_;< " .. r.modes[4] .. " >]" else - formspec = formspec .. "mode;" .. modes[4] .. "]" + formspec = formspec .. "mode;" .. r.modes[4] .. "]" end --]] return formspec -end - -technic.register_power_tool("replacer:replacer", replacer.max_charge) - -minetest.register_tool("replacer:replacer", { - description = "Node replacement tool", - inventory_image = "replacer_replacer.png", - stack_max = 1, -- it has to store information - thus only one can be stacked - wear_represents = "technic_RE_charge", - on_refill = technic.refill_RE_charge, - liquids_pointable = true, -- it is ok to painit in/with water - --node_placement_prediction = nil, - metadata = "default:dirt", -- default replacement: common dirt - - on_place = function(itemstack, placer, pt) - if not placer - or not pt then - return - end - - local keys = placer:get_player_control() - local name = placer:get_player_name() - local creative_enabled = creative.is_enabled_for(name) - local has_give = minetest.check_player_privs(name, "give") - - -- is special-key held? (aka fast-key) - if keys.aux1 then - -- fetch current mode - local node, mode = get_data(itemstack) - -- increment and roll-over mode - mode = modes[modes[mode]%#modes+1] - -- update tool - set_data(itemstack, node, mode) - -- spam chat - inform(name, "Mode changed to: " .. mode .. ": " .. mode_infos[mode]) - -- return changed tool - return itemstack - end - - -- If not holding sneak key, place node(s) - if not keys.sneak then - return replacer.replace(itemstack, placer, pt, true) - end - - -- Select new node - if pt.type ~= "node" then - inform(name, "Error: No node selected.") - return - end - - local node, mode = get_data(itemstack) - node = minetest.get_node_or_nil(pt.under) or node - - local inv = placer:get_inventory() - if not (creative_enabled and has_give) - and not inv:contains_item("main", node.name) then - if creative_enabled then - if minetest.get_item_group(node.name, - "not_in_creative_inventory") > 0 then - -- search for a drop available in creative inventory - local found_item = false - local drops = minetest.get_node_drops(node.name) - for i = 1,#drops do - local name = drops[i] - if minetest.registered_nodes[name] - and minetest.get_item_group(name, - "not_in_creative_inventory") == 0 then - node.name = name - found_item = true - break - end - end - if not found_item then - inform(name, "Node not in creative invenotry: \"" .. - node.name .. "\".") - return - end - end - else - local found_item = false - -- search for a drop that the player has if possible - local drops = minetest.get_node_drops(node.name) - for i = 1,#drops do - local name = drops[i] - if minetest.registered_nodes[name] - and inv:contains_item("main", name) then - node.name = name - found_item = true - break - end - end - if not found_item then - -- search for a drop available in creative inventory - -- that first configuring the replacer, - -- then digging the nodes works - for i = 1,#drops do - local name = drops[i] - if minetest.registered_nodes[name] - and minetest.get_item_group(name, - "not_in_creative_inventory") == 0 then - node.name = name - found_item = true - break - end - end - end - if not found_item - and not has_give then - inform(name, "Item not in your inventory: '" .. node.name .. - "'.") - return - end - end - end - - local metadata = set_data(itemstack, node, mode) - - inform(name, "Node replacement tool set to: '" .. metadata .. "'.") - - return itemstack --data changed - end, - --- on_drop = func(itemstack, dropper, pos), - - on_use = function(...) - -- Replace nodes - return replacer.replace(...) - end, -}) - -local function replacer_register_on_player_receive_fields(player, form_name, fields) - -- no need to process if it's not expected formspec that triggered call - if form_name ~= replacer_form_name_modes then return end - -- no need to process if user closed formspec without changing mode - if nil == fields.mode then return end - - -- collect some information - local itemstack = player:get_wielded_item() - local node, _ = get_data(itemstack) - local mode = fields.mode - local name = player:get_player_name() - - -- set metadata and itemstring - set_data(itemstack, node, mode) - -- update wielded item - player:set_wielded_item(itemstack) - --[[ NOTE: for now I leave this code here in case we later make this a setting in - some way that does not mute all messages of tool - -- spam players chat with information - inform(name, "Mode changed to: " .. mode .. ": " .. mode_infos[mode]) - --]] -end --- listen to submitted fields -minetest.register_on_player_receive_fields(replacer_register_on_player_receive_fields) - -local poshash = minetest.hash_node_position - --- cache results of minetest.get_node -local known_nodes = {} -local function get_node(pos) - local i = poshash(pos) - local node = known_nodes[i] - if node then - return node - end - node = minetest.get_node(pos) - known_nodes[i] = node - return node -end - --- tests if there's a node at pos which should be replaced -local function replaceable(pos, name, pname) - return get_node(pos).name == name - and not minetest.is_protected(pos, pname) -end - -local trans_nodes = {} -local function node_translucent(name) - if trans_nodes[name] ~= nil then - return trans_nodes[name] - end - local data = minetest.registered_nodes[name] - if data - and (not data.drawtype or data.drawtype == "normal") then - trans_nodes[name] = false - return false - end - trans_nodes[name] = true - return true -end - -local function field_position(pos, data) - return replaceable(pos, data.name, data.pname) - and node_translucent( - get_node(vector.add(data.above, pos)).name) ~= data.right_clicked -end - -local offsets_touch = { - {x =-1, y = 0, z = 0}, - {x = 1, y = 0, z = 0}, - {x = 0, y =-1, z = 0}, - {x = 0, y = 1, z = 0}, - {x = 0, y = 0, z =-1}, - {x = 0, y = 0, z = 1}, -} - --- 3x3x3 hollow cube -local offsets_hollowcube = {} -for x = -1, 1 do - for y = -1, 1 do - for z = -1, 1 do - local p = {x = x, y = y, z = z} - if x ~= 0 - or y ~= 0 - or z ~= 0 then - offsets_hollowcube[#offsets_hollowcube + 1] = p - end - end - end -end - --- To get the crust, first nodes near it need to be collected -local function crust_above_position(pos, data) - -- test if the node at pos is a translucent node and not part of the crust - local nd = get_node(pos).name - if nd == data.name - or not node_translucent(nd) then - return false - end - -- test if a node of the crust is near pos - for i = 1, 26 do - local p2 = offsets_hollowcube[i] - if replaceable(vector.add(pos, p2), data.name, data.pname) then - return true - end - end - return false -end - --- used to get nodes the crust belongs to -local function crust_under_position(pos, data) - if not replaceable(pos, data.name, data.pname) then - return false - end - for i = 1, 26 do - local p2 = offsets_hollowcube[i] - if data.aboves[poshash(vector.add(pos, p2))] then - return true - end - end - return false -end - --- extract the crust from the nodes the crust belongs to -local function reduce_crust_ps(data) - local newps = {} - local n = 0 - for i = 1, data.num do - local p = data.ps[i] - for i = 1,6 do - local p2 = offsets_touch[i] - if data.aboves[poshash(vector.add(p, p2))] then - n = n + 1 - newps[n] = p - break - end - end - end - data.ps = newps - data.num = n -end - --- gets the air nodes touching the crust -local function reduce_crust_above_ps(data) - local newps = {} - local n = 0 - for i = 1, data.num do - local p = data.ps[i] - if replaceable(p, "air", data.pname) then - for i = 1, 6 do - local p2 = offsets_touch[i] - if replaceable(vector.add(p, p2), data.name, data.pname) then - n = n + 1 - newps[n] = p - break - end - end - end - end - data.ps = newps - data.num = n -end - -local function mantle_position(pos, data) - if not replaceable(pos, data.name, data.pname) then - return false - end - for i = 1, 6 do - if get_node(vector.add(pos, offsets_touch[i])).name ~= data.name then - return true - end - end - return false -end - --- finds out positions using depth first search -local function get_ps(pos, fdata, adps, max) - adps = adps or offsets_touch - - local tab = {} - local num = 0 - - local todo = {pos} - local ti = 1 - - local tab_avoid = {} - - while ti ~= 0 do - local p = todo[ti] - --~ todo[ti] = nil - ti = ti - 1 - - for _, p2 in pairs(adps) do - p2 = vector.add(p, p2) - local i = poshash(p2) - if not tab_avoid[i] - and fdata.func(p2, fdata) then - - num = num + 1 - tab[num] = p2 - - ti = ti + 1 - todo[ti] = p2 - - tab_avoid[i] = true - - if max - and num >= max then - return false - end - end - end - end - return tab, num, tab_avoid -end +end -- get_form_modes -- replaces one node with another one and returns if it was successful -local function replace_single_node(pos, node, nnd, player, name, inv, creative) +function replacer.replace_single_node(pos, node, nnd, player, name, inv, creative) if minetest.is_protected(pos, name) then - return false, "Protected at " .. minetest.pos_to_string(pos) + return false, rb.protected_at:format(minetest.pos_to_string(pos)) end if replacer.blacklist[node.name] then - return false, "Replacing blocks of the type '" .. - node.name .. - "' is not allowed on this server. Replacement failed." + return false, rb.blacklisted:format(node.name) end -- do not replace if there is nothing to be done if node.name == nnd.name then -- only the orientation was changed - if node.param1 ~= nnd.param1 - or node.param2 ~= nnd.param2 then + if (node.param1 ~= nnd.param1) or (node.param2 ~= nnd.param2) then minetest.swap_node(pos, nnd) end return true end -- does the player carry at least one of the desired nodes with him? - if not creative - and not inv:contains_item("main", nnd.name) then - return false, "You have no further '" .. (nnd.name or "?") .. - "'. Replacement failed." + if (not creative) and (not inv:contains_item("main", nnd.name)) then + return false, rb.run_out:format(nnd.name or "?") end local ndef = minetest.registered_nodes[node.name] if not ndef then - return false, "Unknown node: " .. node.name + return false, rb.attempt_unknown_replace:format(node.name) end local new_ndef = minetest.registered_nodes[nnd.name] if not new_ndef then - return false, "Unknown node should be placed: " .. nnd.name + return false, rb.attempt_unknown_place:format(nnd.name) end -- dig the current node if needed @@ -469,18 +129,18 @@ local function replace_single_node(pos, node, nnd, player, name, inv, creative) ndef.on_dig(pos, node, player) -- test if digging worked local dug_node = minetest.get_node_or_nil(pos) - if not dug_node - or not minetest.registered_nodes[dug_node.name].buildable_to then - return false, "Couldn't dig '" .. node.name .. "' properly." + if (not dug_node) or + (not minetest.registered_nodes[dug_node.name].buildable_to) then + return false, rb.can_not_dig:format(node.name) end end -- place the node similar to how a player does it -- (other than the pointed_thing) local newitem, succ = new_ndef.on_place(ItemStack(nnd.name), player, - {type = "node", under = vector.new(pos), above = vector.new(pos)}) - if succ == false then - return false, "Couldn't place '" .. nnd.name .. "'." + { type = "node", under = vector.new(pos), above = vector.new(pos) }) + if false == succ then + return false, rb.can_not_place:format(nnd.name) end -- update inventory in survival mode @@ -488,7 +148,7 @@ local function replace_single_node(pos, node, nnd, player, name, inv, creative) -- consume the item inv:remove_item("main", nnd.name .. " 1") -- if placing the node didn't result in empty stack… - if newitem:to_string() ~= "" then + if "" ~= newitem:to_string() then inv:add_item("main", newitem) end end @@ -508,32 +168,34 @@ local function replace_single_node(pos, node, nnd, player, name, inv, creative) end return true -end +end -- replace_single_node -- the function which happens when the replacer is used function replacer.replace(itemstack, user, pt, right_clicked) - if not user - or not pt then + if (not user) or (not pt) then return end - + local keys = user:get_player_control() local name = user:get_player_name() - + local creative_enabled = creative.is_enabled_for(name) + local has_give = minetest.check_player_privs(name, "give") + local is_technic = itemstack:get_name() == replacer.tool_name_technic + local modes_are_available = is_technic or has_give or creative_enabled + -- is special-key held? (aka fast-key) if keys.aux1 then + if not modes_are_available then return itemstack end -- fetch current mode - local _, mode = get_data(itemstack) + local _, mode = r.get_data(itemstack) -- Show formspec to choose mode - minetest.show_formspec(name, replacer_form_name_modes, get_form_modes(mode)) + minetest.show_formspec(name, r.form_name_modes, r.get_form_modes(mode)) -- return unchanged tool return itemstack end - local creative_enabled = creative.is_enabled_for(name) - - if pt.type ~= "node" then - inform(name, "Error: " .. pt.type .. " is not a node.") + if "node" ~= pt.type then + r.inform(name, rb.not_a_node:format(pt.type)) return end @@ -541,59 +203,63 @@ function replacer.replace(itemstack, user, pt, right_clicked) local node_toreplace = minetest.get_node_or_nil(pos) if not node_toreplace then - inform(name, "Target node not yet loaded. Please wait a " .. - "moment for the server to catch up.") + r.inform(name, rb.wait_for_load) return end - local nnd, mode = get_data(itemstack) - if node_toreplace.name == nnd.name - and node_toreplace.param1 == nnd.param1 - and node_toreplace.param2 == nnd.param2 then - inform(name, "Nothing to replace.") + local nnd, mode = r.get_data(itemstack) + if (node_toreplace.name == nnd.name) + and (node_toreplace.param1 == nnd.param1) + and (node_toreplace.param2 == nnd.param2) then + r.inform(name, rb.nothing_to_replace) return end if replacer.blacklist[nnd.name] then - minetest.chat_send_player(name, "Placing blocks of the type '" .. - nnd.name .. - "' with the replacer is not allowed on this server. " .. - "Replacement failed.") + minetest.chat_send_player(name, rb.blacklisted:format(nnd.name)) return end - if mode == "single" then - local succ, err = replace_single_node(pos, node_toreplace, nnd, user, + if not modes_are_available then + mode = r.modes[1] + end + + if r.modes[1] == mode then + -- single + local succ, err = replacer.replace_single_node(pos, node_toreplace, nnd, user, name, user:get_inventory(), creative_enabled) - if not succ then - inform(name, err) + r.inform(name, err) end return end + local max_nodes = replacer.max_nodes local meta = minetest.deserialize(itemstack:get_metadata()) - if not meta or not meta.charge - or meta.charge < replacer.charge_per_node then - inform(name, "Not enough charge to use this mode.") - return - end + if replacer.has_technic_mod and (not (creative_enabled or has_give)) then + if (not meta) or (not meta.charge) or (meta.charge < replacer.charge_per_node) then + r.inform(name, rb.need_more_charge) + return + end - local max_charge_to_use = math.min(meta.charge, replacer.max_charge) - local max_nodes = math.floor(max_charge_to_use / replacer.charge_per_node) - if max_nodes > replacer.max_nodes then - max_nodes = replacer.max_nodes + local max_charge_to_use = math.min(meta.charge, replacer.max_charge) + max_nodes = math.floor(max_charge_to_use / replacer.charge_per_node) + if max_nodes > replacer.max_nodes then + max_nodes = replacer.max_nodes + end end local ps, num - if mode == "field" then + if r.modes[2] == mode then + -- field -- get connected positions for plane field replacing local pdif = vector.subtract(pt.above, pt.under) local adps, n = {}, 1 - for _, i in pairs{"x", "y", "z"} do - if pdif[i] == 0 then + local p + for _, i in pairs{ "x", "y", "z" } do + if 0 == pdif[i] then for a = -1, 1, 2 do - local p = {x = 0, y = 0, z = 0} + p = { x = 0, y = 0, z = 0 } p[i] = a adps[n] = p n = n + 1 @@ -603,82 +269,261 @@ function replacer.replace(itemstack, user, pt, right_clicked) if right_clicked then pdif = vector.multiply(pdif, -1) end - right_clicked = right_clicked and true or false - ps, num = get_ps(pos, {func = field_position, name = node_toreplace.name, - pname = name, above = pdif, right_clicked = right_clicked}, adps, max_nodes) - elseif mode == "crust" then - local nodename_clicked = get_node(pt.under).name - local aps, n, aboves = get_ps(pt.above, {func = crust_above_position, - name = nodename_clicked, pname = name}, nil, max_nodes) + right_clicked = (right_clicked and true) or false + ps, num = rp.get_ps(pos, { func = rp.field_position, name = node_toreplace.name, + pname = name, above = pdif, right_clicked = right_clicked }, adps, max_nodes) + elseif r.modes[3] == mode then + -- crust + local nodename_clicked = rp.get_node(pt.under).name + local aps, n, aboves = rp.get_ps(pt.above, { func = rp.crust_above_position, + name = nodename_clicked, pname = name }, nil, max_nodes) if aps then if right_clicked then - local data = {ps = aps, num = n, name = nodename_clicked, pname = name} - reduce_crust_above_ps(data) + local data = { ps = aps, num = n, name = nodename_clicked, pname = name } + rp.reduce_crust_above_ps(data) ps, num = data.ps, data.num else - ps, num = get_ps(pt.under, {func = crust_under_position, - name = node_toreplace.name, pname = name, aboves = aboves}, - offsets_hollowcube, max_nodes) + ps, num = rp.get_ps(pt.under, { func = rp.crust_under_position, + name = node_toreplace.name, pname = name, aboves = aboves }, + rp.offsets_hollowcube, max_nodes) if ps then - local data = {aboves = aboves, ps = ps, num = num} - reduce_crust_ps(data) + local data = { aboves = aboves, ps = ps, num = num } + rp.reduce_crust_ps(data) ps, num = data.ps, data.num end end end - elseif mode == "chunkborder" then - ps, num = get_ps(pos, {func = mantle_position, name = node_toreplace.name, - pname = name}, nil, max_nodes) + elseif r.modes[4] == mode then + -- chunkborder + ps, num = rp.get_ps(pos, { func = rp.mantle_position, name = node_toreplace.name, + pname = name }, nil, max_nodes) end -- reset known nodes table - known_nodes = {} + replacer.patterns.known_nodes = {} if not ps then - inform(name, "Aborted, too many nodes detected.") + r.inform(name, rb.too_many_nodes_detected) return end if 0 == num then - local succ, err = replace_single_node(pos, node_toreplace, nnd, user, + local succ, err = r.replace_single_node(pos, node_toreplace, nnd, user, name, user:get_inventory(), creative_enabled) - if not succ then - inform(name, err) + r.inform(name, err) end return end local charge_needed = replacer.charge_per_node * num - if meta.charge < charge_needed then - inform(name, "Need " .. charge_needed .. " charge to replace " .. num .. " nodes.") - return + if replacer.has_technic_mod and (not (creative_enabled or has_give)) then + if (meta.charge < charge_needed) then + r.inform(name, rb.charge_required:format(charge_needed, num)) + return + end end -- set nodes local inv = user:get_inventory() for i = 1, num do local pos = ps[i] - local succ, err = replace_single_node(pos, minetest.get_node(pos), nnd, + local succ, err = r.replace_single_node(pos, minetest.get_node(pos), nnd, user, name, inv, creative_enabled) if not succ then - inform(name, err) - if not technic.creative_mode then - meta.charge = meta.charge - replacer.charge_per_node * i - technic.set_RE_wear(itemstack, meta.charge, replacer.max_charge) - itemstack:set_metadata(minetest.serialize(meta)) - return itemstack + r.inform(name, err) + if replacer.has_technic_mod and (not technic.creative_mode) then + if not (creative_enabled or has_give) then + meta.charge = meta.charge - replacer.charge_per_node * i + technic.set_RE_wear(itemstack, meta.charge, replacer.max_charge) + itemstack:set_metadata(minetest.serialize(meta)) + return itemstack + end end return end end - if not technic.creative_mode then - meta.charge = meta.charge - replacer.charge_per_node * num - technic.set_RE_wear(itemstack, meta.charge, replacer.max_charge) - itemstack:set_metadata(minetest.serialize(meta)) + if replacer.has_technic_mod and (not technic.creative_mode) then + if not (creative_enabled or has_give) then + meta.charge = meta.charge - charge_needed + technic.set_RE_wear(itemstack, meta.charge, replacer.max_charge) + itemstack:set_metadata(minetest.serialize(meta)) + return itemstack + end + end + r.inform(name, rb.count_replaced:format(num)) +end -- replacer.replace + +-- right-click with tool -> place set node +-- special+right-click -> cycle mode (if tool/privs permit) +-- sneak+right-click -> set node +function replacer.common_on_place(itemstack, placer, pt) + if (not placer) or (not pt) then + return + end + + local keys = placer:get_player_control() + local name = placer:get_player_name() + local creative_enabled = creative.is_enabled_for(name) + local has_give = minetest.check_player_privs(name, "give") + local is_technic = itemstack:get_name() == replacer.tool_name_technic + local modes_are_available = is_technic or has_give or creative_enabled + + -- is special-key held? (aka fast-key) + if keys.aux1 then + -- don't want anybody to think that special+rc = place + if not modes_are_available then return end + -- fetch current mode + local node, mode = r.get_data(itemstack) + -- increment and roll-over mode +print(dump(mode)) + mode = r.modes[r.modes[mode] % #r.modes + 1] + -- update tool + r.set_data(itemstack, node, mode) + -- spam chat + r.inform(name, rb.mode_changed:format(mode, r.mode_infos[mode])) + -- return changed tool return itemstack end - inform(name, num .. " nodes replaced.") + + -- If not holding sneak key, place node(s) + if not keys.sneak then + return replacer.replace(itemstack, placer, pt, true) + end + + -- Select new node + if pt.type ~= "node" then + r.inform(name, rb.none_selected) + return + end + + local node, mode = r.get_data(itemstack) + node = minetest.get_node_or_nil(pt.under) or node + + if not modes_are_available then + mode = r.modes[1] + end + + local inv = placer:get_inventory() + if (not (creative_enabled and has_give)) + and (not inv:contains_item("main", node.name)) then + -- not in inv and not (creative and give) + local found_item = false + local drops = minetest.get_node_drops(node.name) + if creative_enabled then + if minetest.get_item_group(node.name, + "not_in_creative_inventory") > 0 then + -- search for a drop available in creative inventory + for i = 1, #drops do + local name = drops[i] + if minetest.registered_nodes[name] + and minetest.get_item_group(name, + "not_in_creative_inventory") == 0 then + node.name = name + found_item = true + break + end + end + if not found_item then + r.inform(name, rb.not_in_creative:format(node.name)) + return + end + end + else + -- search for a drop that the player has if possible + for i = 1, #drops do + local name = drops[i] + if minetest.registered_nodes[name] + and inv:contains_item("main", name) then + node.name = name + found_item = true + break + end + end + if not found_item then + -- search for a drop available in creative inventory + -- that first configuring the replacer, + -- then digging the nodes works + for i = 1, #drops do + local name = drops[i] + if minetest.registered_nodes[name] + and minetest.get_item_group(name, + "not_in_creative_inventory") == 0 then + node.name = name + found_item = true + break + end + end + end + if (not found_item) and (not has_give) then + inform(name, rb.not_in_inventory:format(node.name)) + return + end + end + end + + local metadata = r.set_data(itemstack, node, mode) + + r.inform(name, rb.set_to:format(metadata)) + + return itemstack --data changed +end -- common_on_place + +function replacer.tool_def_basic() + return { + description = rb.description_basic, + inventory_image = "replacer_replacer.png", + stack_max = 1, -- it has to store information - thus only one can be stacked + liquids_pointable = true, -- it is ok to painit in/with water + --node_placement_prediction = nil, + --metadata = "default:dirt", -- default replacement: common dirt + + -- on_drop = func(itemstack, dropper, pos), + + -- place node(s) + on_place = replacer.common_on_place, --function(...) return common_on_place(...) end, + + -- Replace node(s) + on_use = replacer.replace --function(...) return replacer.replace(...) end, + } +end + +minetest.register_tool(replacer.tool_name_basic, replacer.tool_def_basic()) + +if replacer.has_technic_mod then + function replacer.tool_def_technic() + local def = replacer.tool_def_basic() + def.description = rb.description_technic + def.wear_represents = "technic_RE_charge" + def.on_refill = technic.refill_RE_charge + return def + end + technic.register_power_tool(replacer.tool_name_technic, replacer.max_charge) + minetest.register_tool(replacer.tool_name_technic, replacer.tool_def_technic()) end +function replacer.register_on_player_receive_fields(player, form_name, fields) + -- no need to process if it's not expected formspec that triggered call + if form_name ~= replacer.form_name_modes then return end + -- no need to process if user closed formspec without changing mode + if nil == fields.mode then return end + + -- collect some information + local itemstack = player:get_wielded_item() + local node, _ = r.get_data(itemstack) + local mode = fields.mode + local name = player:get_player_name() + + -- set metadata and itemstring + r.set_data(itemstack, node, mode) + -- update wielded item + player:set_wielded_item(itemstack) + --[[ NOTE: for now I leave this code here in case we later make this a setting in + some way that does not mute all messages of tool + -- spam players chat with information + r.inform(name, rb.set_to:format(mode, r.mode_infos[mode])) + --]] +end +-- listen to submitted fields +minetest.register_on_player_receive_fields(replacer.register_on_player_receive_fields) diff --git a/replacer_blabla.lua b/replacer_blabla.lua new file mode 100644 index 0000000..dc5453c --- /dev/null +++ b/replacer_blabla.lua @@ -0,0 +1,29 @@ +replacer.blabla = {} +replacer.blabla.log = "[replacer] %s: %s" +replacer.blabla.mode_single = "Replace single node." +replacer.blabla.mode_field = "Left click: Replace field of nodes of a kind where a translucent node is in front of it. Right click: Replace field of air where no translucent node is behind the air." +replacer.blabla.mode_crust = "Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air. Right click: Replace air nodes which touch the crust" +replacer.blabla.mode_chunkborder = "TODO: chunkborder" + +replacer.blabla.protected_at = "Protected at %s" +replacer.blabla.blacklisted = 'Replacing nodes of type "%s" is not allowed on this server. Replacement failed.' +replacer.blabla.run_out = 'You have no further "%s". Replacement failed.' +replacer.blabla.attempt_unknown_replace = 'Unknown node: "%s"' +replacer.blabla.attempt_unknown_place = 'Unknown node to place: "%s"' +replacer.blabla.can_not_dig = 'Could not dig "%s" properly.' +replacer.blabla.can_not_place = 'Could not place "%s".' +replacer.blabla.not_a_node = 'Error: "%s" is not a node.' +replacer.blabla.wait_for_load = "Target node not yet loaded. Please wait a moment for the server to catch up." +replacer.blabla.nothing_to_replace = "Nothing to replace." +replacer.blabla.need_more_charge = "Not enough charge to use this mode." +replacer.blabla.too_many_nodes_detected = "Aborted, too many nodes detected." +replacer.blabla.charge_required = "Need %s charge to replace %s nodes." +replacer.blabla.count_replaced = "%s nodes replaced." +replacer.blabla.mode_changed = "Mode changed to %s: %s" +replacer.blabla.none_selected = "Error: No node selected." +replacer.blabla.not_in_creative = 'Item not in creative invenotry: "%s".' +replacer.blabla.not_in_inventory = 'Item not in your inventory: "%s".' +replacer.blabla.set_to = 'Node replacement tool set to: "%s".' +replacer.blabla.description_basic = "Node replacement tool" +replacer.blabla.description_technic = "Node replacement tool (technic)" + diff --git a/replacer_patterns.lua b/replacer_patterns.lua new file mode 100644 index 0000000..f3de9b7 --- /dev/null +++ b/replacer_patterns.lua @@ -0,0 +1,193 @@ +replacer.patterns = {} +local rp = replacer.patterns +local poshash = minetest.hash_node_position + +-- cache results of minetest.get_node +replacer.patterns.known_nodes = {} +function replacer.patterns.get_node(pos) + local i = poshash(pos) + local node = rp.known_nodes[i] + if nil ~= node then + return node + end + node = minetest.get_node(pos) + rp.known_nodes[i] = node + return node +end + +-- tests if there's a node at pos which should be replaced +function replacer.patterns.replaceable(pos, name, pname) + return (rp.get_node(pos).name == name) and (not minetest.is_protected(pos, pname)) +end + +replacer.patterns.translucent_nodes = {} +function replacer.patterns.node_translucent(name) + local is_translucent = rp.translucent_nodes[name] + if nil ~= is_translucent then + return is_translucent + end + local data = minetest.registered_nodes[name] + if data and ((not data.drawtype) or ("normal" == data.drawtype)) then + rp.translucent_nodes[name] = false + return false + end + rp.translucent_nodes[name] = true + return true +end + +function replacer.patterns.field_position(pos, data) + return rp.replaceable(pos, data.name, data.pname) + and rp.node_translucent( + rp.get_node(vector.add(data.above, pos)).name) ~= data.right_clicked +end + +replacer.patterns.offsets_touch = { + { x =-1, y = 0, z = 0 }, + { x = 1, y = 0, z = 0 }, + { x = 0, y =-1, z = 0 }, + { x = 0, y = 1, z = 0 }, + { x = 0, y = 0, z =-1 }, + { x = 0, y = 0, z = 1 }, +} + +-- 3x3x3 hollow cube +replacer.patterns.offsets_hollowcube = {} +local p +for x = -1, 1 do + for y = -1, 1 do + for z = -1, 1 do + if (0 ~= x) or (0 ~= y) or (0 ~= z) then + p = { x = x, y = y, z = z } + rp.offsets_hollowcube[#rp.offsets_hollowcube + 1] = p + end + end + end +end + +-- To get the crust, first nodes near it need to be collected +function replacer.patterns.crust_above_position(pos, data) + -- test if the node at pos is a translucent node and not part of the crust + local nd = rp.get_node(pos).name + if (nd == data.name) or (not rp.node_translucent(nd)) then + return false + end + -- test if a node of the crust is near pos + local p2 + for i = 1, 26 do + p2 = rp.offsets_hollowcube[i] + if rp.replaceable(vector.add(pos, p2), data.name, data.pname) then + return true + end + end + return false +end + +-- used to get nodes the crust belongs to +function replacer.patterns.crust_under_position(pos, data) + if not rp.replaceable(pos, data.name, data.pname) then + return false + end + local p2 + for i = 1, 26 do + p2 = rp.offsets_hollowcube[i] + if data.aboves[poshash(vector.add(pos, p2))] then + return true + end + end + return false +end + +-- extract the crust from the nodes the crust belongs to +function replacer.patterns.reduce_crust_ps(data) + local newps = {} + local n = 0 + local p, p2 + for i = 1, data.num do + p = data.ps[i] + for i = 1, 6 do + p2 = rp.offsets_touch[i] + if data.aboves[poshash(vector.add(p, p2))] then + n = n + 1 + newps[n] = p + break + end + end + end + data.ps = newps + data.num = n +end + +-- gets the air nodes touching the crust +function replacer.patterns.reduce_crust_above_ps(data) + local newps = {} + local n = 0 + local p, p2 + for i = 1, data.num do + p = data.ps[i] + if rp.replaceable(p, "air", data.pname) then + for i = 1, 6 do + p2 = rp.offsets_touch[i] + if rp.replaceable(vector.add(p, p2), data.name, data.pname) then + n = n + 1 + newps[n] = p + break + end + end + end + end + data.ps = newps + data.num = n +end + +function replacer.patterns.mantle_position(pos, data) + if not rp.replaceable(pos, data.name, data.pname) then + return false + end + for i = 1, 6 do + if rp.get_node(vector.add(pos, rp.offsets_touch[i])).name ~= data.name then + return true + end + end + return false +end + +-- finds out positions using depth first search +function replacer.patterns.get_ps(pos, fdata, adps, max) + adps = adps or rp.offsets_touch + + local tab = {} + local num = 0 + + local todo = { pos } + local ti = 1 + + local tab_avoid = {} + local p, i + + while 0 ~= ti do + p = todo[ti] + --~ todo[ti] = nil + ti = ti - 1 + + for _, p2 in pairs(adps) do + p2 = vector.add(p, p2) + i = poshash(p2) + if (not tab_avoid[i]) and fdata.func(p2, fdata) then + + num = num + 1 + tab[num] = p2 + + ti = ti + 1 + todo[ti] = p2 + + tab_avoid[i] = true + + if max and (num >= max) then + return false + end + end -- if + end -- for + end -- while + return tab, num, tab_avoid +end + From aef774387b82cd339ee6b08853a82395d4c40382 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Wed, 5 Feb 2020 21:44:14 +0100 Subject: [PATCH 023/366] temporary crafting recipes --- crafts.lua | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/crafts.lua b/crafts.lua index 891cc8e..479683b 100644 --- a/crafts.lua +++ b/crafts.lua @@ -1,19 +1,40 @@ - minetest.register_craft({ - output = "replacer:replacer", + output = replacer.tool_name_basic, recipe = { - {'default:chest', '', ''}, - {'', 'technic:green_energy_crystal', ''}, - {'', '', 'default:chest'}, + { 'default:chest', 'default:gold_ingot', '' }, + { '', 'default:mese_crystal_fragment', '' }, + { 'default:steel_ingot', '', 'default:chest' }, } }) +-- only if technic mod is installed +if replacer.has_technic_mod then + minetest.register_craft({ + output = replacer.tool_name_technic, + recipe = { + { replacer.tool_name_basic, '', '' }, + { '', 'technic:green_energy_crystal', '' }, + { '', '', '' }, + } + }) + -- direct upgrade craft, is this any good? + minetest.register_craft({ + output = replacer.tool_name_technic, + recipe = { + { 'default:chest', '', 'default:gold_ingot' }, + { '', 'default:mese_crystal_fragment', 'technic:green_energy_crystal' }, + { 'default:steel_ingot', '', 'default:chest' }, + } + }) +end + + minetest.register_craft({ output = 'replacer:inspect', recipe = { - { 'default:torch'}, - { 'default:stick'}, + { 'default:torch' }, + { 'default:stick' }, } }) From 154cfcf9f3738f637de36cb2b4c1e55bfd6c7291 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Thu, 6 Feb 2020 22:17:46 +0100 Subject: [PATCH 024/366] remove debug message remainder --- replacer.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/replacer.lua b/replacer.lua index 6d397e3..845ccc8 100644 --- a/replacer.lua +++ b/replacer.lua @@ -377,7 +377,6 @@ function replacer.common_on_place(itemstack, placer, pt) -- fetch current mode local node, mode = r.get_data(itemstack) -- increment and roll-over mode -print(dump(mode)) mode = r.modes[r.modes[mode] % #r.modes + 1] -- update tool r.set_data(itemstack, node, mode) From 98e0e92b8fc32793779b76f51d02a90dee2fab1f Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Thu, 6 Feb 2020 22:19:43 +0100 Subject: [PATCH 025/366] proper substitution syntax (not crucial) --- replacer_blabla.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replacer_blabla.lua b/replacer_blabla.lua index dc5453c..ad5e137 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -17,7 +17,7 @@ replacer.blabla.wait_for_load = "Target node not yet loaded. Please wait a momen replacer.blabla.nothing_to_replace = "Nothing to replace." replacer.blabla.need_more_charge = "Not enough charge to use this mode." replacer.blabla.too_many_nodes_detected = "Aborted, too many nodes detected." -replacer.blabla.charge_required = "Need %s charge to replace %s nodes." +replacer.blabla.charge_required = "Need %d charge to replace %d nodes." replacer.blabla.count_replaced = "%s nodes replaced." replacer.blabla.mode_changed = "Mode changed to %s: %s" replacer.blabla.none_selected = "Error: No node selected." From bffc5d3596fa1f48a90257ca9ff08efaf7eeb550 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Thu, 6 Feb 2020 22:23:49 +0100 Subject: [PATCH 026/366] do as much as possible, then abbort --- replacer.lua | 3 +-- replacer_patterns.lua | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/replacer.lua b/replacer.lua index 845ccc8..5ce6532 100644 --- a/replacer.lua +++ b/replacer.lua @@ -319,8 +319,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) local charge_needed = replacer.charge_per_node * num if replacer.has_technic_mod and (not (creative_enabled or has_give)) then if (meta.charge < charge_needed) then - r.inform(name, rb.charge_required:format(charge_needed, num)) - return + num = math.floor(meta.charge / replacer.charge_per_node) end end diff --git a/replacer_patterns.lua b/replacer_patterns.lua index f3de9b7..7d04c5f 100644 --- a/replacer_patterns.lua +++ b/replacer_patterns.lua @@ -183,7 +183,7 @@ function replacer.patterns.get_ps(pos, fdata, adps, max) tab_avoid[i] = true if max and (num >= max) then - return false + return tab, num, tab_avoid --false end end -- if end -- for From 7613e67581b6a9719d64dfdcc557636fa491315f Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 7 Feb 2020 03:23:11 +0100 Subject: [PATCH 027/366] use get_meta() instead of depricated get_metadata() and make code easier to read and less repititons in the process --- replacer.lua | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/replacer.lua b/replacer.lua index 5ce6532..d081d85 100644 --- a/replacer.lua +++ b/replacer.lua @@ -170,6 +170,28 @@ function replacer.replace_single_node(pos, node, nnd, player, name, inv, creativ return true end -- replace_single_node +if replacer.has_technic_mod then + -- technic still stores data serialized, so this is the nearest we get to current standard + function replacer.get_charge(itemstack) + local meta = minetest.deserialize(itemstack:get_meta():get_string('')) + if (not meta) or (not meta.charge) then + return 0 + end + return meta.charge + end + + function replacer.set_charge(itemstack, charge, max) + technic.set_RE_wear(itemstack, charge, max) + local metaRef = itemstack:get_meta() + local meta = minetest.deserialize(metaRef:get_string('')) + if (not meta) or (not meta.charge) then + meta = { charge = 0 } + end + meta.charge = charge + metaRef:set_string('', minetest.serialize(meta)) + end +end + -- the function which happens when the replacer is used function replacer.replace(itemstack, user, pt, right_clicked) if (not user) or (not pt) then @@ -235,14 +257,14 @@ function replacer.replace(itemstack, user, pt, right_clicked) end local max_nodes = replacer.max_nodes - local meta = minetest.deserialize(itemstack:get_metadata()) + local charge = r.get_charge(itemstack) if replacer.has_technic_mod and (not (creative_enabled or has_give)) then - if (not meta) or (not meta.charge) or (meta.charge < replacer.charge_per_node) then + if charge < replacer.charge_per_node then r.inform(name, rb.need_more_charge) return end - local max_charge_to_use = math.min(meta.charge, replacer.max_charge) + local max_charge_to_use = math.min(charge, replacer.max_charge) max_nodes = math.floor(max_charge_to_use / replacer.charge_per_node) if max_nodes > replacer.max_nodes then max_nodes = replacer.max_nodes @@ -303,6 +325,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) replacer.patterns.known_nodes = {} if not ps then + -- TODO: does this ever happen anymore? r.inform(name, rb.too_many_nodes_detected) return end @@ -318,8 +341,8 @@ function replacer.replace(itemstack, user, pt, right_clicked) local charge_needed = replacer.charge_per_node * num if replacer.has_technic_mod and (not (creative_enabled or has_give)) then - if (meta.charge < charge_needed) then - num = math.floor(meta.charge / replacer.charge_per_node) + if (charge < charge_needed) then + num = math.floor(charge / replacer.charge_per_node) end end @@ -333,9 +356,8 @@ function replacer.replace(itemstack, user, pt, right_clicked) r.inform(name, err) if replacer.has_technic_mod and (not technic.creative_mode) then if not (creative_enabled or has_give) then - meta.charge = meta.charge - replacer.charge_per_node * i - technic.set_RE_wear(itemstack, meta.charge, replacer.max_charge) - itemstack:set_metadata(minetest.serialize(meta)) + charge = charge - replacer.charge_per_node * i + r.set_charge(itemstack, charge, replacer.max_charge) return itemstack end end @@ -345,9 +367,8 @@ function replacer.replace(itemstack, user, pt, right_clicked) if replacer.has_technic_mod and (not technic.creative_mode) then if not (creative_enabled or has_give) then - meta.charge = meta.charge - charge_needed - technic.set_RE_wear(itemstack, meta.charge, replacer.max_charge) - itemstack:set_metadata(minetest.serialize(meta)) + charge = charge - charge_needed + r.set_charge(itemstack, charge, replacer.max_charge) return itemstack end end From 9aff9715d8428bd9d84874f44daf71e9c11ca643 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 7 Feb 2020 06:20:53 +0100 Subject: [PATCH 028/366] cleanup --- replacer.lua | 54 ++++++++++++++++++++----------------------- replacer_patterns.lua | 3 +-- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/replacer.lua b/replacer.lua index d081d85..d0c2e36 100644 --- a/replacer.lua +++ b/replacer.lua @@ -54,6 +54,28 @@ function replacer.set_data(stack, node, mode) return metadata end +if replacer.has_technic_mod then + -- technic still stores data serialized, so this is the nearest we get to current standard + function replacer.get_charge(itemstack) + local meta = minetest.deserialize(itemstack:get_meta():get_string('')) + if (not meta) or (not meta.charge) then + return 0 + end + return meta.charge + end + + function replacer.set_charge(itemstack, charge, max) + technic.set_RE_wear(itemstack, charge, max) + local metaRef = itemstack:get_meta() + local meta = minetest.deserialize(metaRef:get_string('')) + if (not meta) or (not meta.charge) then + meta = { charge = 0 } + end + meta.charge = charge + metaRef:set_string('', minetest.serialize(meta)) + end +end + replacer.form_name_modes = "replacer_replacer_mode_change" function replacer.get_form_modes(current_mode) -- TODO: possibly add the info here instead of as @@ -170,28 +192,6 @@ function replacer.replace_single_node(pos, node, nnd, player, name, inv, creativ return true end -- replace_single_node -if replacer.has_technic_mod then - -- technic still stores data serialized, so this is the nearest we get to current standard - function replacer.get_charge(itemstack) - local meta = minetest.deserialize(itemstack:get_meta():get_string('')) - if (not meta) or (not meta.charge) then - return 0 - end - return meta.charge - end - - function replacer.set_charge(itemstack, charge, max) - technic.set_RE_wear(itemstack, charge, max) - local metaRef = itemstack:get_meta() - local meta = minetest.deserialize(metaRef:get_string('')) - if (not meta) or (not meta.charge) then - meta = { charge = 0 } - end - meta.charge = charge - metaRef:set_string('', minetest.serialize(meta)) - end -end - -- the function which happens when the replacer is used function replacer.replace(itemstack, user, pt, right_clicked) if (not user) or (not pt) then @@ -496,15 +496,10 @@ function replacer.tool_def_basic() stack_max = 1, -- it has to store information - thus only one can be stacked liquids_pointable = true, -- it is ok to painit in/with water --node_placement_prediction = nil, - --metadata = "default:dirt", -- default replacement: common dirt - - -- on_drop = func(itemstack, dropper, pos), - -- place node(s) - on_place = replacer.common_on_place, --function(...) return common_on_place(...) end, - + on_place = replacer.common_on_place, -- Replace node(s) - on_use = replacer.replace --function(...) return replacer.replace(...) end, + on_use = replacer.replace } end @@ -546,3 +541,4 @@ function replacer.register_on_player_receive_fields(player, form_name, fields) end -- listen to submitted fields minetest.register_on_player_receive_fields(replacer.register_on_player_receive_fields) + diff --git a/replacer_patterns.lua b/replacer_patterns.lua index 7d04c5f..6402b7d 100644 --- a/replacer_patterns.lua +++ b/replacer_patterns.lua @@ -166,7 +166,6 @@ function replacer.patterns.get_ps(pos, fdata, adps, max) while 0 ~= ti do p = todo[ti] - --~ todo[ti] = nil ti = ti - 1 for _, p2 in pairs(adps) do @@ -183,7 +182,7 @@ function replacer.patterns.get_ps(pos, fdata, adps, max) tab_avoid[i] = true if max and (num >= max) then - return tab, num, tab_avoid --false + return tab, num, tab_avoid end end -- if end -- for From cbee68c80d6f8f4189e067c7896a506c9f5a78c2 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 7 Feb 2020 06:21:57 +0100 Subject: [PATCH 029/366] add server settings to hide recipes --- crafts.lua | 52 +++++++++++++++++++++++++++++----------------------- init.lua | 5 +++++ 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/crafts.lua b/crafts.lua index 479683b..2e3dc26 100644 --- a/crafts.lua +++ b/crafts.lua @@ -1,36 +1,42 @@ -minetest.register_craft({ - output = replacer.tool_name_basic, - recipe = { - { 'default:chest', 'default:gold_ingot', '' }, - { '', 'default:mese_crystal_fragment', '' }, - { 'default:steel_ingot', '', 'default:chest' }, - } -}) - - --- only if technic mod is installed -if replacer.has_technic_mod then +if not replacer.hide_recipe_basic then minetest.register_craft({ - output = replacer.tool_name_technic, - recipe = { - { replacer.tool_name_basic, '', '' }, - { '', 'technic:green_energy_crystal', '' }, - { '', '', '' }, - } - }) - -- direct upgrade craft, is this any good? - minetest.register_craft({ - output = replacer.tool_name_technic, + output = replacer.tool_name_basic, recipe = { { 'default:chest', '', 'default:gold_ingot' }, - { '', 'default:mese_crystal_fragment', 'technic:green_energy_crystal' }, + { '', 'default:mese_crystal_fragment', '' }, { 'default:steel_ingot', '', 'default:chest' }, } }) end +-- only if technic mod is installed +if replacer.has_technic_mod then + if not replacer.hide_recipe_technic_upgrade then + minetest.register_craft({ + output = replacer.tool_name_technic, + recipe = { + { replacer.tool_name_basic, 'technic:green_energy_crystal', '' }, + { '', '', '' }, + { '', '', '' }, + } + }) + end + if not replacer.hide_recipe_technic_direct then + -- direct upgrade craft + minetest.register_craft({ + output = replacer.tool_name_technic, + recipe = { + { 'default:chest', 'technic:green_energy_crystal', 'default:gold_ingot' }, + { '', 'default:mese_crystal_fragment', '' }, + { 'default:steel_ingot', '', 'default:chest' }, + } + }) + end +end + + minetest.register_craft({ output = 'replacer:inspect', recipe = { diff --git a/init.lua b/init.lua index 0e674ec..48f29b6 100644 --- a/init.lua +++ b/init.lua @@ -58,6 +58,11 @@ replacer.charge_per_node = 15 -- node count limit replacer.max_nodes = tonumber(minetest.settings:get("replacer.max_nodes") or "3168") +-- select which recipes to hide (not all combinations make sense) +replacer.hide_recipe_basic = 1 == (tonumber(minetest.settings:get('replacer.hide_recipe_basic')) or 0) +replacer.hide_recipe_technic_upgrade = 1 == (tonumber(minetest.settings:get('replacer.hide_recipe_technic_upgrade')) or 0) +replacer.hide_recipe_technic_direct = 1 == (tonumber(minetest.settings:get('replacer.hide_recipe_technic_direct')) or 1) + replacer.has_technic_mod = minetest.get_modpath('technic') -- adds a tool for inspecting nodes and entities From e56b579186de56c0db925ac08fe60624e32432cf Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 7 Feb 2020 06:23:01 +0100 Subject: [PATCH 030/366] update changelog and readme --- README.md | 43 +++++++++++++++++++++++++++++++++++-------- init.lua | 13 +++++++++++++ 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d30cbdf..d86940b 100644 --- a/README.md +++ b/README.md @@ -5,30 +5,53 @@ It replaces nodes with a previously selected other type of node (i.e. places sai into a brick wall). # Crafting +Availability of recipes can be configured with server settings. +Basic replacer: +``` + | chest | | gold ingot | + | | mese fragment | | + | steel ingot | | chest | +``` +Or `/giveme replacer:replacer` +Technic replacer as upgrade to basic tool: ``` - | chest | | | - | | green energy crystal | | - | | | chest | + | replacer:replacer | green energy crystal | | + | | | | + | | | | ``` -Or just use `/giveme replacer:replacer` +Or `/giveme replacer:replacer_technic` + +Technic replacer directly crafted: +``` + | chest | green energy crystal | gold ingot | + | | mese fragment | | + | steel ingot | | chest | +``` +Or `/giveme replacer:replacer_technic` # Usage Sneak-right-click on a node of which type you want to replace other nodes with. - Left-click (normal usage) on any nodes you want to replace with that type. Right-click to place a node of that type onto clicked node. + Left-click (normal usage) on any nodes you want to replace with that type. + Right-click to place a node of that type onto clicked node. When in creative mode, the node will just be replaced. Your inventory will not be changed. -When *not* in creative mode, digging will be simulated and you will get what was there. In return, the replacement node -will be taken from your inventory. +When *not* in creative mode, digging will be simulated and you will get what was there. +In return, the replacement node will be taken from your inventory. + +If technic mod is installed, modes are available and use depletes charge. +This is true for users without "give" privs and also on servers not running in creative mode. # Modes Special-right-click on a node or special-left-click anywhere to change the mode. Single-mode does not need any charge. The other modes do. -The second tool included in this mod is the inspector. +# Inspection tool + +The third tool included in this mod is the inspector. Crafting: ``` @@ -41,6 +64,10 @@ Just wield it and click on any node or entity you want to know more about. A lim # Settings * **replacer.max_nodes** max allowed nodes to replace (default: 3168) +* **replacer.hide_recipe_basic** hide the basic recipe (default: 0) +These two require technic to be installed, if not they are hidden no matter how you set them +* **replacer.hide_recipe_technic_upgrade** hide the upgrade recipe (default: 0) +* **replacer.hide_recipe_technic_direct** hide the direct technic recipe (default: 1) # Contributors diff --git a/init.lua b/init.lua index 48f29b6..17c3c84 100644 --- a/init.lua +++ b/init.lua @@ -19,6 +19,19 @@ -- Version 3.0 -- Changelog: +-- * SwissalpS added backward compatibility for non technic servers, restored +-- creative/give behaviour and fixed the 'too many nodes detected' issue +-- * S-S-X and some players from pandorabox.io requested and inspired ideas to +-- implement which SwissalpS tried to satisfy. +-- * SwissalpS added method to change mode via formspec +-- * BuckarooBanzay added server-setting max_nodes, moved crafts and replacer to +-- separate files, added .luacheckrc and cleaned up inspection tool, fixing +-- some issues on the way and updated readme to look nice +-- * coil0 made modes available as technic tool and added limits +-- * OgelGames fixed digging to be simulated properly +-- * SwissalpS merged Sokomine's and HybridDog's versions +-- * HybridDog added modes for creative mode +-- * coil0 fixed issue by using buildable_to -- 09.12.2017 * Got rid of outdated minetest.env -- * Fixed error in protection function. -- * Fixed minor bugs. From 6a5579472a701bcdb06d3815780d79340262c383 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 7 Feb 2020 08:49:31 +0100 Subject: [PATCH 031/366] store mode in separate meta-string for easier detection by other mods --- replacer.lua | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/replacer.lua b/replacer.lua index d0c2e36..7d82870 100644 --- a/replacer.lua +++ b/replacer.lua @@ -29,15 +29,16 @@ replacer.mode_colours[r.modes[3]] = "#9F6200" replacer.mode_colours[r.modes[4]] = "#FF5457" function replacer.get_data(stack) - local data = stack:get_meta():get_string("replacer"):split(" ") or {} + local metaRef = stack:get_meta() + local data = metaRef:get_string("replacer"):split(" ") or {} local node = { name = data[1] or r.tool_default_node, param1 = tonumber(data[2]) or 0, param2 = tonumber(data[3]) or 0 } - local mode = r.modes[1] - if data[4] and r.modes[data[4]] then - mode = data[4] + local mode = metaRef:get_string("mode") + if nil == r.modes[mode] then + mode = r.modes[1] end return node, mode end @@ -46,11 +47,11 @@ function replacer.set_data(stack, node, mode) mode = mode or r.modes[1] local metadata = (node.name or replacer.tool_default_node) .. " " .. tostring(node.param1 or 0) .. " " - .. tostring(node.param2 or 0) .. " " - .. mode - local meta = stack:get_meta() - meta:set_string("replacer", metadata) - meta:set_string("color", r.mode_colours[mode]) + .. tostring(node.param2 or 0) + local metaRef = stack:get_meta() + metaRef:set_string("mode", mode) + metaRef:set_string("replacer", metadata) + metaRef:set_string("color", r.mode_colours[mode]) return metadata end From 597e8f1d09d41715ad25a6b7c656fd73bfd535b0 Mon Sep 17 00:00:00 2001 From: SX Date: Sat, 8 Feb 2020 06:43:04 +0200 Subject: [PATCH 032/366] fix crash: attempt to call nil as function --- replacer.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replacer.lua b/replacer.lua index 7d82870..2edcb53 100644 --- a/replacer.lua +++ b/replacer.lua @@ -477,7 +477,7 @@ function replacer.common_on_place(itemstack, placer, pt) end end if (not found_item) and (not has_give) then - inform(name, rb.not_in_inventory:format(node.name)) + r.inform(name, rb.not_in_inventory:format(node.name)) return end end From 7fdd94e9f1d8fa443d53129305555660297aae87 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 10 Feb 2020 14:28:16 +0100 Subject: [PATCH 033/366] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d86940b..c8c9bf1 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Just wield it and click on any node or entity you want to know more about. A lim # Settings * **replacer.max_nodes** max allowed nodes to replace (default: 3168) -* **replacer.hide_recipe_basic** hide the basic recipe (default: 0) +* **replacer.hide_recipe_basic** hide the basic recipe (default: 0)
These two require technic to be installed, if not they are hidden no matter how you set them * **replacer.hide_recipe_technic_upgrade** hide the upgrade recipe (default: 0) * **replacer.hide_recipe_technic_direct** hide the direct technic recipe (default: 1) From 1a2a30c119a806e5dc79a7dbf970b5aa3d140283 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Thu, 13 Feb 2020 22:18:49 +0100 Subject: [PATCH 034/366] adding settingtypes.txt for GUI users --- settingtypes.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 settingtypes.txt diff --git a/settingtypes.txt b/settingtypes.txt new file mode 100644 index 0000000..e5daa77 --- /dev/null +++ b/settingtypes.txt @@ -0,0 +1,5 @@ +#Replace/place up to this many nodes when using modes other than single. +#Depending on server hardware and amount of users, this value needs adapting. +#On singleplayer you can mostly use a higher value. +#The default is 3168 +replacer.max_nodes (Maximum nodes to replace with one click) int 3168 From 7acbc92bb3ae6b7ccd40f85adec4aaa12049a0d7 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Sun, 16 Feb 2020 21:04:51 +0100 Subject: [PATCH 035/366] added sittingtypes.txt entries for all settings There should not be any trouble by switch to bool instead of int --- init.lua | 14 ++++++++++---- settingtypes.txt | 14 ++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/init.lua b/init.lua index 17c3c84..0fcd1ad 100644 --- a/init.lua +++ b/init.lua @@ -69,12 +69,18 @@ replacer.blacklist["protector:protect2"] = true; replacer.max_charge = 30000 replacer.charge_per_node = 15 -- node count limit -replacer.max_nodes = tonumber(minetest.settings:get("replacer.max_nodes") or "3168") +replacer.max_nodes = tonumber(minetest.settings:get("replacer.max_nodes") or 3168) -- select which recipes to hide (not all combinations make sense) -replacer.hide_recipe_basic = 1 == (tonumber(minetest.settings:get('replacer.hide_recipe_basic')) or 0) -replacer.hide_recipe_technic_upgrade = 1 == (tonumber(minetest.settings:get('replacer.hide_recipe_technic_upgrade')) or 0) -replacer.hide_recipe_technic_direct = 1 == (tonumber(minetest.settings:get('replacer.hide_recipe_technic_direct')) or 1) +replacer.hide_recipe_basic = + minetest.settings:get_bool('replacer.hide_recipe_basic') or false +replacer.hide_recipe_technic_upgrade = + minetest.settings:get_bool('replacer.hide_recipe_technic_upgrade') or false +replacer.hide_recipe_technic_direct = + minetest.settings:get_bool('replacer.hide_recipe_technic_direct') +if nil == replacer.hide_recipe_technic_direct then + replacer.hide_recipe_technic_direct = true +end replacer.has_technic_mod = minetest.get_modpath('technic') diff --git a/settingtypes.txt b/settingtypes.txt index e5daa77..20f58d3 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -1,5 +1,11 @@ -#Replace/place up to this many nodes when using modes other than single. -#Depending on server hardware and amount of users, this value needs adapting. -#On singleplayer you can mostly use a higher value. -#The default is 3168 +# Replace / place up to this many nodes when using modes other than single. +# Depending on server hardware and amount of users, this value needs adapting. +# On singleplayer you can mostly use a higher value. +# The default is 3168 replacer.max_nodes (Maximum nodes to replace with one click) int 3168 +# You may choose to hide basic recipe but then make sure to enable the technic direct one +replacer.hide_recipe_basic (Hide basic recipe) bool false +# Hide the upgrade recipe. Only available if technic is installed. +replacer.hide_recipe_technic_upgrade (Hide upgrade recipe) bool false +# Hide the direct upgrade recipe. Only available if technic is installed. +replacer.hide_recipe_technic_direct (Hide direct recipe) bool true From 6686a6f5e41738605ac7e9707eee3f23b4015025 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 21 Feb 2020 19:01:05 +0100 Subject: [PATCH 036/366] bugfix creative mode --- replacer.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/replacer.lua b/replacer.lua index 2edcb53..22570c5 100644 --- a/replacer.lua +++ b/replacer.lua @@ -258,8 +258,9 @@ function replacer.replace(itemstack, user, pt, right_clicked) end local max_nodes = replacer.max_nodes - local charge = r.get_charge(itemstack) + local charge if replacer.has_technic_mod and (not (creative_enabled or has_give)) then + charge = r.get_charge(itemstack) if charge < replacer.charge_per_node then r.inform(name, rb.need_more_charge) return From 48aec8c9241c153abae7b607fe9b66f84ec3635e Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 21 Feb 2020 19:09:00 +0100 Subject: [PATCH 037/366] whitespace --- init.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/init.lua b/init.lua index 0fcd1ad..079d623 100644 --- a/init.lua +++ b/init.lua @@ -52,18 +52,18 @@ local path = minetest.get_modpath("replacer") replacer = {} -replacer.blacklist = {}; +replacer.blacklist = {} -- playing with tnt and creative building are usually contradictory -- (except when doing large-scale landscaping in singleplayer) -replacer.blacklist["tnt:boom"] = true; -replacer.blacklist["tnt:gunpowder"] = true; -replacer.blacklist["tnt:gunpowder_burning"] = true; -replacer.blacklist["tnt:tnt"] = true; +replacer.blacklist["tnt:boom"] = true +replacer.blacklist["tnt:gunpowder"] = true +replacer.blacklist["tnt:gunpowder_burning"] = true +replacer.blacklist["tnt:tnt"] = true -- prevent accidental replacement of your protector -replacer.blacklist["protector:protect"] = true; -replacer.blacklist["protector:protect2"] = true; +replacer.blacklist["protector:protect"] = true +replacer.blacklist["protector:protect2"] = true -- charge limits replacer.max_charge = 30000 From 608c8c42ac3154f3b9393a85773eb01361cdd101 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 21 Feb 2020 20:11:59 +0100 Subject: [PATCH 038/366] limit certain nodes to individual max Some nodes have cpu intensive side-effects when placed. To avoid lag, this commit adds mechanism to limit per node. --- init.lua | 4 ++++ replacer.lua | 29 ++++++++++++++++++++++++++++- replacer_blabla.lua | 3 +++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 079d623..6ac73af 100644 --- a/init.lua +++ b/init.lua @@ -52,6 +52,10 @@ local path = minetest.get_modpath("replacer") replacer = {} +-- limit by node, use replacer.register_limit(sName, iMax) +replacer.limit_list = {} + +-- don't allow these at all replacer.blacklist = {} -- playing with tnt and creative building are usually contradictory diff --git a/replacer.lua b/replacer.lua index 22570c5..2134d66 100644 --- a/replacer.lua +++ b/replacer.lua @@ -28,6 +28,33 @@ replacer.mode_colours[r.modes[2]] = "#54FFAC" replacer.mode_colours[r.modes[3]] = "#9F6200" replacer.mode_colours[r.modes[4]] = "#FF5457" +local is_int = function(value) + return type(value) == 'number' and math.floor(value) == value +end + +function replacer.register_limit(node_name, node_max) + -- ignore nil and negative numbers + if (nil == node_max) or (0 > node_max) then + return + end + -- ignore non-integers + if not is_int(node_max) then + return + end + -- add to blacklist if limit is zero + if 0 == node_max then + replacer.blacklist[node_name] = true + minetest.log("info", rb.blacklist_insert:format(node_name)) + return + end + -- log info if already limited + if nil ~= r.limit_list[node_name] then + minetest.log("info", rb.limit_override:format(node_name, r.limit_list[node_name])) + end + r.limit_list[node_name] = node_max + minetest.log("info", rb.limit_insert:format(node_name, node_max)) +end + function replacer.get_data(stack) local metaRef = stack:get_meta() local data = metaRef:get_string("replacer"):split(" ") or {} @@ -257,7 +284,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) return end - local max_nodes = replacer.max_nodes + local max_nodes = r.limit_list[nnd.name] or r.max_nodes local charge if replacer.has_technic_mod and (not (creative_enabled or has_give)) then charge = r.get_charge(itemstack) diff --git a/replacer_blabla.lua b/replacer_blabla.lua index ad5e137..c715ec4 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -26,4 +26,7 @@ replacer.blabla.not_in_inventory = 'Item not in your inventory: "%s".' replacer.blabla.set_to = 'Node replacement tool set to: "%s".' replacer.blabla.description_basic = "Node replacement tool" replacer.blabla.description_technic = "Node replacement tool (technic)" +replacer.blabla.limit_override = 'Setting already set node-limit for "%s" was %d.' +replacer.blabla.limit_insert = 'Setting node-limit for "%s" to %d.' +replacer.blabla.blacklist_insert = 'Blacklisted "%s".' From cecc92bdaf1e688be4575fab7d0eee905ad84d18 Mon Sep 17 00:00:00 2001 From: HybridDog Date: Sun, 22 Mar 2020 09:44:57 +0100 Subject: [PATCH 039/366] Remove chunkborder mode code --- replacer.lua | 24 +++++------------------- replacer_blabla.lua | 1 - 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/replacer.lua b/replacer.lua index 2134d66..575159f 100644 --- a/replacer.lua +++ b/replacer.lua @@ -11,7 +11,7 @@ function replacer.inform(name, msg) minetest.log("info", rb.log:format(name, msg)) end -replacer.modes = { "single", "field", "crust", "chunkborder" } +replacer.modes = {"single", "field", "crust"} for n = 1, #r.modes do r.modes[r.modes[n]] = n end @@ -20,13 +20,11 @@ replacer.mode_infos = {} replacer.mode_infos[r.modes[1]] = rb.mode_single replacer.mode_infos[r.modes[2]] = rb.mode_field replacer.mode_infos[r.modes[3]] = rb.mode_crust -replacer.mode_infos[r.modes[4]] = rb.mode_chunkborder replacer.mode_colours = {} replacer.mode_colours[r.modes[1]] = "#ffffff" replacer.mode_colours[r.modes[2]] = "#54FFAC" replacer.mode_colours[r.modes[3]] = "#9F6200" -replacer.mode_colours[r.modes[4]] = "#FF5457" local is_int = function(value) return type(value) == 'number' and math.floor(value) == value @@ -129,14 +127,6 @@ function replacer.get_form_modes(current_mode) formspec = formspec .. "mode;" .. r.modes[3] .. "]" end -- TODO: enable mode when it is available - --[[ - formspec = formspec .. "button_exit[1.9,1.4;2,0.5;" - if r.modes[4] == current_mode then - formspec = formspec .. "_;< " .. r.modes[4] .. " >]" - else - formspec = formspec .. "mode;" .. r.modes[4] .. "]" - end - --]] return formspec end -- get_form_modes @@ -225,14 +215,14 @@ function replacer.replace(itemstack, user, pt, right_clicked) if (not user) or (not pt) then return end - + local keys = user:get_player_control() local name = user:get_player_name() local creative_enabled = creative.is_enabled_for(name) local has_give = minetest.check_player_privs(name, "give") local is_technic = itemstack:get_name() == replacer.tool_name_technic local modes_are_available = is_technic or has_give or creative_enabled - + -- is special-key held? (aka fast-key) if keys.aux1 then if not modes_are_available then return itemstack end @@ -273,7 +263,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) if not modes_are_available then mode = r.modes[1] end - + if r.modes[1] == mode then -- single local succ, err = replacer.replace_single_node(pos, node_toreplace, nnd, user, @@ -344,10 +334,6 @@ function replacer.replace(itemstack, user, pt, right_clicked) end end end - elseif r.modes[4] == mode then - -- chunkborder - ps, num = rp.get_ps(pos, { func = rp.mantle_position, name = node_toreplace.name, - pname = name }, nil, max_nodes) end -- reset known nodes table @@ -448,7 +434,7 @@ function replacer.common_on_place(itemstack, placer, pt) local node, mode = r.get_data(itemstack) node = minetest.get_node_or_nil(pt.under) or node - + if not modes_are_available then mode = r.modes[1] end diff --git a/replacer_blabla.lua b/replacer_blabla.lua index c715ec4..b3d3d4b 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -3,7 +3,6 @@ replacer.blabla.log = "[replacer] %s: %s" replacer.blabla.mode_single = "Replace single node." replacer.blabla.mode_field = "Left click: Replace field of nodes of a kind where a translucent node is in front of it. Right click: Replace field of air where no translucent node is behind the air." replacer.blabla.mode_crust = "Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air. Right click: Replace air nodes which touch the crust" -replacer.blabla.mode_chunkborder = "TODO: chunkborder" replacer.blabla.protected_at = "Protected at %s" replacer.blabla.blacklisted = 'Replacing nodes of type "%s" is not allowed on this server. Replacement failed.' From 60dd6ff41a4bfc590f5ce400ac004b0b5a13b768 Mon Sep 17 00:00:00 2001 From: HybridDog Date: Sun, 22 Mar 2020 10:34:41 +0100 Subject: [PATCH 040/366] Add data structures --- datastructures.lua | 338 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 338 insertions(+) create mode 100644 datastructures.lua diff --git a/datastructures.lua b/datastructures.lua new file mode 100644 index 0000000..588d437 --- /dev/null +++ b/datastructures.lua @@ -0,0 +1,338 @@ +local funcs = {} + +local stack_mt +stack_mt = { + __index = { + push = function(self, v) + self.n = self.n+1 + self[self.n] = v + end, + pop = function(self) + local v = self[self.n] + self[self.n] = nil + self.n = self.n-1 + return v + end, + top = function(self) + return self[self.n] + end, + get = function(self, i) + if i <= 0 then + return self[self.n + i] + end + return self[i] + end, + is_empty = function(self) + return self.n == 0 + end, + size = function(self) + return self.n + end, + clone = function(self, copy_element) + local stack + if copy_element then + stack = {n = self.n, true} + for i = 1, self.n do + stack[i] = copy_element(self[i]) + end + else + stack, n = self:to_table() + stack.n = n + end + setmetatable(stack, stack_mt) + return stack + end, + to_table = function(self) + local t = {} + for i = 1, self.n do + t[i] = self[i] + end + return t, self.n + end, + to_string = function(self, value_tostring) + if self.n == 0 then + return "empty stack" + end + value_tostring = value_tostring or tostring + local t = {} + for i = 1, self.n do + t[i] = value_tostring(self[i]) + end + return self.n .. " elements; bottom to top: " .. + table.concat(t, ", ") + end, + } +} + +function funcs.create_stack(data) + local stack + if type(data) == "table" + and data.input then + stack = data.input + stack.n = data.n or #data.input + else + -- setting the first element to true makes it ~10 times faster with + -- luajit when the stack always contains less or equal to one element + stack = {n = 0, true} + end + setmetatable(stack, stack_mt) + return stack +end + + +local fifo_mt +fifo_mt = { + __index = { + add = function(self, v) + local n = self.n_in+1 + self.n_in = n + self.sink[n] = v + end, + take = function(self) + local p = self.p_out + if p <= self.n_out then + local v = self.source[p] + self.source[p] = nil + self.p_out = p+1 + return v + end + -- source is empty, swap it with sink + self.source, self.sink = self.sink, self.source + self.n_out = self.n_in + self.n_in = 0 + local v = self.source[1] + self.source[1] = nil + self.p_out = 2 + return v + end, + peek = function(self) + local p = self.p_out + if p <= self.n_out then + return self.source[p] + end + -- source is empty + return self.sink[1] + end, + is_empty = function(self) + return self.n_in == 0 and self.p_out == self.n_out+1 + end, + size = function(self) + return self.n_in + self.n_out - self.p_out + 1 + end, + clone = function(self, copy_element) + local source, n = self:to_table() + if copy_element then + for i = 1, n do + source[i] = copy_element(source[i]) + end + end + local fifo = {n_in = 0, n_out = n, p_out = 1, + sink = {true}, source = source} + setmetatable(fifo, fifo_mt) + return fifo + end, + to_table = function(self) + local t = {} + local k = 1 + for i = self.p_out, self.n_out do + t[k] = self.source[i] + k = k+1 + end + for i = 1, self.n_in do + t[k] = self.sink[i] + k = k+1 + end + return t, k-1 + end, + to_string = function(self, value_tostring) + local size = self:size() + if size == 0 then + return "empty fifo" + end + value_tostring = value_tostring or tostring + local t = self:to_table() + for i = 1, #t do + t[i] = value_tostring(t[i]) + end + return size .. " elements; oldest to newest: " .. + table.concat(t, ", ") + end, + } +} + +function funcs.create_queue(data) + local fifo + if type(data) == "table" + and data.input then + fifo = {n_in = 0, n_out = data.n or #data.input, p_out = 1, + sink = {true}, source = data.input} + else + fifo = {n_in = 0, n_out = 0, p_out = 1, sink = {true}, source = {true}} + end + setmetatable(fifo, fifo_mt) + return fifo +end + + +local function sift_up(binary_heap, i) + local p = math.floor(i / 2) + while p > 0 + and binary_heap.compare(binary_heap[i], binary_heap[p]) do + -- new data has higher priority than its parent + binary_heap[i], binary_heap[p] = binary_heap[p], binary_heap[i] + i = p + p = math.floor(p / 2) + end +end + +local function sift_down(binary_heap, i) + local n = binary_heap.n + while true do + local l = i + i + local r = l+1 + if l > n then + break + end + if r > n then + if binary_heap.compare(binary_heap[l], binary_heap[i]) then + binary_heap[i], binary_heap[l] = binary_heap[l], binary_heap[i] + end + break + end + local preferred_child = + binary_heap.compare(binary_heap[l], binary_heap[r]) and l or r + if not binary_heap.compare(binary_heap[preferred_child], + binary_heap[i]) then + break + end + binary_heap[i], binary_heap[preferred_child] = + binary_heap[preferred_child], binary_heap[i] + i = preferred_child + end +end + +local function build(binary_heap) + for i = math.floor(binary_heap.n / 2), 1, -1 do + sift_down(binary_heap, i) + end +end + +local binary_heap_mt +binary_heap_mt = { + __index = { + peek = function(self) + return self[1] + end, + add = function(self, v) + local i = self.n+1 + self.n = i + self[i] = v + sift_up(self, i) + end, + take = function(self) + local v = self[1] + self[1] = self[self.n] + self[self.n] = nil + self.n = self.n-1 + sift_down(self, 1) + return v + end, + find = function(self, cond) + for i = 1, self.n do + if cond(self[i]) then + return i + end + end + end, + change_element = function(self, v, i) + i = i or 1 + local priority_lower = self.compare(self[i], v) + self[i] = v + if priority_lower then + sift_down(self, i) + elseif i > 1 then + sift_up(self, i) + end + end, + merge = function(self, other) + local n = self.n + for i = 1, other.n do + self[n + i] = other[i] + end + self.n = n + other.n + build(self) + end, + is_empty = function(self) + return self.n == 0 + end, + size = function(self) + return self.n + end, + clone = function(self, copy_element) + local binary_heap, n = self:to_table() + if copy_element then + for i = 1, n do + binary_heap[i] = copy_element(binary_heap[i]) + end + end + binary_heap.n = n + binary_heap.compare = self.compare + setmetatable(binary_heap, binary_heap_mt) + return binary_heap + end, + to_table = function(self) + local t = {} + for i = 1, self.n do + t[i] = self[i] + end + return t, self.n + end, + sort = function(self) + for i = self.n, 1, -1 do + self[i], self[1] = self[1], self[i] + self.n = self.n-1 + sift_down(self, 1) + end + setmetatable(self, nil) + self.compare = nil + end, + to_string = function(self, value_tostring) + if self.n == 0 then + return "empty binary heap" + end + value_tostring = value_tostring or tostring + local t = {} + for i = 1, self.n do + local sep = "" + if i > 1 then + sep = (math.log(i) / math.log(2)) % 1 == 0 and "; " or ", " + end + t[i] = sep .. value_tostring(self[i]) + end + return self.n .. " elements: " .. table.concat(t, "") + end, + } +} + +function funcs.create_binary_heap(data) + local compare = data + if type(data) == "table" then + if data.input then + -- make data.elements a binary heap + local binary_heap = data.input + binary_heap.n = data.n or #binary_heap + binary_heap.compare = data.compare + setmetatable(binary_heap, binary_heap_mt) + if not data.input_sorted then + build(binary_heap) + end + return + end + compare = data.compare + end + local binary_heap = {compare = compare, n = 0, true} + setmetatable(binary_heap, binary_heap_mt) + return binary_heap +end + +return funcs From 13dfb4dea97fc8f4fcf3b0c386bccc9e3079fdaa Mon Sep 17 00:00:00 2001 From: HybridDog Date: Sun, 22 Mar 2020 10:35:13 +0100 Subject: [PATCH 041/366] Add a time limit when placing the nodes --- init.lua | 2 ++ replacer.lua | 61 +++++++++++++++++++++++++++++++++++++----------- settingtypes.txt | 3 +++ 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/init.lua b/init.lua index 6ac73af..b4b8503 100644 --- a/init.lua +++ b/init.lua @@ -74,6 +74,8 @@ replacer.max_charge = 30000 replacer.charge_per_node = 15 -- node count limit replacer.max_nodes = tonumber(minetest.settings:get("replacer.max_nodes") or 3168) +-- Time limit when placing the nodes, in seconds +replacer.max_time = tonumber(minetest.settings:get("replacer.max_time") or 1.0) -- select which recipes to hide (not all combinations make sense) replacer.hide_recipe_basic = diff --git a/replacer.lua b/replacer.lua index 2134d66..9977e97 100644 --- a/replacer.lua +++ b/replacer.lua @@ -28,6 +28,9 @@ replacer.mode_colours[r.modes[2]] = "#54FFAC" replacer.mode_colours[r.modes[3]] = "#9F6200" replacer.mode_colours[r.modes[4]] = "#FF5457" +local path = minetest.get_modpath("replacer") +local datastructures = dofile(path .. "/datastructures.lua") + local is_int = function(value) return type(value) == 'number' and math.floor(value) == value end @@ -82,6 +85,7 @@ function replacer.set_data(stack, node, mode) return metadata end +local discharge_replacer if replacer.has_technic_mod then -- technic still stores data serialized, so this is the nearest we get to current standard function replacer.get_charge(itemstack) @@ -102,6 +106,17 @@ if replacer.has_technic_mod then meta.charge = charge metaRef:set_string('', minetest.serialize(meta)) end + + function discharge_replacer(creative_enabled, has_give, charge, itemstack, + num_nodes) + if not technic.creative_mode and not (creative_enabled or has_give) then + charge = charge - replacer.charge_per_node * num_nodes + r.set_charge(itemstack, charge, replacer.max_charge) + return itemstack + end + end +else + function discharge_replacer() end end replacer.form_name_modes = "replacer_replacer_mode_change" @@ -225,14 +240,14 @@ function replacer.replace(itemstack, user, pt, right_clicked) if (not user) or (not pt) then return end - + local keys = user:get_player_control() local name = user:get_player_name() local creative_enabled = creative.is_enabled_for(name) local has_give = minetest.check_player_privs(name, "give") local is_technic = itemstack:get_name() == replacer.tool_name_technic local modes_are_available = is_technic or has_give or creative_enabled - + -- is special-key held? (aka fast-key) if keys.aux1 then if not modes_are_available then return itemstack end @@ -273,7 +288,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) if not modes_are_available then mode = r.modes[1] end - + if r.modes[1] == mode then -- single local succ, err = replacer.replace_single_node(pos, node_toreplace, nnd, user, @@ -376,21 +391,39 @@ function replacer.replace(itemstack, user, pt, right_clicked) end -- set nodes + local t_start = minetest.get_us_time() + -- TODO + local max_time_us = 1000000 * replacer.max_time + -- Turn ps into a binary heap + datastructures.create_binary_heap({ + input = ps, + n = num, + compare = function(pos1, pos2) + -- Return true iff pos1 is nearer to the start position than pos2 + local n1 = (pos1.x - pos.x) ^ 2 + (pos1.y - pos.y) ^ 2 + + (pos1.z - pos.z) ^ 2 + local n2 = (pos2.x - pos.x) ^ 2 + (pos2.y - pos.y) ^ 2 + + (pos2.z - pos.z) ^ 2 + return n1 < n2 + end, + }) local inv = user:get_inventory() - for i = 1, num do - local pos = ps[i] + local num_nodes = 0 + while not ps:is_empty() do + num_nodes = num_nodes+1 + -- Take the position nearest to the start position + local pos = ps:take() local succ, err = r.replace_single_node(pos, minetest.get_node(pos), nnd, user, name, inv, creative_enabled) if not succ then r.inform(name, err) - if replacer.has_technic_mod and (not technic.creative_mode) then - if not (creative_enabled or has_give) then - charge = charge - replacer.charge_per_node * i - r.set_charge(itemstack, charge, replacer.max_charge) - return itemstack - end - end - return + return discharge_replacer(creative_enabled, has_give, charge, + itemstack, num_nodes) + end + if minetest.get_us_time() - t_start > max_time_us then + r.inform(name, "Too much time has elapsed") + return discharge_replacer(creative_enabled, has_give, charge, + itemstack, num_nodes) end end @@ -448,7 +481,7 @@ function replacer.common_on_place(itemstack, placer, pt) local node, mode = r.get_data(itemstack) node = minetest.get_node_or_nil(pt.under) or node - + if not modes_are_available then mode = r.modes[1] end diff --git a/settingtypes.txt b/settingtypes.txt index 20f58d3..1449ef3 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -3,6 +3,9 @@ # On singleplayer you can mostly use a higher value. # The default is 3168 replacer.max_nodes (Maximum nodes to replace with one click) int 3168 +# Some nodes take a long time to be placed. This value limits the time +# in seconds in which the nodes are placed. +replacer.max_time (Time limit when putting nodes) float 1.0 # You may choose to hide basic recipe but then make sure to enable the technic direct one replacer.hide_recipe_basic (Hide basic recipe) bool false # Hide the upgrade recipe. Only available if technic is installed. From e8847a7f0b8859c31997736b76aa9581daf5bba8 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Wed, 25 Mar 2020 21:39:22 +0100 Subject: [PATCH 042/366] cleanup --- datastructures.lua | 40 ++++++++++++++++++++-------------------- replacer.lua | 5 ++--- replacer_blabla.lua | 2 +- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/datastructures.lua b/datastructures.lua index 588d437..ac07f67 100644 --- a/datastructures.lua +++ b/datastructures.lua @@ -4,13 +4,13 @@ local stack_mt stack_mt = { __index = { push = function(self, v) - self.n = self.n+1 + self.n = self.n + 1 self[self.n] = v end, pop = function(self) local v = self[self.n] self[self.n] = nil - self.n = self.n-1 + self.n = self.n - 1 return v end, top = function(self) @@ -31,7 +31,7 @@ stack_mt = { clone = function(self, copy_element) local stack if copy_element then - stack = {n = self.n, true} + stack = { n = self.n, true } for i = 1, self.n do stack[i] = copy_element(self[i]) end @@ -73,7 +73,7 @@ function funcs.create_stack(data) else -- setting the first element to true makes it ~10 times faster with -- luajit when the stack always contains less or equal to one element - stack = {n = 0, true} + stack = { n = 0, true } end setmetatable(stack, stack_mt) return stack @@ -84,7 +84,7 @@ local fifo_mt fifo_mt = { __index = { add = function(self, v) - local n = self.n_in+1 + local n = self.n_in + 1 self.n_in = n self.sink[n] = v end, @@ -93,7 +93,7 @@ fifo_mt = { if p <= self.n_out then local v = self.source[p] self.source[p] = nil - self.p_out = p+1 + self.p_out = p + 1 return v end -- source is empty, swap it with sink @@ -114,7 +114,7 @@ fifo_mt = { return self.sink[1] end, is_empty = function(self) - return self.n_in == 0 and self.p_out == self.n_out+1 + return self.n_in == 0 and self.p_out == self.n_out + 1 end, size = function(self) return self.n_in + self.n_out - self.p_out + 1 @@ -126,8 +126,8 @@ fifo_mt = { source[i] = copy_element(source[i]) end end - local fifo = {n_in = 0, n_out = n, p_out = 1, - sink = {true}, source = source} + local fifo = { n_in = 0, n_out = n, p_out = 1, + sink = { true }, source = source } setmetatable(fifo, fifo_mt) return fifo end, @@ -136,13 +136,13 @@ fifo_mt = { local k = 1 for i = self.p_out, self.n_out do t[k] = self.source[i] - k = k+1 + k = k + 1 end for i = 1, self.n_in do t[k] = self.sink[i] - k = k+1 + k = k + 1 end - return t, k-1 + return t, k - 1 end, to_string = function(self, value_tostring) local size = self:size() @@ -164,10 +164,10 @@ function funcs.create_queue(data) local fifo if type(data) == "table" and data.input then - fifo = {n_in = 0, n_out = data.n or #data.input, p_out = 1, - sink = {true}, source = data.input} + fifo = { n_in = 0, n_out = data.n or #data.input, p_out = 1, + sink = { true }, source = data.input } else - fifo = {n_in = 0, n_out = 0, p_out = 1, sink = {true}, source = {true}} + fifo = { n_in = 0, n_out = 0, p_out = 1, sink = { true }, source = { true } } end setmetatable(fifo, fifo_mt) return fifo @@ -189,7 +189,7 @@ local function sift_down(binary_heap, i) local n = binary_heap.n while true do local l = i + i - local r = l+1 + local r = l + 1 if l > n then break end @@ -224,7 +224,7 @@ binary_heap_mt = { return self[1] end, add = function(self, v) - local i = self.n+1 + local i = self.n + 1 self.n = i self[i] = v sift_up(self, i) @@ -233,7 +233,7 @@ binary_heap_mt = { local v = self[1] self[1] = self[self.n] self[self.n] = nil - self.n = self.n-1 + self.n = self.n - 1 sift_down(self, 1) return v end, @@ -290,7 +290,7 @@ binary_heap_mt = { sort = function(self) for i = self.n, 1, -1 do self[i], self[1] = self[1], self[i] - self.n = self.n-1 + self.n = self.n - 1 sift_down(self, 1) end setmetatable(self, nil) @@ -330,7 +330,7 @@ function funcs.create_binary_heap(data) end compare = data.compare end - local binary_heap = {compare = compare, n = 0, true} + local binary_heap = { compare = compare, n = 0, true } setmetatable(binary_heap, binary_heap_mt) return binary_heap end diff --git a/replacer.lua b/replacer.lua index cfd4e68..bdc0360 100644 --- a/replacer.lua +++ b/replacer.lua @@ -107,7 +107,7 @@ if replacer.has_technic_mod then function discharge_replacer(creative_enabled, has_give, charge, itemstack, num_nodes) - if not technic.creative_mode and not (creative_enabled or has_give) then + if (not technic.creative_mode) and (not (creative_enabled or has_give)) then charge = charge - replacer.charge_per_node * num_nodes r.set_charge(itemstack, charge, replacer.max_charge) return itemstack @@ -141,7 +141,6 @@ function replacer.get_form_modes(current_mode) else formspec = formspec .. "mode;" .. r.modes[3] .. "]" end - -- TODO: enable mode when it is available return formspec end -- get_form_modes @@ -407,7 +406,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) itemstack, num_nodes) end if minetest.get_us_time() - t_start > max_time_us then - r.inform(name, "Too much time has elapsed") + r.inform(name, rb.timed_out) return discharge_replacer(creative_enabled, has_give, charge, itemstack, num_nodes) end diff --git a/replacer_blabla.lua b/replacer_blabla.lua index b3d3d4b..3a7c36a 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -28,4 +28,4 @@ replacer.blabla.description_technic = "Node replacement tool (technic)" replacer.blabla.limit_override = 'Setting already set node-limit for "%s" was %d.' replacer.blabla.limit_insert = 'Setting node-limit for "%s" to %d.' replacer.blabla.blacklist_insert = 'Blacklisted "%s".' - +replacer.blabla.timed_out = 'Time-limit reached.' From f7c746484c26a824b853ee8feed80b6a81e0f958 Mon Sep 17 00:00:00 2001 From: HybridDog Date: Thu, 26 Mar 2020 15:07:43 +0100 Subject: [PATCH 043/366] Add documentation I've added information about the replacer modes; I hope that the images uploaded to github comments do not disappear. API information can be added later in another file. --- README.md | 1 + doc/usage.md | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 doc/usage.md diff --git a/README.md b/README.md index c8c9bf1..0160dfe 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ This is true for users without "give" privs and also on servers not running in c Special-right-click on a node or special-left-click anywhere to change the mode. Single-mode does not need any charge. The other modes do. +For a description of the modes with pictures, refer to doc/usage.md. # Inspection tool diff --git a/doc/usage.md b/doc/usage.md new file mode 100644 index 0000000..8c14999 --- /dev/null +++ b/doc/usage.md @@ -0,0 +1,40 @@ + +## Replacer Modes + +Situation: the player points at a node and wants to use the replacer.
+* Bright blue: the ray of sight and pointed thing above and under +* Different nodes: + * White: air + * Dark grey: a solid node which should be replaced + * Brown: another solid node adjacent to the grey one + * Yellow green: a translucent node, such as leaves or glass + * Red (in later pictures): the node which the replacer (re)places +* The black thing: it should depict an eye for the camera position. +![replacer_template](https://user-images.githubusercontent.com/3192173/74016149-36b36200-4992-11ea-86d1-2d3b64035557.png) + + + +### Single Mode + +Left click: +![replacer_single_leftclick](https://user-images.githubusercontent.com/3192173/74015937-e1775080-4991-11ea-912b-4f4e75c53918.png) + +Right click: +![replacer_single_rightclick](https://user-images.githubusercontent.com/3192173/74015939-e20fe700-4991-11ea-9e4d-8f8c8900024d.png) + +### Field Mode + +The replacer changes nodes in a 2D slice (it is 1D in these illustrations). +Left click: +![replacer_field_leftclick](https://user-images.githubusercontent.com/3192173/74015955-e63c0480-4991-11ea-95b9-4b312bc62ed1.png) +Right click: +![replacer_field_rightclick](https://user-images.githubusercontent.com/3192173/74015933-e0deba00-4991-11ea-8321-de9c0499dcf3.png) + +### Crust Mode + +Left click: the replacer changes visually adjacent nodes (of the same type) on a surface +![replacer_crust_leftclick](https://user-images.githubusercontent.com/3192173/74015951-e5a36e00-4991-11ea-8cdf-f8b1c8897da9.png) + +Right click: the replacer places nodes onto the surface so that the surface below it is hidden; the added crust can be bounded by other solid nodes but not translucent nodes +![replacer_crust_rightclick](https://user-images.githubusercontent.com/3192173/74015954-e63c0480-4991-11ea-956c-ee6848c182be.png) + From 38d250e625d812f860248ca73e77ebe31a94adc1 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Tue, 12 May 2020 16:30:06 +0200 Subject: [PATCH 044/366] Fixes crash when using trellis as item --- replacer.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/replacer.lua b/replacer.lua index bdc0360..718823a 100644 --- a/replacer.lua +++ b/replacer.lua @@ -193,7 +193,11 @@ function replacer.replace_single_node(pos, node, nnd, player, name, inv, creativ -- (other than the pointed_thing) local newitem, succ = new_ndef.on_place(ItemStack(nnd.name), player, { type = "node", under = vector.new(pos), above = vector.new(pos) }) - if false == succ then + -- replacing with trellis set, succ is returned but newitem is nil + -- possible that other nodes react the same way. + -- this allows users to dig nodes, I don't see reason to stop that + -- as long as no crash occurs - SwissalpS + if (false == succ) or (nil == newitem) then return false, rb.can_not_place:format(nnd.name) end From 56b2dc00d87b5e99b435b35f64275f9a54a273bb Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 15 Oct 2020 02:11:42 +0200 Subject: [PATCH 045/366] first pass --- inspect.lua | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/inspect.lua b/inspect.lua index 4648a74..95a8b5a 100644 --- a/inspect.lua +++ b/inspect.lua @@ -52,7 +52,7 @@ replacer.inspect = function(_, user, pointed_thing, mode, show_receipe) local text = 'This is ' local ref = pointed_thing.ref if (not(ref)) then - text = text..'a broken object. We have no further information about it. It is located' + text = text..'a broken object. We have no further information about it.\nIt is located' elseif (ref:is_player()) then text = text..'your fellow player \"'..tostring(ref:get_player_name())..'\"' else @@ -82,8 +82,8 @@ replacer.inspect = function(_, user, pointed_thing, mode, show_receipe) minetest.chat_send_player(name, text) return nil elseif (pointed_thing.type ~= 'node') then - minetest.chat_send_player(name, 'Sorry. This is an unkown something of type \"'.. - tostring(pointed_thing.type)..'\". No information available.') + minetest.chat_send_player(name, 'Sorry. This is an unkown something of type\n\"'.. + tostring(pointed_thing.type)..'\".\nNo information available.') return nil end @@ -91,14 +91,14 @@ replacer.inspect = function(_, user, pointed_thing, mode, show_receipe) local node = minetest.get_node_or_nil(pos) if (node == nil) then - minetest.chat_send_player(name, "Error: Target node not yet loaded. Please wait a moment for the server to catch up.") + minetest.chat_send_player(name, "Error: Target node not yet loaded.\nPlease wait a moment for the server to catch up.") return nil end local text = ' ['..tostring(node.name)..'] with param2='..tostring(node.param2).. ' at '..minetest.pos_to_string(pos)..'.' if (not(minetest.registered_nodes[node.name])) then - text = 'This node is an UNKOWN block'..text + text = 'This node is UNKOWN'..text else text = 'This is a \"'..tostring(minetest.registered_nodes[node.name].description or ' - no description provided -')..'\" block'..text @@ -256,11 +256,11 @@ replacer.inspect_show_crafting = function(name, node_name, fields) if ( minetest.registered_nodes[node_name]) then if ( minetest.registered_nodes[node_name].description and minetest.registered_nodes[node_name].description~= "") then - desc = "\""..minetest.registered_nodes[node_name].description.."\" block" + desc = "\""..minetest.registered_nodes[node_name].description.."\" node" elseif (minetest.registered_nodes[node_name].name) then - desc = "\""..minetest.registered_nodes[node_name].name.."\" block" + desc = "\""..minetest.registered_nodes[node_name].name.."\" node" else - desc = " - no description provided - block" + desc = " - no description provided - node" end elseif (minetest.registered_items[node_name]) then if ( minetest.registered_items[node_name].description @@ -293,7 +293,7 @@ replacer.inspect_show_crafting = function(name, node_name, fields) formspec = formspec.." with param2="..tostring(fields.param2) end if (fields.light) then - formspec = formspec.." and receiving "..tostring(fields.light).." light" + formspec = formspec.."\nand receiving "..tostring(fields.light).." light" end formspec = formspec..".]" end From 823c782a701bf3443c8938ba97b3434a068c4a31 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Thu, 15 Oct 2020 05:44:13 +0200 Subject: [PATCH 046/366] general cleanup --- inspect.lua | 466 +++++++++++++++++++++++++++++----------------------- 1 file changed, 257 insertions(+), 209 deletions(-) diff --git a/inspect.lua b/inspect.lua index 95a8b5a..a5fd357 100644 --- a/inspect.lua +++ b/inspect.lua @@ -2,127 +2,122 @@ replacer.image_replacements = {} -- support for RealTest -if (minetest.get_modpath("trees") - and minetest.get_modpath("core") - and minetest.get_modpath("instruments") - and minetest.get_modpath("anvil") - and minetest.get_modpath("scribing_table")) then - - replacer.image_replacements["group:planks"] = "trees:pine_planks" - replacer.image_replacements["group:plank"] = "trees:pine_plank" - replacer.image_replacements["group:wood"] = "trees:pine_planks" - replacer.image_replacements["group:tree"] = "trees:pine_log" - replacer.image_replacements["group:sapling"] = "trees:pine_sapling" - replacer.image_replacements["group:leaves"] = "trees:pine_leaves" - replacer.image_replacements["default:furnace"] = "oven:oven" - replacer.image_replacements["default:furnace_active"] = "oven:oven_active" +if minetest.get_modpath('trees') + and minetest.get_modpath('core') + and minetest.get_modpath('instruments') + and minetest.get_modpath('anvil') + and minetest.get_modpath('scribing_table') +then + replacer.image_replacements['group:planks'] = 'trees:pine_planks' + replacer.image_replacements['group:plank'] = 'trees:pine_plank' + replacer.image_replacements['group:wood'] = 'trees:pine_planks' + replacer.image_replacements['group:tree'] = 'trees:pine_log' + replacer.image_replacements['group:sapling'] = 'trees:pine_sapling' + replacer.image_replacements['group:leaves'] = 'trees:pine_leaves' + replacer.image_replacements['default:furnace'] = 'oven:oven' + replacer.image_replacements['default:furnace_active'] = 'oven:oven_active' end -minetest.register_tool("replacer:inspect", -{ - description = "Node inspection tool", +minetest.register_tool('replacer:inspect', { + description = 'Node inspection tool', groups = {}, - inventory_image = "replacer_inspect.png", - wield_image = "", - wield_scale = {x=1,y=1,z=1}, + inventory_image = 'replacer_inspect.png', + wield_image = '', + wield_scale = { x = 1,y = 1,z = 1 }, liquids_pointable = true, -- it is ok to request information about liquids on_use = function(itemstack, user, pointed_thing) - return replacer.inspect(itemstack, user, pointed_thing, nil, true) --false) + return replacer.inspect(itemstack, user, pointed_thing) end, on_place = function(itemstack, placer, pointed_thing) - return replacer.inspect(itemstack, placer, pointed_thing, nil, true) + return replacer.inspect(itemstack, placer, pointed_thing) end, }) -replacer.inspect = function(_, user, pointed_thing, mode, show_receipe) - - if (user == nil or pointed_thing == nil) then +replacer.inspect = function(_, user, pointed_thing, mode) + if nil == user or nil == pointed_thing then return nil end local name = user:get_player_name() local keys = user:get_player_control() - if (keys["sneak"]) then - show_receipe = true - end - if (pointed_thing.type == 'object') then + if 'object' == pointed_thing.type then local text = 'This is ' local ref = pointed_thing.ref - if (not(ref)) then - text = text..'a broken object. We have no further information about it.\nIt is located' - elseif (ref:is_player()) then - text = text..'your fellow player \"'..tostring(ref:get_player_name())..'\"' + if not ref then + text = text .. 'a broken object. We have no further information ' + .. 'about it. It is located' + elseif ref:is_player() then + text = text .. 'your fellow player "' .. ref:get_player_name() .. '"' else local luaob = ref:get_luaentity() - if( luaob and luaob.get_staticdata) then - text = text..'entity \"'..tostring( luaob.name )..'\"' + if luaob and luaob.get_staticdata then + text = text .. 'entity "' .. luaob.name .. '"' local sdata = luaob:get_staticdata() - if (0 < #sdata) then + if 0 < #sdata then sdata = minetest.deserialize(sdata) or {} - if (sdata.itemstring) then - text = text..' ['..tostring(sdata.itemstring)..']' - if (show_receipe) then - -- the fields part is used here to provide additional information about the entity - replacer.inspect_show_crafting(name, sdata.itemstring, { luaob=luaob}) + if sdata.itemstring then + text = text .. ' [' .. sdata.itemstring .. ']' + if show_receipe then + -- the fields part is used here to provide + -- additional information about the entity + replacer.inspect_show_crafting( + name, + sdata.itemstring, + { luaob = luaob }) end end - if (sdata.age) then - text = text..', dropped '..tostring(math.floor(sdata.age/60))..' minutes ago' + if sdata.age then + text = text .. ', dropped ' + .. tostring(math.floor(sdata.age / 60)) + .. ' minutes ago' end end else - text = text..'object \"'..tostring(ref:get_entity_name())..'\"' + text = text .. 'object "' .. ref:get_entity_name() .. '"' end end - text = text..' at '..minetest.pos_to_string(ref:getpos()) + text = text .. ' at ' .. minetest.pos_to_string(ref:getpos()) minetest.chat_send_player(name, text) return nil - elseif (pointed_thing.type ~= 'node') then - minetest.chat_send_player(name, 'Sorry. This is an unkown something of type\n\"'.. - tostring(pointed_thing.type)..'\".\nNo information available.') + elseif 'node' ~= pointed_thing.type then + minetest.chat_send_player(name, 'Sorry, this is an unkown something ' + .. 'of type "' .. pointed_thing.type .. '". ' + .. 'No information available.') return nil end local pos = minetest.get_pointed_thing_position(pointed_thing, mode) local node = minetest.get_node_or_nil(pos) - if (node == nil) then - minetest.chat_send_player(name, "Error: Target node not yet loaded.\nPlease wait a moment for the server to catch up.") + if not node then + minetest.chat_send_player(name, 'Error: Target node not yet loaded. ' + .. 'Please wait a moment for the server to catch up.') return nil end - local text = ' ['..tostring(node.name)..'] with param2='..tostring(node.param2).. - ' at '..minetest.pos_to_string(pos)..'.' - if (not(minetest.registered_nodes[node.name])) then - text = 'This node is UNKOWN'..text - else - text = 'This is a \"'..tostring(minetest.registered_nodes[node.name].description or - ' - no description provided -')..'\" block'..text - end - local protected_info = "" - if (minetest.is_protected( pos, name)) then + local protected_info = '' + if minetest.is_protected(pos, name) then protected_info = 'WARNING: You can\'t dig this node. It is protected.' - elseif (minetest.is_protected(pos, '_THIS_NAME_DOES_NOT_EXIST_')) then + elseif minetest.is_protected(pos, '_THIS_NAME_DOES_NOT_EXIST_') then protected_info = 'INFO: You can dig this node, but others can\'t.' end - text = text..' '..protected_info --- no longer spam the chat; the craft guide is more informative --- minetest.chat_send_player(name, text) - if (show_receipe) then -- get light of the node at the current time - local light = minetest.get_node_light(pos, nil) - if (light==0) then - light = minetest.get_node_light({x=pos.x,y=pos.y+1,z=pos.z}) - end - -- the fields part is used here to provide additional information about the node - replacer.inspect_show_crafting(name, node.name, {pos=pos, param2=node.param2, light=light, protected_info=protected_info}) + local light = minetest.get_node_light(pos, nil) + if 0 == light then + light = minetest.get_node_light({ x = pos.x, y = pos.y + 1, z = pos.z }) end - return nil; -- no item shall be removed from inventory + -- the fields part is used here to provide additional + -- information about the node + replacer.inspect_show_crafting(name, node.name, { + pos = pos, param2 = node.param2, light = light, + protected_info = protected_info }) + + return nil -- no item shall be removed from inventory end -- some common groups @@ -131,7 +126,8 @@ replacer.group_placeholder['group:wood'] = 'default:wood' replacer.group_placeholder['group:tree'] = 'default:tree' replacer.group_placeholder['group:sapling']= 'default:sapling' replacer.group_placeholder['group:stick'] = 'default:stick' -replacer.group_placeholder['group:stone'] = 'default:cobble' -- 'default:stone' point people to the cheaper cobble +-- 'default:stone' point people to the cheaper cobble +replacer.group_placeholder['group:stone'] = 'default:cobble' replacer.group_placeholder['group:sand'] = 'default:sand' replacer.group_placeholder['group:leaves'] = 'default:leaves' replacer.group_placeholder['group:wood_slab'] = 'stairs:slab_wood' @@ -139,48 +135,52 @@ replacer.group_placeholder['group:wool'] = 'wool:white' -- handle the standard dye color groups -if (minetest.get_modpath("dye") and dye and dye.basecolors) then - for i,color in ipairs(dye.basecolors) do - local def = minetest.registered_items["dye:"..color] - if (def and def.groups) then - for k,v in pairs(def.groups) do - if (k ~= 'dye') then - replacer.group_placeholder['group:dye,'..k] = 'dye:'..color +if minetest.get_modpath('dye') and dye and dye.basecolors then + for i, color in ipairs(dye.basecolors) do + local def = minetest.registered_items['dye:' .. color] + if def and def.groups then + for k, v in pairs(def.groups) do + if 'dye' ~= k then + replacer.group_placeholder['group:dye,' .. k] = 'dye:' .. color end end - replacer.group_placeholder['group:flower,color_'..color] = 'dye:'..color + replacer.group_placeholder['group:flower,color_' .. color] = 'dye:' .. color end end end replacer.image_button_link = function(stack_string) local group = '' - if (replacer.image_replacements[stack_string]) then + if replacer.image_replacements[stack_string] then stack_string = replacer.image_replacements[stack_string] end - if (replacer.group_placeholder[stack_string]) then + if replacer.group_placeholder[stack_string] then stack_string = replacer.group_placeholder[stack_string] group = 'G' end -- TODO: show information about other groups not handled above local stack = ItemStack(stack_string) - local new_node_name = stack_string - if (stack and stack:get_name()) then - new_node_name = stack:get_name() - end - return tostring(stack_string)..';'..tostring(new_node_name)..';'..group + local new_node_name = stack:get_name() + return stack_string .. ';' .. new_node_name .. ';' .. group end replacer.add_circular_saw_receipe = function(node_name, receipes) - if (not(node_name) or not(minetest.get_modpath("moreblocks")) or not(circular_saw) or not(circular_saw.names) or (node_name=='moreblocks:circular_saw')) then + if not node_name + or not minetest.get_modpath('moreblocks') + or not circular_saw or not circular_saw.names + or 'moreblocks:circular_saw' == node_name + then return end local help = node_name:split(':') - if (not(help) or #help ~= 2 or help[1]=='stairs') then + if not help or 2 ~= #help or 'stairs' == help[1] then return end - help2 = help[2]:split('_') - if (not(help2) or #help2 < 2 or (help2[1]~='micro' and help2[1]~='panel' and help2[1]~='stair' and help2[1]~='slab')) then + local help2 = help[2]:split('_') + if not help2 or 2 > #help2 + or ('micro' ~= help2[1] and 'panel' ~= help2[1] and 'stair' ~= help2[1] + and 'slab' ~= help2[1]) + then return end -- for i,v in ipairs(circular_saw.names) do @@ -188,35 +188,46 @@ replacer.add_circular_saw_receipe = function(node_name, receipes) -- TODO: write better and more correct method of getting the names of the materials -- TODO: make sure only nodes produced by the saw are listed here -help[1]='default' - local basic_node_name = help[1]..':'..help2[2] + help[1] = 'default' + local basic_node_name = help[1] .. ':' .. help2[2] -- node found that fits into the saw - receipes[#receipes+1] = { method = 'saw', type = 'saw', items = { basic_node_name}, output = node_name} + receipes[#receipes + 1] = { + method = 'saw', + type = 'saw', + items = { basic_node_name }, + output = node_name + } return receipes end + replacer.add_colormachine_receipe = function(node_name, receipes) - if (not(minetest.get_modpath("colormachine")) or not(colormachine)) then + if not minetest.get_modpath('colormachine') or not colormachine then return end - local res = colormachine.get_node_name_painted(node_name, "") + local res = colormachine.get_node_name_painted(node_name, '') - if (not(res) or not(res.possible) or #res.possible < 1) then + if not res or not res.possible or 1 > #res.possible then return end -- paintable node found - receipes[#receipes+1] = { method = 'colormachine', type = 'colormachine', items = { res.possible[1]}, output = node_name} + receipes[#receipes + 1] = { + method = 'colormachine', + type = 'colormachine', + items = { res.possible[1] }, + output = node_name + } return receipes end replacer.inspect_show_crafting = function(name, node_name, fields) - if (not(name)) then + if not name then return end local receipe_nr = 1 - if (not(node_name)) then + if not node_name then node_name = fields.node_name receipe_nr = tonumber(fields.receipe_nr) end @@ -225,12 +236,14 @@ replacer.inspect_show_crafting = function(name, node_name, fields) node_name = stack:get_name() -- the player may ask for receipes of indigrents to the current receipe - if (fields) then - for k,v in pairs(fields) do - if (v and v=="" and (minetest.registered_items[k] - or minetest.registered_nodes[k] - or minetest.registered_craftitems[k] - or minetest.registered_tools[k])) then + if fields then + for k, v in pairs(fields) do + if v and '' == v + and minetest.registered_items[k] + or minetest.registered_nodes[k] + or minetest.registered_craftitems[k] + or minetest.registered_tools[k] + then node_name = k receipe_nr = 1 end @@ -238,7 +251,7 @@ replacer.inspect_show_crafting = function(name, node_name, fields) end local res = minetest.get_all_craft_recipes(node_name) - if (not(res)) then + if not res then res = {} end -- add special receipes for nodes created by machines @@ -246,149 +259,184 @@ replacer.inspect_show_crafting = function(name, node_name, fields) replacer.add_colormachine_receipe(node_name, res) -- offer all alternate creafting receipes thrugh prev/next buttons - if ( fields and fields.prev_receipe and receipe_nr > 1) then + if fields and fields.prev_receipe and 1 < receipe_nr then receipe_nr = receipe_nr - 1 - elseif (fields and fields.next_receipe and receipe_nr < #res) then + elseif fields and fields.next_receipe and receipe_nr < #res then receipe_nr = receipe_nr + 1 end - local desc = nil - if ( minetest.registered_nodes[node_name]) then - if ( minetest.registered_nodes[node_name].description - and minetest.registered_nodes[node_name].description~= "") then - desc = "\""..minetest.registered_nodes[node_name].description.."\" node" - elseif (minetest.registered_nodes[node_name].name) then - desc = "\""..minetest.registered_nodes[node_name].name.."\" node" + local desc = ' - no description provided - ' + if minetest.registered_nodes[node_name] then + if minetest.registered_nodes[node_name].description + and '' ~= minetest.registered_nodes[node_name].description + then + desc = minetest.registered_nodes[node_name].description + elseif minetest.registered_nodes[node_name].name then + desc = minetest.registered_nodes[node_name].name else - desc = " - no description provided - node" + desc = ' - no node description provided - ' end - elseif (minetest.registered_items[node_name]) then - if ( minetest.registered_items[node_name].description - and minetest.registered_items[node_name].description~= "") then - desc = "\""..minetest.registered_items[node_name].description.."\" item" - elseif (minetest.registered_items[node_name].name) then - desc = "\""..minetest.registered_items[node_name].name.."\" item" + elseif minetest.registered_items[node_name] then + if minetest.registered_items[node_name].description + and '' ~= minetest.registered_items[node_name].description + then + desc = minetest.registered_items[node_name].description + elseif minetest.registered_items[node_name].name then + desc = minetest.registered_items[node_name].name else - desc = " - no description provided - item" + desc = ' - no item description provided - ' end end - if (not(desc) or desc=="") then - desc = ' - no description provided - ' - end - local formspec = "size[6,6]".. - "label[0,5.5;This is a "..minetest.formspec_escape(desc)..".]".. - "button_exit[5.0,4.3;1,0.5;quit;Exit]".. - "label[0,0;Name:]".. - "field[20,20;0.1,0.1;node_name;node_name;"..node_name.."]".. -- invisible field for passing on information - "field[21,21;0.1,0.1;receipe_nr;receipe_nr;"..tostring(receipe_nr).."]".. -- another invisible field - "label[1,0;"..tostring(node_name).."]".. - "item_image_button[5,2;1.0,1.0;"..tostring(node_name)..";normal;]" - - -- provide additional information regarding the node in particular that has been inspected - if (fields.pos) then - formspec = formspec.."label[0.0,0.3;Located at ".. - minetest.formspec_escape(minetest.pos_to_string(fields.pos)) - if (fields.param2) then - formspec = formspec.." with param2="..tostring(fields.param2) - end - if (fields.light) then - formspec = formspec.."\nand receiving "..tostring(fields.light).." light" - end - formspec = formspec..".]" + local formspec = 'size[6,6]' + .. 'label[0,0;Name: ' .. node_name .. ']' + .. 'item_image_button[5,2;1.0,1.0;' .. node_name .. ';normal;]' + .. 'button_exit[5.0,4.3;1,0.5;quit;Exit]' + .. 'label[0,5.5;This is: ' .. minetest.formspec_escape(desc) .. ']' + -- invisible field for passing on information + .. 'field[20,20;0.1,0.1;node_name;node_name;' .. node_name .. ']' + -- another invisible field + .. 'field[21,21;0.1,0.1;receipe_nr;receipe_nr;' .. tostring(receipe_nr) .. ']' + + -- provide additional information regarding the node in particular + -- that has been inspected + formspec = formspec .. 'label[0.0,0.3;' + if fields.pos then + formspec = formspec .. 'Located at ' + .. minetest.formspec_escape(minetest.pos_to_string(fields.pos)) + end + if fields.param2 then + formspec = formspec .. ' with param2 of ' .. tostring(fields.param2) + end + formspec = formspec .. ']' + if fields.light then + formspec = formspec .. 'label[0.0,0.6;and receiving ' + .. tostring(fields.light) .. ' light]' end -- show information about protection - if (fields.protected_info and fields.protected_info ~= "") then - formspec = formspec.."label[0.0,4.5;"..minetest.formspec_escape(fields.protected_info).."]" + if fields.protected_info and '' ~= fields.protected_info then + formspec = formspec .. 'label[0.0,4.5;' + .. minetest.formspec_escape(fields.protected_info) .. ']' end - if (not(res) or receipe_nr > #res or receipe_nr < 1) then + if #res < receipe_nr or 1 > receipe_nr then receipe_nr = 1 end - if (res and receipe_nr > 1) then - formspec = formspec.."button[3.8,5;1,0.5;prev_receipe;prev]" + if 1 < receipe_nr then + formspec = formspec .. 'button[3.8,5;1,0.5;prev_receipe;prev]' end - if (res and receipe_nr < #res) then - formspec = formspec.."button[5.0,5.0;1,0.5;next_receipe;next]" + if #res > receipe_nr then + formspec = formspec .. 'button[5.0,5.0;1,0.5;next_receipe;next]' end - if (not(res) or #res<1) then - formspec = formspec..'label[3,1;No receipes.]' - if (minetest.registered_nodes[node_name] - and minetest.registered_nodes[node_name].drop) then + if 1 > #res then + formspec = formspec .. 'label[3,1;No receipes.]' + if minetest.registered_nodes[node_name] + and minetest.registered_nodes[node_name].drop + then local drop = minetest.registered_nodes[node_name].drop - if (drop) then - if ( type(drop)=='string' and drop ~= node_name) then - formspec = formspec.."label[2,1.6;Drops on dig:]".. - "item_image_button[2,2;1.0,1.0;"..replacer.image_button_link(drop).."]" - elseif (type(drop)=='table' and drop.items) then - local droplist = {} - for _,drops in ipairs(drop.items) do - for _,item in ipairs(drops.items) do - -- avoid duplicates; but include the item itshelf - droplist[item] = 1 - end - end - local i = 1 - formspec = formspec.."label[2,1.6;May drop on dig:]" - for k,v in pairs(droplist) do - formspec = formspec.. - "item_image_button["..(((i-1)%3)+1)..","..math.floor(((i-1)/3)+2)..";1.0,1.0;"..replacer.image_button_link(k).."]" - i = i+1 + if 'string' == type(drop) and drop ~= node_name then + formspec = formspec .. 'label[2,1.6;Drops on dig:]' + .. 'item_image_button[2,2;1.0,1.0;' + .. replacer.image_button_link(drop) .. ']' + elseif 'table' == type(drop) and drop.items then + local droplist = {} + for _, drops in ipairs(drop.items) do + for _,item in ipairs(drops.items) do + -- avoid duplicates; but include the item itshelf + droplist[item] = 1 end end + local i = 1 + formspec = formspec .. 'label[2,1.6;May drop on dig:]' + for k, v in pairs(droplist) do + formspec = formspec .. 'item_image_button[' + .. (((i - 1) % 3) + 1) .. ',' + .. tostring(math.floor(((i - 1) / 3) + 2)) + .. ';1.0,1.0;' .. replacer.image_button_link(k) .. ']' + i = i + 1 + end end end else - formspec = formspec.."label[1,5;Alternate "..tostring(receipe_nr).."/"..tostring(#res).."]" - -- reverse order; default receipes (and thus the most intresting ones) are usually the oldest - local receipe = res[#res+1-receipe_nr] - if (receipe.type=='normal' and receipe.items) then + formspec = formspec .. 'label[1,5;Alternate ' .. tostring(receipe_nr) + .. '/' .. tostring(#res) .. ']' + -- reverse order; default receipes (and thus the most intresting ones) + -- are usually the oldest + local receipe = res[#res + 1 - receipe_nr] + if 'normal' == receipe.type and receipe.items then local width = receipe.width - if (not(width) or width==0) then + if not width or 0 == width then width = 3 end - for i=1,9 do - if (receipe.items[i]) then - formspec = formspec.."item_image_button["..(((i-1)%width)+1)..','..(math.floor((i-1)/width)+1)..";1.0,1.0;".. - replacer.image_button_link(receipe.items[i]).."]" + for i = 1, 9 do + if receipe.items[i] then + formspec = formspec .. 'item_image_button[' + .. (((i - 1) % width) + 1) .. ',' + .. tostring(math.floor((i - 1) / width) + 1) + .. ';1.0,1.0;' + .. replacer.image_button_link(receipe.items[i]) .. ']' end end - elseif (receipe.type=='cooking' and receipe.items and #receipe.items==1 - and receipe.output=="") then - formspec = formspec.."item_image_button[1,1;3.4,3.4;"..replacer.image_button_link('default:furnace_active').."]".. --default_furnace_front.png]".. - "item_image_button[2.9,2.7;1.0,1.0;"..replacer.image_button_link(receipe.items[1]).."]".. - "label[1.0,0;"..tostring(receipe.items[1]).."]".. - "label[0,0.5;This can be used as a fuel.]" - elseif (receipe.type=='cooking' and receipe.items and #receipe.items==1) then - formspec = formspec.."item_image_button[1,1;3.4,3.4;"..replacer.image_button_link('default:furnace').."]".. --default_furnace_front.png]".. - "item_image_button[2.9,2.7;1.0,1.0;"..replacer.image_button_link(receipe.items[1]).."]" - elseif (receipe.type=='colormachine' and receipe.items and #receipe.items==1) then - formspec = formspec.."item_image_button[1,1;3.4,3.4;"..replacer.image_button_link('colormachine:colormachine').."]".. --colormachine_front.png]".. - "item_image_button[2,2;1.0,1.0;"..replacer.image_button_link(receipe.items[1]).."]" - elseif (receipe.type=='saw' and receipe.items and #receipe.items==1) then - --formspec = formspec.."item_image[1,1;3.4,3.4;moreblocks:circular_saw]".. - formspec = formspec.."item_image_button[1,1;3.4,3.4;"..replacer.image_button_link('moreblocks:circular_saw').."]".. - "item_image_button[2,0.6;1.0,1.0;"..replacer.image_button_link(receipe.items[1]).."]" + elseif 'cooking' == receipe.type + and receipe.items + and 1 == #receipe.items + and '' == receipe.output + then + formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' + .. replacer.image_button_link('default:furnace_active') .. ']' + .. 'item_image_button[2.9,2.7;1.0,1.0;' + .. replacer.image_button_link(receipe.items[1]) .. ']' + .. 'label[1.0,0;' .. tostring(receipe.items[1]) .. ']' + .. 'label[0,0.5;This can be used as a fuel.' .. ']' + elseif 'cooking' == receipe.type + and receipe.items + and 1 == #receipe.items + then + formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' + .. replacer.image_button_link('default:furnace') .. ']' + .. 'item_image_button[2.9,2.7;1.0,1.0;' + .. replacer.image_button_link(receipe.items[1]) .. ']' + elseif 'colormachine' == receipe.type + and receipe.items + and 1 == #receipe.items + then + formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' + .. replacer.image_button_link('colormachine:colormachine') .. ']' + .. 'item_image_button[2,2;1.0,1.0;' + .. replacer.image_button_link(receipe.items[1]) .. ']' + elseif 'saw' == receipe.type + and receipe.items + and 1 == #receipe.items + then + formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' + .. replacer.image_button_link('moreblocks:circular_saw') .. ']' + .. 'item_image_button[2,0.6;1.0,1.0;' + .. replacer.image_button_link(receipe.items[1]) .. ']' else - formspec = formspec..'label[3,1;Error: Unkown receipe.]' + formspec = formspec .. 'label[3,1;Error: Unkown receipe.]' end -- show how many of the items the receipe will yield local outstack = ItemStack(receipe.output) - if (outstack and outstack:get_count() and outstack:get_count()>1) then - formspec = formspec..'label[5.5,2.5;'..tostring(outstack:get_count())..']' + local out_count = outstack:get_count() + if 1 < out_count then + formspec = formspec .. 'label[5.5,2.5;' .. tostring(out_count) .. ']' end end - minetest.show_formspec(name, "replacer:crafting", formspec) + minetest.show_formspec(name, 'replacer:crafting', formspec) end -- translate general formspec calls back to specific calls replacer.form_input_handler = function(player, formname, fields) - if (formname and formname == "replacer:crafting" and player and not(fields.quit)) then + if formname and 'replacer:crafting' == formname + and player and not fields.quit + then replacer.inspect_show_crafting(player:get_player_name(), nil, fields) return - end + end end --- establish a callback so that input from the player-specific formspec gets handled +-- establish a callback so that input from the player-specific +-- formspec gets handled minetest.register_on_player_receive_fields(replacer.form_input_handler) + From d162085d93f20e53157cf4fbf20dbab30e6a6d56 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 15 Oct 2020 06:01:09 +0200 Subject: [PATCH 047/366] update changelog --- init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/init.lua b/init.lua index b4b8503..a666a4c 100644 --- a/init.lua +++ b/init.lua @@ -19,6 +19,7 @@ -- Version 3.0 -- Changelog: +-- 15.10.2020 * SwissalpS cleaned up inspector code and made inspector better readable on smaller screens -- * SwissalpS added backward compatibility for non technic servers, restored -- creative/give behaviour and fixed the 'too many nodes detected' issue -- * S-S-X and some players from pandorabox.io requested and inspired ideas to From dd113c6b449c2f5c88a9952bbed944af1a7532ad Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 16 Oct 2020 01:24:38 +0200 Subject: [PATCH 048/366] Create usageField.md --- doc/usageField.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 doc/usageField.md diff --git a/doc/usageField.md b/doc/usageField.md new file mode 100644 index 0000000..e40ee0e --- /dev/null +++ b/doc/usageField.md @@ -0,0 +1,13 @@ +## Field Mode + +The replacer changes nodes in a 2D slice. + +### Left click: + +![field_left_click_2_135844](https://user-images.githubusercontent.com/161979/96177701-8b01df00-0f2e-11eb-92e6-9dab76616fe7.png) +Before is depicted above and after is below +![field_left_click_3_135856](https://user-images.githubusercontent.com/161979/96177702-8b9a7580-0f2e-11eb-9006-c055198092b9.png) + +### Right click: +TODO: + From 13accea6eac709435f95e20a37e44d71a0c5340c Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 16 Oct 2020 01:39:51 +0200 Subject: [PATCH 049/366] Update usageField.md --- doc/usageField.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/usageField.md b/doc/usageField.md index e40ee0e..b308266 100644 --- a/doc/usageField.md +++ b/doc/usageField.md @@ -1,13 +1,17 @@ ## Field Mode -The replacer changes nodes in a 2D slice. ### Left click: +The replacer changes nodes in a 2D slice. ![field_left_click_2_135844](https://user-images.githubusercontent.com/161979/96177701-8b01df00-0f2e-11eb-92e6-9dab76616fe7.png) -Before is depicted above and after is below +Before is depicted above and after is below. ![field_left_click_3_135856](https://user-images.githubusercontent.com/161979/96177702-8b9a7580-0f2e-11eb-9006-c055198092b9.png) ### Right click: -TODO: +The replacer places nodes in a 2D slice onto given surface following contour. + +![field_right_click_0_003725](https://user-images.githubusercontent.com/161979/96196639-2ce5f380-0f50-11eb-8115-4c986cce313f.png) +Before is depicted above and after is below. +![field_right_click_1_003729](https://user-images.githubusercontent.com/161979/96196647-31121100-0f50-11eb-94cc-5e05e44772d9.png) From 1c3f91a72370c73695ec60bb08b55a6f2e0ee319 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 16 Oct 2020 01:46:59 +0200 Subject: [PATCH 050/366] Create usageCrust.md --- doc/usageCrust.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 doc/usageCrust.md diff --git a/doc/usageCrust.md b/doc/usageCrust.md new file mode 100644 index 0000000..2614ec1 --- /dev/null +++ b/doc/usageCrust.md @@ -0,0 +1,15 @@ +## Crust Mode + +### Left click: +The replacer changes visually adjacent nodes (of the same type) on a surface + +Before is depicted above and after is below. + + +### Right click: +The replacer places nodes onto the surface so that the surface below it is hidden; the added crust can be bounded by other solid nodes but not translucent nodes. + +![crust_right_click_0_143612](https://user-images.githubusercontent.com/161979/96177419-28a8de80-0f2e-11eb-8c28-15caa3ea9335.png) +Before is depicted above and after is below. +![crust_right_click_1_143622](https://user-images.githubusercontent.com/161979/96177422-29417500-0f2e-11eb-955c-fcc3213733fd.png) + From 367e3298be55d674f84c5b1ce8983df4ba403a6f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 16 Oct 2020 01:59:46 +0200 Subject: [PATCH 051/366] Update usageCrust.md --- doc/usageCrust.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/usageCrust.md b/doc/usageCrust.md index 2614ec1..8717be5 100644 --- a/doc/usageCrust.md +++ b/doc/usageCrust.md @@ -2,8 +2,9 @@ ### Left click: The replacer changes visually adjacent nodes (of the same type) on a surface - +![crust_left_click_0_015353](https://user-images.githubusercontent.com/161979/96197649-02496a00-0f53-11eb-9538-d809689d51fb.png) Before is depicted above and after is below. +![crust_left_click_1_015402](https://user-images.githubusercontent.com/161979/96197651-02e20080-0f53-11eb-9e72-f1ccecceb09c.png) ### Right click: From 3cdf754edf81853928ce1c81b9717e7933acfe74 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 16 Oct 2020 02:43:37 +0200 Subject: [PATCH 052/366] Create usageSingle.md --- doc/usageSingle.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 doc/usageSingle.md diff --git a/doc/usageSingle.md b/doc/usageSingle.md new file mode 100644 index 0000000..9159eb8 --- /dev/null +++ b/doc/usageSingle.md @@ -0,0 +1,15 @@ +## Single Mode + +### Left click: +The replacer changes visually adjacent nodes (of the same type) on a surface. + + +Before is depicted above and after is below. + + +### Right click: +The replacer places nodes onto the surface so that the surface below it is hidden; the added crust can be bounded by other solid nodes but not translucent nodes. + +![single_right_click_0_023544](https://user-images.githubusercontent.com/161979/96200006-27d97200-0f59-11eb-9928-58491380fe15.png) +Before is depicted above and after is below. +![single_right_click_1_023551](https://user-images.githubusercontent.com/161979/96200007-28720880-0f59-11eb-8606-def11db1a184.png) From bbb95574772b686e7c90b879c78f190943c7d551 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 16 Oct 2020 02:45:41 +0200 Subject: [PATCH 053/366] Update usageSingle.md --- doc/usageSingle.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/usageSingle.md b/doc/usageSingle.md index 9159eb8..fd61416 100644 --- a/doc/usageSingle.md +++ b/doc/usageSingle.md @@ -1,14 +1,14 @@ ## Single Mode ### Left click: -The replacer changes visually adjacent nodes (of the same type) on a surface. +The replacer changes the clicked node. Before is depicted above and after is below. ### Right click: -The replacer places nodes onto the surface so that the surface below it is hidden; the added crust can be bounded by other solid nodes but not translucent nodes. +The replacer places a node onto the surface. ![single_right_click_0_023544](https://user-images.githubusercontent.com/161979/96200006-27d97200-0f59-11eb-9928-58491380fe15.png) Before is depicted above and after is below. From 2296adb90ef5e47414f4215ec2e3ef0e8ee50270 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 16 Oct 2020 02:57:17 +0200 Subject: [PATCH 054/366] Update usageSingle.md --- doc/usageSingle.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/usageSingle.md b/doc/usageSingle.md index fd61416..b6f837a 100644 --- a/doc/usageSingle.md +++ b/doc/usageSingle.md @@ -3,9 +3,9 @@ ### Left click: The replacer changes the clicked node. - +![single_left_click_0_025357](https://user-images.githubusercontent.com/161979/96200805-227d2700-0f5b-11eb-9115-0b4a31cb89cc.png) Before is depicted above and after is below. - +![single_left_click_1_025400](https://user-images.githubusercontent.com/161979/96200806-2315bd80-0f5b-11eb-8d8f-32fa401cde79.png) ### Right click: The replacer places a node onto the surface. From aa9f9cbb9d734e84d8e6899967c0f56813ba2708 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 16 Oct 2020 03:05:35 +0200 Subject: [PATCH 055/366] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0160dfe..8f50fa6 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,10 @@ This is true for users without "give" privs and also on servers not running in c Special-right-click on a node or special-left-click anywhere to change the mode. Single-mode does not need any charge. The other modes do. -For a description of the modes with pictures, refer to doc/usage.md. +For a description of the modes with pictures, refer to [doc/usage.md](doc/usage.md). +* [Single Mode (doc/usageSingle.md)](doc/usageSingle.md) +* [Field Mode (doc/usageField.md)](doc/usageField.md) +* [Crust Mode (doc/usageCrust.md)](doc/usageCrust.md) # Inspection tool From 84c5a873874866d5766057a89151e02215a54c5e Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Sat, 14 Nov 2020 07:46:02 +0100 Subject: [PATCH 056/366] adding some more info in description of tool settings --- replacer.lua | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/replacer.lua b/replacer.lua index 718823a..04c45ea 100644 --- a/replacer.lua +++ b/replacer.lua @@ -73,13 +73,26 @@ end function replacer.set_data(stack, node, mode) mode = mode or r.modes[1] - local metadata = (node.name or replacer.tool_default_node) .. " " - .. tostring(node.param1 or 0) .. " " - .. tostring(node.param2 or 0) + local param1 = tostring(node.param1 or 0) + local param2 = tostring(node.param2 or 0) + local nodeName = node.name or replacer.tool_default_node + local metadata = nodeName .. " " .. param1 .. " " .. param2 local metaRef = stack:get_meta() metaRef:set_string("mode", mode) metaRef:set_string("replacer", metadata) metaRef:set_string("color", r.mode_colours[mode]) + local nodeDescription = nodeName + if minetest.registered_items[node.name] + and minetest.registered_items[node.name].description + then + nodeDescription = minetest.registered_items[node.name].description + end + local toolItemName = stack:get_name() + local toolName = minetest.registered_items[toolItemName].description + local description = toolName .. "\n" + .. param1 .. " " .. param2 .. " " .. nodeDescription -- .. "\n" .. mode + + metaRef:set_string("description", description) return metadata end From 002579df3fff1d726505b5345241b1cdc1e6b34d Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Wed, 18 Nov 2020 04:18:40 +0100 Subject: [PATCH 057/366] nicer layout also chat message improved --- replacer.lua | 10 ++++++---- replacer_blabla.lua | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/replacer.lua b/replacer.lua index 04c45ea..68dbd31 100644 --- a/replacer.lua +++ b/replacer.lua @@ -89,11 +89,13 @@ function replacer.set_data(stack, node, mode) end local toolItemName = stack:get_name() local toolName = minetest.registered_items[toolItemName].description + local short_description = "(" .. param1 .. " " .. param2 .. ") " .. node.name local description = toolName .. "\n" - .. param1 .. " " .. param2 .. " " .. nodeDescription -- .. "\n" .. mode + .. short_description .. "\n" + .. nodeDescription metaRef:set_string("description", description) - return metadata + return short_description end local discharge_replacer @@ -546,9 +548,9 @@ function replacer.common_on_place(itemstack, placer, pt) end end - local metadata = r.set_data(itemstack, node, mode) + local short_description = r.set_data(itemstack, node, mode) - r.inform(name, rb.set_to:format(metadata)) + r.inform(name, rb.set_to:format(short_description)) return itemstack --data changed end -- common_on_place diff --git a/replacer_blabla.lua b/replacer_blabla.lua index 3a7c36a..b5cc986 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -22,10 +22,11 @@ replacer.blabla.mode_changed = "Mode changed to %s: %s" replacer.blabla.none_selected = "Error: No node selected." replacer.blabla.not_in_creative = 'Item not in creative invenotry: "%s".' replacer.blabla.not_in_inventory = 'Item not in your inventory: "%s".' -replacer.blabla.set_to = 'Node replacement tool set to: "%s".' +replacer.blabla.set_to = 'Node replacement tool set to:\n%s.' replacer.blabla.description_basic = "Node replacement tool" replacer.blabla.description_technic = "Node replacement tool (technic)" replacer.blabla.limit_override = 'Setting already set node-limit for "%s" was %d.' replacer.blabla.limit_insert = 'Setting node-limit for "%s" to %d.' replacer.blabla.blacklist_insert = 'Blacklisted "%s".' replacer.blabla.timed_out = 'Time-limit reached.' + From ca74517d1b7b548d4fd829d9af39c844e6d7aebb Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 19 Nov 2020 16:36:56 +0100 Subject: [PATCH 058/366] remove depricated get_entity_name needs to be tested if line 81 can be provoked at all --- inspect.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/inspect.lua b/inspect.lua index a5fd357..f90396d 100644 --- a/inspect.lua +++ b/inspect.lua @@ -54,7 +54,7 @@ replacer.inspect = function(_, user, pointed_thing, mode) else local luaob = ref:get_luaentity() if luaob and luaob.get_staticdata then - text = text .. 'entity "' .. luaob.name .. '"' + text = text .. 'an entity "' .. luaob.name .. '"' local sdata = luaob:get_staticdata() if 0 < #sdata then sdata = minetest.deserialize(sdata) or {} @@ -75,8 +75,10 @@ replacer.inspect = function(_, user, pointed_thing, mode) .. ' minutes ago' end end + elseif luaob + text = text .. 'an object "' .. luaob.name .. '"' else - text = text .. 'object "' .. ref:get_entity_name() .. '"' + text = text .. 'an object' end end From e744a76b9ce9af594b4204af1b4b16e4744f1138 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 18 Dec 2020 14:57:10 +0100 Subject: [PATCH 059/366] add optional depend on unifieddyes --- init.lua | 3 +++ mod.conf | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index a666a4c..2175b66 100644 --- a/init.lua +++ b/init.lua @@ -90,6 +90,9 @@ if nil == replacer.hide_recipe_technic_direct then end replacer.has_technic_mod = minetest.get_modpath('technic') + and minetest.global_exists('technic') +replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') + and minetest.global_exists('unifieddyes') -- adds a tool for inspecting nodes and entities dofile(path .. "/inspect.lua") diff --git a/mod.conf b/mod.conf index 6471d28..51e4871 100644 --- a/mod.conf +++ b/mod.conf @@ -1,4 +1,5 @@ name = replacer description = Replacement tool for creative building and tool to inspect nodes. depends = default -optional_depends = dye, technic +optional_depends = dye, technic, unifieddyes + From 7ad8899d891803bc384ab240cbb8db70a5d07c48 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 18 Dec 2020 16:03:50 +0100 Subject: [PATCH 060/366] syntax fix --- inspect.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inspect.lua b/inspect.lua index f90396d..e6c816a 100644 --- a/inspect.lua +++ b/inspect.lua @@ -75,7 +75,7 @@ replacer.inspect = function(_, user, pointed_thing, mode) .. ' minutes ago' end end - elseif luaob + elseif luaob then text = text .. 'an object "' .. luaob.name .. '"' else text = text .. 'an object' From 18b56e3a7c461f22d2bf3fd4941559fc63149c5f Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 18 Dec 2020 17:48:40 +0100 Subject: [PATCH 061/366] added colour info for unifieddyes compatible nodes --- replacer.lua | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/replacer.lua b/replacer.lua index 68dbd31..91bd008 100644 --- a/replacer.lua +++ b/replacer.lua @@ -56,6 +56,34 @@ function replacer.register_limit(node_name, node_max) minetest.log("info", rb.limit_insert:format(node_name, node_max)) end +-- from: http://lua-users.org/wiki/StringRecipes +local function titleCase(str) + local function titleCaseHelper(first, rest) + return first:upper() .. rest:lower() + end + -- Add extra characters to the pattern if you need to. _ and ' are + -- found in the middle of identifiers and English words. + -- We must also put %w_' into [%w_'] to make it handle normal stuff + -- and extra stuff the same. + -- This also turns hex numbers into, eg. 0Xa7d4 + str = str:gsub("(%a)([%w_']*)", titleCaseHelper) + return str +end + +function replacer.colourName(param2, def) + param2 = tonumber(param2) + if r.has_unifieddyes_mod and param2 and def and def.palette + and def.groups and def.groups.ud_param2_colorable + and 0 < def.groups.ud_param2_colorable + then + local s = unifieddyes.make_readable_color( + unifieddyes.color_to_name(param2, def)) + return ' ' .. s + else + return '' + end +end + function replacer.get_data(stack) local metaRef = stack:get_meta() local data = metaRef:get_string("replacer"):split(" ") or {} @@ -81,18 +109,19 @@ function replacer.set_data(stack, node, mode) metaRef:set_string("mode", mode) metaRef:set_string("replacer", metadata) metaRef:set_string("color", r.mode_colours[mode]) + local nodeDef = minetest.registered_items[node.name] local nodeDescription = nodeName - if minetest.registered_items[node.name] - and minetest.registered_items[node.name].description - then - nodeDescription = minetest.registered_items[node.name].description + if nodeDef and nodeDef.description then + nodeDescription = nodeDef.description end + local colourName = r.colourName(param2, nodeDef) local toolItemName = stack:get_name() local toolName = minetest.registered_items[toolItemName].description - local short_description = "(" .. param1 .. " " .. param2 .. ") " .. node.name + local short_description = "(" .. param1 .. " " .. param2 + .. colourName .. ") " .. node.name local description = toolName .. "\n" .. short_description .. "\n" - .. nodeDescription + .. nodeDescription -- .. titleCase(colourName) metaRef:set_string("description", description) return short_description From 81cd878bc9b9671a1319853bf6a0606ac078317b Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 18 Dec 2020 17:50:00 +0100 Subject: [PATCH 062/366] adding colormachine as optional dependency --- init.lua | 2 ++ mod.conf | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 2175b66..6beee38 100644 --- a/init.lua +++ b/init.lua @@ -89,6 +89,8 @@ if nil == replacer.hide_recipe_technic_direct then replacer.hide_recipe_technic_direct = true end +replacer.has_colormachine_mod = minetest.get_modpath('colormachine') + and minetest.global_exists('colormachine') replacer.has_technic_mod = minetest.get_modpath('technic') and minetest.global_exists('technic') replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') diff --git a/mod.conf b/mod.conf index 51e4871..21a3e8b 100644 --- a/mod.conf +++ b/mod.conf @@ -1,5 +1,5 @@ name = replacer description = Replacement tool for creative building and tool to inspect nodes. depends = default -optional_depends = dye, technic, unifieddyes +optional_depends = colormachine, dye, technic, unifieddyes From 47d3456b551fc36924b2833697a62173d9596346 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 18 Dec 2020 20:00:48 +0100 Subject: [PATCH 063/366] spelling fix: recipes --- inspect.lua | 117 ++++++++++++++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 59 deletions(-) diff --git a/inspect.lua b/inspect.lua index e6c816a..513b5c1 100644 --- a/inspect.lua +++ b/inspect.lua @@ -60,7 +60,7 @@ replacer.inspect = function(_, user, pointed_thing, mode) sdata = minetest.deserialize(sdata) or {} if sdata.itemstring then text = text .. ' [' .. sdata.itemstring .. ']' - if show_receipe then + if show_recipe then -- the fields part is used here to provide -- additional information about the entity replacer.inspect_show_crafting( @@ -166,7 +166,7 @@ replacer.image_button_link = function(stack_string) return stack_string .. ';' .. new_node_name .. ';' .. group end -replacer.add_circular_saw_receipe = function(node_name, receipes) +replacer.add_circular_saw_recipe = function(node_name, recipes) if not node_name or not minetest.get_modpath('moreblocks') or not circular_saw or not circular_saw.names @@ -193,18 +193,18 @@ replacer.add_circular_saw_receipe = function(node_name, receipes) help[1] = 'default' local basic_node_name = help[1] .. ':' .. help2[2] -- node found that fits into the saw - receipes[#receipes + 1] = { + recipes[#recipes + 1] = { method = 'saw', type = 'saw', items = { basic_node_name }, output = node_name } - return receipes + return recipes end -replacer.add_colormachine_receipe = function(node_name, receipes) - if not minetest.get_modpath('colormachine') or not colormachine then +replacer.add_colormachine_recipe = function(node_name, recipes) + if not replacer.has_colormachine_mod then return end local res = colormachine.get_node_name_painted(node_name, '') @@ -213,13 +213,13 @@ replacer.add_colormachine_receipe = function(node_name, receipes) return end -- paintable node found - receipes[#receipes + 1] = { + recipes[#recipes + 1] = { method = 'colormachine', type = 'colormachine', items = { res.possible[1] }, output = node_name } - return receipes + return recipes end @@ -227,17 +227,16 @@ replacer.inspect_show_crafting = function(name, node_name, fields) if not name then return end - - local receipe_nr = 1 + local recipe_nr = 1 if not node_name then node_name = fields.node_name - receipe_nr = tonumber(fields.receipe_nr) + recipe_nr = tonumber(fields.recipe_nr) end -- turn it into an item stack so that we can handle dropped stacks etc local stack = ItemStack(node_name) node_name = stack:get_name() - -- the player may ask for receipes of indigrents to the current receipe + -- the player may ask for recipes of indigrents to the current recipe if fields then for k, v in pairs(fields) do if v and '' == v @@ -247,7 +246,7 @@ replacer.inspect_show_crafting = function(name, node_name, fields) or minetest.registered_tools[k] then node_name = k - receipe_nr = 1 + recipe_nr = 1 end end end @@ -256,15 +255,15 @@ replacer.inspect_show_crafting = function(name, node_name, fields) if not res then res = {} end - -- add special receipes for nodes created by machines - replacer.add_circular_saw_receipe(node_name, res) - replacer.add_colormachine_receipe(node_name, res) - - -- offer all alternate creafting receipes thrugh prev/next buttons - if fields and fields.prev_receipe and 1 < receipe_nr then - receipe_nr = receipe_nr - 1 - elseif fields and fields.next_receipe and receipe_nr < #res then - receipe_nr = receipe_nr + 1 + -- add special recipes for nodes created by machines + replacer.add_circular_saw_recipe(node_name, res) + replacer.add_colormachine_recipe(node_name, res) + + -- offer all alternate creafting recipes thrugh prev/next buttons + if fields and fields.prev_recipe and 1 < recipe_nr then + recipe_nr = recipe_nr - 1 + elseif fields and fields.next_recipe and recipe_nr < #res then + recipe_nr = recipe_nr + 1 end local desc = ' - no description provided - ' @@ -298,7 +297,7 @@ replacer.inspect_show_crafting = function(name, node_name, fields) -- invisible field for passing on information .. 'field[20,20;0.1,0.1;node_name;node_name;' .. node_name .. ']' -- another invisible field - .. 'field[21,21;0.1,0.1;receipe_nr;receipe_nr;' .. tostring(receipe_nr) .. ']' + .. 'field[21,21;0.1,0.1;recipe_nr;recipe_nr;' .. tostring(recipe_nr) .. ']' -- provide additional information regarding the node in particular -- that has been inspected @@ -322,17 +321,17 @@ replacer.inspect_show_crafting = function(name, node_name, fields) .. minetest.formspec_escape(fields.protected_info) .. ']' end - if #res < receipe_nr or 1 > receipe_nr then - receipe_nr = 1 + if #res < recipe_nr or 1 > recipe_nr then + recipe_nr = 1 end - if 1 < receipe_nr then - formspec = formspec .. 'button[3.8,5;1,0.5;prev_receipe;prev]' + if 1 < recipe_nr then + formspec = formspec .. 'button[3.8,5;1,0.5;prev_recipe;prev]' end - if #res > receipe_nr then - formspec = formspec .. 'button[5.0,5.0;1,0.5;next_receipe;next]' + if #res > recipe_nr then + formspec = formspec .. 'button[5.0,5.0;1,0.5;next_recipe;next]' end if 1 > #res then - formspec = formspec .. 'label[3,1;No receipes.]' + formspec = formspec .. 'label[3,1;No recipes.]' if minetest.registered_nodes[node_name] and minetest.registered_nodes[node_name].drop then @@ -361,71 +360,71 @@ replacer.inspect_show_crafting = function(name, node_name, fields) end end else - formspec = formspec .. 'label[1,5;Alternate ' .. tostring(receipe_nr) + formspec = formspec .. 'label[1,5;Alternate ' .. tostring(recipe_nr) .. '/' .. tostring(#res) .. ']' - -- reverse order; default receipes (and thus the most intresting ones) + -- reverse order; default recipes (and thus the most intresting ones) -- are usually the oldest - local receipe = res[#res + 1 - receipe_nr] - if 'normal' == receipe.type and receipe.items then - local width = receipe.width + local recipe = res[#res + 1 - recipe_nr] + if 'normal' == recipe.type and recipe.items then + local width = recipe.width if not width or 0 == width then width = 3 end for i = 1, 9 do - if receipe.items[i] then + if recipe.items[i] then formspec = formspec .. 'item_image_button[' .. (((i - 1) % width) + 1) .. ',' .. tostring(math.floor((i - 1) / width) + 1) .. ';1.0,1.0;' - .. replacer.image_button_link(receipe.items[i]) .. ']' + .. replacer.image_button_link(recipe.items[i]) .. ']' end end - elseif 'cooking' == receipe.type - and receipe.items - and 1 == #receipe.items - and '' == receipe.output + elseif 'cooking' == recipe.type + and recipe.items + and 1 == #recipe.items + and '' == recipe.output then formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' .. replacer.image_button_link('default:furnace_active') .. ']' .. 'item_image_button[2.9,2.7;1.0,1.0;' - .. replacer.image_button_link(receipe.items[1]) .. ']' - .. 'label[1.0,0;' .. tostring(receipe.items[1]) .. ']' + .. replacer.image_button_link(recipe.items[1]) .. ']' + .. 'label[1.0,0;' .. tostring(recipe.items[1]) .. ']' .. 'label[0,0.5;This can be used as a fuel.' .. ']' - elseif 'cooking' == receipe.type - and receipe.items - and 1 == #receipe.items + elseif 'cooking' == recipe.type + and recipe.items + and 1 == #recipe.items then formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' .. replacer.image_button_link('default:furnace') .. ']' .. 'item_image_button[2.9,2.7;1.0,1.0;' - .. replacer.image_button_link(receipe.items[1]) .. ']' - elseif 'colormachine' == receipe.type - and receipe.items - and 1 == #receipe.items + .. replacer.image_button_link(recipe.items[1]) .. ']' + elseif 'colormachine' == recipe.type + and recipe.items + and 1 == #recipe.items then formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' .. replacer.image_button_link('colormachine:colormachine') .. ']' .. 'item_image_button[2,2;1.0,1.0;' - .. replacer.image_button_link(receipe.items[1]) .. ']' - elseif 'saw' == receipe.type - and receipe.items - and 1 == #receipe.items + .. replacer.image_button_link(recipe.items[1]) .. ']' + elseif 'saw' == recipe.type + and recipe.items + and 1 == #recipe.items then formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' .. replacer.image_button_link('moreblocks:circular_saw') .. ']' .. 'item_image_button[2,0.6;1.0,1.0;' - .. replacer.image_button_link(receipe.items[1]) .. ']' + .. replacer.image_button_link(recipe.items[1]) .. ']' else - formspec = formspec .. 'label[3,1;Error: Unkown receipe.]' + formspec = formspec .. 'label[3,1;Error: Unkown recipe.]' end - -- show how many of the items the receipe will yield - local outstack = ItemStack(receipe.output) + -- show how many of the items the recipe will yield + local outstack = ItemStack(recipe.output) local out_count = outstack:get_count() if 1 < out_count then formspec = formspec .. 'label[5.5,2.5;' .. tostring(out_count) .. ']' end end - minetest.show_formspec(name, 'replacer:crafting', formspec) + minetest.show_formspec(player_name, 'replacer:crafting', formspec) end -- translate general formspec calls back to specific calls From 86d5533a7baae298e7009a3a3160657d4acee779 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 18 Dec 2020 20:01:33 +0100 Subject: [PATCH 064/366] name -> player_name --- inspect.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inspect.lua b/inspect.lua index 513b5c1..0154d66 100644 --- a/inspect.lua +++ b/inspect.lua @@ -223,8 +223,8 @@ replacer.add_colormachine_recipe = function(node_name, recipes) end -replacer.inspect_show_crafting = function(name, node_name, fields) - if not name then +replacer.inspect_show_crafting = function(player_name, node_name, fields) + if not player_name then return end local recipe_nr = 1 From 2f32b12464f74975c00a4fca9679269eab579af6 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 18 Dec 2020 20:02:30 +0100 Subject: [PATCH 065/366] centralized mod checking --- init.lua | 7 +++++++ inspect.lua | 5 ++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/init.lua b/init.lua index 6beee38..e174725 100644 --- a/init.lua +++ b/init.lua @@ -89,6 +89,13 @@ if nil == replacer.hide_recipe_technic_direct then replacer.hide_recipe_technic_direct = true end +replacer.has_basic_dyes = minetest.get_modpath('dye') + and minetest.global_exists('dye') + and dye.basecolors +replacer.has_circular_saw = minetest.get_modpath('moreblocks') + and minetest.global_exists('moreblocks') + and minetest.global_exists('circular_saw') + and circular_saw.names replacer.has_colormachine_mod = minetest.get_modpath('colormachine') and minetest.global_exists('colormachine') replacer.has_technic_mod = minetest.get_modpath('technic') diff --git a/inspect.lua b/inspect.lua index 0154d66..3442ce6 100644 --- a/inspect.lua +++ b/inspect.lua @@ -137,7 +137,7 @@ replacer.group_placeholder['group:wool'] = 'wool:white' -- handle the standard dye color groups -if minetest.get_modpath('dye') and dye and dye.basecolors then +if replacer.has_basic_dyes then for i, color in ipairs(dye.basecolors) do local def = minetest.registered_items['dye:' .. color] if def and def.groups then @@ -168,8 +168,7 @@ end replacer.add_circular_saw_recipe = function(node_name, recipes) if not node_name - or not minetest.get_modpath('moreblocks') - or not circular_saw or not circular_saw.names + or not replacer.has_circular_saw or 'moreblocks:circular_saw' == node_name then return From 70d05da5d0ecd8ed79a5cb1b308a49c3360724fb Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 18 Dec 2020 20:03:32 +0100 Subject: [PATCH 066/366] split to utils.lua and unifieddyes.lua --- init.lua | 4 ++++ replacer.lua | 30 +----------------------------- unifieddyes.lua | 29 +++++++++++++++++++++++++++++ utils.lua | 14 ++++++++++++++ 4 files changed, 48 insertions(+), 29 deletions(-) create mode 100644 unifieddyes.lua create mode 100644 utils.lua diff --git a/init.lua b/init.lua index e174725..8246332 100644 --- a/init.lua +++ b/init.lua @@ -103,6 +103,10 @@ replacer.has_technic_mod = minetest.get_modpath('technic') replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') and minetest.global_exists('unifieddyes') +-- utilities +dofile(path .. "/utils.lua") +-- unifiedddyes support functions +dofile(path .. "/unifieddyes.lua") -- adds a tool for inspecting nodes and entities dofile(path .. "/inspect.lua") dofile(path .. "/replacer_blabla.lua") diff --git a/replacer.lua b/replacer.lua index 91bd008..4fe6a26 100644 --- a/replacer.lua +++ b/replacer.lua @@ -56,34 +56,6 @@ function replacer.register_limit(node_name, node_max) minetest.log("info", rb.limit_insert:format(node_name, node_max)) end --- from: http://lua-users.org/wiki/StringRecipes -local function titleCase(str) - local function titleCaseHelper(first, rest) - return first:upper() .. rest:lower() - end - -- Add extra characters to the pattern if you need to. _ and ' are - -- found in the middle of identifiers and English words. - -- We must also put %w_' into [%w_'] to make it handle normal stuff - -- and extra stuff the same. - -- This also turns hex numbers into, eg. 0Xa7d4 - str = str:gsub("(%a)([%w_']*)", titleCaseHelper) - return str -end - -function replacer.colourName(param2, def) - param2 = tonumber(param2) - if r.has_unifieddyes_mod and param2 and def and def.palette - and def.groups and def.groups.ud_param2_colorable - and 0 < def.groups.ud_param2_colorable - then - local s = unifieddyes.make_readable_color( - unifieddyes.color_to_name(param2, def)) - return ' ' .. s - else - return '' - end -end - function replacer.get_data(stack) local metaRef = stack:get_meta() local data = metaRef:get_string("replacer"):split(" ") or {} @@ -121,7 +93,7 @@ function replacer.set_data(stack, node, mode) .. colourName .. ") " .. node.name local description = toolName .. "\n" .. short_description .. "\n" - .. nodeDescription -- .. titleCase(colourName) + .. nodeDescription -- .. r.titleCase(colourName) metaRef:set_string("description", description) return short_description diff --git a/unifieddyes.lua b/unifieddyes.lua new file mode 100644 index 0000000..2602117 --- /dev/null +++ b/unifieddyes.lua @@ -0,0 +1,29 @@ +if not replacer.has_unifieddyes_mod then + function replacer.colourName(param2, nodeDef) return '' end + function replacer.addUnifieddyesRecipe(nodeName, recipes) return recipes end + return +end + + +function replacer.addUnifieddyesRecipe(nodeName, recipes) + local nodeDef = minetest.registered_items[nodeName] +print(dump(nodeDef)) + return recipes +end + + +function replacer.colourName(param2, nodeDef) + param2 = tonumber(param2) + if param2 and nodeDef and nodeDef.palette + and nodeDef.groups and nodeDef.groups.ud_param2_colorable + and 0 < nodeDef.groups.ud_param2_colorable + then + -- TODO: check if is coloured at all, some nodes have neutral states + local s = unifieddyes.make_readable_color( + unifieddyes.color_to_name(param2, nodeDef)) + return ' ' .. s + else + return '' + end +end + diff --git a/utils.lua b/utils.lua new file mode 100644 index 0000000..e1121e1 --- /dev/null +++ b/utils.lua @@ -0,0 +1,14 @@ +-- from: http://lua-users.org/wiki/StringRecipes +function replacer.titleCase(str) + local function titleCaseHelper(first, rest) + return first:upper() .. rest:lower() + end + -- Add extra characters to the pattern if you need to. _ and ' are + -- found in the middle of identifiers and English words. + -- We must also put %w_' into [%w_'] to make it handle normal stuff + -- and extra stuff the same. + -- This also turns hex numbers into, eg. 0Xa7d4 + str = str:gsub("(%a)([%w_']*)", titleCaseHelper) + return str +end + From f3b217dc134cf4a06dd2b5d7dde7edb1082de2d4 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 18 Dec 2020 20:04:12 +0100 Subject: [PATCH 067/366] add moreblocks to optional dependencies --- mod.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod.conf b/mod.conf index 21a3e8b..353583d 100644 --- a/mod.conf +++ b/mod.conf @@ -1,5 +1,5 @@ name = replacer description = Replacement tool for creative building and tool to inspect nodes. depends = default -optional_depends = colormachine, dye, technic, unifieddyes +optional_depends = colormachine, dye, moreblocks, technic, unifieddyes From 33d75ed57a73b88b2c047de42ea6411b920a41f1 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 18 Dec 2020 21:36:01 +0100 Subject: [PATCH 068/366] show correct recipe when clicking on painted nodes also don't show colour name in replacer info if the node is neutral --- inspect.lua | 1 + replacer.lua | 6 ++++- unifieddyes.lua | 64 +++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/inspect.lua b/inspect.lua index 3442ce6..c04734b 100644 --- a/inspect.lua +++ b/inspect.lua @@ -257,6 +257,7 @@ replacer.inspect_show_crafting = function(player_name, node_name, fields) -- add special recipes for nodes created by machines replacer.add_circular_saw_recipe(node_name, res) replacer.add_colormachine_recipe(node_name, res) + replacer.unifieddyes.addRecipe(fields.param2, node_name, res) -- offer all alternate creafting recipes thrugh prev/next buttons if fields and fields.prev_recipe and 1 < recipe_nr then diff --git a/replacer.lua b/replacer.lua index 4fe6a26..5b5b946 100644 --- a/replacer.lua +++ b/replacer.lua @@ -5,6 +5,7 @@ replacer.tool_default_node = "default:dirt" local r = replacer local rb = replacer.blabla local rp = replacer.patterns +local rud = replacer.unifieddyes function replacer.inform(name, msg) minetest.chat_send_player(name, msg) @@ -86,7 +87,10 @@ function replacer.set_data(stack, node, mode) if nodeDef and nodeDef.description then nodeDescription = nodeDef.description end - local colourName = r.colourName(param2, nodeDef) + local colourName = rud.colourName(param2, nodeDef) + if 0 < #colourName then + colourName = " " .. colourName + end local toolItemName = stack:get_name() local toolName = minetest.registered_items[toolItemName].description local short_description = "(" .. param1 .. " " .. param2 diff --git a/unifieddyes.lua b/unifieddyes.lua index 2602117..8b55ba8 100644 --- a/unifieddyes.lua +++ b/unifieddyes.lua @@ -1,29 +1,67 @@ +replacer.unifieddyes = {} +local ud = replacer.unifieddyes + if not replacer.has_unifieddyes_mod then - function replacer.colourName(param2, nodeDef) return '' end - function replacer.addUnifieddyesRecipe(nodeName, recipes) return recipes end + function ud.colourName(param2, nodeDef) return '' end + function ud.addRecipe(nodeName, recipes) return recipes end return end -function replacer.addUnifieddyesRecipe(nodeName, recipes) +-- for inspector formspec +function replacer.unifieddyes.addRecipe(param2, nodeName, recipes) + if not param2 then + return recipes + end + local nodeDef = minetest.registered_items[nodeName] -print(dump(nodeDef)) + if ud.isAirbrushed(nodeDef) then + -- find the correct recipe and append it to bottom of list + local first, last + local needle = 'u0002' .. tostring(param2) + for i, t in ipairs(recipes) do + first, last = t.output:find(needle) + if nil ~= first then + recipes[#recipes + 1] = t + return recipes + end + end + end + return recipes end -function replacer.colourName(param2, nodeDef) +function replacer.unifieddyes.colourName(param2, nodeDef) param2 = tonumber(param2) - if param2 and nodeDef and nodeDef.palette - and nodeDef.groups and nodeDef.groups.ud_param2_colorable - and 0 < nodeDef.groups.ud_param2_colorable - then - -- TODO: check if is coloured at all, some nodes have neutral states - local s = unifieddyes.make_readable_color( - unifieddyes.color_to_name(param2, nodeDef)) - return ' ' .. s + if param2 and ud.isAirbrushed(nodeDef) then + return unifieddyes.make_readable_color( + unifieddyes.color_to_name(param2, nodeDef)) + else + return '' + end +end + + +function replacer.unifieddyes.dyeName(param2, nodeDef) + param2 = tonumber(param2) + if param2 and ud.isAirbrushed(nodeDef) then + return 'dye:' .. unifieddyes.color_to_name(param2, nodeDef) else return '' end end + +function replacer.unifieddyes.isAirbrushCompatible(nodeDef) + return nodeDef and nodeDef.palette + and nodeDef.groups and nodeDef.groups.ud_param2_colorable + and 0 < nodeDef.groups.ud_param2_colorable +end + + +function replacer.unifieddyes.isAirbrushed(nodeDef) + return replacer.unifieddyes.isAirbrushCompatible(nodeDef) + and (not nodeDef.airbrush_replacement_node) +end + From d259ac2063cacf71c85c1a50ad266722f96af165 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Fri, 18 Dec 2020 21:36:11 +0100 Subject: [PATCH 069/366] whitespace --- inspect.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/inspect.lua b/inspect.lua index c04734b..eeda564 100644 --- a/inspect.lua +++ b/inspect.lua @@ -226,6 +226,7 @@ replacer.inspect_show_crafting = function(player_name, node_name, fields) if not player_name then return end + local recipe_nr = 1 if not node_name then node_name = fields.node_name @@ -254,6 +255,7 @@ replacer.inspect_show_crafting = function(player_name, node_name, fields) if not res then res = {} end + -- add special recipes for nodes created by machines replacer.add_circular_saw_recipe(node_name, res) replacer.add_colormachine_recipe(node_name, res) From 825f82a75b935dc5477e3742cada5c9e17f61538 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Sat, 19 Dec 2020 00:49:13 +0100 Subject: [PATCH 070/366] add bakedclay as optional dependency --- init.lua | 1 + inspect.lua | 12 ++++++++++++ mod.conf | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 8246332..28a506a 100644 --- a/init.lua +++ b/init.lua @@ -89,6 +89,7 @@ if nil == replacer.hide_recipe_technic_direct then replacer.hide_recipe_technic_direct = true end +replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') and minetest.global_exists('dye') and dye.basecolors diff --git a/inspect.lua b/inspect.lua index eeda564..01f7a10 100644 --- a/inspect.lua +++ b/inspect.lua @@ -136,6 +136,18 @@ replacer.group_placeholder['group:wood_slab'] = 'stairs:slab_wood' replacer.group_placeholder['group:wool'] = 'wool:white' +-- add bakedclay items +if replacer.has_bakedclay then + replacer.group_placeholder['group:bakedclay'] = 'bakedclay:natural' + -- unfortunately bakedclay does not expose anything, so we have to manually + -- maintain the list + local rgp = replacer.group_placeholder + rgp['group:flower,color_cyan'] = 'bakedclay:delphinium' + rgp['group:flower,color_pink'] = 'bakedclay:lazarus' + rgp['group:flower,color_dark_green'] = 'bakedclay:mannagrass' + rgp['group:flower,color_magenta'] = 'bakedclay:thistle' +end + -- handle the standard dye color groups if replacer.has_basic_dyes then for i, color in ipairs(dye.basecolors) do diff --git a/mod.conf b/mod.conf index 353583d..feff229 100644 --- a/mod.conf +++ b/mod.conf @@ -1,5 +1,5 @@ name = replacer description = Replacement tool for creative building and tool to inspect nodes. depends = default -optional_depends = colormachine, dye, moreblocks, technic, unifieddyes +optional_depends = bakedclay, colormachine, dye, moreblocks, technic, unifieddyes From 0e9cb681282fd543e85e1f80e44c460421011dbd Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Sat, 19 Dec 2020 00:50:00 +0100 Subject: [PATCH 071/366] better detection of nodes that have been painted --- unifieddyes.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/unifieddyes.lua b/unifieddyes.lua index 8b55ba8..d4b3d5b 100644 --- a/unifieddyes.lua +++ b/unifieddyes.lua @@ -61,7 +61,12 @@ end function replacer.unifieddyes.isAirbrushed(nodeDef) - return replacer.unifieddyes.isAirbrushCompatible(nodeDef) - and (not nodeDef.airbrush_replacement_node) + if not replacer.unifieddyes.isAirbrushCompatible(nodeDef) then + return false + end + if nil ~= nodeDef.name:find('_tinted$') then + return true + end + return not nodeDef.airbrush_replacement_node end From bf6a5f683be3657cd96c1117cd4384a0df9b8361 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Sat, 19 Dec 2020 00:50:41 +0100 Subject: [PATCH 072/366] fix some default game group icons --- inspect.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/inspect.lua b/inspect.lua index 01f7a10..a2c3ace 100644 --- a/inspect.lua +++ b/inspect.lua @@ -134,7 +134,26 @@ replacer.group_placeholder['group:sand'] = 'default:sand' replacer.group_placeholder['group:leaves'] = 'default:leaves' replacer.group_placeholder['group:wood_slab'] = 'stairs:slab_wood' replacer.group_placeholder['group:wool'] = 'wool:white' +replacer.group_placeholder['group:coal'] = 'default:coal_lump' +-- add default game dyes +for _, color in pairs(dye.dyes) do + replacer.group_placeholder['group:dye,color_' .. color[1]] = 'dye:' .. color[1] +end + +-- add default game flowers +do + local name, groups + for _, flower in pairs(flowers.datas) do + name = flower[1] + groups = flower[4] + for k, _ in pairs(groups) do + if 1 == k:find('color_') then + replacer.group_placeholder['group:flower,' .. k] = 'flowers:' .. name + end + end + end +end -- add bakedclay items if replacer.has_bakedclay then From fb17c705aa0e0f6237b8a6dd8854c030ac1e2a3c Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Sat, 19 Dec 2020 00:51:00 +0100 Subject: [PATCH 073/366] comments --- inspect.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/inspect.lua b/inspect.lua index a2c3ace..c6b5679 100644 --- a/inspect.lua +++ b/inspect.lua @@ -286,6 +286,10 @@ replacer.inspect_show_crafting = function(player_name, node_name, fields) if not res then res = {} end +--print(dump(res)) + -- TODO: filter out invalid recipes with no items + -- such as "group:flower,color_dark_grey" + -- -- add special recipes for nodes created by machines replacer.add_circular_saw_recipe(node_name, res) @@ -398,6 +402,7 @@ replacer.inspect_show_crafting = function(player_name, node_name, fields) -- reverse order; default recipes (and thus the most intresting ones) -- are usually the oldest local recipe = res[#res + 1 - recipe_nr] +--print(dump(recipe)) if 'normal' == recipe.type and recipe.items then local width = recipe.width if not width or 0 == width then From 839f7668170ee82bc4bb1a0ed0fd75a0a88f5749 Mon Sep 17 00:00:00 2001 From: HybridDog Date: Thu, 26 Mar 2020 15:47:56 +0100 Subject: [PATCH 074/366] Replace get_ps with a more memory-efficient search --- init.lua | 2 + replacer.lua | 5 +- replacer_patterns.lua | 110 ++++++++++++++++++++++++++++-------------- 3 files changed, 78 insertions(+), 39 deletions(-) diff --git a/init.lua b/init.lua index 28a506a..de89794 100644 --- a/init.lua +++ b/init.lua @@ -108,6 +108,8 @@ replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') dofile(path .. "/utils.lua") -- unifiedddyes support functions dofile(path .. "/unifieddyes.lua") + +replacer.datastructures = dofile(path .. "/datastructures.lua") -- adds a tool for inspecting nodes and entities dofile(path .. "/inspect.lua") dofile(path .. "/replacer_blabla.lua") diff --git a/replacer.lua b/replacer.lua index 5b5b946..8d28267 100644 --- a/replacer.lua +++ b/replacer.lua @@ -27,9 +27,6 @@ replacer.mode_colours[r.modes[1]] = "#ffffff" replacer.mode_colours[r.modes[2]] = "#54FFAC" replacer.mode_colours[r.modes[3]] = "#9F6200" -local path = minetest.get_modpath("replacer") -local datastructures = dofile(path .. "/datastructures.lua") - local is_int = function(value) return type(value) == 'number' and math.floor(value) == value end @@ -404,7 +401,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) -- TODO local max_time_us = 1000000 * replacer.max_time -- Turn ps into a binary heap - datastructures.create_binary_heap({ + replacer.datastructures.create_binary_heap({ input = ps, n = num, compare = function(pos1, pos2) diff --git a/replacer_patterns.lua b/replacer_patterns.lua index 6402b7d..7854908 100644 --- a/replacer_patterns.lua +++ b/replacer_patterns.lua @@ -151,42 +151,82 @@ function replacer.patterns.mantle_position(pos, data) return false end --- finds out positions using depth first search -function replacer.patterns.get_ps(pos, fdata, adps, max) - adps = adps or rp.offsets_touch - local tab = {} - local num = 0 - - local todo = { pos } - local ti = 1 - - local tab_avoid = {} - local p, i - - while 0 ~= ti do - p = todo[ti] - ti = ti - 1 - - for _, p2 in pairs(adps) do - p2 = vector.add(p, p2) - i = poshash(p2) - if (not tab_avoid[i]) and fdata.func(p2, fdata) then - - num = num + 1 - tab[num] = p2 - - ti = ti + 1 - todo[ti] = p2 - - tab_avoid[i] = true - - if max and (num >= max) then - return tab, num, tab_avoid +-- Algorithm created by sofar and changed by others: +-- https://github.com/minetest/minetest/commit/d7908ee49480caaab63d05c8a53d93103579d7a9 + +local function search_dfs(go, p, apply_move, moves) + local num_moves = #moves + + -- Uncomment if the starting position should be walked even if its + -- neighbours cannot be walked + --~ go(p) + + -- The stack contains the path to the current position; + -- an element of it contains a position and direction (index to moves) + local s = replacer.datastructures.create_stack() + -- The neighbor order we will visit from our table. + local v = 1 + + while true do + -- Push current state onto the stack. + s:push({p = p, v = v}) + -- Go to the next position. + p = apply_move(p, moves[v]) + -- Now we check out the node. If it is in need of an update, + -- it will let us know in the return value (true = updated). + local can_go, abort = go(p) + if not can_go then + if abort then + return + end + -- If we don't need to "recurse" (walk) to it then pop + -- our previous pos off the stack and continue from there, + -- with the v value we were at when we last were at that + -- node + repeat + local pop = s:pop() + p = pop.p + v = pop.v + -- If there's nothing left on the stack, and no + -- more sides to walk to, we're done and can exit + if s:is_empty() and v == num_moves then + return end - end -- if - end -- for - end -- while - return tab, num, tab_avoid + until v < num_moves + -- The next round walk the next neighbor in list. + v = v + 1 + else + -- If we did need to walk the neighbor/current position, then + -- start walking from here from the walk order start (1), + -- and not the order we just pushed up the stack. + v = 1 + end + end end + +function replacer.patterns.get_ps(pos, fdata, moves, max_positions) + moves = moves or rp.offsets_touch + max_positions = max_positions or math.huge + -- visiteds has only positions where fdata.func evaluated to true + local visiteds = {} + local founds = {} + local n_founds = 0 + local function go(p) + local vi = poshash(p) + if visiteds[vi] or not fdata.func(p, fdata) then + return false + end + n_founds = n_founds+1 + founds[n_founds] = p + visiteds[vi] = true + if n_founds >= max_positions then + -- Abort, too many positions + return false, true + end + return true + end + search_dfs(go, pos, vector.add, moves) + return founds, n_founds, visiteds +end From c3fd0bc4486733d34a316c34916418ba113a13a0 Mon Sep 17 00:00:00 2001 From: HybridDog Date: Thu, 26 Mar 2020 16:18:42 +0100 Subject: [PATCH 075/366] Remove outdated code and try to make the code more readable --- replacer.lua | 94 ++++++++++++++++++++++++------------------- replacer_blabla.lua | 1 - replacer_patterns.lua | 26 +++++------- 3 files changed, 63 insertions(+), 58 deletions(-) diff --git a/replacer.lua b/replacer.lua index 8d28267..536917e 100644 --- a/replacer.lua +++ b/replacer.lua @@ -326,59 +326,72 @@ function replacer.replace(itemstack, user, pt, right_clicked) end local ps, num - if r.modes[2] == mode then - -- field - -- get connected positions for plane field replacing - local pdif = vector.subtract(pt.above, pt.under) - local adps, n = {}, 1 + if mode == "field" then + -- Get four walk directions which are orthogonal to the field + local normal = vector.subtract(pt.above, pt.under) + local dirs, n = {}, 1 local p - for _, i in pairs{ "x", "y", "z" } do - if 0 == pdif[i] then + for coord in pairs(normal) do + if normal[coord] == 0 then for a = -1, 1, 2 do - p = { x = 0, y = 0, z = 0 } - p[i] = a - adps[n] = p + p = {x = 0, y = 0, z = 0} + p[coord] = a + dirs[n] = p n = n + 1 end end end + -- The normal is used as offset to test if the searched position + -- is next to the field; the offset goes in the other direction when + -- a right click happens if right_clicked then - pdif = vector.multiply(pdif, -1) + normal = vector.multiply(normal, -1) end + -- Search along the plane next to the field right_clicked = (right_clicked and true) or false - ps, num = rp.get_ps(pos, { func = rp.field_position, name = node_toreplace.name, - pname = name, above = pdif, right_clicked = right_clicked }, adps, max_nodes) - elseif r.modes[3] == mode then - -- crust + ps, num = rp.search_positions({ + startpos = pos, + fdata = {func = rp.field_position, name = node_toreplace.name, + pname = name, above = normal, right_clicked = right_clicked}, + moves = dirs, + max_positions = max_nodes + }) + elseif mode == "crust" then + -- Search positions of air (or similar) nodes next to the crust local nodename_clicked = rp.get_node(pt.under).name - local aps, n, aboves = rp.get_ps(pt.above, { func = rp.crust_above_position, - name = nodename_clicked, pname = name }, nil, max_nodes) - if aps then - if right_clicked then - local data = { ps = aps, num = n, name = nodename_clicked, pname = name } - rp.reduce_crust_above_ps(data) - ps, num = data.ps, data.num - else - ps, num = rp.get_ps(pt.under, { func = rp.crust_under_position, - name = node_toreplace.name, pname = name, aboves = aboves }, - rp.offsets_hollowcube, max_nodes) - if ps then - local data = { aboves = aboves, ps = ps, num = num } - rp.reduce_crust_ps(data) - ps, num = data.ps, data.num - end - end + local aps, n, aboves = rp.search_positions({ + startpos = pt.above, + fdata = {func = rp.crust_above_position, name = nodename_clicked, + pname = name}, + moves = rp.offsets_touch, + max_positions = max_nodes + }) + if right_clicked then + -- Remove positions which are not directly touching the crust + local data = {ps = aps, num = n, name = nodename_clicked, + pname = name} + rp.reduce_crust_above_ps(data) + ps, num = data.ps, data.num + else + -- Search crust positions which are next to the previously found + -- air (or similar) node positions + ps, num = rp.search_positions({ + startpos = pt.under, + fdata = {func = rp.crust_under_position, + name = node_toreplace.name, pname = name, + aboves = aboves}, + moves = rp.offsets_hollowcube, + max_positions = max_nodes + }) + -- Keep only positions which are directly touching those previously + -- found positions + local data = {aboves = aboves, ps = ps, num = num} + rp.reduce_crust_ps(data) + ps, num = data.ps, data.num end end - -- reset known nodes table - replacer.patterns.known_nodes = {} - - if not ps then - -- TODO: does this ever happen anymore? - r.inform(name, rb.too_many_nodes_detected) - return - end + replacer.patterns.reset_nodes_cache() if 0 == num then local succ, err = r.replace_single_node(pos, node_toreplace, nnd, user, @@ -398,7 +411,6 @@ function replacer.replace(itemstack, user, pt, right_clicked) -- set nodes local t_start = minetest.get_us_time() - -- TODO local max_time_us = 1000000 * replacer.max_time -- Turn ps into a binary heap replacer.datastructures.create_binary_heap({ diff --git a/replacer_blabla.lua b/replacer_blabla.lua index b5cc986..143c0d6 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -15,7 +15,6 @@ replacer.blabla.not_a_node = 'Error: "%s" is not a node.' replacer.blabla.wait_for_load = "Target node not yet loaded. Please wait a moment for the server to catch up." replacer.blabla.nothing_to_replace = "Nothing to replace." replacer.blabla.need_more_charge = "Not enough charge to use this mode." -replacer.blabla.too_many_nodes_detected = "Aborted, too many nodes detected." replacer.blabla.charge_required = "Need %d charge to replace %d nodes." replacer.blabla.count_replaced = "%s nodes replaced." replacer.blabla.mode_changed = "Mode changed to %s: %s" diff --git a/replacer_patterns.lua b/replacer_patterns.lua index 7854908..1dbebd7 100644 --- a/replacer_patterns.lua +++ b/replacer_patterns.lua @@ -15,6 +15,11 @@ function replacer.patterns.get_node(pos) return node end +-- The cache is only valid as long as no node is changed in the world. +function replacer.patterns.reset_nodes_cache() + replacer.patterns.known_nodes = {} +end + -- tests if there's a node at pos which should be replaced function replacer.patterns.replaceable(pos, name, pname) return (rp.get_node(pos).name == name) and (not minetest.is_protected(pos, pname)) @@ -139,18 +144,6 @@ function replacer.patterns.reduce_crust_above_ps(data) data.num = n end -function replacer.patterns.mantle_position(pos, data) - if not rp.replaceable(pos, data.name, data.pname) then - return false - end - for i = 1, 6 do - if rp.get_node(vector.add(pos, rp.offsets_touch[i])).name ~= data.name then - return true - end - end - return false -end - -- Algorithm created by sofar and changed by others: -- https://github.com/minetest/minetest/commit/d7908ee49480caaab63d05c8a53d93103579d7a9 @@ -206,9 +199,10 @@ local function search_dfs(go, p, apply_move, moves) end -function replacer.patterns.get_ps(pos, fdata, moves, max_positions) - moves = moves or rp.offsets_touch - max_positions = max_positions or math.huge +function replacer.patterns.search_positions(params) + moves = params.moves + max_positions = params.max_positions + local fdata = params.fdata -- visiteds has only positions where fdata.func evaluated to true local visiteds = {} local founds = {} @@ -227,6 +221,6 @@ function replacer.patterns.get_ps(pos, fdata, moves, max_positions) end return true end - search_dfs(go, pos, vector.add, moves) + search_dfs(go, params.startpos, vector.add, moves) return founds, n_founds, visiteds end From 297490aa6938a7597edfd085c79dacb17bbabdf8 Mon Sep 17 00:00:00 2001 From: HybridDog Date: Thu, 26 Mar 2020 16:49:52 +0100 Subject: [PATCH 076/366] Do a limited search within a sphere if too many positions are found --- init.lua | 2 +- replacer.lua | 11 +++++++++-- replacer_patterns.lua | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/init.lua b/init.lua index de89794..3b36966 100644 --- a/init.lua +++ b/init.lua @@ -74,7 +74,7 @@ replacer.blacklist["protector:protect2"] = true replacer.max_charge = 30000 replacer.charge_per_node = 15 -- node count limit -replacer.max_nodes = tonumber(minetest.settings:get("replacer.max_nodes") or 3168) +replacer.max_nodes = tonumber(minetest.settings:get("replacer.max_nodes") or 716) -- Time limit when placing the nodes, in seconds replacer.max_time = tonumber(minetest.settings:get("replacer.max_time") or 1.0) diff --git a/replacer.lua b/replacer.lua index 536917e..59b8522 100644 --- a/replacer.lua +++ b/replacer.lua @@ -354,7 +354,8 @@ function replacer.replace(itemstack, user, pt, right_clicked) fdata = {func = rp.field_position, name = node_toreplace.name, pname = name, above = normal, right_clicked = right_clicked}, moves = dirs, - max_positions = max_nodes + max_positions = max_nodes, + radius_exceeded = 4, }) elseif mode == "crust" then -- Search positions of air (or similar) nodes next to the crust @@ -364,7 +365,8 @@ function replacer.replace(itemstack, user, pt, right_clicked) fdata = {func = rp.crust_above_position, name = nodename_clicked, pname = name}, moves = rp.offsets_touch, - max_positions = max_nodes + max_positions = max_nodes, + radius_exceeded = 4, }) if right_clicked then -- Remove positions which are not directly touching the crust @@ -429,6 +431,11 @@ function replacer.replace(itemstack, user, pt, right_clicked) local num_nodes = 0 while not ps:is_empty() do num_nodes = num_nodes+1 + if num_nodes > max_nodes then + -- This can happen if too many nodes were detected and the nodes + -- limit has been set to a small value + break + end -- Take the position nearest to the start position local pos = ps:take() local succ, err = r.replace_single_node(pos, minetest.get_node(pos), nnd, diff --git a/replacer_patterns.lua b/replacer_patterns.lua index 1dbebd7..0ac72f5 100644 --- a/replacer_patterns.lua +++ b/replacer_patterns.lua @@ -200,9 +200,10 @@ end function replacer.patterns.search_positions(params) - moves = params.moves - max_positions = params.max_positions + local moves = params.moves + local max_positions = params.max_positions local fdata = params.fdata + local startpos = params.startpos -- visiteds has only positions where fdata.func evaluated to true local visiteds = {} local founds = {} @@ -221,6 +222,36 @@ function replacer.patterns.search_positions(params) end return true end - search_dfs(go, params.startpos, vector.add, moves) + search_dfs(go, startpos, vector.add, moves) + if n_founds < max_positions or not params.radius_exceeded then + return founds, n_founds, visiteds + end + + -- Too many positions were found, so search again but only within + -- a limited sphere around startpos + local rr = params.radius_exceeded ^ 2 + local visiteds_old = visiteds + visiteds = {} + founds = {} + n_founds = 0 + local function go(p) + local vi = poshash(p) + if visiteds[vi] then + return false + end + local d = vector.subtract(p, startpos) + if d.x * d.x + d.y * d.y + d.z * d.z > rr then + -- Outside of the sphere + return false + end + if not visiteds_old[vi] and not fdata.func(p, fdata) then + return false + end + n_founds = n_founds+1 + founds[n_founds] = p + visiteds[vi] = true + return true + end + search_dfs(go, startpos, vector.add, moves) return founds, n_founds, visiteds end From 2ecd04441d12e612493bb23633b58d83d62a0a7c Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Mon, 22 Mar 2021 22:41:05 +0100 Subject: [PATCH 077/366] whitespace --- inspect.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/inspect.lua b/inspect.lua index c6b5679..e508883 100644 --- a/inspect.lua +++ b/inspect.lua @@ -27,12 +27,12 @@ minetest.register_tool('replacer:inspect', { liquids_pointable = true, -- it is ok to request information about liquids on_use = function(itemstack, user, pointed_thing) - return replacer.inspect(itemstack, user, pointed_thing) - end, + return replacer.inspect(itemstack, user, pointed_thing) + end, - on_place = function(itemstack, placer, pointed_thing) - return replacer.inspect(itemstack, placer, pointed_thing) - end, + on_place = function(itemstack, placer, pointed_thing) + return replacer.inspect(itemstack, placer, pointed_thing) + end, }) From ea00418f8a6b1c73b477a0f79d6171bec16f9831 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Mon, 22 Mar 2021 22:42:26 +0100 Subject: [PATCH 078/366] potential bug-fix and nicer coords --- inspect.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/inspect.lua b/inspect.lua index e508883..544f4b9 100644 --- a/inspect.lua +++ b/inspect.lua @@ -35,6 +35,13 @@ minetest.register_tool('replacer:inspect', { end, }) +local function nice_pos_string(pos) + local no_info = '' + if 'table' ~= type(pos) then return no_info end + if not (pos.x and pos.y and pos.z) then return no_info end + pos = { x = math.floor(pos.x), y = math.floor(pos.y), z = math.floor(pos.z) } + return minetest.pos_to_string(pos) +end replacer.inspect = function(_, user, pointed_thing, mode) if nil == user or nil == pointed_thing then @@ -82,7 +89,9 @@ replacer.inspect = function(_, user, pointed_thing, mode) end end - text = text .. ' at ' .. minetest.pos_to_string(ref:getpos()) + if ref then + text = text .. ' at ' .. nice_pos_string(ref:getpos()) + end minetest.chat_send_player(name, text) return nil elseif 'node' ~= pointed_thing.type then From fbc406f9cd49b8a1f9c7eaa733b808e3f10bc9e8 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Mon, 22 Mar 2021 22:43:46 +0100 Subject: [PATCH 079/366] show owner and protection information Strangely, when testing on mobs spawned by /spawnentity vanish after using inspection tool on them. --- inspect.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/inspect.lua b/inspect.lua index 544f4b9..b532a43 100644 --- a/inspect.lua +++ b/inspect.lua @@ -81,6 +81,13 @@ replacer.inspect = function(_, user, pointed_thing, mode) .. tostring(math.floor(sdata.age / 60)) .. ' minutes ago' end + if sdata.owner then + text = text .. ' owned' + if true == sdata.protected then + text = text .. ' and protected' + end + text = text .. ' by ' .. sdata.owner + end end elseif luaob then text = text .. 'an object "' .. luaob.name .. '"' From 191ef5bf8adb404ea3393da46ac0bfbe56416829 Mon Sep 17 00:00:00 2001 From: SwissalpS Date: Tue, 23 Mar 2021 00:41:49 +0100 Subject: [PATCH 080/366] show more info about traders and farmers --- inspect.lua | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/inspect.lua b/inspect.lua index b532a43..29640eb 100644 --- a/inspect.lua +++ b/inspect.lua @@ -51,6 +51,7 @@ replacer.inspect = function(_, user, pointed_thing, mode) local keys = user:get_player_control() if 'object' == pointed_thing.type then + local inventory_text = nil local text = 'This is ' local ref = pointed_thing.ref if not ref then @@ -84,10 +85,38 @@ replacer.inspect = function(_, user, pointed_thing, mode) if sdata.owner then text = text .. ' owned' if true == sdata.protected then - text = text .. ' and protected' + if true == sdata.locked then + text = text .. ', protected and locked' + else + text = text .. ' and protected' + end + else + if true == sdata.locked then + text = text .. ' and locked' + end end text = text .. ' by ' .. sdata.owner end + if 'string' == type(sdata.order) then + text = text .. ' with order to ' .. sdata.order + end + if 'table' == type(sdata.inv) then + local item_count = 0 + local type_count = 0 + for k, v in pairs(sdata.inv) do + type_count = type_count + 1 + item_count = item_count + v + end + if 0 < type_count then + inventory_text = '\nHas ' + if 1 < type_count then + inventory_text = inventory_text .. type_count + .. ' different types of items, ' + end + inventory_text = inventory_text .. 'total of ' + .. item_count .. ' items in inventory.' + end + end end elseif luaob then text = text .. 'an object "' .. luaob.name .. '"' @@ -99,6 +128,7 @@ replacer.inspect = function(_, user, pointed_thing, mode) if ref then text = text .. ' at ' .. nice_pos_string(ref:getpos()) end + if inventory_text then text = text .. inventory_text end minetest.chat_send_player(name, text) return nil elseif 'node' ~= pointed_thing.type then From 530ecdad0e85e8abd38d0d42aa5208c734628eeb Mon Sep 17 00:00:00 2001 From: SX <50966843+S-S-X@users.noreply.github.com> Date: Sun, 18 Jul 2021 02:38:46 +0300 Subject: [PATCH 081/366] Simple check for missing item --- replacer.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/replacer.lua b/replacer.lua index 5b5b946..0dc3072 100644 --- a/replacer.lua +++ b/replacer.lua @@ -92,6 +92,10 @@ function replacer.set_data(stack, node, mode) colourName = " " .. colourName end local toolItemName = stack:get_name() + if (not toolItemName) or (not minetest.registered_items[toolItemName]) then + metaRef:set_string("description", "Unknown item") + return "Unknown item" + end local toolName = minetest.registered_items[toolItemName].description local short_description = "(" .. param1 .. " " .. param2 .. colourName .. ") " .. node.name From 92cec2fc32ba2bc4668253a4f2b953ebf45fd6ba Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 30 Sep 2021 12:58:54 +0200 Subject: [PATCH 082/366] Fix Unknown Item crash earlier also added some description without giving away how to 'exploit' --- replacer.lua | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/replacer.lua b/replacer.lua index 0dc3072..97bfd4a 100644 --- a/replacer.lua +++ b/replacer.lua @@ -74,6 +74,14 @@ end function replacer.set_data(stack, node, mode) mode = mode or r.modes[1] + local toolItemName = stack:get_name() + local toolDef = minetest.registered_items[toolItemName] + -- some accidents or deliberate actions can be harmful + -- if user has an unknown item. So we check here to + -- prevent possible server crash + if (not toolItemName) or (not toolDef) then + return "Unkown Item" + end local param1 = tostring(node.param1 or 0) local param2 = tostring(node.param2 or 0) local nodeName = node.name or replacer.tool_default_node @@ -91,12 +99,7 @@ function replacer.set_data(stack, node, mode) if 0 < #colourName then colourName = " " .. colourName end - local toolItemName = stack:get_name() - if (not toolItemName) or (not minetest.registered_items[toolItemName]) then - metaRef:set_string("description", "Unknown item") - return "Unknown item" - end - local toolName = minetest.registered_items[toolItemName].description + local toolName = toolDef.description local short_description = "(" .. param1 .. " " .. param2 .. colourName .. ") " .. node.name local description = toolName .. "\n" From a6a952c49ecf32c21c539147aa6f03451d9f7e23 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 30 Sep 2021 13:02:14 +0200 Subject: [PATCH 083/366] whitespace --- replacer.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replacer.lua b/replacer.lua index 97bfd4a..524d05b 100644 --- a/replacer.lua +++ b/replacer.lua @@ -101,7 +101,7 @@ function replacer.set_data(stack, node, mode) end local toolName = toolDef.description local short_description = "(" .. param1 .. " " .. param2 - .. colourName .. ") " .. node.name + .. colourName .. ") " .. node.name local description = toolName .. "\n" .. short_description .. "\n" .. nodeDescription -- .. r.titleCase(colourName) From 8faea5c509edfbc39b3c0836f265f3777f447255 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 30 Sep 2021 13:05:26 +0200 Subject: [PATCH 084/366] changelog update --- init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/init.lua b/init.lua index 28a506a..c9824cf 100644 --- a/init.lua +++ b/init.lua @@ -19,6 +19,8 @@ -- Version 3.0 -- Changelog: +-- 30.09.2021 * SwissalpS merged patch provided by S-S-X to prevent a rare but possible crash with +-- Unknown Items in hotbar -- 15.10.2020 * SwissalpS cleaned up inspector code and made inspector better readable on smaller screens -- * SwissalpS added backward compatibility for non technic servers, restored -- creative/give behaviour and fixed the 'too many nodes detected' issue From 1a856d665eb5fd25569066c46c52b3342280dcee Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 30 Sep 2021 14:04:11 +0200 Subject: [PATCH 085/366] cleanup tool set messages moved the strings to replacer_blabla.lua --- replacer.lua | 9 ++++----- replacer_blabla.lua | 2 ++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/replacer.lua b/replacer.lua index 524d05b..a67ca94 100644 --- a/replacer.lua +++ b/replacer.lua @@ -100,11 +100,10 @@ function replacer.set_data(stack, node, mode) colourName = " " .. colourName end local toolName = toolDef.description - local short_description = "(" .. param1 .. " " .. param2 - .. colourName .. ") " .. node.name - local description = toolName .. "\n" - .. short_description .. "\n" - .. nodeDescription -- .. r.titleCase(colourName) + local short_description = rb.tool_short_description:format( + param1, param2, colourName, node.name) + local description = rb.tool_long_description:format( + toolName, short_description, nodeDescription) -- r.titleCase(colourName)) metaRef:set_string("description", description) return short_description diff --git a/replacer_blabla.lua b/replacer_blabla.lua index b5cc986..d539656 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -29,4 +29,6 @@ replacer.blabla.limit_override = 'Setting already set node-limit for "%s" was %d replacer.blabla.limit_insert = 'Setting node-limit for "%s" to %d.' replacer.blabla.blacklist_insert = 'Blacklisted "%s".' replacer.blabla.timed_out = 'Time-limit reached.' +replacer.blabla.tool_short_description = "(%s %s%s) %s" +replacer.blabla.tool_long_description = "%s\n%s\n%s" From 6892aa353cefcc1153d6b4d651ec1a3adfe0f85e Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 30 Sep 2021 14:04:27 +0200 Subject: [PATCH 086/366] whitespace --- replacer_blabla.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/replacer_blabla.lua b/replacer_blabla.lua index d539656..143e1d9 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -3,7 +3,6 @@ replacer.blabla.log = "[replacer] %s: %s" replacer.blabla.mode_single = "Replace single node." replacer.blabla.mode_field = "Left click: Replace field of nodes of a kind where a translucent node is in front of it. Right click: Replace field of air where no translucent node is behind the air." replacer.blabla.mode_crust = "Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air. Right click: Replace air nodes which touch the crust" - replacer.blabla.protected_at = "Protected at %s" replacer.blabla.blacklisted = 'Replacing nodes of type "%s" is not allowed on this server. Replacement failed.' replacer.blabla.run_out = 'You have no further "%s". Replacement failed.' From c4ac78bfa756ac6dee961701fc8a25446b8ee567 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 30 Sep 2021 14:07:08 +0200 Subject: [PATCH 087/366] changelog update --- init.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index c9824cf..429f4a6 100644 --- a/init.lua +++ b/init.lua @@ -20,7 +20,8 @@ -- Changelog: -- 30.09.2021 * SwissalpS merged patch provided by S-S-X to prevent a rare but possible crash with --- Unknown Items in hotbar +-- Unknown Items in hotbar +-- * Also cleaned up tool change messages to blabla.lua -- 15.10.2020 * SwissalpS cleaned up inspector code and made inspector better readable on smaller screens -- * SwissalpS added backward compatibility for non technic servers, restored -- creative/give behaviour and fixed the 'too many nodes detected' issue From 0c992d92021c851af233cba67b2beda9f3e82acf Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 30 Sep 2021 14:24:07 +0200 Subject: [PATCH 088/366] homogonized quote usage in replacer_blabla.lua --- replacer_blabla.lua | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/replacer_blabla.lua b/replacer_blabla.lua index 143e1d9..8ef3dad 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -1,9 +1,9 @@ replacer.blabla = {} -replacer.blabla.log = "[replacer] %s: %s" -replacer.blabla.mode_single = "Replace single node." -replacer.blabla.mode_field = "Left click: Replace field of nodes of a kind where a translucent node is in front of it. Right click: Replace field of air where no translucent node is behind the air." -replacer.blabla.mode_crust = "Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air. Right click: Replace air nodes which touch the crust" -replacer.blabla.protected_at = "Protected at %s" +replacer.blabla.log = '[replacer] %s: %s' +replacer.blabla.mode_single = 'Replace single node.' +replacer.blabla.mode_field = 'Left click: Replace field of nodes of a kind where a translucent node is in front of it. Right click: Replace field of air where no translucent node is behind the air.' +replacer.blabla.mode_crust = 'Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air. Right click: Replace air nodes which touch the crust' +replacer.blabla.protected_at = 'Protected at %s' replacer.blabla.blacklisted = 'Replacing nodes of type "%s" is not allowed on this server. Replacement failed.' replacer.blabla.run_out = 'You have no further "%s". Replacement failed.' replacer.blabla.attempt_unknown_replace = 'Unknown node: "%s"' @@ -11,23 +11,23 @@ replacer.blabla.attempt_unknown_place = 'Unknown node to place: "%s"' replacer.blabla.can_not_dig = 'Could not dig "%s" properly.' replacer.blabla.can_not_place = 'Could not place "%s".' replacer.blabla.not_a_node = 'Error: "%s" is not a node.' -replacer.blabla.wait_for_load = "Target node not yet loaded. Please wait a moment for the server to catch up." -replacer.blabla.nothing_to_replace = "Nothing to replace." -replacer.blabla.need_more_charge = "Not enough charge to use this mode." -replacer.blabla.too_many_nodes_detected = "Aborted, too many nodes detected." -replacer.blabla.charge_required = "Need %d charge to replace %d nodes." -replacer.blabla.count_replaced = "%s nodes replaced." -replacer.blabla.mode_changed = "Mode changed to %s: %s" -replacer.blabla.none_selected = "Error: No node selected." +replacer.blabla.wait_for_load = 'Target node not yet loaded. Please wait a moment for the server to catch up.' +replacer.blabla.nothing_to_replace = 'Nothing to replace.' +replacer.blabla.need_more_charge = 'Not enough charge to use this mode.' +replacer.blabla.too_many_nodes_detected = 'Aborted, too many nodes detected.' +replacer.blabla.charge_required = 'Need %d charge to replace %d nodes.' +replacer.blabla.count_replaced = '%s nodes replaced.' +replacer.blabla.mode_changed = 'Mode changed to %s: %s' +replacer.blabla.none_selected = 'Error: No node selected.' replacer.blabla.not_in_creative = 'Item not in creative invenotry: "%s".' replacer.blabla.not_in_inventory = 'Item not in your inventory: "%s".' replacer.blabla.set_to = 'Node replacement tool set to:\n%s.' -replacer.blabla.description_basic = "Node replacement tool" -replacer.blabla.description_technic = "Node replacement tool (technic)" +replacer.blabla.description_basic = 'Node replacement tool' +replacer.blabla.description_technic = 'Node replacement tool (technic)' replacer.blabla.limit_override = 'Setting already set node-limit for "%s" was %d.' replacer.blabla.limit_insert = 'Setting node-limit for "%s" to %d.' replacer.blabla.blacklist_insert = 'Blacklisted "%s".' replacer.blabla.timed_out = 'Time-limit reached.' -replacer.blabla.tool_short_description = "(%s %s%s) %s" -replacer.blabla.tool_long_description = "%s\n%s\n%s" +replacer.blabla.tool_short_description = '(%s %s%s) %s' +replacer.blabla.tool_long_description = '%s\n%s\n%s' From 41e05fd42b98f895b9891c7f399a29b7d4f870f6 Mon Sep 17 00:00:00 2001 From: SX <50966843+S-S-X@users.noreply.github.com> Date: Tue, 2 Nov 2021 02:33:37 +0200 Subject: [PATCH 089/366] Use new Technic Plus tool API --- replacer.lua | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/replacer.lua b/replacer.lua index a67ca94..f4274c2 100644 --- a/replacer.lua +++ b/replacer.lua @@ -111,24 +111,29 @@ end local discharge_replacer if replacer.has_technic_mod then - -- technic still stores data serialized, so this is the nearest we get to current standard - function replacer.get_charge(itemstack) - local meta = minetest.deserialize(itemstack:get_meta():get_string('')) - if (not meta) or (not meta.charge) then - return 0 + if technic.plus then + replacer.get_charge = technic.get_RE_charge + replacer.set_charge = technic.set_RE_charge + else + -- technic still stores data serialized, so this is the nearest we get to current standard + function replacer.get_charge(itemstack) + local meta = minetest.deserialize(itemstack:get_meta():get_string('')) + if (not meta) or (not meta.charge) then + return 0 + end + return meta.charge end - return meta.charge - end - function replacer.set_charge(itemstack, charge, max) - technic.set_RE_wear(itemstack, charge, max) - local metaRef = itemstack:get_meta() - local meta = minetest.deserialize(metaRef:get_string('')) - if (not meta) or (not meta.charge) then - meta = { charge = 0 } + function replacer.set_charge(itemstack, charge, max) + technic.set_RE_wear(itemstack, charge, max) + local metaRef = itemstack:get_meta() + local meta = minetest.deserialize(metaRef:get_string('')) + if (not meta) or (not meta.charge) then + meta = { charge = 0 } + end + meta.charge = charge + metaRef:set_string('', minetest.serialize(meta)) end - meta.charge = charge - metaRef:set_string('', minetest.serialize(meta)) end function discharge_replacer(creative_enabled, has_give, charge, itemstack, From 812f176daa9daeb0f05199a2735b0d32aa9497a2 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 2 Dec 2021 22:27:18 +0100 Subject: [PATCH 090/366] whitespace cleanup --- init.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/init.lua b/init.lua index 429f4a6..278604d 100644 --- a/init.lua +++ b/init.lua @@ -108,15 +108,15 @@ replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') and minetest.global_exists('unifieddyes') -- utilities -dofile(path .. "/utils.lua") +dofile(path .. '/utils.lua') -- unifiedddyes support functions -dofile(path .. "/unifieddyes.lua") +dofile(path .. '/unifieddyes.lua') -- adds a tool for inspecting nodes and entities -dofile(path .. "/inspect.lua") -dofile(path .. "/replacer_blabla.lua") -dofile(path .. "/replacer_patterns.lua") -dofile(path .. "/replacer.lua") -dofile(path .. "/crafts.lua") +dofile(path .. '/inspect.lua') +dofile(path .. '/replacer_blabla.lua') +dofile(path .. '/replacer_patterns.lua') +dofile(path .. '/replacer.lua') +dofile(path .. '/crafts.lua') -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- print('[replacer] loaded') From f9c85ea285c223429db0cb81e391a4d6c37a0914 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 2 Dec 2021 22:27:47 +0100 Subject: [PATCH 091/366] add chatcommand --- chat_commands.lua | 34 ++++++++++++++++++++++++++++++++++ replacer_blabla.lua | 6 ++++++ 2 files changed, 40 insertions(+) create mode 100644 chat_commands.lua diff --git a/chat_commands.lua b/chat_commands.lua new file mode 100644 index 0000000..09d1ac1 --- /dev/null +++ b/chat_commands.lua @@ -0,0 +1,34 @@ + +local rb = replacer.blabla + +replacer.chatcommand_mute = { + + params = rb.ccm_params, + description = rb.ccm_description, + func = function(name, param) + + local player = minetest.get_player_by_name(name) + if not player then + return false, rb.ccm_player_not_found + end + local meta = player:get_meta() + if not meta then + return false, rb.ccm_player_meta_error + end + + local lower = string.lower(param) + if 'on' == lower then + meta:set_int('replacer_mute', 1) + elseif 'off' == lower then + meta:set_int('replacer_mute', 0) + else + return false, rb.ccm_hint + end + + return true, '' + + end +} + +minetest.register_chatcommand('replacer_mute', replacer.chatcommand_mute) + diff --git a/replacer_blabla.lua b/replacer_blabla.lua index 8ef3dad..a37883c 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -30,4 +30,10 @@ replacer.blabla.blacklist_insert = 'Blacklisted "%s".' replacer.blabla.timed_out = 'Time-limit reached.' replacer.blabla.tool_short_description = '(%s %s%s) %s' replacer.blabla.tool_long_description = '%s\n%s\n%s' +replacer.blabla.ccm_params = '[ on | off ]' +replacer.blabla.ccm_description = 'Toggles mute of replacer tool.\nWhen on, no ' + .. 'messages are posted to chat. If off, verbose mode is on.' +replacer.blabla.ccm_player_not_found = 'Player not found' +replacer.blabla.ccm_player_meta_error = 'Player meta not existant' +replacer.blabla.ccm_hint = 'Valid parameter is either "on" or "off"' From 4be57da35bb9d4d13dcc9c1be6d547d6d224827c Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 2 Dec 2021 22:28:32 +0100 Subject: [PATCH 092/366] use muting --- init.lua | 1 + replacer.lua | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 278604d..2d771dd 100644 --- a/init.lua +++ b/init.lua @@ -117,6 +117,7 @@ dofile(path .. '/replacer_blabla.lua') dofile(path .. '/replacer_patterns.lua') dofile(path .. '/replacer.lua') dofile(path .. '/crafts.lua') +dofile(path .. '/chat_commands.lua') -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- print('[replacer] loaded') diff --git a/replacer.lua b/replacer.lua index f4274c2..bfc42f3 100644 --- a/replacer.lua +++ b/replacer.lua @@ -8,8 +8,13 @@ local rp = replacer.patterns local rud = replacer.unifieddyes function replacer.inform(name, msg) + minetest.log('info', rb.log:format(name, msg)) + local player = minetest.get_player_by_name(name) + if not player then return end + local meta = player:get_meta() + if not meta then return end + if 0 < meta:get_int('replacer_mute') then return end minetest.chat_send_player(name, msg) - minetest.log("info", rb.log:format(name, msg)) end replacer.modes = {"single", "field", "crust"} From 94fc003fd000945ffc7f930e3257f642ea22d121 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 2 Dec 2021 22:36:53 +0100 Subject: [PATCH 093/366] version bump 3.1 --- init.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 2d771dd..0c35e70 100644 --- a/init.lua +++ b/init.lua @@ -16,9 +16,10 @@ along with this program. If not, see . --]] --- Version 3.0 +-- Version 3.1 -- Changelog: +-- 02.12.2021 * SwissalpS added /replacer_mute command -- 30.09.2021 * SwissalpS merged patch provided by S-S-X to prevent a rare but possible crash with -- Unknown Items in hotbar -- * Also cleaned up tool change messages to blabla.lua From 174e768a7a713fb4f75d30cedb252dec51552d9a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 12 Jan 2022 21:19:05 +0100 Subject: [PATCH 094/366] improve field and crust modes respect param2 when replacing in field mode not doing so in crust mode as that would break usefulness also check for vacuum when placing in crust mode --- replacer.lua | 1 + replacer_patterns.lua | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/replacer.lua b/replacer.lua index bfc42f3..cbbc327 100644 --- a/replacer.lua +++ b/replacer.lua @@ -366,6 +366,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) end right_clicked = (right_clicked and true) or false ps, num = rp.get_ps(pos, { func = rp.field_position, name = node_toreplace.name, + param2 = node_toreplace.param2, pname = name, above = pdif, right_clicked = right_clicked }, adps, max_nodes) elseif r.modes[3] == mode then -- crust diff --git a/replacer_patterns.lua b/replacer_patterns.lua index 6402b7d..d660c0b 100644 --- a/replacer_patterns.lua +++ b/replacer_patterns.lua @@ -16,8 +16,21 @@ function replacer.patterns.get_node(pos) end -- tests if there's a node at pos which should be replaced -function replacer.patterns.replaceable(pos, name, pname) - return (rp.get_node(pos).name == name) and (not minetest.is_protected(pos, pname)) +function replacer.patterns.replaceable(pos, name, pname, param2) + local node = rp.get_node(pos) + if nil == param2 then + -- crust mode ignores param2 + if 'air' ~= name then + return (node.name == name) and (not minetest.is_protected(pos, pname)) + end + -- right clicking in crust mode checks for air, but vacuum should work too + -- TODO: add mechanism to register allowed types + -- some servers might have other nodes like mars-lights that should be allowed too + -- maybe dummy lights, on the other hand, it might be useful to be able to stop replacer with dummy lights + return (('air' == node.name) or ('vacuum:vacuum' == node.name)) and (not minetest.is_protected(pos, pname)) + end + -- in field mode we also check that param2 is the same as the initial node that was clicked on + return (node.name == name) and (node.param2 == param2) and (not minetest.is_protected(pos, pname)) end replacer.patterns.translucent_nodes = {} @@ -36,7 +49,7 @@ function replacer.patterns.node_translucent(name) end function replacer.patterns.field_position(pos, data) - return rp.replaceable(pos, data.name, data.pname) + return rp.replaceable(pos, data.name, data.pname, data.param2) and rp.node_translucent( rp.get_node(vector.add(data.above, pos)).name) ~= data.right_clicked end From d4374109b390bf27446407fd329486b4e3ac9bc4 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 12 Jan 2022 21:25:19 +0100 Subject: [PATCH 095/366] version bump --- init.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 0c35e70..7cbc2e9 100644 --- a/init.lua +++ b/init.lua @@ -16,9 +16,11 @@ along with this program. If not, see . --]] --- Version 3.1 +-- Version 3.2 (20220112) -- Changelog: +-- 12.01.2022 * SwissalpS improved field mode: when replacing also check for same param2 +-- improved crust mode: when placing also allow vacuum instead of only air -- 02.12.2021 * SwissalpS added /replacer_mute command -- 30.09.2021 * SwissalpS merged patch provided by S-S-X to prevent a rare but possible crash with -- Unknown Items in hotbar @@ -57,6 +59,8 @@ local path = minetest.get_modpath("replacer") replacer = {} +replacer.version = 20220112 + -- limit by node, use replacer.register_limit(sName, iMax) replacer.limit_list = {} From 8423f3464e1179a0780a7d9450daccf34b7b9ddb Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 13 Jan 2022 04:19:14 +0100 Subject: [PATCH 096/366] cleanup: double to single quotes --- init.lua | 20 +++++------ replacer.lua | 83 +++++++++++++++++++++---------------------- replacer_patterns.lua | 4 +-- 3 files changed, 53 insertions(+), 54 deletions(-) diff --git a/init.lua b/init.lua index 94cab56..00f6d66 100644 --- a/init.lua +++ b/init.lua @@ -55,7 +55,7 @@ -- * receipe changed -- * inventory image added -local path = minetest.get_modpath("replacer") +local path = minetest.get_modpath('replacer') replacer = {} @@ -69,22 +69,22 @@ replacer.blacklist = {} -- playing with tnt and creative building are usually contradictory -- (except when doing large-scale landscaping in singleplayer) -replacer.blacklist["tnt:boom"] = true -replacer.blacklist["tnt:gunpowder"] = true -replacer.blacklist["tnt:gunpowder_burning"] = true -replacer.blacklist["tnt:tnt"] = true +replacer.blacklist['tnt:boom'] = true +replacer.blacklist['tnt:gunpowder'] = true +replacer.blacklist['tnt:gunpowder_burning'] = true +replacer.blacklist['tnt:tnt'] = true -- prevent accidental replacement of your protector -replacer.blacklist["protector:protect"] = true -replacer.blacklist["protector:protect2"] = true +replacer.blacklist['protector:protect'] = true +replacer.blacklist['protector:protect2'] = true -- charge limits replacer.max_charge = 30000 replacer.charge_per_node = 15 -- node count limit -replacer.max_nodes = tonumber(minetest.settings:get("replacer.max_nodes") or 3168) --- Time limit when placing the nodes, in seconds -replacer.max_time = tonumber(minetest.settings:get("replacer.max_time") or 1.0) +replacer.max_nodes = tonumber(minetest.settings:get('replacer.max_nodes') or 3168) +-- Time limit when placing the nodes, in seconds (not including search time) +replacer.max_time = tonumber(minetest.settings:get('replacer.max_time') or 1.0) -- select which recipes to hide (not all combinations make sense) replacer.hide_recipe_basic = diff --git a/replacer.lua b/replacer.lua index b87898f..b8d0944 100644 --- a/replacer.lua +++ b/replacer.lua @@ -1,6 +1,6 @@ -replacer.tool_name_basic = "replacer:replacer" -replacer.tool_name_technic = "replacer:replacer_technic" -replacer.tool_default_node = "default:dirt" +replacer.tool_name_basic = 'replacer:replacer' +replacer.tool_name_technic = 'replacer:replacer_technic' +replacer.tool_default_node = 'default:dirt' local r = replacer local rb = replacer.blabla @@ -17,7 +17,7 @@ function replacer.inform(name, msg) minetest.chat_send_player(name, msg) end -replacer.modes = {"single", "field", "crust"} +replacer.modes = { 'single', 'field', 'crust' } for n = 1, #r.modes do r.modes[r.modes[n]] = n end @@ -28,10 +28,9 @@ replacer.mode_infos[r.modes[2]] = rb.mode_field replacer.mode_infos[r.modes[3]] = rb.mode_crust replacer.mode_colours = {} -replacer.mode_colours[r.modes[1]] = "#ffffff" -replacer.mode_colours[r.modes[2]] = "#54FFAC" -replacer.mode_colours[r.modes[3]] = "#9F6200" - +replacer.mode_colours[r.modes[1]] = '#ffffff' +replacer.mode_colours[r.modes[2]] = '#54FFAC' +replacer.mode_colours[r.modes[3]] = '#9F6200' local is_int = function(value) return type(value) == 'number' and math.floor(value) == value @@ -49,26 +48,26 @@ function replacer.register_limit(node_name, node_max) -- add to blacklist if limit is zero if 0 == node_max then replacer.blacklist[node_name] = true - minetest.log("info", rb.blacklist_insert:format(node_name)) + minetest.log('info', rb.blacklist_insert:format(node_name)) return end -- log info if already limited if nil ~= r.limit_list[node_name] then - minetest.log("info", rb.limit_override:format(node_name, r.limit_list[node_name])) + minetest.log('info', rb.limit_override:format(node_name, r.limit_list[node_name])) end r.limit_list[node_name] = node_max - minetest.log("info", rb.limit_insert:format(node_name, node_max)) + minetest.log('info', rb.limit_insert:format(node_name, node_max)) end function replacer.get_data(stack) local metaRef = stack:get_meta() - local data = metaRef:get_string("replacer"):split(" ") or {} + local data = metaRef:get_string('replacer'):split(' ') or {} local node = { name = data[1] or r.tool_default_node, param1 = tonumber(data[2]) or 0, param2 = tonumber(data[3]) or 0 } - local mode = metaRef:get_string("mode") + local mode = metaRef:get_string('mode') if nil == r.modes[mode] then mode = r.modes[1] end @@ -88,11 +87,11 @@ function replacer.set_data(stack, node, mode) local param1 = tostring(node.param1 or 0) local param2 = tostring(node.param2 or 0) local nodeName = node.name or replacer.tool_default_node - local metadata = nodeName .. " " .. param1 .. " " .. param2 + local metadata = nodeName .. ' ' .. param1 .. ' ' .. param2 local metaRef = stack:get_meta() - metaRef:set_string("mode", mode) - metaRef:set_string("replacer", metadata) - metaRef:set_string("color", r.mode_colours[mode]) + metaRef:set_string('mode', mode) + metaRef:set_string('replacer', metadata) + metaRef:set_string('color', r.mode_colours[mode]) local nodeDef = minetest.registered_items[node.name] local nodeDescription = nodeName if nodeDef and nodeDef.description then @@ -108,7 +107,7 @@ function replacer.set_data(stack, node, mode) local description = rb.tool_long_description:format( toolName, short_description, nodeDescription) -- r.titleCase(colourName)) - metaRef:set_string("description", description) + metaRef:set_string('description', description) return short_description end @@ -151,29 +150,29 @@ else function discharge_replacer() end end -replacer.form_name_modes = "replacer_replacer_mode_change" +replacer.form_name_modes = 'replacer_replacer_mode_change' function replacer.get_form_modes(current_mode) -- TODO: possibly add the info here instead of as -- a chat message - local formspec = "size[3.9,2]" - .. "label[0,0;Choose mode]" - .. "button_exit[0.0,0.6;2,0.5;" + local formspec = 'size[3.9,2]' + .. 'label[0,0;Choose mode]' + .. 'button_exit[0.0,0.6;2,0.5;' if r.modes[1] == current_mode then - formspec = formspec .. "_;< " .. r.modes[1] .. " >]" + formspec = formspec .. '_;< ' .. r.modes[1] .. ' >]' else - formspec = formspec .. "mode;" .. r.modes[1] .. "]" + formspec = formspec .. 'mode;' .. r.modes[1] .. ']' end - formspec = formspec .. "button_exit[1.9,0.6;2,0.5;" + formspec = formspec .. 'button_exit[1.9,0.6;2,0.5;' if r.modes[2] == current_mode then - formspec = formspec .. "_;< " .. r.modes[2] .. " >]" + formspec = formspec .. '_;< ' .. r.modes[2] .. ' >]' else - formspec = formspec .. "mode;" .. r.modes[2] .. "]" + formspec = formspec .. 'mode;' .. r.modes[2] .. ']' end - formspec = formspec .. "button_exit[0.0,1.4;2,0.5;" + formspec = formspec .. 'button_exit[0.0,1.4;2,0.5;' if r.modes[3] == current_mode then - formspec = formspec .. "_;< " .. r.modes[3] .. " >]" + formspec = formspec .. '_;< ' .. r.modes[3] .. ' >]' else - formspec = formspec .. "mode;" .. r.modes[3] .. "]" + formspec = formspec .. 'mode;' .. r.modes[3] .. ']' end return formspec end -- get_form_modes @@ -198,8 +197,8 @@ function replacer.replace_single_node(pos, node, nnd, player, name, inv, creativ end -- does the player carry at least one of the desired nodes with him? - if (not creative) and (not inv:contains_item("main", nnd.name)) then - return false, rb.run_out:format(nnd.name or "?") + if (not creative) and (not inv:contains_item('main', nnd.name)) then + return false, rb.run_out:format(nnd.name or '?') end local ndef = minetest.registered_nodes[node.name] @@ -226,7 +225,7 @@ function replacer.replace_single_node(pos, node, nnd, player, name, inv, creativ -- place the node similar to how a player does it -- (other than the pointed_thing) local newitem, succ = new_ndef.on_place(ItemStack(nnd.name), player, - { type = "node", under = vector.new(pos), above = vector.new(pos) }) + { type = 'node', under = vector.new(pos), above = vector.new(pos) }) -- replacing with trellis set, succ is returned but newitem is nil -- possible that other nodes react the same way. -- this allows users to dig nodes, I don't see reason to stop that @@ -238,10 +237,10 @@ function replacer.replace_single_node(pos, node, nnd, player, name, inv, creativ -- update inventory in survival mode if not creative then -- consume the item - inv:remove_item("main", nnd.name .. " 1") + inv:remove_item('main', nnd.name .. ' 1') -- if placing the node didn't result in empty stack… - if "" ~= newitem:to_string() then - inv:add_item("main", newitem) + if '' ~= newitem:to_string() then + inv:add_item('main', newitem) end end @@ -271,7 +270,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) local keys = user:get_player_control() local name = user:get_player_name() local creative_enabled = creative.is_enabled_for(name) - local has_give = minetest.check_player_privs(name, "give") + local has_give = minetest.check_player_privs(name, 'give') local is_technic = itemstack:get_name() == replacer.tool_name_technic local modes_are_available = is_technic or has_give or creative_enabled @@ -286,7 +285,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) return itemstack end - if "node" ~= pt.type then + if 'node' ~= pt.type then r.inform(name, rb.not_a_node:format(pt.type)) return end @@ -497,7 +496,7 @@ function replacer.common_on_place(itemstack, placer, pt) local keys = placer:get_player_control() local name = placer:get_player_name() local creative_enabled = creative.is_enabled_for(name) - local has_give = minetest.check_player_privs(name, "give") + local has_give = minetest.check_player_privs(name, 'give') local is_technic = itemstack:get_name() == replacer.tool_name_technic local modes_are_available = is_technic or has_give or creative_enabled @@ -523,7 +522,7 @@ function replacer.common_on_place(itemstack, placer, pt) end -- Select new node - if pt.type ~= "node" then + if 'node' ~= pt.type then r.inform(name, rb.none_selected) return end @@ -603,7 +602,7 @@ end -- common_on_place function replacer.tool_def_basic() return { description = rb.description_basic, - inventory_image = "replacer_replacer.png", + inventory_image = 'replacer_replacer.png', stack_max = 1, -- it has to store information - thus only one can be stacked liquids_pointable = true, -- it is ok to painit in/with water --node_placement_prediction = nil, @@ -620,7 +619,7 @@ if replacer.has_technic_mod then function replacer.tool_def_technic() local def = replacer.tool_def_basic() def.description = rb.description_technic - def.wear_represents = "technic_RE_charge" + def.wear_represents = 'technic_RE_charge' def.on_refill = technic.refill_RE_charge return def end diff --git a/replacer_patterns.lua b/replacer_patterns.lua index 504cff7..b71a8da 100644 --- a/replacer_patterns.lua +++ b/replacer_patterns.lua @@ -45,7 +45,7 @@ function replacer.patterns.node_translucent(name) return is_translucent end local data = minetest.registered_nodes[name] - if data and ((not data.drawtype) or ("normal" == data.drawtype)) then + if data and ((not data.drawtype) or ('normal' == data.drawtype)) then rp.translucent_nodes[name] = false return false end @@ -142,7 +142,7 @@ function replacer.patterns.reduce_crust_above_ps(data) local p, p2 for i = 1, data.num do p = data.ps[i] - if rp.replaceable(p, "air", data.pname) then + if rp.replaceable(p, 'air', data.pname) then for i = 1, 6 do p2 = rp.offsets_touch[i] if rp.replaceable(vector.add(p, p2), data.name, data.pname) then From 9fdff6049974f5cb9a1996cc85bbd277b53d95cd Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 13 Jan 2022 04:28:37 +0100 Subject: [PATCH 097/366] cleanup: whitespace and some combined with double to single quotation marks --- replacer.lua | 69 +++++++++++++++++++++++++++---------------- replacer_patterns.lua | 7 +++-- 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/replacer.lua b/replacer.lua index b8d0944..e00d469 100644 --- a/replacer.lua +++ b/replacer.lua @@ -253,8 +253,8 @@ function replacer.replace_single_node(pos, node, nnd, player, name, inv, creativ end -- fix orientation if needed - if placed_node.param1 ~= nnd.param1 - or placed_node.param2 ~= nnd.param2 then + if placed_node.param1 ~= nnd.param1 or + placed_node.param2 ~= nnd.param2 then minetest.swap_node(pos, nnd) end @@ -301,7 +301,8 @@ function replacer.replace(itemstack, user, pt, right_clicked) local nnd, mode = r.get_data(itemstack) if (node_toreplace.name == nnd.name) and (node_toreplace.param1 == nnd.param1) - and (node_toreplace.param2 == nnd.param2) then + and (node_toreplace.param2 == nnd.param2) + then r.inform(name, rb.nothing_to_replace) return end @@ -317,8 +318,8 @@ function replacer.replace(itemstack, user, pt, right_clicked) if r.modes[1] == mode then -- single - local succ, err = replacer.replace_single_node(pos, node_toreplace, nnd, user, - name, user:get_inventory(), creative_enabled) + local succ, err = replacer.replace_single_node(pos, node_toreplace, nnd, + user, name, user:get_inventory(), has_creative_or_give) if not succ then r.inform(name, err) end @@ -349,7 +350,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) local dirs, n = {}, 1 local p for coord in pairs(normal) do - if normal[coord] == 0 then + if 0 == normal[coord] then for a = -1, 1, 2 do p = { x = 0, y = 0, z = 0 } p[coord] = a @@ -369,9 +370,12 @@ function replacer.replace(itemstack, user, pt, right_clicked) ps, num = rp.search_positions({ startpos = pos, fdata = { - func = rp.field_position, name = node_toreplace.name, + func = rp.field_position, + name = node_toreplace.name, param2 = node_toreplace.param2, - pname = name, above = normal, right_clicked = right_clicked + pname = name, + above = normal, + right_clicked = right_clicked }, moves = dirs, max_positions = max_nodes, @@ -383,16 +387,23 @@ function replacer.replace(itemstack, user, pt, right_clicked) local nodename_clicked = rp.get_node(pt.under).name local aps, n, aboves = rp.search_positions({ startpos = pt.above, - fdata = {func = rp.crust_above_position, name = nodename_clicked, - pname = name}, + fdata = { + func = rp.crust_above_position, + name = nodename_clicked, + pname = name + }, moves = rp.offsets_touch, max_positions = max_nodes, radius_exceeded = 4, }) if right_clicked then -- Remove positions which are not directly touching the crust - local data = {ps = aps, num = n, name = nodename_clicked, - pname = name} + local data = { + ps = aps, + num = n, + name = nodename_clicked, + pname = name + } rp.reduce_crust_above_ps(data) ps, num = data.ps, data.num else @@ -400,15 +411,18 @@ function replacer.replace(itemstack, user, pt, right_clicked) -- air (or similar) node positions ps, num = rp.search_positions({ startpos = pt.under, - fdata = {func = rp.crust_under_position, - name = node_toreplace.name, pname = name, - aboves = aboves}, + fdata = { + func = rp.crust_under_position, + name = node_toreplace.name, + pname = name, + aboves = aboves + }, moves = rp.offsets_hollowcube, max_positions = max_nodes }) -- Keep only positions which are directly touching those previously -- found positions - local data = {aboves = aboves, ps = ps, num = num} + local data = { aboves = aboves, ps = ps, num = num } rp.reduce_crust_ps(data) ps, num = data.ps, data.num end @@ -452,7 +466,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) local inv = user:get_inventory() local num_nodes = 0 while not ps:is_empty() do - num_nodes = num_nodes+1 + num_nodes = num_nodes + 1 if num_nodes > max_nodes then -- This can happen if too many nodes were detected and the nodes -- limit has been set to a small value @@ -489,7 +503,7 @@ end -- replacer.replace -- special+right-click -> cycle mode (if tool/privs permit) -- sneak+right-click -> set node function replacer.common_on_place(itemstack, placer, pt) - if (not placer) or (not pt) then + if (not placer) or (not pt) then return end @@ -546,9 +560,10 @@ function replacer.common_on_place(itemstack, placer, pt) -- search for a drop available in creative inventory for i = 1, #drops do local name = drops[i] - if minetest.registered_nodes[name] - and minetest.get_item_group(name, - "not_in_creative_inventory") == 0 then + if minetest.registered_nodes[name] and + 0 == minetest.get_item_group(name, + 'not_in_creative_inventory') + then node.name = name found_item = true break @@ -563,8 +578,9 @@ function replacer.common_on_place(itemstack, placer, pt) -- search for a drop that the player has if possible for i = 1, #drops do local name = drops[i] - if minetest.registered_nodes[name] - and inv:contains_item("main", name) then + if minetest.registered_nodes[name] and + inv:contains_item('main', name) + then node.name = name found_item = true break @@ -576,9 +592,10 @@ function replacer.common_on_place(itemstack, placer, pt) -- then digging the nodes works for i = 1, #drops do local name = drops[i] - if minetest.registered_nodes[name] - and minetest.get_item_group(name, - "not_in_creative_inventory") == 0 then + if minetest.registered_nodes[name] and + 0 == minetest.get_item_group(name, + 'not_in_creative_inventory') + then node.name = name found_item = true break diff --git a/replacer_patterns.lua b/replacer_patterns.lua index b71a8da..b82ebbb 100644 --- a/replacer_patterns.lua +++ b/replacer_patterns.lua @@ -176,7 +176,7 @@ local function search_dfs(go, p, apply_move, moves) while true do -- Push current state onto the stack. - s:push({p = p, v = v}) + s:push({ p = p, v = v }) -- Go to the next position. p = apply_move(p, moves[v]) -- Now we check out the node. If it is in need of an update, @@ -226,7 +226,7 @@ function replacer.patterns.search_positions(params) if visiteds[vi] or not fdata.func(p, fdata) then return false end - n_founds = n_founds+1 + n_founds = n_founds + 1 founds[n_founds] = p visiteds[vi] = true if n_founds >= max_positions then @@ -260,7 +260,7 @@ function replacer.patterns.search_positions(params) if not visiteds_old[vi] and not fdata.func(p, fdata) then return false end - n_founds = n_founds+1 + n_founds = n_founds + 1 founds[n_founds] = p visiteds[vi] = true return true @@ -268,3 +268,4 @@ function replacer.patterns.search_positions(params) search_dfs(go, startpos, vector.add, moves) return founds, n_founds, visiteds end + From 713a0ad15d2e12ad65f975f51ab83d2d92387ac7 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 13 Jan 2022 04:32:22 +0100 Subject: [PATCH 098/366] combine creative and give, refactor discharge() --- replacer.lua | 57 ++++++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/replacer.lua b/replacer.lua index e00d469..c1d975f 100644 --- a/replacer.lua +++ b/replacer.lua @@ -111,7 +111,6 @@ function replacer.set_data(stack, node, mode) return short_description end -local discharge_replacer if replacer.has_technic_mod then if technic.plus then replacer.get_charge = technic.get_RE_charge @@ -138,16 +137,16 @@ if replacer.has_technic_mod then end end - function discharge_replacer(creative_enabled, has_give, charge, itemstack, - num_nodes) - if (not technic.creative_mode) and (not (creative_enabled or has_give)) then + function replacer.discharge(has_creative_or_give, charge, itemstack, num_nodes) + if (not technic.creative_mode) and (not has_creative_or_give) then charge = charge - replacer.charge_per_node * num_nodes r.set_charge(itemstack, charge, replacer.max_charge) return itemstack end end else - function discharge_replacer() end + function replacer.discharge() end + function replacer.get_charge() return replacer.max_charge end end replacer.form_name_modes = 'replacer_replacer_mode_change' @@ -271,8 +270,9 @@ function replacer.replace(itemstack, user, pt, right_clicked) local name = user:get_player_name() local creative_enabled = creative.is_enabled_for(name) local has_give = minetest.check_player_privs(name, 'give') + local has_creative_or_give = creative_enabled or has_give local is_technic = itemstack:get_name() == replacer.tool_name_technic - local modes_are_available = is_technic or has_give or creative_enabled + local modes_are_available = is_technic or creative_enabled -- is special-key held? (aka fast-key) if keys.aux1 then @@ -327,9 +327,8 @@ function replacer.replace(itemstack, user, pt, right_clicked) end local max_nodes = r.limit_list[nnd.name] or r.max_nodes - local charge - if replacer.has_technic_mod and (not (creative_enabled or has_give)) then - charge = r.get_charge(itemstack) + local charge = r.get_charge(itemstack) + if not has_creative_or_give then if charge < replacer.charge_per_node then r.inform(name, rb.need_more_charge) return @@ -432,7 +431,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) if 0 == num then local succ, err = r.replace_single_node(pos, node_toreplace, nnd, user, - name, user:get_inventory(), creative_enabled) + name, user:get_inventory(), has_creative_or_give) if not succ then r.inform(name, err) end @@ -440,8 +439,8 @@ function replacer.replace(itemstack, user, pt, right_clicked) end local charge_needed = replacer.charge_per_node * num - if replacer.has_technic_mod and (not (creative_enabled or has_give)) then - if (charge < charge_needed) then + if not has_creative_or_give then + if charge < charge_needed then num = math.floor(charge / replacer.charge_per_node) end end @@ -476,27 +475,20 @@ function replacer.replace(itemstack, user, pt, right_clicked) -- Take the position nearest to the start position local pos = ps:take() local succ, err = r.replace_single_node(pos, minetest.get_node(pos), nnd, - user, name, inv, creative_enabled) + user, name, inv, has_creative_or_give) if not succ then r.inform(name, err) - return discharge_replacer(creative_enabled, has_give, charge, - itemstack, num_nodes) + break end if minetest.get_us_time() - t_start > max_time_us then r.inform(name, rb.timed_out) - return discharge_replacer(creative_enabled, has_give, charge, - itemstack, num_nodes) + break end end - if replacer.has_technic_mod and (not technic.creative_mode) then - if not (creative_enabled or has_give) then - charge = charge - charge_needed - r.set_charge(itemstack, charge, replacer.max_charge) - return itemstack - end - end - r.inform(name, rb.count_replaced:format(num)) + r.discharge(has_creative_or_give, charge, itemstack, num_nodes) + if has_creative_or_give then r.inform(name, rb.count_replaced:format(num_nodes)) end + return itemstack end -- replacer.replace -- right-click with tool -> place set node @@ -511,8 +503,9 @@ function replacer.common_on_place(itemstack, placer, pt) local name = placer:get_player_name() local creative_enabled = creative.is_enabled_for(name) local has_give = minetest.check_player_privs(name, 'give') + local has_creative_or_give = creative_enabled or has_give local is_technic = itemstack:get_name() == replacer.tool_name_technic - local modes_are_available = is_technic or has_give or creative_enabled + local modes_are_available = is_technic or creative_enabled -- is special-key held? (aka fast-key) if keys.aux1 then @@ -549,14 +542,16 @@ function replacer.common_on_place(itemstack, placer, pt) end local inv = placer:get_inventory() - if (not (creative_enabled and has_give)) - and (not inv:contains_item("main", node.name)) then + if (not (creative_enabled and has_give)) and + (not inv:contains_item('main', node.name)) + then -- not in inv and not (creative and give) local found_item = false local drops = minetest.get_node_drops(node.name) - if creative_enabled then - if minetest.get_item_group(node.name, - "not_in_creative_inventory") > 0 then + if has_creative_or_give then + if 0 < minetest.get_item_group(node.name, + 'not_in_creative_inventory') + then -- search for a drop available in creative inventory for i = 1, #drops do local name = drops[i] From ea68794a060853291fff53a844195a6676342066 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 13 Jan 2022 04:39:14 +0100 Subject: [PATCH 099/366] adjustments to how recalc works --- init.lua | 4 ++++ replacer.lua | 2 -- replacer_patterns.lua | 7 +++---- settingtypes.txt | 4 ++++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/init.lua b/init.lua index 00f6d66..fbef9b6 100644 --- a/init.lua +++ b/init.lua @@ -85,6 +85,10 @@ replacer.charge_per_node = 15 replacer.max_nodes = tonumber(minetest.settings:get('replacer.max_nodes') or 3168) -- Time limit when placing the nodes, in seconds (not including search time) replacer.max_time = tonumber(minetest.settings:get('replacer.max_time') or 1.0) +-- Radius limit factor when more possible positions are found than either max_nodes or charge +-- Set to 0 or less for behaviour of before version 3.3 +-- [see replacer_patterns.lua>replacer.patterns.search_positions()] +replacer.radius_factor = tonumber(minetest.settings:get('replacer.radius_factor') or 0.4) -- select which recipes to hide (not all combinations make sense) replacer.hide_recipe_basic = diff --git a/replacer.lua b/replacer.lua index c1d975f..aeb4c3a 100644 --- a/replacer.lua +++ b/replacer.lua @@ -378,7 +378,6 @@ function replacer.replace(itemstack, user, pt, right_clicked) }, moves = dirs, max_positions = max_nodes, - radius_exceeded = 4, }) elseif r.modes[3] == mode then -- crust @@ -393,7 +392,6 @@ function replacer.replace(itemstack, user, pt, right_clicked) }, moves = rp.offsets_touch, max_positions = max_nodes, - radius_exceeded = 4, }) if right_clicked then -- Remove positions which are not directly touching the crust diff --git a/replacer_patterns.lua b/replacer_patterns.lua index b82ebbb..19f98dc 100644 --- a/replacer_patterns.lua +++ b/replacer_patterns.lua @@ -236,13 +236,13 @@ function replacer.patterns.search_positions(params) return true end search_dfs(go, startpos, vector.add, moves) - if n_founds < max_positions or not params.radius_exceeded then + if n_founds < max_positions or 0 >= replacer.radius_factor then return founds, n_founds, visiteds end -- Too many positions were found, so search again but only within -- a limited sphere around startpos - local rr = params.radius_exceeded ^ 2 + local rr = math.floor(max_positions ^ replacer.radius_factor + .5) local visiteds_old = visiteds visiteds = {} founds = {} @@ -252,8 +252,7 @@ function replacer.patterns.search_positions(params) if visiteds[vi] then return false end - local d = vector.subtract(p, startpos) - if d.x * d.x + d.y * d.y + d.z * d.z > rr then + if vector.distance(p, startpos) > rr then -- Outside of the sphere return false end diff --git a/settingtypes.txt b/settingtypes.txt index 1449ef3..921b64a 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -6,9 +6,13 @@ replacer.max_nodes (Maximum nodes to replace with one click) int 3168 # Some nodes take a long time to be placed. This value limits the time # in seconds in which the nodes are placed. replacer.max_time (Time limit when putting nodes) float 1.0 +# Radius limit factor when more possible positions are found than either max_nodes or charge +# Set to 0 or less for behaviour of before version 3.3 +replacer.radius_factor (A factor to adjust size limit) float 0.4 # You may choose to hide basic recipe but then make sure to enable the technic direct one replacer.hide_recipe_basic (Hide basic recipe) bool false # Hide the upgrade recipe. Only available if technic is installed. replacer.hide_recipe_technic_upgrade (Hide upgrade recipe) bool false # Hide the direct upgrade recipe. Only available if technic is installed. replacer.hide_recipe_technic_direct (Hide direct recipe) bool true + From efad6d8895d0b0afc47760b06f21628998e3f5d1 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 13 Jan 2022 04:39:35 +0100 Subject: [PATCH 100/366] version bump 3.3 --- init.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index fbef9b6..dcfc5f6 100644 --- a/init.lua +++ b/init.lua @@ -16,9 +16,12 @@ along with this program. If not, see . --]] --- Version 3.2 (20220112) +-- Version 3.3 (20220113) -- Changelog: +-- 13.01.2022 * SwissalpS worked in HybridDog's nicer pattern algorithm, modifying a little. +-- Also cleaned up some code and give-priv does not grant modes anymore, +-- creative still does. -- 12.01.2022 * SwissalpS improved field mode: when replacing also check for same param2 -- improved crust mode: when placing also allow vacuum instead of only air -- 02.12.2021 * SwissalpS added /replacer_mute command From de370465aa12b55ad5e575eef868b22693b65bc6 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 15:37:13 +0100 Subject: [PATCH 101/366] technic cable plate support also makes infrastructure for post on_place actions besides adding support for direct placing of certain nodes that have special nodes depending on rotation. --- compat_technic.lua | 14 ++++++++++++++ init.lua | 16 ++++++++++++++++ replacer.lua | 29 +++++++++++++++++++++++++---- replacer_blabla.lua | 4 ++++ 4 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 compat_technic.lua diff --git a/compat_technic.lua b/compat_technic.lua new file mode 100644 index 0000000..6ac2bbc --- /dev/null +++ b/compat_technic.lua @@ -0,0 +1,14 @@ +-- adds exceptions for technic cable plates +local lTiers = { 'lv', 'mv', 'hv' } +local lPlates = { '_digi_cable_plate_', '_cable_plate_' } +local sDropName, sBaseName +for _, sTier in ipairs(lTiers) do + for _, sPlate in ipairs(lPlates) do + sBaseName = 'technic:' .. sTier .. sPlate + sDropName = sBaseName .. '1' + for i = 2, 6 do + replacer.register_exception(sBaseName .. tostring(i), sDropName) + end + end +end + diff --git a/init.lua b/init.lua index 7cbc2e9..80e479f 100644 --- a/init.lua +++ b/init.lua @@ -64,6 +64,18 @@ replacer.version = 20220112 -- limit by node, use replacer.register_limit(sName, iMax) replacer.limit_list = {} +-- some nodes don't rotate using param2. They can be added +-- using replacer.register_exception(node_name, inv_node_name[, callback_function]) +-- where: node_name is the itemstring of node when placed in world +-- inv_node_name the itemstring of item in inventory to consume +-- callback_function is optional and will be called after node is placed. +-- It must return true on success and false, error_message on fail. +-- In order to register only a callback, pass two identical itemstrings. +-- Generally the callback is not needed as on_place() is called on the placed node +-- callback signature is: (pos, old_node_def, new_node_def, player_ref) +replacer.exception_map = {} +replacer.exception_callbacks = {} + -- don't allow these at all replacer.blacklist = {} @@ -123,6 +135,10 @@ dofile(path .. '/replacer_patterns.lua') dofile(path .. '/replacer.lua') dofile(path .. '/crafts.lua') dofile(path .. '/chat_commands.lua') +-- add cable plate exceptions +if replacer.has_technic_mod then + dofile(path .. '/compat_technic.lua') +end -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- print('[replacer] loaded') diff --git a/replacer.lua b/replacer.lua index cbbc327..4ce2a82 100644 --- a/replacer.lua +++ b/replacer.lua @@ -61,6 +61,17 @@ function replacer.register_limit(node_name, node_max) r.limit_list[node_name] = node_max minetest.log("info", rb.limit_insert:format(node_name, node_max)) end +function replacer.register_exception(node_name, drop_name, callback) + if r.exception_map[node_name] then + minetest.log('info', rb.reg_rot_exception_override:format(node_name)) + end + r.exception_map[node_name] = drop_name + minetest.log('info', rb.reg_rot_exception:format(node_name, drop_name)) + + if 'function' ~= type(callback) then return end + r.exception_callbacks[node_name] = callback + minetest.log('info', rb.reg_exception_callback:format(node_name)) +end -- register_exception function replacer.get_data(stack) local metaRef = stack:get_meta() @@ -200,7 +211,8 @@ function replacer.replace_single_node(pos, node, nnd, player, name, inv, creativ end -- does the player carry at least one of the desired nodes with him? - if (not creative) and (not inv:contains_item("main", nnd.name)) then + local inv_name = r.exception_map[nnd.name] or nnd.name + if (not creative) and (not inv:contains_item('main', inv_name)) then return false, rb.run_out:format(nnd.name or "?") end @@ -240,7 +252,7 @@ function replacer.replace_single_node(pos, node, nnd, player, name, inv, creativ -- update inventory in survival mode if not creative then -- consume the item - inv:remove_item("main", nnd.name .. " 1") + inv:remove_item("main", inv_name .. " 1") -- if placing the node didn't result in empty stack… if "" ~= newitem:to_string() then inv:add_item("main", newitem) @@ -261,6 +273,13 @@ function replacer.replace_single_node(pos, node, nnd, player, name, inv, creativ minetest.swap_node(pos, nnd) end + if 'function' == type(r.exception_callbacks[nnd.name]) then + local bRes, sMsg = r.exception_callbacks[nnd.name](pos, node, nnd, player) + if (not bRes) and sMsg and ('' ~= sMsg) then + r.inform(name, rb.callback_error:format(sMsg)) + end + end + return true end -- replace_single_node @@ -513,8 +532,10 @@ function replacer.common_on_place(itemstack, placer, pt) end local inv = placer:get_inventory() - if (not (creative_enabled and has_give)) - and (not inv:contains_item("main", node.name)) then + if (not (creative_enabled and has_give)) and + (not inv:contains_item("main", node.name)) and + (not r.exception_map[node.name]) + then -- not in inv and not (creative and give) local found_item = false local drops = minetest.get_node_drops(node.name) diff --git a/replacer_blabla.lua b/replacer_blabla.lua index a37883c..b0df580 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -36,4 +36,8 @@ replacer.blabla.ccm_description = 'Toggles mute of replacer tool.\nWhen on, no ' replacer.blabla.ccm_player_not_found = 'Player not found' replacer.blabla.ccm_player_meta_error = 'Player meta not existant' replacer.blabla.ccm_hint = 'Valid parameter is either "on" or "off"' +replacer.blabla.reg_rot_exception_override = 'replacer.register_rotation_exception ' + .. 'for "%s" already exists.' +replacer.blabla.reg_rot_exception = 'replacer.registered exception for "%s" to "%s"' +replacer.blabla.reg_exception_callback = 'replacer.registered after on_place callback for "%s"' From f2d11e7fe4aad5bbdb015137d3983b4d2472fe24 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 15:39:30 +0100 Subject: [PATCH 102/366] add scaffold for constraints --- init.lua | 1 + replacer_constrain.lua | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 replacer_constrain.lua diff --git a/init.lua b/init.lua index 80e479f..8eefa44 100644 --- a/init.lua +++ b/init.lua @@ -132,6 +132,7 @@ dofile(path .. '/unifieddyes.lua') dofile(path .. '/inspect.lua') dofile(path .. '/replacer_blabla.lua') dofile(path .. '/replacer_patterns.lua') +dofile(path .. '/replacer_constrain.lua') dofile(path .. '/replacer.lua') dofile(path .. '/crafts.lua') dofile(path .. '/chat_commands.lua') diff --git a/replacer_constrain.lua b/replacer_constrain.lua new file mode 100644 index 0000000..ddb6d61 --- /dev/null +++ b/replacer_constrain.lua @@ -0,0 +1,18 @@ +-- TODO: move all intervention functions in here, rename blacklist +-- +local r = replacer +local rb = replacer.blabla + +-- function that other mods, especially custom server mods, +-- can override. e.g. restrict usage of replacer in certain +-- areas, privs, throttling etc. +-- This is called before replacing the node/air and expects +-- a boolean return and in the case of fail, an optional message +-- that will be sent to player +function replacer.permit_replace(pos, old_node_def, new_node_def, + player_ref, player_name, player_inv, creative_or_give) + -- TODO: move protection check here + -- TODO: check inhibit_list + return true +end -- permit_replace + From 789a4295719f77548267dbe03da1d5cb3bf2f8e1 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 15:40:32 +0100 Subject: [PATCH 103/366] only send message if it is present and not empty --- replacer.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/replacer.lua b/replacer.lua index 4ce2a82..fa50eca 100644 --- a/replacer.lua +++ b/replacer.lua @@ -8,11 +8,11 @@ local rp = replacer.patterns local rud = replacer.unifieddyes function replacer.inform(name, msg) + if (not msg) or ('' == msg) then return end minetest.log('info', rb.log:format(name, msg)) local player = minetest.get_player_by_name(name) if not player then return end - local meta = player:get_meta() - if not meta then return end + local meta = player:get_meta() if not meta then return end if 0 < meta:get_int('replacer_mute') then return end minetest.chat_send_player(name, msg) end From 209a2c8286a49070d62ccddedb5228530f0de81d Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 15:42:01 +0100 Subject: [PATCH 104/366] 'whitespace' changes --- replacer.lua | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/replacer.lua b/replacer.lua index fa50eca..19e8ae0 100644 --- a/replacer.lua +++ b/replacer.lua @@ -15,7 +15,7 @@ function replacer.inform(name, msg) local meta = player:get_meta() if not meta then return end if 0 < meta:get_int('replacer_mute') then return end minetest.chat_send_player(name, msg) -end +end -- inform replacer.modes = {"single", "field", "crust"} for n = 1, #r.modes do @@ -60,7 +60,8 @@ function replacer.register_limit(node_name, node_max) end r.limit_list[node_name] = node_max minetest.log("info", rb.limit_insert:format(node_name, node_max)) -end +end -- register_limit + function replacer.register_exception(node_name, drop_name, callback) if r.exception_map[node_name] then minetest.log('info', rb.reg_rot_exception_override:format(node_name)) @@ -86,7 +87,7 @@ function replacer.get_data(stack) mode = r.modes[1] end return node, mode -end +end -- get_data function replacer.set_data(stack, node, mode) mode = mode or r.modes[1] @@ -123,7 +124,7 @@ function replacer.set_data(stack, node, mode) metaRef:set_string("description", description) return short_description -end +end -- set_data local discharge_replacer if replacer.has_technic_mod then From a62d281dcc48fe2f3c5a986c75ba915589cf3ff3 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 15:42:27 +0100 Subject: [PATCH 105/366] use inform --- replacer.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replacer.lua b/replacer.lua index 19e8ae0..9d4bd36 100644 --- a/replacer.lua +++ b/replacer.lua @@ -330,7 +330,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) end if replacer.blacklist[nnd.name] then - minetest.chat_send_player(name, rb.blacklisted:format(nnd.name)) + r.inform(name, rb.blacklisted:format(nnd.name)) return end From 6eedf1ea2ee1b2b540427a3b3de0866c4a48e588 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 15:43:56 +0100 Subject: [PATCH 106/366] shorten blabla --- replacer_blabla.lua | 79 +++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/replacer_blabla.lua b/replacer_blabla.lua index b0df580..b105fe2 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -1,43 +1,44 @@ replacer.blabla = {} -replacer.blabla.log = '[replacer] %s: %s' -replacer.blabla.mode_single = 'Replace single node.' -replacer.blabla.mode_field = 'Left click: Replace field of nodes of a kind where a translucent node is in front of it. Right click: Replace field of air where no translucent node is behind the air.' -replacer.blabla.mode_crust = 'Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air. Right click: Replace air nodes which touch the crust' -replacer.blabla.protected_at = 'Protected at %s' -replacer.blabla.blacklisted = 'Replacing nodes of type "%s" is not allowed on this server. Replacement failed.' -replacer.blabla.run_out = 'You have no further "%s". Replacement failed.' -replacer.blabla.attempt_unknown_replace = 'Unknown node: "%s"' -replacer.blabla.attempt_unknown_place = 'Unknown node to place: "%s"' -replacer.blabla.can_not_dig = 'Could not dig "%s" properly.' -replacer.blabla.can_not_place = 'Could not place "%s".' -replacer.blabla.not_a_node = 'Error: "%s" is not a node.' -replacer.blabla.wait_for_load = 'Target node not yet loaded. Please wait a moment for the server to catch up.' -replacer.blabla.nothing_to_replace = 'Nothing to replace.' -replacer.blabla.need_more_charge = 'Not enough charge to use this mode.' -replacer.blabla.too_many_nodes_detected = 'Aborted, too many nodes detected.' -replacer.blabla.charge_required = 'Need %d charge to replace %d nodes.' -replacer.blabla.count_replaced = '%s nodes replaced.' -replacer.blabla.mode_changed = 'Mode changed to %s: %s' -replacer.blabla.none_selected = 'Error: No node selected.' -replacer.blabla.not_in_creative = 'Item not in creative invenotry: "%s".' -replacer.blabla.not_in_inventory = 'Item not in your inventory: "%s".' -replacer.blabla.set_to = 'Node replacement tool set to:\n%s.' -replacer.blabla.description_basic = 'Node replacement tool' -replacer.blabla.description_technic = 'Node replacement tool (technic)' -replacer.blabla.limit_override = 'Setting already set node-limit for "%s" was %d.' -replacer.blabla.limit_insert = 'Setting node-limit for "%s" to %d.' -replacer.blabla.blacklist_insert = 'Blacklisted "%s".' -replacer.blabla.timed_out = 'Time-limit reached.' -replacer.blabla.tool_short_description = '(%s %s%s) %s' -replacer.blabla.tool_long_description = '%s\n%s\n%s' -replacer.blabla.ccm_params = '[ on | off ]' -replacer.blabla.ccm_description = 'Toggles mute of replacer tool.\nWhen on, no ' +local rb = replacer.blabla +rb.log = '[replacer] %s: %s' +rb.mode_single = 'Replace single node.' +rb.mode_field = 'Left click: Replace field of nodes of a kind where a translucent node is in front of it. Right click: Replace field of air where no translucent node is behind the air.' +rb.mode_crust = 'Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air. Right click: Replace air nodes which touch the crust' +rb.protected_at = 'Protected at %s' +rb.blacklisted = 'Replacing nodes of type "%s" is not allowed on this server. Replacement failed.' +rb.run_out = 'You have no further "%s". Replacement failed.' +rb.attempt_unknown_replace = 'Unknown node: "%s"' +rb.attempt_unknown_place = 'Unknown node to place: "%s"' +rb.can_not_dig = 'Could not dig "%s" properly.' +rb.can_not_place = 'Could not place "%s".' +rb.not_a_node = 'Error: "%s" is not a node.' +rb.wait_for_load = 'Target node not yet loaded. Please wait a moment for the server to catch up.' +rb.nothing_to_replace = 'Nothing to replace.' +rb.need_more_charge = 'Not enough charge to use this mode.' +rb.too_many_nodes_detected = 'Aborted, too many nodes detected.' +rb.charge_required = 'Need %d charge to replace %d nodes.' +rb.count_replaced = '%s nodes replaced.' +rb.mode_changed = 'Mode changed to %s: %s' +rb.none_selected = 'Error: No node selected.' +rb.not_in_creative = 'Item not in creative invenotry: "%s".' +rb.not_in_inventory = 'Item not in your inventory: "%s".' +rb.set_to = 'Node replacement tool set to:\n%s.' +rb.description_basic = 'Node replacement tool' +rb.description_technic = 'Node replacement tool (technic)' +rb.limit_override = 'Setting already set node-limit for "%s" was %d.' +rb.limit_insert = 'Setting node-limit for "%s" to %d.' +rb.blacklist_insert = 'Blacklisted "%s".' +rb.timed_out = 'Time-limit reached.' +rb.tool_short_description = '(%s %s%s) %s' +rb.tool_long_description = '%s\n%s\n%s' +rb.ccm_params = '[ on | off ]' +rb.ccm_description = 'Toggles mute of replacer tool.\nWhen on, no ' .. 'messages are posted to chat. If off, verbose mode is on.' -replacer.blabla.ccm_player_not_found = 'Player not found' -replacer.blabla.ccm_player_meta_error = 'Player meta not existant' -replacer.blabla.ccm_hint = 'Valid parameter is either "on" or "off"' -replacer.blabla.reg_rot_exception_override = 'replacer.register_rotation_exception ' +rb.ccm_player_not_found = 'Player not found' +rb.ccm_player_meta_error = 'Player meta not existant' +rb.ccm_hint = 'Valid parameter is either "on" or "off"' +rb.reg_rot_exception_override = 'replacer.register_rotation_exception ' .. 'for "%s" already exists.' -replacer.blabla.reg_rot_exception = 'replacer.registered exception for "%s" to "%s"' -replacer.blabla.reg_exception_callback = 'replacer.registered after on_place callback for "%s"' +rb.reg_rot_exception = 'replacer.registered exception for "%s" to "%s"' +rb.reg_exception_callback = 'replacer.registered after on_place callback for "%s"' From 50989266d83c90de1360191fefad5f448e9c5eac Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 16:13:45 +0100 Subject: [PATCH 107/366] version bump 3.4 --- init.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 7e7e001..df116f5 100644 --- a/init.lua +++ b/init.lua @@ -16,9 +16,10 @@ along with this program. If not, see . --]] --- Version 3.3 (20220113) +-- Version 3.4 (20220114) -- Changelog: +-- 14.01.2022 * SwissalpS added support for cable plates and similar nodes -- 13.01.2022 * SwissalpS worked in HybridDog's nicer pattern algorithm, modifying a little. -- Also cleaned up some code and give-priv does not grant modes anymore, -- creative still does. From 8fb9db6e99c7da4fb45e563ed7eb37dde3a70ed0 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 16:18:41 +0100 Subject: [PATCH 108/366] add override-able replace check function This allows servers to restrict usage under dynamic conditions --- replacer.lua | 9 +++------ replacer_constrain.lua | 11 +++++++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/replacer.lua b/replacer.lua index 7223099..f49b502 100644 --- a/replacer.lua +++ b/replacer.lua @@ -190,12 +190,9 @@ end -- get_form_modes -- replaces one node with another one and returns if it was successful function replacer.replace_single_node(pos, node, nnd, player, name, inv, creative) - if minetest.is_protected(pos, name) then - return false, rb.protected_at:format(minetest.pos_to_string(pos)) - end - - if replacer.blacklist[node.name] then - return false, rb.blacklisted:format(node.name) + local bRes, sMsg = replacer.permit_replace(pos, node, nnd, player, name, inv, creative) + if not bRes then + return false, sMsg end -- do not replace if there is nothing to be done diff --git a/replacer_constrain.lua b/replacer_constrain.lua index ddb6d61..6ae9ce6 100644 --- a/replacer_constrain.lua +++ b/replacer_constrain.lua @@ -11,8 +11,15 @@ local rb = replacer.blabla -- that will be sent to player function replacer.permit_replace(pos, old_node_def, new_node_def, player_ref, player_name, player_inv, creative_or_give) - -- TODO: move protection check here - -- TODO: check inhibit_list + + if minetest.is_protected(pos, player_name) then + return false, rb.protected_at:format(minetest.pos_to_string(pos)) + end + + if replacer.blacklist[old_node_def.name] then + return false, rb.blacklisted:format(old_node_def.name) + end + return true end -- permit_replace From 9f628131d76357235c068082207a03bd4b8e9c52 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 16:22:07 +0100 Subject: [PATCH 109/366] move restriction related from init to constrain --- init.lua | 54 +----------------------------------------- replacer_constrain.lua | 54 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 55 deletions(-) diff --git a/init.lua b/init.lua index df116f5..e86c3ae 100644 --- a/init.lua +++ b/init.lua @@ -65,58 +65,6 @@ replacer = {} replacer.version = 20220112 --- limit by node, use replacer.register_limit(sName, iMax) -replacer.limit_list = {} - --- some nodes don't rotate using param2. They can be added --- using replacer.register_exception(node_name, inv_node_name[, callback_function]) --- where: node_name is the itemstring of node when placed in world --- inv_node_name the itemstring of item in inventory to consume --- callback_function is optional and will be called after node is placed. --- It must return true on success and false, error_message on fail. --- In order to register only a callback, pass two identical itemstrings. --- Generally the callback is not needed as on_place() is called on the placed node --- callback signature is: (pos, old_node_def, new_node_def, player_ref) -replacer.exception_map = {} -replacer.exception_callbacks = {} - --- don't allow these at all -replacer.blacklist = {} - --- playing with tnt and creative building are usually contradictory --- (except when doing large-scale landscaping in singleplayer) -replacer.blacklist['tnt:boom'] = true -replacer.blacklist['tnt:gunpowder'] = true -replacer.blacklist['tnt:gunpowder_burning'] = true -replacer.blacklist['tnt:tnt'] = true - --- prevent accidental replacement of your protector -replacer.blacklist['protector:protect'] = true -replacer.blacklist['protector:protect2'] = true - --- charge limits -replacer.max_charge = 30000 -replacer.charge_per_node = 15 --- node count limit -replacer.max_nodes = tonumber(minetest.settings:get('replacer.max_nodes') or 3168) --- Time limit when placing the nodes, in seconds (not including search time) -replacer.max_time = tonumber(minetest.settings:get('replacer.max_time') or 1.0) --- Radius limit factor when more possible positions are found than either max_nodes or charge --- Set to 0 or less for behaviour of before version 3.3 --- [see replacer_patterns.lua>replacer.patterns.search_positions()] -replacer.radius_factor = tonumber(minetest.settings:get('replacer.radius_factor') or 0.4) - --- select which recipes to hide (not all combinations make sense) -replacer.hide_recipe_basic = - minetest.settings:get_bool('replacer.hide_recipe_basic') or false -replacer.hide_recipe_technic_upgrade = - minetest.settings:get_bool('replacer.hide_recipe_technic_upgrade') or false -replacer.hide_recipe_technic_direct = - minetest.settings:get_bool('replacer.hide_recipe_technic_direct') -if nil == replacer.hide_recipe_technic_direct then - replacer.hide_recipe_technic_direct = true -end - replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') and minetest.global_exists('dye') @@ -140,8 +88,8 @@ replacer.datastructures = dofile(path .. '/datastructures.lua') -- adds a tool for inspecting nodes and entities dofile(path .. '/inspect.lua') dofile(path .. '/replacer_blabla.lua') -dofile(path .. '/replacer_patterns.lua') dofile(path .. '/replacer_constrain.lua') +dofile(path .. '/replacer_patterns.lua') dofile(path .. '/replacer.lua') dofile(path .. '/crafts.lua') dofile(path .. '/chat_commands.lua') diff --git a/replacer_constrain.lua b/replacer_constrain.lua index 6ae9ce6..a637370 100644 --- a/replacer_constrain.lua +++ b/replacer_constrain.lua @@ -1,8 +1,58 @@ --- TODO: move all intervention functions in here, rename blacklist --- local r = replacer local rb = replacer.blabla +-- limit by node, use replacer.register_limit(sName, iMax) +replacer.limit_list = {} + +-- some nodes don't rotate using param2. They can be added +-- using replacer.register_exception(node_name, inv_node_name[, callback_function]) +-- where: node_name is the itemstring of node when placed in world +-- inv_node_name the itemstring of item in inventory to consume +-- callback_function is optional and will be called after node is placed. +-- It must return true on success and false, error_message on fail. +-- In order to register only a callback, pass two identical itemstrings. +-- Generally the callback is not needed as on_place() is called on the placed node +-- callback signature is: (pos, old_node_def, new_node_def, player_ref) +replacer.exception_map = {} +replacer.exception_callbacks = {} + +-- don't allow these at all +replacer.blacklist = {} + +-- playing with tnt and creative building are usually contradictory +-- (except when doing large-scale landscaping in singleplayer) +replacer.blacklist['tnt:boom'] = true +replacer.blacklist['tnt:gunpowder'] = true +replacer.blacklist['tnt:gunpowder_burning'] = true +replacer.blacklist['tnt:tnt'] = true + +-- prevent accidental replacement of your protector +replacer.blacklist['protector:protect'] = true +replacer.blacklist['protector:protect2'] = true + +-- charge limits +replacer.max_charge = 30000 +replacer.charge_per_node = 15 +-- node count limit +replacer.max_nodes = tonumber(minetest.settings:get('replacer.max_nodes') or 3168) +-- Time limit when placing the nodes, in seconds (not including search time) +replacer.max_time = tonumber(minetest.settings:get('replacer.max_time') or 1.0) +-- Radius limit factor when more possible positions are found than either max_nodes or charge +-- Set to 0 or less for behaviour of before version 3.3 +-- [see replacer_patterns.lua>replacer.patterns.search_positions()] +replacer.radius_factor = tonumber(minetest.settings:get('replacer.radius_factor') or 0.4) + +-- select which recipes to hide (not all combinations make sense) +replacer.hide_recipe_basic = + minetest.settings:get_bool('replacer.hide_recipe_basic') or false +replacer.hide_recipe_technic_upgrade = + minetest.settings:get_bool('replacer.hide_recipe_technic_upgrade') or false +replacer.hide_recipe_technic_direct = + minetest.settings:get_bool('replacer.hide_recipe_technic_direct') +if nil == replacer.hide_recipe_technic_direct then + replacer.hide_recipe_technic_direct = true +end + -- function that other mods, especially custom server mods, -- can override. e.g. restrict usage of replacer in certain -- areas, privs, throttling etc. From 24cd04d992139a236056a3892982f3d0941d34d9 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 16:28:03 +0100 Subject: [PATCH 110/366] move inform() to utils.lua --- replacer.lua | 10 ---------- utils.lua | 16 +++++++++++++++- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/replacer.lua b/replacer.lua index f49b502..fd45fd3 100644 --- a/replacer.lua +++ b/replacer.lua @@ -7,16 +7,6 @@ local rb = replacer.blabla local rp = replacer.patterns local rud = replacer.unifieddyes -function replacer.inform(name, msg) - if (not msg) or ('' == msg) then return end - minetest.log('info', rb.log:format(name, msg)) - local player = minetest.get_player_by_name(name) - if not player then return end - local meta = player:get_meta() if not meta then return end - if 0 < meta:get_int('replacer_mute') then return end - minetest.chat_send_player(name, msg) -end -- inform - replacer.modes = { 'single', 'field', 'crust' } for n = 1, #r.modes do r.modes[r.modes[n]] = n diff --git a/utils.lua b/utils.lua index e1121e1..e9db532 100644 --- a/utils.lua +++ b/utils.lua @@ -1,3 +1,17 @@ +function replacer.inform(name, message) + if (not message) or ('' == message) then return end + + minetest.log('info', rb.log:format(name, message)) + local player = minetest.get_player_by_name(name) + if not player then return end + + local meta = player:get_meta() if not meta then return end + + if 0 < meta:get_int('replacer_mute') then return end + minetest.chat_send_player(name, message) + +end -- inform + -- from: http://lua-users.org/wiki/StringRecipes function replacer.titleCase(str) local function titleCaseHelper(first, rest) @@ -10,5 +24,5 @@ function replacer.titleCase(str) -- This also turns hex numbers into, eg. 0Xa7d4 str = str:gsub("(%a)([%w_']*)", titleCaseHelper) return str -end +end -- titleCase From b33bc84aab0b871dafaccce52eaa77c12608eca1 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 16:42:50 +0100 Subject: [PATCH 111/366] moved register functions --- replacer.lua | 39 --------------------------------------- replacer_constrain.lua | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 39 deletions(-) diff --git a/replacer.lua b/replacer.lua index fd45fd3..90d79d3 100644 --- a/replacer.lua +++ b/replacer.lua @@ -22,45 +22,6 @@ replacer.mode_colours[r.modes[1]] = '#ffffff' replacer.mode_colours[r.modes[2]] = '#54FFAC' replacer.mode_colours[r.modes[3]] = '#9F6200' -local is_int = function(value) - return type(value) == 'number' and math.floor(value) == value -end - -function replacer.register_limit(node_name, node_max) - -- ignore nil and negative numbers - if (nil == node_max) or (0 > node_max) then - return - end - -- ignore non-integers - if not is_int(node_max) then - return - end - -- add to blacklist if limit is zero - if 0 == node_max then - replacer.blacklist[node_name] = true - minetest.log('info', rb.blacklist_insert:format(node_name)) - return - end - -- log info if already limited - if nil ~= r.limit_list[node_name] then - minetest.log('info', rb.limit_override:format(node_name, r.limit_list[node_name])) - end - r.limit_list[node_name] = node_max - minetest.log('info', rb.limit_insert:format(node_name, node_max)) -end -- register_limit - -function replacer.register_exception(node_name, drop_name, callback) - if r.exception_map[node_name] then - minetest.log('info', rb.reg_rot_exception_override:format(node_name)) - end - r.exception_map[node_name] = drop_name - minetest.log('info', rb.reg_rot_exception:format(node_name, drop_name)) - - if 'function' ~= type(callback) then return end - r.exception_callbacks[node_name] = callback - minetest.log('info', rb.reg_exception_callback:format(node_name)) -end -- register_exception - function replacer.get_data(stack) local metaRef = stack:get_meta() local data = metaRef:get_string('replacer'):split(' ') or {} diff --git a/replacer_constrain.lua b/replacer_constrain.lua index a637370..d157d11 100644 --- a/replacer_constrain.lua +++ b/replacer_constrain.lua @@ -73,3 +73,37 @@ function replacer.permit_replace(pos, old_node_def, new_node_def, return true end -- permit_replace +function replacer.register_exception(node_name, drop_name, callback) + if r.exception_map[node_name] then + minetest.log('info', rb.reg_rot_exception_override:format(node_name)) + end + r.exception_map[node_name] = drop_name + minetest.log('info', rb.reg_rot_exception:format(node_name, drop_name)) + + if 'function' ~= type(callback) then return end + r.exception_callbacks[node_name] = callback + minetest.log('info', rb.reg_exception_callback:format(node_name)) +end -- register_exception + +local function is_positive_int(value) + return (type(value) == 'number') and (math.floor(value) == value) and (0 <= value) +end +function replacer.register_limit(node_name, node_max) + -- ignore nil, negative numbers and non-integers + if not is_positive_int(node_max) then + return + end + -- add to blacklist if limit is zero + if 0 == node_max then + replacer.blacklist[node_name] = true + minetest.log('info', rb.blacklist_insert:format(node_name)) + return + end + -- log info if already limited + if nil ~= r.limit_list[node_name] then + minetest.log('info', rb.limit_override:format(node_name, r.limit_list[node_name])) + end + r.limit_list[node_name] = node_max + minetest.log('info', rb.limit_insert:format(node_name, node_max)) +end -- register_limit + From 6daf21b1267631c6ea10abdffc663c1be96aa8a0 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 16:44:38 +0100 Subject: [PATCH 112/366] moved path def --- init.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/init.lua b/init.lua index e86c3ae..50b1a2a 100644 --- a/init.lua +++ b/init.lua @@ -59,8 +59,6 @@ -- * receipe changed -- * inventory image added -local path = minetest.get_modpath('replacer') - replacer = {} replacer.version = 20220112 @@ -80,6 +78,7 @@ replacer.has_technic_mod = minetest.get_modpath('technic') replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') and minetest.global_exists('unifieddyes') +local path = minetest.get_modpath('replacer') -- utilities dofile(path .. '/utils.lua') -- unifiedddyes support functions From 9d605b169360996cc98504eeea6d81e200ecc76e Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 16:55:57 +0100 Subject: [PATCH 113/366] rename blacklist to deny_list --- replacer.lua | 4 ++-- replacer_blabla.lua | 4 ++-- replacer_constrain.lua | 24 ++++++++++++------------ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/replacer.lua b/replacer.lua index 90d79d3..4ec0af6 100644 --- a/replacer.lua +++ b/replacer.lua @@ -275,8 +275,8 @@ function replacer.replace(itemstack, user, pt, right_clicked) return end - if replacer.blacklist[nnd.name] then - r.inform(name, rb.blacklisted:format(nnd.name)) + if replacer.deny_list[nnd.name] then + r.inform(name, rb.deny_listed:format(nnd.name)) return end diff --git a/replacer_blabla.lua b/replacer_blabla.lua index b105fe2..78dbf24 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -5,7 +5,7 @@ rb.mode_single = 'Replace single node.' rb.mode_field = 'Left click: Replace field of nodes of a kind where a translucent node is in front of it. Right click: Replace field of air where no translucent node is behind the air.' rb.mode_crust = 'Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air. Right click: Replace air nodes which touch the crust' rb.protected_at = 'Protected at %s' -rb.blacklisted = 'Replacing nodes of type "%s" is not allowed on this server. Replacement failed.' +rb.deny_listed = 'Replacing nodes of type "%s" is not allowed on this server. Replacement failed.' rb.run_out = 'You have no further "%s". Replacement failed.' rb.attempt_unknown_replace = 'Unknown node: "%s"' rb.attempt_unknown_place = 'Unknown node to place: "%s"' @@ -27,7 +27,7 @@ rb.description_basic = 'Node replacement tool' rb.description_technic = 'Node replacement tool (technic)' rb.limit_override = 'Setting already set node-limit for "%s" was %d.' rb.limit_insert = 'Setting node-limit for "%s" to %d.' -rb.blacklist_insert = 'Blacklisted "%s".' +rb.deny_list_insert = 'Added "%s" to deny list.' rb.timed_out = 'Time-limit reached.' rb.tool_short_description = '(%s %s%s) %s' rb.tool_long_description = '%s\n%s\n%s' diff --git a/replacer_constrain.lua b/replacer_constrain.lua index d157d11..011b459 100644 --- a/replacer_constrain.lua +++ b/replacer_constrain.lua @@ -17,18 +17,18 @@ replacer.exception_map = {} replacer.exception_callbacks = {} -- don't allow these at all -replacer.blacklist = {} +replacer.deny_list = {} -- playing with tnt and creative building are usually contradictory -- (except when doing large-scale landscaping in singleplayer) -replacer.blacklist['tnt:boom'] = true -replacer.blacklist['tnt:gunpowder'] = true -replacer.blacklist['tnt:gunpowder_burning'] = true -replacer.blacklist['tnt:tnt'] = true +replacer.deny_list['tnt:boom'] = true +replacer.deny_list['tnt:gunpowder'] = true +replacer.deny_list['tnt:gunpowder_burning'] = true +replacer.deny_list['tnt:tnt'] = true -- prevent accidental replacement of your protector -replacer.blacklist['protector:protect'] = true -replacer.blacklist['protector:protect2'] = true +replacer.deny_list['protector:protect'] = true +replacer.deny_list['protector:protect2'] = true -- charge limits replacer.max_charge = 30000 @@ -66,8 +66,8 @@ function replacer.permit_replace(pos, old_node_def, new_node_def, return false, rb.protected_at:format(minetest.pos_to_string(pos)) end - if replacer.blacklist[old_node_def.name] then - return false, rb.blacklisted:format(old_node_def.name) + if replacer.deny_list[old_node_def.name] then + return false, rb.deny_listed:format(old_node_def.name) end return true @@ -93,10 +93,10 @@ function replacer.register_limit(node_name, node_max) if not is_positive_int(node_max) then return end - -- add to blacklist if limit is zero + -- add to deny_list if limit is zero if 0 == node_max then - replacer.blacklist[node_name] = true - minetest.log('info', rb.blacklist_insert:format(node_name)) + replacer.deny_list[node_name] = true + minetest.log('info', rb.deny_list_insert:format(node_name)) return end -- log info if already limited From b236d41279c95b9493dc321f8ae08e615275ad12 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 17:09:05 +0100 Subject: [PATCH 114/366] bug cleanup from refactor --- init.lua | 3 ++- utils.lua | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 50b1a2a..aefe5a0 100644 --- a/init.lua +++ b/init.lua @@ -79,6 +79,8 @@ replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') and minetest.global_exists('unifieddyes') local path = minetest.get_modpath('replacer') +-- strings for translation +dofile(path .. '/replacer_blabla.lua') -- utilities dofile(path .. '/utils.lua') -- unifiedddyes support functions @@ -86,7 +88,6 @@ dofile(path .. '/unifieddyes.lua') replacer.datastructures = dofile(path .. '/datastructures.lua') -- adds a tool for inspecting nodes and entities dofile(path .. '/inspect.lua') -dofile(path .. '/replacer_blabla.lua') dofile(path .. '/replacer_constrain.lua') dofile(path .. '/replacer_patterns.lua') dofile(path .. '/replacer.lua') diff --git a/utils.lua b/utils.lua index e9db532..e0297fd 100644 --- a/utils.lua +++ b/utils.lua @@ -1,3 +1,5 @@ +local rb = replacer.blabla + function replacer.inform(name, message) if (not message) or ('' == message) then return end From 6bd0ab26b704fac7eb00fffbb3a2848bb84741bd Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 14 Jan 2022 17:21:53 +0100 Subject: [PATCH 115/366] version bump 3.5 --- init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/init.lua b/init.lua index aefe5a0..42c908b 100644 --- a/init.lua +++ b/init.lua @@ -16,9 +16,10 @@ along with this program. If not, see . --]] --- Version 3.4 (20220114) +-- Version 3.5 (20220115) -- Changelog: +-- 15.01.2022 * SwissalpS refactored constraints and renamed blacklist to deny_list -- 14.01.2022 * SwissalpS added support for cable plates and similar nodes -- 13.01.2022 * SwissalpS worked in HybridDog's nicer pattern algorithm, modifying a little. -- Also cleaned up some code and give-priv does not grant modes anymore, @@ -60,8 +61,7 @@ -- * inventory image added replacer = {} - -replacer.version = 20220112 +replacer.version = 20220115 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From ae12f9118b83d66c91e02615755c712cd7602e6b Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 18 Jan 2022 13:08:56 +0100 Subject: [PATCH 116/366] whitespace (and non functional changes) --- chat_commands.lua | 5 ++--- compat_technic.lua | 14 ++++++------- datastructures.lua | 47 ++++++++++++++++++++++-------------------- init.lua | 46 ++++++++++++++++++++--------------------- inspect.lua | 2 +- replacer.lua | 33 +++++++++++++++-------------- replacer_constrain.lua | 25 ++++++++++++---------- replacer_patterns.lua | 29 +++++++++++++------------- unifieddyes.lua | 10 ++++----- 9 files changed, 109 insertions(+), 102 deletions(-) diff --git a/chat_commands.lua b/chat_commands.lua index 09d1ac1..22a69b5 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -6,13 +6,12 @@ replacer.chatcommand_mute = { params = rb.ccm_params, description = rb.ccm_description, func = function(name, param) - local player = minetest.get_player_by_name(name) - if not player then + if not player then -- TODO: seems unlikely to happen return false, rb.ccm_player_not_found end local meta = player:get_meta() - if not meta then + if not meta then -- TODO: seems unlikely to happen return false, rb.ccm_player_meta_error end diff --git a/compat_technic.lua b/compat_technic.lua index 6ac2bbc..034f053 100644 --- a/compat_technic.lua +++ b/compat_technic.lua @@ -3,12 +3,12 @@ local lTiers = { 'lv', 'mv', 'hv' } local lPlates = { '_digi_cable_plate_', '_cable_plate_' } local sDropName, sBaseName for _, sTier in ipairs(lTiers) do - for _, sPlate in ipairs(lPlates) do - sBaseName = 'technic:' .. sTier .. sPlate - sDropName = sBaseName .. '1' - for i = 2, 6 do - replacer.register_exception(sBaseName .. tostring(i), sDropName) - end - end + for _, sPlate in ipairs(lPlates) do + sBaseName = 'technic:' .. sTier .. sPlate + sDropName = sBaseName .. '1' + for i = 2, 6 do + replacer.register_exception(sBaseName .. tostring(i), sDropName) + end + end end diff --git a/datastructures.lua b/datastructures.lua index ac07f67..33414f5 100644 --- a/datastructures.lua +++ b/datastructures.lua @@ -17,13 +17,13 @@ stack_mt = { return self[self.n] end, get = function(self, i) - if i <= 0 then + if 0 >= i then return self[self.n + i] end return self[i] end, is_empty = function(self) - return self.n == 0 + return 0 == self.n end, size = function(self) return self.n @@ -50,23 +50,23 @@ stack_mt = { return t, self.n end, to_string = function(self, value_tostring) - if self.n == 0 then - return "empty stack" + if 0 == self.n then + return 'empty stack' end value_tostring = value_tostring or tostring local t = {} for i = 1, self.n do t[i] = value_tostring(self[i]) end - return self.n .. " elements; bottom to top: " .. - table.concat(t, ", ") + return self.n .. ' elements; bottom to top: ' + .. table_concat(t, ', ') end, } } function funcs.create_stack(data) local stack - if type(data) == "table" + if 'table' == type(data) and data.input then stack = data.input stack.n = data.n or #data.input @@ -114,7 +114,7 @@ fifo_mt = { return self.sink[1] end, is_empty = function(self) - return self.n_in == 0 and self.p_out == self.n_out + 1 + return 0 == self.n_in and self.p_out == self.n_out + 1 end, size = function(self) return self.n_in + self.n_out - self.p_out + 1 @@ -146,23 +146,23 @@ fifo_mt = { end, to_string = function(self, value_tostring) local size = self:size() - if size == 0 then - return "empty fifo" + if 0 == size then + return 'empty fifo' end value_tostring = value_tostring or tostring local t = self:to_table() for i = 1, #t do t[i] = value_tostring(t[i]) end - return size .. " elements; oldest to newest: " .. table.concat(t, ", ") + return size .. ' elements; oldest to newest: ' end, } } function funcs.create_queue(data) local fifo - if type(data) == "table" + if 'table' == type(data) and data.input then fifo = { n_in = 0, n_out = data.n or #data.input, p_out = 1, sink = { true }, source = data.input } @@ -177,7 +177,8 @@ end local function sift_up(binary_heap, i) local p = math.floor(i / 2) while p > 0 - and binary_heap.compare(binary_heap[i], binary_heap[p]) do + and binary_heap.compare(binary_heap[i], binary_heap[p]) + do -- new data has higher priority than its parent binary_heap[i], binary_heap[p] = binary_heap[p], binary_heap[i] i = p @@ -201,8 +202,9 @@ local function sift_down(binary_heap, i) end local preferred_child = binary_heap.compare(binary_heap[l], binary_heap[r]) and l or r - if not binary_heap.compare(binary_heap[preferred_child], - binary_heap[i]) then + if not binary_heap.compare( + binary_heap[preferred_child], binary_heap[i]) + then break end binary_heap[i], binary_heap[preferred_child] = @@ -250,7 +252,7 @@ binary_heap_mt = { self[i] = v if priority_lower then sift_down(self, i) - elseif i > 1 then + elseif 1 < i then sift_up(self, i) end end, @@ -263,7 +265,7 @@ binary_heap_mt = { build(self) end, is_empty = function(self) - return self.n == 0 + return 0 == self.n end, size = function(self) return self.n @@ -297,15 +299,15 @@ binary_heap_mt = { self.compare = nil end, to_string = function(self, value_tostring) - if self.n == 0 then - return "empty binary heap" + if 0 == self.n then + return 'empty binary heap' end value_tostring = value_tostring or tostring local t = {} for i = 1, self.n do - local sep = "" - if i > 1 then sep = (math.log(i) / math.log(2)) % 1 == 0 and "; " or ", " + local sep = '' + if 1 < i then end t[i] = sep .. value_tostring(self[i]) end @@ -316,7 +318,7 @@ binary_heap_mt = { function funcs.create_binary_heap(data) local compare = data - if type(data) == "table" then + if 'table' == type(data) then if data.input then -- make data.elements a binary heap local binary_heap = data.input @@ -336,3 +338,4 @@ function funcs.create_binary_heap(data) end return funcs + diff --git a/init.lua b/init.lua index 42c908b..6a25afd 100644 --- a/init.lua +++ b/init.lua @@ -1,19 +1,19 @@ --[[ - Replacement tool for creative building (Mod for MineTest) Copyright (C) 2013 Sokomine + Replacement tool for creative building (Mod for MineTest) - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . --]] -- Version 3.5 (20220115) @@ -78,24 +78,24 @@ replacer.has_technic_mod = minetest.get_modpath('technic') replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') and minetest.global_exists('unifieddyes') -local path = minetest.get_modpath('replacer') +local path = minetest.get_modpath('replacer') .. '/' -- strings for translation -dofile(path .. '/replacer_blabla.lua') +dofile(path .. 'replacer_blabla.lua') -- utilities -dofile(path .. '/utils.lua') +dofile(path .. 'utils.lua') -- unifiedddyes support functions -dofile(path .. '/unifieddyes.lua') -replacer.datastructures = dofile(path .. '/datastructures.lua') +dofile(path .. 'unifieddyes.lua') +replacer.datastructures = dofile(path .. 'datastructures.lua') -- adds a tool for inspecting nodes and entities -dofile(path .. '/inspect.lua') -dofile(path .. '/replacer_constrain.lua') -dofile(path .. '/replacer_patterns.lua') -dofile(path .. '/replacer.lua') -dofile(path .. '/crafts.lua') -dofile(path .. '/chat_commands.lua') +dofile(path .. 'inspect.lua') +dofile(path .. 'replacer_constrain.lua') +dofile(path .. 'replacer_patterns.lua') +dofile(path .. 'replacer.lua') +dofile(path .. 'crafts.lua') +dofile(path .. 'chat_commands.lua') -- add cable plate exceptions if replacer.has_technic_mod then - dofile(path .. '/compat_technic.lua') + dofile(path .. 'compat_technic.lua') end -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- diff --git a/inspect.lua b/inspect.lua index 29640eb..bebc8f6 100644 --- a/inspect.lua +++ b/inspect.lua @@ -334,7 +334,7 @@ replacer.inspect_show_crafting = function(player_name, node_name, fields) end --print(dump(res)) -- TODO: filter out invalid recipes with no items - -- such as "group:flower,color_dark_grey" + -- such as "group:flower,color_dark_grey" -- -- add special recipes for nodes created by machines diff --git a/replacer.lua b/replacer.lua index 4ec0af6..a142ac8 100644 --- a/replacer.lua +++ b/replacer.lua @@ -74,7 +74,7 @@ function replacer.set_data(stack, node, mode) return short_description end -- set_data -if replacer.has_technic_mod then +if r.has_technic_mod then if technic.plus then replacer.get_charge = technic.get_RE_charge replacer.set_charge = technic.set_RE_charge @@ -102,14 +102,14 @@ if replacer.has_technic_mod then function replacer.discharge(has_creative_or_give, charge, itemstack, num_nodes) if (not technic.creative_mode) and (not has_creative_or_give) then - charge = charge - replacer.charge_per_node * num_nodes - r.set_charge(itemstack, charge, replacer.max_charge) + charge = charge - r.charge_per_node * num_nodes + r.set_charge(itemstack, charge, r.max_charge) return itemstack end end else function replacer.discharge() end - function replacer.get_charge() return replacer.max_charge end + function replacer.get_charge() return r.max_charge end end replacer.form_name_modes = 'replacer_replacer_mode_change' @@ -361,11 +361,12 @@ function replacer.replace(itemstack, user, pt, right_clicked) moves = rp.offsets_touch, max_positions = max_nodes, }) + local data if right_clicked then -- Remove positions which are not directly touching the crust - local data = { ps = aps, num = n, + data = { name = nodename_clicked, pname = name } @@ -393,7 +394,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) end end - replacer.patterns.reset_nodes_cache() + rp.reset_nodes_cache() if 0 == num then local succ, err = r.replace_single_node(pos, node_toreplace, nnd, user, @@ -404,7 +405,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) return end - local charge_needed = replacer.charge_per_node * num + local charge_needed = r.charge_per_node * found_count if not has_creative_or_give then if charge < charge_needed then num = math.floor(charge / replacer.charge_per_node) @@ -414,8 +415,8 @@ function replacer.replace(itemstack, user, pt, right_clicked) -- set nodes local t_start = minetest.get_us_time() -- TODO - local max_time_us = 1000000 * replacer.max_time -- Turn ps into a binary heap + local max_time_us = 1000000 * r.max_time r.datastructures.create_binary_heap({ input = ps, n = num, @@ -455,7 +456,7 @@ function replacer.replace(itemstack, user, pt, right_clicked) r.discharge(has_creative_or_give, charge, itemstack, num_nodes) if has_creative_or_give then r.inform(name, rb.count_replaced:format(num_nodes)) end return itemstack -end -- replacer.replace +end -- on_use -- right-click with tool -> place set node -- special+right-click -> cycle mode (if tool/privs permit) @@ -470,7 +471,7 @@ function replacer.common_on_place(itemstack, placer, pt) local creative_enabled = creative.is_enabled_for(name) local has_give = minetest.check_player_privs(name, 'give') local has_creative_or_give = creative_enabled or has_give - local is_technic = itemstack:get_name() == replacer.tool_name_technic + local is_technic = itemstack:get_name() == r.tool_name_technic local modes_are_available = is_technic or creative_enabled -- is special-key held? (aka fast-key) @@ -576,7 +577,7 @@ function replacer.common_on_place(itemstack, placer, pt) r.inform(name, rb.set_to:format(short_description)) return itemstack --data changed -end -- common_on_place +end -- on_place function replacer.tool_def_basic() return { @@ -592,18 +593,18 @@ function replacer.tool_def_basic() } end -minetest.register_tool(replacer.tool_name_basic, replacer.tool_def_basic()) +minetest.register_tool(r.tool_name_basic, r.tool_def_basic()) -if replacer.has_technic_mod then +if r.has_technic_mod then function replacer.tool_def_technic() - local def = replacer.tool_def_basic() + local def = r.tool_def_basic() def.description = rb.description_technic def.wear_represents = 'technic_RE_charge' def.on_refill = technic.refill_RE_charge return def end - technic.register_power_tool(replacer.tool_name_technic, replacer.max_charge) - minetest.register_tool(replacer.tool_name_technic, replacer.tool_def_technic()) + technic.register_power_tool(r.tool_name_technic, r.max_charge) + minetest.register_tool(r.tool_name_technic, r.tool_def_technic()) end function replacer.register_on_player_receive_fields(player, form_name, fields) diff --git a/replacer_constrain.lua b/replacer_constrain.lua index 011b459..59b3eba 100644 --- a/replacer_constrain.lua +++ b/replacer_constrain.lua @@ -7,12 +7,12 @@ replacer.limit_list = {} -- some nodes don't rotate using param2. They can be added -- using replacer.register_exception(node_name, inv_node_name[, callback_function]) -- where: node_name is the itemstring of node when placed in world --- inv_node_name the itemstring of item in inventory to consume --- callback_function is optional and will be called after node is placed. --- It must return true on success and false, error_message on fail. --- In order to register only a callback, pass two identical itemstrings. --- Generally the callback is not needed as on_place() is called on the placed node --- callback signature is: (pos, old_node_def, new_node_def, player_ref) +-- inv_node_name the itemstring of item in inventory to consume +-- callback_function is optional and will be called after node is placed. +-- It must return true on success and false, error_message on fail. +-- In order to register only a callback, pass two identical itemstrings. +-- Generally the callback is not needed as on_place() is called on the placed node +-- callback signature is: (pos, old_node_def, new_node_def, player_ref) replacer.exception_map = {} replacer.exception_callbacks = {} @@ -60,17 +60,17 @@ end -- a boolean return and in the case of fail, an optional message -- that will be sent to player function replacer.permit_replace(pos, old_node_def, new_node_def, - player_ref, player_name, player_inv, creative_or_give) + player_ref, player_name, player_inv, creative_or_give) if minetest.is_protected(pos, player_name) then return false, rb.protected_at:format(minetest.pos_to_string(pos)) + if r.deny_list[old_node_def.name] then + return false, rb.deny_listed:format(old_node_def.name) end - if replacer.deny_list[old_node_def.name] then - return false, rb.deny_listed:format(old_node_def.name) end - return true + return true end -- permit_replace function replacer.register_exception(node_name, drop_name, callback) @@ -81,6 +81,7 @@ function replacer.register_exception(node_name, drop_name, callback) minetest.log('info', rb.reg_rot_exception:format(node_name, drop_name)) if 'function' ~= type(callback) then return end + r.exception_callbacks[node_name] = callback minetest.log('info', rb.reg_exception_callback:format(node_name)) end -- register_exception @@ -93,12 +94,14 @@ function replacer.register_limit(node_name, node_max) if not is_positive_int(node_max) then return end + -- add to deny_list if limit is zero if 0 == node_max then - replacer.deny_list[node_name] = true minetest.log('info', rb.deny_list_insert:format(node_name)) + r.deny_list[node_name] = true return end + -- log info if already limited if nil ~= r.limit_list[node_name] then minetest.log('info', rb.limit_override:format(node_name, r.limit_list[node_name])) diff --git a/replacer_patterns.lua b/replacer_patterns.lua index 19f98dc..23f2303 100644 --- a/replacer_patterns.lua +++ b/replacer_patterns.lua @@ -13,11 +13,11 @@ function replacer.patterns.get_node(pos) node = minetest.get_node(pos) rp.known_nodes[i] = node return node -end +end -- get_node -- The cache is only valid as long as no node is changed in the world. function replacer.patterns.reset_nodes_cache() - replacer.patterns.known_nodes = {} + rp.known_nodes = {} end -- tests if there's a node at pos which should be replaced @@ -34,9 +34,10 @@ function replacer.patterns.replaceable(pos, name, pname, param2) -- maybe dummy lights, on the other hand, it might be useful to be able to stop replacer with dummy lights return (('air' == node.name) or ('vacuum:vacuum' == node.name)) and (not minetest.is_protected(pos, pname)) end - -- in field mode we also check that param2 is the same as the initial node that was clicked on return (node.name == name) and (node.param2 == param2) and (not minetest.is_protected(pos, pname)) -end + -- in field mode we also check that param2 is the same as the + -- initial node that was clicked on +end -- replaceable replacer.patterns.translucent_nodes = {} function replacer.patterns.node_translucent(name) @@ -51,13 +52,13 @@ function replacer.patterns.node_translucent(name) end rp.translucent_nodes[name] = true return true -end +end -- node_translucent function replacer.patterns.field_position(pos, data) return rp.replaceable(pos, data.name, data.pname, data.param2) and rp.node_translucent( rp.get_node(vector.add(data.above, pos)).name) ~= data.right_clicked -end +end -- field_position replacer.patterns.offsets_touch = { { x =-1, y = 0, z = 0 }, @@ -98,7 +99,7 @@ function replacer.patterns.crust_above_position(pos, data) end end return false -end +end -- crust_above_position -- used to get nodes the crust belongs to function replacer.patterns.crust_under_position(pos, data) @@ -113,7 +114,7 @@ function replacer.patterns.crust_under_position(pos, data) end end return false -end +end -- crust_under_position -- extract the crust from the nodes the crust belongs to function replacer.patterns.reduce_crust_ps(data) @@ -133,7 +134,7 @@ function replacer.patterns.reduce_crust_ps(data) end data.ps = newps data.num = n -end +end -- reduce_crust_ps -- gets the air nodes touching the crust function replacer.patterns.reduce_crust_above_ps(data) @@ -155,7 +156,7 @@ function replacer.patterns.reduce_crust_above_ps(data) end data.ps = newps data.num = n -end +end -- reduce_crust_above_ps -- Algorithm created by sofar and changed by others: @@ -170,7 +171,7 @@ local function search_dfs(go, p, apply_move, moves) -- The stack contains the path to the current position; -- an element of it contains a position and direction (index to moves) - local s = replacer.datastructures.create_stack() + local s = r.datastructures.create_stack() -- The neighbor order we will visit from our table. local v = 1 @@ -209,7 +210,7 @@ local function search_dfs(go, p, apply_move, moves) v = 1 end end -end +end -- search_dfs function replacer.patterns.search_positions(params) @@ -236,7 +237,7 @@ function replacer.patterns.search_positions(params) return true end search_dfs(go, startpos, vector.add, moves) - if n_founds < max_positions or 0 >= replacer.radius_factor then + if n_founds < max_positions or 0 >= r.radius_factor then return founds, n_founds, visiteds end @@ -266,5 +267,5 @@ function replacer.patterns.search_positions(params) end search_dfs(go, startpos, vector.add, moves) return founds, n_founds, visiteds -end +end -- search_positions diff --git a/unifieddyes.lua b/unifieddyes.lua index d4b3d5b..dbfb9f4 100644 --- a/unifieddyes.lua +++ b/unifieddyes.lua @@ -29,7 +29,7 @@ function replacer.unifieddyes.addRecipe(param2, nodeName, recipes) end return recipes -end +end -- add_recipe function replacer.unifieddyes.colourName(param2, nodeDef) @@ -40,7 +40,7 @@ function replacer.unifieddyes.colourName(param2, nodeDef) else return '' end -end +end -- colour_name function replacer.unifieddyes.dyeName(param2, nodeDef) @@ -50,14 +50,14 @@ function replacer.unifieddyes.dyeName(param2, nodeDef) else return '' end -end +end -- dye_name function replacer.unifieddyes.isAirbrushCompatible(nodeDef) return nodeDef and nodeDef.palette and nodeDef.groups and nodeDef.groups.ud_param2_colorable and 0 < nodeDef.groups.ud_param2_colorable -end +end -- is_airbrush_compatible function replacer.unifieddyes.isAirbrushed(nodeDef) @@ -68,5 +68,5 @@ function replacer.unifieddyes.isAirbrushed(nodeDef) return true end return not nodeDef.airbrush_replacement_node -end +end -- is_airbrushed From 93850f64c6f298f6352cc23df6a1b57f53b4bff4 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 18 Jan 2022 13:32:57 +0100 Subject: [PATCH 117/366] var renaming and local-izing methods and some other speed related changes --- datastructures.lua | 15 +- inspect.lua | 2 +- replacer.lua | 314 ++++++++++++++++++++++------------------- replacer_constrain.lua | 6 +- replacer_patterns.lua | 44 +++--- unifieddyes.lua | 42 +++--- utils.lua | 9 +- 7 files changed, 240 insertions(+), 192 deletions(-) diff --git a/datastructures.lua b/datastructures.lua index 33414f5..ded6b38 100644 --- a/datastructures.lua +++ b/datastructures.lua @@ -1,4 +1,7 @@ local funcs = {} +local floor = math.floor +local log = math.log +local table_concat = table.concat local stack_mt stack_mt = { @@ -154,8 +157,8 @@ fifo_mt = { for i = 1, #t do t[i] = value_tostring(t[i]) end - table.concat(t, ", ") return size .. ' elements; oldest to newest: ' + .. table_concat(t, ', ') end, } } @@ -175,14 +178,14 @@ end local function sift_up(binary_heap, i) - local p = math.floor(i / 2) + local p = floor(i * .5) while p > 0 and binary_heap.compare(binary_heap[i], binary_heap[p]) do -- new data has higher priority than its parent binary_heap[i], binary_heap[p] = binary_heap[p], binary_heap[i] i = p - p = math.floor(p / 2) + p = floor(p * .5) end end @@ -214,7 +217,7 @@ local function sift_down(binary_heap, i) end local function build(binary_heap) - for i = math.floor(binary_heap.n / 2), 1, -1 do + for i = floor(binary_heap.n * .5), 1, -1 do sift_down(binary_heap, i) end end @@ -305,13 +308,13 @@ binary_heap_mt = { value_tostring = value_tostring or tostring local t = {} for i = 1, self.n do - sep = (math.log(i) / math.log(2)) % 1 == 0 and "; " or ", " local sep = '' if 1 < i then + sep = (0 == (log(i) / log(2)) % 1) and '; ' or ', ' end t[i] = sep .. value_tostring(self[i]) end - return self.n .. " elements: " .. table.concat(t, "") + return self.n .. ' elements: ' .. table_concat(t, '0') end, } } diff --git a/inspect.lua b/inspect.lua index bebc8f6..92a9b5f 100644 --- a/inspect.lua +++ b/inspect.lua @@ -340,7 +340,7 @@ replacer.inspect_show_crafting = function(player_name, node_name, fields) -- add special recipes for nodes created by machines replacer.add_circular_saw_recipe(node_name, res) replacer.add_colormachine_recipe(node_name, res) - replacer.unifieddyes.addRecipe(fields.param2, node_name, res) + replacer.unifieddyes.add_recipe(fields.param2, node_name, res) -- offer all alternate creafting recipes thrugh prev/next buttons if fields and fields.prev_recipe and 1 < recipe_nr then diff --git a/replacer.lua b/replacer.lua index a142ac8..80bf9fb 100644 --- a/replacer.lua +++ b/replacer.lua @@ -2,10 +2,29 @@ replacer.tool_name_basic = 'replacer:replacer' replacer.tool_name_technic = 'replacer:replacer_technic' replacer.tool_default_node = 'default:dirt' +-- pulling to local scope especially those used in loops local r = replacer local rb = replacer.blabla local rp = replacer.patterns local rud = replacer.unifieddyes +-- math +local max, min, floor = math.max, math.min, math.floor +local core_check_player_privs = minetest.check_player_privs +local core_get_node = minetest.get_node +local core_get_node_or_nil = minetest.get_node_or_nil +local core_get_node_drops = minetest.get_node_drops +local core_get_item_group = minetest.get_item_group +local core_registered_items = minetest.registered_items +local core_registered_nodes = minetest.registered_nodes +local core_swap_node = minetest.swap_node +local deserialize = minetest.deserialize +local has_creative = creative.is_enabled_for +local serialize = minetest.serialize +local us_time = minetest.get_us_time +-- vector +local vector_multiply = vector.multiply +local vector_new = vector.new +local vector_subtract = vector.subtract replacer.modes = { 'single', 'field', 'crust' } for n = 1, #r.modes do @@ -23,8 +42,8 @@ replacer.mode_colours[r.modes[2]] = '#54FFAC' replacer.mode_colours[r.modes[3]] = '#9F6200' function replacer.get_data(stack) - local metaRef = stack:get_meta() - local data = metaRef:get_string('replacer'):split(' ') or {} + local meta = stack:get_meta() + local data = meta:get_string('replacer'):split(' ') or {} local node = { name = data[1] or r.tool_default_node, param1 = tonumber(data[2]) or 0, @@ -39,38 +58,38 @@ end -- get_data function replacer.set_data(stack, node, mode) mode = mode or r.modes[1] - local toolItemName = stack:get_name() - local toolDef = minetest.registered_items[toolItemName] + local tool_itemstring = stack:get_name() + local tool_def = core_registered_items[tool_itemstring] -- some accidents or deliberate actions can be harmful -- if user has an unknown item. So we check here to -- prevent possible server crash - if (not toolItemName) or (not toolDef) then return 'Unkown Item' + if (not tool_itemstring) or (not tool_def) then end local param1 = tostring(node.param1 or 0) local param2 = tostring(node.param2 or 0) - local nodeName = node.name or replacer.tool_default_node - local metadata = nodeName .. ' ' .. param1 .. ' ' .. param2 - local metaRef = stack:get_meta() - metaRef:set_string('mode', mode) - metaRef:set_string('replacer', metadata) - metaRef:set_string('color', r.mode_colours[mode]) - local nodeDef = minetest.registered_items[node.name] - local nodeDescription = nodeName - if nodeDef and nodeDef.description then - nodeDescription = nodeDef.description - end - local colourName = rud.colourName(param2, nodeDef) - if 0 < #colourName then - colourName = " " .. colourName - end - local toolName = toolDef.description + local node_name = node.name or r.tool_default_node + local data = node_name .. ' ' .. param1 .. ' ' .. param2 + local meta = stack:get_meta() + meta:set_string('mode', mode.major .. '.' .. mode.minor) + meta:set_string('replacer', data) + meta:set_string('color', r.mode_colours[mode.major][mode.minor]) + local node_def = core_registered_items[node_name] + local node_description = node_name + if node_def and node_def.description then + node_description = node_def.description + end + local colour_name = rud.colour_name(param2, node_def) + if 0 < #colour_name then + colour_name = ' ' .. colour_name + end + local tool_name = tool_def.description local short_description = rb.tool_short_description:format( - param1, param2, colourName, node.name) + param1, param2, colour_name, node_name) local description = rb.tool_long_description:format( - toolName, short_description, nodeDescription) -- r.titleCase(colourName)) + tool_name, short_description, node_description) -- r.titleCase(colour_name)) - metaRef:set_string('description', description) + meta:set_string('description', description) return short_description end -- set_data @@ -81,7 +100,7 @@ if r.has_technic_mod then else -- technic still stores data serialized, so this is the nearest we get to current standard function replacer.get_charge(itemstack) - local meta = minetest.deserialize(itemstack:get_meta():get_string('')) + local meta = deserialize(itemstack:get_meta():get_string('')) if (not meta) or (not meta.charge) then return 0 end @@ -90,17 +109,17 @@ if r.has_technic_mod then function replacer.set_charge(itemstack, charge, max) technic.set_RE_wear(itemstack, charge, max) - local metaRef = itemstack:get_meta() - local meta = minetest.deserialize(metaRef:get_string('')) - if (not meta) or (not meta.charge) then - meta = { charge = 0 } + local meta = itemstack:get_meta() + local data = deserialize(meta:get_string('')) + if (not data) or (not data.charge) then + data = { charge = 0 } end - meta.charge = charge - metaRef:set_string('', minetest.serialize(meta)) + data.charge = charge + meta:set_string('', serialize(data)) end end - function replacer.discharge(has_creative_or_give, charge, itemstack, num_nodes) + function replacer.discharge(itemstack, charge, num_nodes, has_creative_or_give) if (not technic.creative_mode) and (not has_creative_or_give) then charge = charge - r.charge_per_node * num_nodes r.set_charge(itemstack, charge, r.max_charge) @@ -140,58 +159,62 @@ function replacer.get_form_modes(current_mode) end -- get_form_modes -- replaces one node with another one and returns if it was successful -function replacer.replace_single_node(pos, node, nnd, player, name, inv, creative) - local bRes, sMsg = replacer.permit_replace(pos, node, nnd, player, name, inv, creative) - if not bRes then - return false, sMsg +function replacer.replace_single_node(pos, node_old, node_new, player, + name, inv, creative) + local succ, error = r.permit_replace(pos, node_old, node_new, player, + name, inv, creative) + if not succ then + return false, error end -- do not replace if there is nothing to be done - if node.name == nnd.name then + if node_old.name == node_new.name then -- only the orientation was changed - if (node.param1 ~= nnd.param1) or (node.param2 ~= nnd.param2) then - minetest.swap_node(pos, nnd) + if (node_old.param1 ~= node_new.param1) + or (node_old.param2 ~= node_new.param2) + then + core_swap_node(pos, node_new) end return true end + local inv_name = r.exception_map[node_new.name] or node_new.name -- does the player carry at least one of the desired nodes with him? - local inv_name = r.exception_map[nnd.name] or nnd.name if (not creative) and (not inv:contains_item('main', inv_name)) then - return false, rb.run_out:format(nnd.name or '?') + return false, rb.run_out:format(node_new.name or '?') end - local ndef = minetest.registered_nodes[node.name] - if not ndef then - return false, rb.attempt_unknown_replace:format(node.name) + local node_old_def = core_registered_nodes[node_old.name] + if not node_old_def then + return false, rb.attempt_unknown_replace:format(node_old.name) end - local new_ndef = minetest.registered_nodes[nnd.name] - if not new_ndef then - return false, rb.attempt_unknown_place:format(nnd.name) + local node_new_def = core_registered_nodes[node_new.name] + if not node_new_def then + return false, rb.attempt_unknown_place:format(node_new.name) end -- dig the current node if needed - if not ndef.buildable_to then + if not node_old_def.buildable_to then -- give the player the item by simulating digging if possible - ndef.on_dig(pos, node, player) + node_old_def.on_dig(pos, node_old, player) -- test if digging worked - local dug_node = minetest.get_node_or_nil(pos) + local dug_node = core_get_node_or_nil(pos) if (not dug_node) or - (not minetest.registered_nodes[dug_node.name].buildable_to) then - return false, rb.can_not_dig:format(node.name) + (not core_registered_nodes[dug_node.name].buildable_to) then + return false, rb.can_not_dig:format(node_old.name) end end -- place the node similar to how a player does it -- (other than the pointed_thing) - local newitem, succ = new_ndef.on_place(ItemStack(nnd.name), player, - { type = 'node', under = vector.new(pos), above = vector.new(pos) }) - -- replacing with trellis set, succ is returned but newitem is nil + local new_item, succ = node_new_def.on_place(ItemStack(node_new.name), player, + { type = 'node', under = vector_new(pos), above = vector_new(pos) }) + -- replacing with trellis set, succ is returned but new_item is nil -- possible that other nodes react the same way. -- this allows users to dig nodes, I don't see reason to stop that -- as long as no crash occurs - SwissalpS - if (false == succ) or (nil == newitem) then - return false, rb.can_not_place:format(nnd.name) + if (false == succ) or (nil == new_item) then + return false, rb.can_not_place:format(node_new.name) end -- update inventory in survival mode @@ -199,28 +222,29 @@ function replacer.replace_single_node(pos, node, nnd, player, name, inv, creativ -- consume the item inv:remove_item('main', inv_name .. ' 1') -- if placing the node didn't result in empty stack… - if '' ~= newitem:to_string() then - inv:add_item('main', newitem) + if '' ~= new_item:to_string() then + inv:add_item('main', new_item) end end -- test whether the placed node differs from the supposed node - local placed_node = minetest.get_node(pos) - if placed_node.name ~= nnd.name then + local placed_node = core_get_node(pos) + if placed_node.name ~= node_new.name then -- Sometimes placing doesn't put the node but does something different -- e.g. when placing snow on snow with the snow mod return true end -- fix orientation if needed - if placed_node.param1 ~= nnd.param1 or - placed_node.param2 ~= nnd.param2 then - minetest.swap_node(pos, nnd) + if placed_node.param1 ~= node_new.param1 or + placed_node.param2 ~= node_new.param2 then + core_swap_node(pos, node_new) end - if 'function' == type(r.exception_callbacks[nnd.name]) then - local bRes, sMsg = r.exception_callbacks[nnd.name](pos, node, nnd, player) - if (not bRes) and sMsg and ('' ~= sMsg) then + if 'function' == type(r.exception_callbacks[node_new.name]) then + succ, error = r.exception_callbacks[node_new.name]( + pos, node_old, node_new, player) + if (not succ) and error and ('' ~= sMsg) then r.inform(name, rb.callback_error:format(sMsg)) end end @@ -229,17 +253,18 @@ function replacer.replace_single_node(pos, node, nnd, player, name, inv, creativ end -- replace_single_node -- the function which happens when the replacer is used -function replacer.replace(itemstack, user, pt, right_clicked) - if (not user) or (not pt) then +function replacer.on_use(itemstack, player, pt, right_clicked) + if (not player) or (not pt) then return end - local keys = user:get_player_control() - local name = user:get_player_name() - local creative_enabled = creative.is_enabled_for(name) - local has_give = minetest.check_player_privs(name, 'give') + local succ, error + local keys = player:get_player_control() + local name = player:get_player_name() + local creative_enabled = has_creative(name) + local has_give = core_check_player_privs(name, 'give') local has_creative_or_give = creative_enabled or has_give - local is_technic = itemstack:get_name() == replacer.tool_name_technic + local is_technic = itemstack:get_name() == r.tool_name_technic local modes_are_available = is_technic or creative_enabled -- is special-key held? (aka fast-key) @@ -259,18 +284,18 @@ function replacer.replace(itemstack, user, pt, right_clicked) end local pos = minetest.get_pointed_thing_position(pt, right_clicked) - local node_toreplace = minetest.get_node_or_nil(pos) + local node_old = core_get_node_or_nil(pos) - if not node_toreplace then + if not node_old then r.inform(name, rb.wait_for_load) return end - local nnd, mode = r.get_data(itemstack) if (node_toreplace.name == nnd.name) and (node_toreplace.param1 == nnd.param1) and (node_toreplace.param2 == nnd.param2) then + local node_new, mode = r.get_data(itemstack) r.inform(name, rb.nothing_to_replace) return end @@ -285,19 +310,20 @@ function replacer.replace(itemstack, user, pt, right_clicked) end if r.modes[1] == mode then + if 1 == mode.major then -- single - local succ, err = replacer.replace_single_node(pos, node_toreplace, nnd, - user, name, user:get_inventory(), has_creative_or_give) + succ, error = r.replace_single_node(pos, node_old, node_new, + player, name, inv, has_creative_or_give) if not succ then - r.inform(name, err) + r.inform(name, error) end return end - local max_nodes = r.limit_list[nnd.name] or r.max_nodes + local max_nodes = r.limit_list[node_new.name] or r.max_nodes local charge = r.get_charge(itemstack) if not has_creative_or_give then - if charge < replacer.charge_per_node then + if charge < r.charge_per_node then r.inform(name, rb.need_more_charge) return end @@ -309,11 +335,11 @@ function replacer.replace(itemstack, user, pt, right_clicked) end end - local ps, num - if r.modes[2] == mode then + local found_positions, found_count + if 2 == mode.major then -- field -- Get four walk directions which are orthogonal to the field - local normal = vector.subtract(pt.above, pt.under) + local normal = vector_subtract(pt.above, pt.under) local dirs, n = {}, 1 local p for coord in pairs(normal) do @@ -330,16 +356,16 @@ function replacer.replace(itemstack, user, pt, right_clicked) -- is next to the field; the offset goes in the other direction when -- a right click happens if right_clicked then - normal = vector.multiply(normal, -1) + normal = vector_multiply(normal, -1) end -- Search along the plane next to the field right_clicked = (right_clicked and true) or false - ps, num = rp.search_positions({ + found_positions, found_count = rp.search_positions({ startpos = pos, fdata = { func = rp.field_position, - name = node_toreplace.name, - param2 = node_toreplace.param2, + name = node_old.name, + param2 = node_old.param2, pname = name, above = normal, right_clicked = right_clicked @@ -347,11 +373,11 @@ function replacer.replace(itemstack, user, pt, right_clicked) moves = dirs, max_positions = max_nodes, }) - elseif r.modes[3] == mode then + elseif 3 == mode.major then -- crust -- Search positions of air (or similar) nodes next to the crust local nodename_clicked = rp.get_node(pt.under).name - local aps, n, aboves = rp.search_positions({ + local unders, under_count, aboves = rp.search_positions({ startpos = pt.above, fdata = { func = rp.crust_above_position, @@ -364,22 +390,22 @@ function replacer.replace(itemstack, user, pt, right_clicked) local data if right_clicked then -- Remove positions which are not directly touching the crust - ps = aps, - num = n, data = { + ps = unders, + num = under_count, name = nodename_clicked, pname = name } rp.reduce_crust_above_ps(data) - ps, num = data.ps, data.num + found_positions, found_count = data.ps, data.num else -- Search crust positions which are next to the previously found -- air (or similar) node positions - ps, num = rp.search_positions({ + found_positions, found_count = rp.search_positions({ startpos = pt.under, fdata = { func = rp.crust_under_position, - name = node_toreplace.name, + name = node_old.name, pname = name, aboves = aboves }, @@ -388,38 +414,39 @@ function replacer.replace(itemstack, user, pt, right_clicked) }) -- Keep only positions which are directly touching those previously -- found positions - local data = { aboves = aboves, ps = ps, num = num } + data = { aboves = aboves, ps = found_positions, num = found_count } rp.reduce_crust_ps(data) - ps, num = data.ps, data.num + found_positions, found_count = data.ps, data.num end end rp.reset_nodes_cache() - if 0 == num then - local succ, err = r.replace_single_node(pos, node_toreplace, nnd, user, - name, user:get_inventory(), has_creative_or_give) + if 0 == found_count then + succ, error = r.replace_single_node(pos, node_old, node_new, player, + name, inv, has_creative_or_give) if not succ then - r.inform(name, err) + r.inform(name, error) end return end local charge_needed = r.charge_per_node * found_count + local possible_count = found_count if not has_creative_or_give then if charge < charge_needed then - num = math.floor(charge / replacer.charge_per_node) + possible_count = floor(charge / r.charge_per_node) end end -- set nodes - local t_start = minetest.get_us_time() + local t_start = us_time() -- TODO - -- Turn ps into a binary heap local max_time_us = 1000000 * r.max_time + -- Turn found_positions into a binary heap r.datastructures.create_binary_heap({ - input = ps, - n = num, + input = found_positions, + n = possible_count, compare = function(pos1, pos2) -- Return true iff pos1 is nearer to the start position than pos2 local n1 = (pos1.x - pos.x) ^ 2 + (pos1.y - pos.y) ^ 2 + @@ -429,47 +456,49 @@ function replacer.replace(itemstack, user, pt, right_clicked) return n1 < n2 end, }) - local inv = user:get_inventory() - local num_nodes = 0 - while not ps:is_empty() do - num_nodes = num_nodes + 1 - if num_nodes > max_nodes then + local actual_node_count = 0 + while not found_positions:is_empty() do + pos = found_positions:take() + node_old = core_get_node(pos) + adjust_new_to_minor(minor, node_old, node_new) + succ, error = r.replace_single_node(pos, node_old, node_new, + player, name, inv, has_creative_or_give) + if not succ then + r.inform(name, error) + break + end + actual_node_count = actual_node_count + 1 + if actual_node_count > max_nodes then -- This can happen if too many nodes were detected and the nodes -- limit has been set to a small value r.inform(name, rb.too_many_nodes_detected) break end - -- Take the position nearest to the start position - local pos = ps:take() - local succ, err = r.replace_single_node(pos, minetest.get_node(pos), nnd, - user, name, inv, has_creative_or_give) - if not succ then - r.inform(name, err) - break - end - if minetest.get_us_time() - t_start > max_time_us then + if us_time() - t_start > max_time_us then r.inform(name, rb.timed_out) break end end - r.discharge(has_creative_or_give, charge, itemstack, num_nodes) - if has_creative_or_give then r.inform(name, rb.count_replaced:format(num_nodes)) end + r.discharge(itemstack, charge, actual_node_count, has_creative_or_give) + if has_creative_or_give then + r.inform(name, rb.count_replaced:format(actual_node_count)) + end return itemstack end -- on_use -- right-click with tool -> place set node -- special+right-click -> cycle mode (if tool/privs permit) -- sneak+right-click -> set node -function replacer.common_on_place(itemstack, placer, pt) - if (not placer) or (not pt) then +function replacer.on_place(itemstack, player, pt) + if (not player) or (not pt) then return end - local keys = placer:get_player_control() - local name = placer:get_player_name() - local creative_enabled = creative.is_enabled_for(name) - local has_give = minetest.check_player_privs(name, 'give') + local keys = player:get_player_control() + local name = player:get_player_name() + local creative_enabled = has_creative(name) + local has_give = core_check_player_privs(name, 'give') local has_creative_or_give = creative_enabled or has_give local is_technic = itemstack:get_name() == r.tool_name_technic local modes_are_available = is_technic or creative_enabled @@ -492,7 +521,7 @@ function replacer.common_on_place(itemstack, placer, pt) -- If not holding sneak key, place node(s) if not keys.sneak then - return replacer.replace(itemstack, placer, pt, true) + return r.on_use(itemstack, player, pt, true) end -- Select new node @@ -502,29 +531,30 @@ function replacer.common_on_place(itemstack, placer, pt) end local node, mode = r.get_data(itemstack) - node = minetest.get_node_or_nil(pt.under) or node + node = core_get_node_or_nil(pt.under) or node + if not modes_are_available then - mode = r.modes[1] + mode = { major = 1, minor = 1 } end - local inv = placer:get_inventory() + local inv = player:get_inventory() if (not (creative_enabled and has_give)) and (not inv:contains_item('main', node.name)) and (not r.exception_map[node.name]) then -- not in inv and not (creative and give) local found_item = false - local drops = minetest.get_node_drops(node.name) + local drops = core_get_node_drops(node.name) if has_creative_or_give then - if 0 < minetest.get_item_group(node.name, + if 0 < core_get_item_group(node.name, 'not_in_creative_inventory') then -- search for a drop available in creative inventory for i = 1, #drops do local name = drops[i] - if minetest.registered_nodes[name] and - 0 == minetest.get_item_group(name, + if core_registered_nodes[name] and + 0 == core_get_item_group(name, 'not_in_creative_inventory') then node.name = name @@ -541,7 +571,7 @@ function replacer.common_on_place(itemstack, placer, pt) -- search for a drop that the player has if possible for i = 1, #drops do local name = drops[i] - if minetest.registered_nodes[name] and + if core_registered_nodes[name] and inv:contains_item('main', name) then node.name = name @@ -555,8 +585,8 @@ function replacer.common_on_place(itemstack, placer, pt) -- then digging the nodes works for i = 1, #drops do local name = drops[i] - if minetest.registered_nodes[name] and - 0 == minetest.get_item_group(name, + if core_registered_nodes[name] and + 0 == core_get_item_group(name, 'not_in_creative_inventory') then node.name = name @@ -587,9 +617,9 @@ function replacer.tool_def_basic() liquids_pointable = true, -- it is ok to painit in/with water --node_placement_prediction = nil, -- place node(s) - on_place = replacer.common_on_place, + on_place = r.on_place, -- Replace node(s) - on_use = replacer.replace + on_use = r.on_use } end diff --git a/replacer_constrain.lua b/replacer_constrain.lua index 59b3eba..4efdb53 100644 --- a/replacer_constrain.lua +++ b/replacer_constrain.lua @@ -1,5 +1,7 @@ local r = replacer local rb = replacer.blabla +local is_protected = minetest.is_protected +local pos_to_string = minetest.pos_to_string -- limit by node, use replacer.register_limit(sName, iMax) replacer.limit_list = {} @@ -62,12 +64,12 @@ end function replacer.permit_replace(pos, old_node_def, new_node_def, player_ref, player_name, player_inv, creative_or_give) - if minetest.is_protected(pos, player_name) then - return false, rb.protected_at:format(minetest.pos_to_string(pos)) if r.deny_list[old_node_def.name] then return false, rb.deny_listed:format(old_node_def.name) end + if is_protected(pos, player_name) then + return false, rb.protected_at:format(pos_to_string(pos)) end return true diff --git a/replacer_patterns.lua b/replacer_patterns.lua index 23f2303..3fe53c0 100644 --- a/replacer_patterns.lua +++ b/replacer_patterns.lua @@ -1,6 +1,12 @@ replacer.patterns = {} +local r = replacer local rp = replacer.patterns +local floor = math.floor +local is_protected = minetest.is_protected local poshash = minetest.hash_node_position +local core_registered_nodes = minetest.registered_nodes +local vector_add = vector.add +local vector_distance = vector.distance -- cache results of minetest.get_node replacer.patterns.known_nodes = {} @@ -21,22 +27,24 @@ function replacer.patterns.reset_nodes_cache() end -- tests if there's a node at pos which should be replaced -function replacer.patterns.replaceable(pos, name, pname, param2) +function replacer.patterns.replaceable(pos, node_name, player_name, param2) local node = rp.get_node(pos) if nil == param2 then -- crust mode ignores param2 - if 'air' ~= name then - return (node.name == name) and (not minetest.is_protected(pos, pname)) + if 'air' ~= node_name then + return (node.name == node_name) and (not is_protected(pos, player_name)) end -- right clicking in crust mode checks for air, but vacuum should work too -- TODO: add mechanism to register allowed types -- some servers might have other nodes like mars-lights that should be allowed too -- maybe dummy lights, on the other hand, it might be useful to be able to stop replacer with dummy lights - return (('air' == node.name) or ('vacuum:vacuum' == node.name)) and (not minetest.is_protected(pos, pname)) + return (('air' == node.name) or ('vacuum:vacuum' == node.name)) + and (not is_protected(pos, player_name)) end - return (node.name == name) and (node.param2 == param2) and (not minetest.is_protected(pos, pname)) -- in field mode we also check that param2 is the same as the -- initial node that was clicked on + return (node.name == node_name) and (node.param2 == param2) + and (not is_protected(pos, player_name)) end -- replaceable replacer.patterns.translucent_nodes = {} @@ -45,8 +53,8 @@ function replacer.patterns.node_translucent(name) if nil ~= is_translucent then return is_translucent end - local data = minetest.registered_nodes[name] - if data and ((not data.drawtype) or ('normal' == data.drawtype)) then + local def = core_registered_nodes[name] + if def and ((not def.drawtype) or ('normal' == def.drawtype)) then rp.translucent_nodes[name] = false return false end @@ -57,7 +65,7 @@ end -- node_translucent function replacer.patterns.field_position(pos, data) return rp.replaceable(pos, data.name, data.pname, data.param2) and rp.node_translucent( - rp.get_node(vector.add(data.above, pos)).name) ~= data.right_clicked + rp.get_node(vector_add(data.above, pos)).name) ~= data.right_clicked end -- field_position replacer.patterns.offsets_touch = { @@ -86,15 +94,15 @@ end -- To get the crust, first nodes near it need to be collected function replacer.patterns.crust_above_position(pos, data) -- test if the node at pos is a translucent node and not part of the crust - local nd = rp.get_node(pos).name - if (nd == data.name) or (not rp.node_translucent(nd)) then + local node_name = rp.get_node(pos).name + if (node_name == data.name) or (not rp.node_translucent(node_name)) then return false end -- test if a node of the crust is near pos local p2 for i = 1, 26 do p2 = rp.offsets_hollowcube[i] - if rp.replaceable(vector.add(pos, p2), data.name, data.pname) then + if rp.replaceable(vector_add(pos, p2), data.name, data.pname) then return true end end @@ -109,7 +117,7 @@ function replacer.patterns.crust_under_position(pos, data) local p2 for i = 1, 26 do p2 = rp.offsets_hollowcube[i] - if data.aboves[poshash(vector.add(pos, p2))] then + if data.aboves[poshash(vector_add(pos, p2))] then return true end end @@ -125,7 +133,7 @@ function replacer.patterns.reduce_crust_ps(data) p = data.ps[i] for i = 1, 6 do p2 = rp.offsets_touch[i] - if data.aboves[poshash(vector.add(p, p2))] then + if data.aboves[poshash(vector_add(p, p2))] then n = n + 1 newps[n] = p break @@ -146,7 +154,7 @@ function replacer.patterns.reduce_crust_above_ps(data) if rp.replaceable(p, 'air', data.pname) then for i = 1, 6 do p2 = rp.offsets_touch[i] - if rp.replaceable(vector.add(p, p2), data.name, data.pname) then + if rp.replaceable(vector_add(p, p2), data.name, data.pname) then n = n + 1 newps[n] = p break @@ -236,14 +244,14 @@ function replacer.patterns.search_positions(params) end return true end - search_dfs(go, startpos, vector.add, moves) + search_dfs(go, startpos, vector_add, moves) if n_founds < max_positions or 0 >= r.radius_factor then return founds, n_founds, visiteds end -- Too many positions were found, so search again but only within -- a limited sphere around startpos - local rr = math.floor(max_positions ^ replacer.radius_factor + .5) + local rr = floor(max_positions ^ r.radius_factor + .5) local visiteds_old = visiteds visiteds = {} founds = {} @@ -253,7 +261,7 @@ function replacer.patterns.search_positions(params) if visiteds[vi] then return false end - if vector.distance(p, startpos) > rr then + if vector_distance(p, startpos) > rr then -- Outside of the sphere return false end @@ -265,7 +273,7 @@ function replacer.patterns.search_positions(params) visiteds[vi] = true return true end - search_dfs(go, startpos, vector.add, moves) + search_dfs(go, startpos, vector_add, moves) return founds, n_founds, visiteds end -- search_positions diff --git a/unifieddyes.lua b/unifieddyes.lua index dbfb9f4..4f0eeb4 100644 --- a/unifieddyes.lua +++ b/unifieddyes.lua @@ -1,21 +1,23 @@ replacer.unifieddyes = {} local ud = replacer.unifieddyes +local make_readable_color = unifieddyes.make_readable_color +local colour_to_name = unifieddyes.color_to_name if not replacer.has_unifieddyes_mod then - function ud.colourName(param2, nodeDef) return '' end - function ud.addRecipe(nodeName, recipes) return recipes end + function ud.colour_name(param2, node_def) return '' end + function ud.add_recipe(node_name, recipes) return recipes end return end -- for inspector formspec -function replacer.unifieddyes.addRecipe(param2, nodeName, recipes) +function replacer.unifieddyes.add_recipe(param2, node_name, recipes) if not param2 then return recipes end - local nodeDef = minetest.registered_items[nodeName] - if ud.isAirbrushed(nodeDef) then + local node_def = minetest.registered_items[node_name] + if ud.is_airbrushed(node_def) then -- find the correct recipe and append it to bottom of list local first, last local needle = 'u0002' .. tostring(param2) @@ -32,41 +34,41 @@ function replacer.unifieddyes.addRecipe(param2, nodeName, recipes) end -- add_recipe -function replacer.unifieddyes.colourName(param2, nodeDef) +function replacer.unifieddyes.colour_name(param2, node_def) param2 = tonumber(param2) - if param2 and ud.isAirbrushed(nodeDef) then - return unifieddyes.make_readable_color( - unifieddyes.color_to_name(param2, nodeDef)) + if param2 and ud.is_airbrushed(node_def) then + return make_readable_color( + colour_to_name(param2, node_def)) else return '' end end -- colour_name -function replacer.unifieddyes.dyeName(param2, nodeDef) +function replacer.unifieddyes.dye_name(param2, node_def) param2 = tonumber(param2) - if param2 and ud.isAirbrushed(nodeDef) then - return 'dye:' .. unifieddyes.color_to_name(param2, nodeDef) + if param2 and ud.is_airbrushed(node_def) then + return 'dye:' .. colour_to_name(param2, node_def) else return '' end end -- dye_name -function replacer.unifieddyes.isAirbrushCompatible(nodeDef) - return nodeDef and nodeDef.palette - and nodeDef.groups and nodeDef.groups.ud_param2_colorable - and 0 < nodeDef.groups.ud_param2_colorable +function replacer.unifieddyes.is_airbrush_compatible(node_def) + return node_def and node_def.palette + and node_def.groups and node_def.groups.ud_param2_colorable + and 0 < node_def.groups.ud_param2_colorable end -- is_airbrush_compatible -function replacer.unifieddyes.isAirbrushed(nodeDef) - if not replacer.unifieddyes.isAirbrushCompatible(nodeDef) then +function replacer.unifieddyes.is_airbrushed(node_def) + if not ud.is_airbrush_compatible(node_def) then return false end - if nil ~= nodeDef.name:find('_tinted$') then + if nil ~= node_def.name:find('_tinted$') then return true end - return not nodeDef.airbrush_replacement_node + return not node_def.airbrush_replacement_node end -- is_airbrushed diff --git a/utils.lua b/utils.lua index e0297fd..02c6246 100644 --- a/utils.lua +++ b/utils.lua @@ -1,16 +1,19 @@ local rb = replacer.blabla +local chat_send_player = minetest.chat_send_player +local get_player_name = minetest.get_player_by_name +local log = minetest.log function replacer.inform(name, message) if (not message) or ('' == message) then return end - minetest.log('info', rb.log:format(name, message)) - local player = minetest.get_player_by_name(name) + log('info', rb.log_messages:format(name, message)) + local player = get_player_by_name(name) if not player then return end local meta = player:get_meta() if not meta then return end if 0 < meta:get_int('replacer_mute') then return end - minetest.chat_send_player(name, message) + chat_send_player(name, message) end -- inform From f26d92caac6df5039317d3a7f593c7f0a4130fee Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 18 Jan 2022 13:41:53 +0100 Subject: [PATCH 118/366] history, modes and formspecs --- init.lua | 2 + replacer.lua | 173 ++++++++++++++++++----------------------- replacer_constrain.lua | 14 ++++ replacer_formspecs.lua | 163 ++++++++++++++++++++++++++++++++++++++ replacer_history.lua | 127 ++++++++++++++++++++++++++++++ 5 files changed, 381 insertions(+), 98 deletions(-) create mode 100644 replacer_formspecs.lua create mode 100644 replacer_history.lua diff --git a/init.lua b/init.lua index 6a25afd..72928ec 100644 --- a/init.lua +++ b/init.lua @@ -89,6 +89,8 @@ replacer.datastructures = dofile(path .. 'datastructures.lua') -- adds a tool for inspecting nodes and entities dofile(path .. 'inspect.lua') dofile(path .. 'replacer_constrain.lua') +dofile(path .. 'replacer_formspecs.lua') +dofile(path .. 'replacer_history.lua') dofile(path .. 'replacer_patterns.lua') dofile(path .. 'replacer.lua') dofile(path .. 'crafts.lua') diff --git a/replacer.lua b/replacer.lua index 80bf9fb..4751cea 100644 --- a/replacer.lua +++ b/replacer.lua @@ -26,21 +26,22 @@ local vector_multiply = vector.multiply local vector_new = vector.new local vector_subtract = vector.subtract -replacer.modes = { 'single', 'field', 'crust' } -for n = 1, #r.modes do - r.modes[r.modes[n]] = n -end - -replacer.mode_infos = {} -replacer.mode_infos[r.modes[1]] = rb.mode_single -replacer.mode_infos[r.modes[2]] = rb.mode_field -replacer.mode_infos[r.modes[3]] = rb.mode_crust - -replacer.mode_colours = {} -replacer.mode_colours[r.modes[1]] = '#ffffff' -replacer.mode_colours[r.modes[2]] = '#54FFAC' -replacer.mode_colours[r.modes[3]] = '#9F6200' - +replacer.mode_major_names = { rb.mode_single, rb.mode_field, rb.mode_crust } +replacer.mode_major_infos = { + rb.mode_single_tooltip, + rb.mode_field_tooltip:gsub('\n', ' '), + rb.mode_crust_tooltip:gsub('\n', ' ') +} +replacer.mode_minor_names = { rb.mode_minor1, rb.mode_minor2, rb.mode_minor3 } +replacer.mode_minor_infos = { + rb.mode_minor1_info, rb.mode_minor2_info, rb.mode_minor3_info +} + +replacer.mode_colours = { + { '#ffffff', '#cccccc', '#999999' }, + { '#38fb9a', '#21cc79', '#10bb68' }, + { '#f4b755', '#d29533', '#9F6200' } +} function replacer.get_data(stack) local meta = stack:get_meta() local data = meta:get_string('replacer'):split(' ') or {} @@ -49,22 +50,29 @@ function replacer.get_data(stack) param1 = tonumber(data[2]) or 0, param2 = tonumber(data[3]) or 0 } - local mode = metaRef:get_string('mode') - if nil == r.modes[mode] then - mode = r.modes[1] - end + local mode, mode_bare = {}, meta:get_string('mode'):split('.') or {} + mode.major = tonumber(mode_bare[1] or 1) or 1 + mode.minor = tonumber(mode_bare[2] or 1) return node, mode end -- get_data function replacer.set_data(stack, node, mode) - mode = mode or r.modes[1] + node = 'table' == type(node) and node or {} + -- allow passing nil mode -> when ignoring mode in history + if 'table' ~= type(mode) then + _, mode = r.get_data(stack) + end local tool_itemstring = stack:get_name() local tool_def = core_registered_items[tool_itemstring] -- some accidents or deliberate actions can be harmful -- if user has an unknown item. So we check here to -- prevent possible server crash - return 'Unkown Item' if (not tool_itemstring) or (not tool_def) then + local t = { + 'Blessed', 'Somewhat known', 'Unknown if known', + 'Pwned', 'Hued', 'Strange', 'Found' + } + return t[os.date('*t').wday] .. ' Item' end local param1 = tostring(node.param1 or 0) local param2 = tostring(node.param2 or 0) @@ -131,33 +139,6 @@ else function replacer.get_charge() return r.max_charge end end -replacer.form_name_modes = 'replacer_replacer_mode_change' -function replacer.get_form_modes(current_mode) - -- TODO: possibly add the info here instead of as - -- a chat message - local formspec = 'size[3.9,2]' - .. 'label[0,0;Choose mode]' - .. 'button_exit[0.0,0.6;2,0.5;' - if r.modes[1] == current_mode then - formspec = formspec .. '_;< ' .. r.modes[1] .. ' >]' - else - formspec = formspec .. 'mode;' .. r.modes[1] .. ']' - end - formspec = formspec .. 'button_exit[1.9,0.6;2,0.5;' - if r.modes[2] == current_mode then - formspec = formspec .. '_;< ' .. r.modes[2] .. ' >]' - else - formspec = formspec .. 'mode;' .. r.modes[2] .. ']' - end - formspec = formspec .. 'button_exit[0.0,1.4;2,0.5;' - if r.modes[3] == current_mode then - formspec = formspec .. '_;< ' .. r.modes[3] .. ' >]' - else - formspec = formspec .. 'mode;' .. r.modes[3] .. ']' - end - return formspec -end -- get_form_modes - -- replaces one node with another one and returns if it was successful function replacer.replace_single_node(pos, node_old, node_new, player, name, inv, creative) @@ -273,7 +254,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) -- fetch current mode local _, mode = r.get_data(itemstack) -- Show formspec to choose mode - minetest.show_formspec(name, r.form_name_modes, r.get_form_modes(mode)) + r.show_mode_formspec(player, mode) -- return unchanged tool return itemstack end @@ -291,25 +272,36 @@ function replacer.on_use(itemstack, player, pt, right_clicked) return end - if (node_toreplace.name == nnd.name) - and (node_toreplace.param1 == nnd.param1) - and (node_toreplace.param2 == nnd.param2) - then local node_new, mode = r.get_data(itemstack) - r.inform(name, rb.nothing_to_replace) - return + if not modes_are_available then + mode = { major = 1, minor = 1 } end - - if replacer.deny_list[nnd.name] then - r.inform(name, rb.deny_listed:format(nnd.name)) + -- utility function to adjust new node to mode.minor + -- returns true if adjustments make them equal + local function adjust_new_to_minor(minor, node_old, node_new) + -- minor mode overrides to node_new + if 2 == minor then + -- node only + node_new.param1 = node.old.param1 + node_new.param2 = node.old.param2 + elseif 3 == minor then + -- rotation only + node_new.name = node_old.name + end + -- can we skip right away? + if (node_old.name == node_new.name) + and (node_old.param1 == node_new.param1) + and (node_old.param2 == node_new.param2) + then + return true + end + end -- adjust_new_to_minor + if adjust_new_to_minor(mode.minor, node_old, node_new) then + r.inform(name, rb.nothing_to_replace) return end - if not modes_are_available then - mode = r.modes[1] - end - - if r.modes[1] == mode then + local inv = player:get_inventory() if 1 == mode.major then -- single succ, error = r.replace_single_node(pos, node_old, node_new, @@ -328,11 +320,10 @@ function replacer.on_use(itemstack, player, pt, right_clicked) return end - local max_charge_to_use = math.min(charge, replacer.max_charge) - max_nodes = math.floor(max_charge_to_use / replacer.charge_per_node) - if max_nodes > replacer.max_nodes then - max_nodes = replacer.max_nodes - end + -- clamp so it works as single mode even without charge + local max_charge_to_use = min(charge, r.max_charge) + max_nodes = floor(max_charge_to_use / r.charge_per_node) + max_nodes = max(1, min(max_nodes, r.max_nodes)) end local found_positions, found_count @@ -488,7 +479,8 @@ function replacer.on_use(itemstack, player, pt, right_clicked) end -- on_use -- right-click with tool -> place set node --- special+right-click -> cycle mode (if tool/privs permit) +-- special+right-click -> cycle major mode (if tool/privs permit) +-- special+sneak+right-click -> cycle minor mode (if tool/privs permit) -- sneak+right-click -> set node function replacer.on_place(itemstack, player, pt) if (not player) or (not pt) then @@ -509,12 +501,21 @@ function replacer.on_place(itemstack, player, pt) if not modes_are_available then return end -- fetch current mode local node, mode = r.get_data(itemstack) - -- increment and roll-over mode - mode = r.modes[r.modes[mode] % #r.modes + 1] + if keys.sneak then + -- increment and roll-over minor mode + mode.minor = mode.minor % 3 + 1 + -- spam chat + r.inform(name, rb.mode_changed:format( + r.mode_minor_names[mode.minor], r.mode_minor_infos[mode.minor])) + else + -- increment and roll-over major mode + mode.major = mode.major % 3 + 1 + -- spam chat + r.inform(name, rb.mode_changed:format( + r.mode_major_names[mode.major], r.mode_major_infos[mode.major])) + end -- update tool r.set_data(itemstack, node, mode) - -- spam chat - r.inform(name, rb.mode_changed:format(mode, r.mode_infos[mode])) -- return changed tool return itemstack end @@ -603,6 +604,7 @@ function replacer.on_place(itemstack, player, pt) end local short_description = r.set_data(itemstack, node, mode) + r.history.add_item(player, mode, node, short_description) r.inform(name, rb.set_to:format(short_description)) @@ -637,28 +639,3 @@ if r.has_technic_mod then minetest.register_tool(r.tool_name_technic, r.tool_def_technic()) end -function replacer.register_on_player_receive_fields(player, form_name, fields) - -- no need to process if it's not expected formspec that triggered call - if form_name ~= replacer.form_name_modes then return end - -- no need to process if user closed formspec without changing mode - if nil == fields.mode then return end - - -- collect some information - local itemstack = player:get_wielded_item() - local node, _ = r.get_data(itemstack) - local mode = fields.mode - local name = player:get_player_name() - - -- set metadata and itemstring - r.set_data(itemstack, node, mode) - -- update wielded item - player:set_wielded_item(itemstack) - --[[ NOTE: for now I leave this code here in case we later make this a setting in - some way that does not mute all messages of tool - -- spam players chat with information - r.inform(name, rb.set_to:format(mode, r.mode_infos[mode])) - --]] -end --- listen to submitted fields -minetest.register_on_player_receive_fields(replacer.register_on_player_receive_fields) - diff --git a/replacer_constrain.lua b/replacer_constrain.lua index 4efdb53..969acd2 100644 --- a/replacer_constrain.lua +++ b/replacer_constrain.lua @@ -44,6 +44,20 @@ replacer.max_time = tonumber(minetest.settings:get('replacer.max_time') or 1.0) -- [see replacer_patterns.lua>replacer.patterns.search_positions()] replacer.radius_factor = tonumber(minetest.settings:get('replacer.radius_factor') or 0.4) +-- priv to allow using history +replacer.history_priv = minetest.settings:get('replacer.history_priv') or 'creative' +-- disable saving history over sessions/reboots. IOW: don't use player meta e.g. if using old MT +replacer.history_disable_persistancy = + minetest.settings:get_bool('replacer.history_disable_persistancy') or false +-- ignored when persistancy is disabled. Interval in minutes to +replacer.history_save_interval = + tonumber(minetest.settings:get('replacer.history_save_interval') or 7) +-- include mode when changing from history +replacer.history_include_mode = + minetest.settings:get_bool('replacer.history_include_mode') or false +-- amount of items in history +replacer.history_max = tonumber(minetest.settings:get('replacer.history_max') or 7) + -- select which recipes to hide (not all combinations make sense) replacer.hide_recipe_basic = minetest.settings:get_bool('replacer.hide_recipe_basic') or false diff --git a/replacer_formspecs.lua b/replacer_formspecs.lua new file mode 100644 index 0000000..5fa4e0a --- /dev/null +++ b/replacer_formspecs.lua @@ -0,0 +1,163 @@ +-- https://github.com/minetest/minetest_docs/blob/413b559f1a49e59c2649eea2835fc7620d407dca/doc/formspecs.adoc#versions +-- https://rubenwardy.com/minetest_modding_book/en/players/formspecs.html + +local r = replacer +local rb = replacer.blabla +local log = minetest.log +local get_player_information = minetest.get_player_information +local mfe = minetest.formspec_escape +local check_player_privs = minetest.check_player_privs +local show_formspec = minetest.show_formspec + +replacer.form_name_modes = 'replacer_replacer_mode_change' + +function replacer.get_form_modes_4(player, mode) + local major, minor = mode.major, mode.minor + local name = player:get_player_name() + local has_history_priv = check_player_privs(name, r.history_priv) + local form_height = has_history_priv and '4.39' or '3' + local tmp_name = '_' + local formspec = 'formspec_version[4]' + .. 'size[5.375,' .. form_height + .. ']padding[0.375,0.375]' + .. 'label[0.33,0.44;' .. mfe(rb.choose_mode) + .. ']button_exit[0.33,0.77;2,0.5;' + if 1 == major then + formspec = formspec .. '_;< ' .. mfe(rb.mode_single) .. ' >' + else + tmp_name = 'mode1' + formspec = formspec .. 'mode1;' .. mfe(rb.mode_single) + end + formspec = formspec .. ']tooltip[' .. tmp_name .. ';' + .. mfe(rb.mode_single_tooltip) .. ']button_exit[2.9,0.77;2,0.5;' + if 2 == major then + tmp_name = '_' + formspec = formspec .. '_;< ' .. mfe(rb.mode_field) .. ' >' + else + tmp_name = 'mode2' + formspec = formspec .. 'mode2;' .. mfe(rb.mode_field) + end + formspec = formspec .. ']tooltip[' .. tmp_name .. ';' + .. mfe(rb.mode_field_tooltip) .. ']button_exit[1.44,1.55;2,0.5;' + if 3 == major then + tmp_name = '_' + formspec = formspec .. '_;< ' .. mfe(rb.mode_crust) .. ' >' + else + tmp_name = 'mode3' + formspec = formspec .. 'mode3;' .. mfe(rb.mode_crust) + end + local minor_dimensions = '0.38,2.22;4.5,0.55' + formspec = formspec .. ']tooltip[' .. tmp_name .. ';' + .. mfe(rb.mode_crust_tooltip) .. ']dropdown[' .. minor_dimensions .. ';minor;' + .. mfe(rb.mode_minor1) .. ',' .. mfe(rb.mode_minor2) .. ',' .. mfe(rb.mode_minor3) + .. ';' .. tostring(minor) .. ';true]tooltip[' .. minor_dimensions .. ';' + .. mfe(rb.mode_minor1 .. ': ' .. rb.mode_minor1_info .. '\n' + .. rb.mode_minor2 .. ': ' .. rb.mode_minor2_info .. '\n' + .. rb.mode_minor3 .. ': ' .. rb.mode_minor3_info) .. ']' + if not has_history_priv then return formspec end + + formspec = formspec .. 'label[0.33,3.22;' .. mfe(rb.choose_history) + .. ']dropdown[0.38,3.55;4.5,0.55;history;' + local db = r.history.get_player_table(player) + for i, data in ipairs(db) do + if r.history_include_mode then + formspec = formspec .. data.mode.major .. '.' .. data.mode.minor .. ' ' + end + formspec = formspec .. mfe(data.human_string) .. ',' + end + formspec = formspec .. '~~~~~~~~~~~~~~;1;true]' + return formspec +end -- get_form_modes_4 + +function replacer.get_form_modes_default(mode) + local major = mode.major + local tmp_name = '_' + local formspec = 'size[3.9,2]' + .. 'label[0,0;' .. mfe(rb.choose_mode) + .. ']button_exit[0.0,0.6;2,0.5;' + if 1 == major then + formspec = formspec .. '_;< ' .. mfe(rb.mode_single) .. ' >' + else + tmp_name = 'mode1' + formspec = formspec .. 'mode1;' .. mfe(rb.mode_single) + end + formspec = formspec .. ']tooltip[' .. tmp_name .. ';' + .. mfe(rb.mode_single_tooltip) .. ']button_exit[1.9,0.6;2,0.5;' + if 2 == major then + formspec = formspec .. '_;< ' .. mfe(rb.mode_field) .. ' >' + else + tmp_name = 'mode2' + formspec = formspec .. 'mode2;' .. mfe(rb.mode_field) + end + formspec = formspec .. ']tooltip[' .. tmp_name .. ';' + .. mfe(rb.mode_field_tooltip) .. ']button_exit[0.0,1.4;2,0.5;' + if 3 == major then + formspec = formspec .. '_;< ' .. mfe(rb.mode_crust) .. ' >' + else + tmp_name = 'mode3' + formspec = formspec .. 'mode3;' .. mfe(rb.mode_crust) + end + formspec = formspec .. ']tooltip[' .. tmp_name .. ';' + .. mfe(rb.mode_crust_tooltip) .. ']' + return formspec +end -- get_form_modes_default + +function replacer.on_player_receive_fields(player, form_name, fields) + -- no need to process if it's not expected formspec that triggered call + if form_name ~= r.form_name_modes then return end + -- collect some information + local name = player:get_player_name() + local wielded = player:get_wielded_item() + local node, mode = r.get_data(wielded) + -- user clicked on currently active mode + if fields._ then return end + if fields.mode1 or fields.mode2 or fields.mode3 then + -- user clicked on one of the major modes + mode.major = (fields.mode1 and 1) or (fields.mode2 and 2) or (fields.mode3 and 3) + elseif fields.minor then + -- clamp to { 1, 2, 3 } + mode.minor = math.min(3, math.max(1, tonumber(fields.minor) or 1)) + elseif fields.history then + -- ignore if user doesn't have privs + if not check_player_privs(name, r.history_priv) then + log('info', rb.formspec_error:format(name, dump(fields))) + return + end + local entry = r.history.get_by_index(player, tonumber(fields.history) or 1) + if not entry then return end + + node = entry.node + mode = r.history_include_mode and entry.mode or nil + elseif fields.quit then + -- user closed formspec with escape or other clicking manouver + return + else + -- some hacked client forging formspec? + log('info', rb.formspec_hacker:format(name, dump(fields))) + return + end + + -- set metadata and itemstring + r.set_data(wielded, node, mode) + -- update wielded item + player:set_wielded_item(wielded) +end -- on_player_receive_fields +-- listen to submitted fields +minetest.register_on_player_receive_fields(r.on_player_receive_fields) + +function replacer.show_mode_formspec(player, mode) + if not player then return end + + local name = player:get_player_name() + local version = get_player_information(name).formspec_version + local formspec + if 4 > version then + formspec = r.get_form_modes_default(mode) + else + -- version 4+ allows us to use proper dropdowns and other gimmics + formspec = r.get_form_modes_4(player, mode) + end + -- show the formspec to player + show_formspec(name, r.form_name_modes, formspec) +end -- show_mode_formspec + diff --git a/replacer_history.lua b/replacer_history.lua new file mode 100644 index 0000000..b8cc09a --- /dev/null +++ b/replacer_history.lua @@ -0,0 +1,127 @@ +replacer.history = {} +replacer.history.db = {} +replacer.history.dirty = {} +local r = replacer +local rb = replacer.blabla +local rud_colour_name = replacer.unifieddyes.colour_name + +function replacer.history.add_item(player, mode, node, short_description) + local name = player:get_player_name() + local db_old = r.history.db[name] + if not db_old then return end + + local i = 1 + local db = { { node = node, mode = mode, human_string = short_description } } + for _, entry in ipairs(db_old) do + if entry.human_string ~= short_description then + i = i + 1 + db[i] = entry + if i == r.history_max then break end + end + end + r.history.db[name] = db + r.history.dirty[name] = true +end -- add_item + +function r.history.auto_save() + minetest.after(r.history_save_interval, r.history.auto_save) + for _, player in ipairs(minetest.get_connected_players()) do + if r.history.dirty[player:get_player_name()] then + r.history.save(player) + end + end +end -- auto_save + +function replacer.history.dealloc_player(player) + r.history.save(player) + r.history.db[player:get_player_name()] = nil +end -- dealloc_player + +function replacer.history.get_by_index(player, index) + return r.history.get_player_table(player)[index] +end -- get_by_index + +function replacer.history.get_player_table(player) + return r.history.db[player:get_player_name()] or {} +end -- get_player_table + +function replacer.history.init_player(player) + local name = player:get_player_name() + if not minetest.check_player_privs(name, r.history_priv) then return end + + local db_strings = + player:get_meta():get_string('replacer_his'):split('||', false, r.history_max) or {} + local db = {} + local data, entry, mode_raw, colour_name, node_def + for i, entry_raw in ipairs(db_strings) do + data = entry_raw:split(' ', false, 4) + mode_raw = data[4] or '1.1' + mode = mode_raw:split('.', false, 2) + entry = { + node = { + name = data[1] or r.tool_default_node, + param1 = tonumber(data[2]) or 0, + param2 = tonumber(data[3]) or 0, + }, + mode = { + major = tonumber(mode[1]) or 1, + minor = tonumber(mode[2]) or 1, + }, + } + node_def = minetest.registered_items[entry.node.name] + colour_name = rud_colour_name(entry.node.param2, node_def) + if 0 < #colour_name then + colour_name = ' ' .. colour_name + end + entry.human_string = tostring(entry.mode.major) .. '.' .. tostring(entry.mode.minor) + .. ' ' .. rb.tool_short_description:format(entry.node.param1, entry.node.param2, + colour_name, entry.node.name) + db[i] = entry + end + r.history.db[name] = db +end -- init_player + +function replacer.history.on_priv_grant(name, granter, priv) + -- skip duplicate calls + if granter then return end + if priv ~= r.history_priv then return end + r.history.init_player(minetest.get_player_by_name(name)) +end -- on_priv_grant + +function replacer.history.on_priv_revoke(name, revoker, priv) + -- skip duplicate calls + if revoker then return end + if priv ~= r.history_priv then return end + r.history.dealloc_player(minetest.get_player_by_name(name)) +end -- on_priv_revoke + +function replacer.history.save(player) + local name = player:get_player_name() + if r.history_disable_persistancy then + r.history.db[name] = nil + r.history.dirty[name] = nil + return + end + + local db = r.history.db[name] + if not db then return end + + local t = {} + for i, entry in ipairs(db) do + if i > r.history_max then break end + t[i] = table.concat({ entry.node.name, entry.node.param1, entry.node.param2, + table.concat({ entry.mode.major, entry.mode.minor }, '.') }, ' ') + end + player:get_meta():set_string('replacer_his', table.concat(t, '||')) + r.history.dirty[name] = nil +end -- save + +minetest.register_on_joinplayer(r.history.init_player) +minetest.register_on_leaveplayer(r.history.dealloc_player) +minetest.register_on_priv_grant(r.history.on_priv_grant) +minetest.register_on_priv_revoke(r.history.on_priv_revoke) +if not r.history_disable_persistancy then + r.history_save_interval = 60 * r.history_save_interval + minetest.after(r.history_save_interval, r.history.auto_save) +end -- if persistancy is enabled + From cf6cc7680722bc0e28a2a4e01612596e6cf3b891 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 18 Jan 2022 13:46:15 +0100 Subject: [PATCH 119/366] locale --- chat_commands.lua | 16 +- i18n.py | 477 +++++++++++++++++++++++++++++++++++++++++ locale/replacer.de.tr | 46 ++++ locale/replacer.es.tr | 46 ++++ locale/replacer.fi.tr | 46 ++++ locale/replacer.fr.tr | 46 ++++ locale/replacer.it.tr | 46 ++++ locale/replacer.pt.tr | 46 ++++ locale/replacer.ru.tr | 46 ++++ locale/template.txt | 46 ++++ replacer_blabla.lua | 114 ++++++---- replacer_constrain.lua | 12 +- 12 files changed, 940 insertions(+), 47 deletions(-) create mode 100755 i18n.py create mode 100644 locale/replacer.de.tr create mode 100644 locale/replacer.es.tr create mode 100644 locale/replacer.fi.tr create mode 100644 locale/replacer.fr.tr create mode 100644 locale/replacer.it.tr create mode 100644 locale/replacer.pt.tr create mode 100644 locale/replacer.ru.tr create mode 100644 locale/template.txt diff --git a/chat_commands.lua b/chat_commands.lua index 22a69b5..e7af86a 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -1,9 +1,17 @@ local rb = replacer.blabla +-- let's hope there isn't a yes that means no in another language :/ +-- TODO: better option would be to simply toggle (see postool) +local lOn = { 'on', 'yes', 'an', 'ja', 'si', 'sí', 'да', 'oui', 'joo', 'juu', 'kyllä', 'sim' } +local lOff = { 'off', 'no', 'aus', 'nein', 'non', 'нет', 'ei', 'fora', 'não' } +local tOn, tOff = {}, {} +for _, s in ipairs(lOn) do tOn[s] = true end +for _, s in ipairs(lOff) do tOff[s] = true end + replacer.chatcommand_mute = { - params = rb.ccm_params, + params = rb.ccm_params:format(rb.on_yes, rb.off_no), description = rb.ccm_description, func = function(name, param) local player = minetest.get_player_by_name(name) @@ -16,12 +24,12 @@ replacer.chatcommand_mute = { end local lower = string.lower(param) - if 'on' == lower then + if tOff[lower] then meta:set_int('replacer_mute', 1) - elseif 'off' == lower then + elseif tOn[lower] then meta:set_int('replacer_mute', 0) else - return false, rb.ccm_hint + return false, rb.ccm_hint:format(rb.on_yes, rb.off_no) end return true, '' diff --git a/i18n.py b/i18n.py new file mode 100755 index 0000000..21c4657 --- /dev/null +++ b/i18n.py @@ -0,0 +1,477 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Script to generate the template file and update the translation files. +# Copy the script into the mod or modpack root folder and run it there. +# +# Copyright (C) 2019 Joachim Stolberg, 2020 FaceDeer, 2020 Louis Royer +# LGPLv2.1+ +# +# See https://github.com/minetest-tools/update_translations for +# potential future updates to this script. + +from __future__ import print_function +import os, fnmatch, re, shutil, errno +from sys import argv as _argv +from sys import stderr as _stderr + +# Running params +params = {"recursive": False, + "help": False, + "mods": False, + "verbose": False, + "folders": [], + "no-old-file": True, + "break-long-lines": True, + "sort": False, + "print-source": False, + "truncate-unused": True, +} +# Available CLI options +options = {"recursive": ['--recursive', '-r'], + "help": ['--help', '-h'], + "mods": ['--installed-mods', '-m'], + "verbose": ['--verbose', '-v'], + "no-old-file": ['--no-old-file', '-O'], + "break-long-lines": ['--break-long-lines', '-b'], + "sort": ['--sort', '-s'], + "print-source": ['--print-source', '-p'], + "truncate-unused": ['--truncate-unused', '-t'], +} + +# Strings longer than this will have extra space added between +# them in the translation files to make it easier to distinguish their +# beginnings and endings at a glance +doublespace_threshold = 80 + +def set_params_folders(tab: list): + '''Initialize params["folders"] from CLI arguments.''' + # Discarding argument 0 (tool name) + for param in tab[1:]: + stop_param = False + for option in options: + if param in options[option]: + stop_param = True + break + if not stop_param: + params["folders"].append(os.path.abspath(param)) + +def set_params(tab: list): + '''Initialize params from CLI arguments.''' + for option in options: + for option_name in options[option]: + if option_name in tab: + params[option] = True + break + +def print_help(name): + '''Prints some help message.''' + print(f'''SYNOPSIS + {name} [OPTIONS] [PATHS...] +DESCRIPTION + {', '.join(options["help"])} + prints this help message + {', '.join(options["recursive"])} + run on all subfolders of paths given + {', '.join(options["mods"])} + run on locally installed modules + {', '.join(options["no-old-file"])} + do not create *.old files + {', '.join(options["sort"])} + sort output strings alphabetically + {', '.join(options["break-long-lines"])} + add extra line breaks before and after long strings + {', '.join(options["print-source"])} + add comments denoting the source file + {', '.join(options["verbose"])} + add output information + {', '.join(options["truncate-unused"])} + delete unused strings from files +''') + + +def main(): + '''Main function''' + set_params(_argv) + set_params_folders(_argv) + if params["help"]: + print_help(_argv[0]) + elif params["recursive"] and params["mods"]: + print("Option --installed-mods is incompatible with --recursive") + else: + # Add recursivity message + print("Running ", end='') + if params["recursive"]: + print("recursively ", end='') + # Running + if params["mods"]: + print(f"on all locally installed modules in {os.path.expanduser('~/.minetest/mods/')}") + run_all_subfolders(os.path.expanduser("~/.minetest/mods")) + elif len(params["folders"]) >= 2: + print("on folder list:", params["folders"]) + for f in params["folders"]: + if params["recursive"]: + run_all_subfolders(f) + else: + update_folder(f) + elif len(params["folders"]) == 1: + print("on folder", params["folders"][0]) + if params["recursive"]: + run_all_subfolders(params["folders"][0]) + else: + update_folder(params["folders"][0]) + else: + print("on folder", os.path.abspath("./")) + if params["recursive"]: + run_all_subfolders(os.path.abspath("./")) + else: + update_folder(os.path.abspath("./")) + +#group 2 will be the string, groups 1 and 3 will be the delimiters (" or ') +#See https://stackoverflow.com/questions/46967465/regex-match-text-in-either-single-or-double-quote +pattern_lua_s = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\s,\)]', re.DOTALL) +pattern_lua_fs = re.compile(r'[\.=^\t,{\(\s]N?FS\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\s,\)]', re.DOTALL) +pattern_lua_bracketed_s = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*\[\[(.*?)\]\][\s,\)]', re.DOTALL) +pattern_lua_bracketed_fs = re.compile(r'[\.=^\t,{\(\s]N?FS\(\s*\[\[(.*?)\]\][\s,\)]', re.DOTALL) + +# Handles "concatenation" .. " of strings" +pattern_concat = re.compile(r'["\'][\s]*\.\.[\s]*["\']', re.DOTALL) + +pattern_tr = re.compile(r'(.*?[^@])=(.*)') +pattern_name = re.compile(r'^name[ ]*=[ ]*([^ \n]*)') +pattern_tr_filename = re.compile(r'\.tr$') +pattern_po_language_code = re.compile(r'(.*)\.po$') + +#attempt to read the mod's name from the mod.conf file or folder name. Returns None on failure +def get_modname(folder): + try: + with open(os.path.join(folder, "mod.conf"), "r", encoding='utf-8') as mod_conf: + for line in mod_conf: + match = pattern_name.match(line) + if match: + return match.group(1) + except FileNotFoundError: + if not os.path.isfile(os.path.join(folder, "modpack.txt")): + folder_name = os.path.basename(folder) + # Special case when run in Minetest's builtin directory + if folder_name == "builtin": + return "__builtin" + else: + return folder_name + else: + return None + return None + +#If there are already .tr files in /locale, returns a list of their names +def get_existing_tr_files(folder): + out = [] + for root, dirs, files in os.walk(os.path.join(folder, 'locale/')): + for name in files: + if pattern_tr_filename.search(name): + out.append(name) + return out + +# A series of search and replaces that massage a .po file's contents into +# a .tr file's equivalent +def process_po_file(text): + # The first three items are for unused matches + text = re.sub(r'#~ msgid "', "", text) + text = re.sub(r'"\n#~ msgstr ""\n"', "=", text) + text = re.sub(r'"\n#~ msgstr "', "=", text) + # comment lines + text = re.sub(r'#.*\n', "", text) + # converting msg pairs into "=" pairs + text = re.sub(r'msgid "', "", text) + text = re.sub(r'"\nmsgstr ""\n"', "=", text) + text = re.sub(r'"\nmsgstr "', "=", text) + # various line breaks and escape codes + text = re.sub(r'"\n"', "", text) + text = re.sub(r'"\n', "\n", text) + text = re.sub(r'\\"', '"', text) + text = re.sub(r'\\n', '@n', text) + # remove header text + text = re.sub(r'=Project-Id-Version:.*\n', "", text) + # remove double-spaced lines + text = re.sub(r'\n\n', '\n', text) + return text + +# Go through existing .po files and, if a .tr file for that language +# *doesn't* exist, convert it and create it. +# The .tr file that results will subsequently be reprocessed so +# any "no longer used" strings will be preserved. +# Note that "fuzzy" tags will be lost in this process. +def process_po_files(folder, modname): + for root, dirs, files in os.walk(os.path.join(folder, 'locale/')): + for name in files: + code_match = pattern_po_language_code.match(name) + if code_match == None: + continue + language_code = code_match.group(1) + tr_name = f'{modname}.{language_code}.tr' + tr_file = os.path.join(root, tr_name) + if os.path.exists(tr_file): + if params["verbose"]: + print(f"{tr_name} already exists, ignoring {name}") + continue + fname = os.path.join(root, name) + with open(fname, "r", encoding='utf-8') as po_file: + if params["verbose"]: + print(f"Importing translations from {name}") + text = process_po_file(po_file.read()) + with open(tr_file, "wt", encoding='utf-8') as tr_out: + tr_out.write(text) + +# from https://stackoverflow.com/questions/600268/mkdir-p-functionality-in-python/600612#600612 +# Creates a directory if it doesn't exist, silently does +# nothing if it already exists +def mkdir_p(path): + try: + os.makedirs(path) + except OSError as exc: # Python >2.5 + if exc.errno == errno.EEXIST and os.path.isdir(path): + pass + else: raise + +# Converts the template dictionary to a text to be written as a file +# dKeyStrings is a dictionary of localized string to source file sets +# dOld is a dictionary of existing translations and comments from +# the previous version of this text +def strings_to_text(dkeyStrings, dOld, mod_name, header_comments): + lOut = [f"# textdomain: {mod_name}"] + if header_comments is not None: + lOut.append(header_comments) + + dGroupedBySource = {} + + for key in dkeyStrings: + sourceList = list(dkeyStrings[key]) + if params["sort"]: + sourceList.sort() + sourceString = "\n".join(sourceList) + listForSource = dGroupedBySource.get(sourceString, []) + listForSource.append(key) + dGroupedBySource[sourceString] = listForSource + + lSourceKeys = list(dGroupedBySource.keys()) + lSourceKeys.sort() + for source in lSourceKeys: + localizedStrings = dGroupedBySource[source] + if params["sort"]: + localizedStrings.sort() + if params["print-source"]: + if lOut[-1] != "": + lOut.append("") + lOut.append(source) + for localizedString in localizedStrings: + val = dOld.get(localizedString, {}) + translation = val.get("translation", "") + comment = val.get("comment") + if params["break-long-lines"] and len(localizedString) > doublespace_threshold and not lOut[-1] == "": + lOut.append("") + if comment != None and comment != "" and not comment.startswith("# textdomain:"): + lOut.append(comment) + lOut.append(f"{localizedString}={translation}") + if params["break-long-lines"] and len(localizedString) > doublespace_threshold: + lOut.append("") + + + unusedExist = False + if not params["truncate-unused"]: + for key in dOld: + if key not in dkeyStrings: + val = dOld[key] + translation = val.get("translation") + comment = val.get("comment") + # only keep an unused translation if there was translated + # text or a comment associated with it + if translation != None and (translation != "" or comment): + if not unusedExist: + unusedExist = True + lOut.append("\n\n##### not used anymore #####\n") + if params["break-long-lines"] and len(key) > doublespace_threshold and not lOut[-1] == "": + lOut.append("") + if comment != None: + lOut.append(comment) + lOut.append(f"{key}={translation}") + if params["break-long-lines"] and len(key) > doublespace_threshold: + lOut.append("") + return "\n".join(lOut) + '\n' + +# Writes a template.txt file +# dkeyStrings is the dictionary returned by generate_template +def write_template(templ_file, dkeyStrings, mod_name): + # read existing template file to preserve comments + existing_template = import_tr_file(templ_file) + + text = strings_to_text(dkeyStrings, existing_template[0], mod_name, existing_template[2]) + mkdir_p(os.path.dirname(templ_file)) + with open(templ_file, "wt", encoding='utf-8') as template_file: + template_file.write(text) + + +# Gets all translatable strings from a lua file +def read_lua_file_strings(lua_file): + lOut = [] + with open(lua_file, encoding='utf-8') as text_file: + text = text_file.read() + #TODO remove comments here + + text = re.sub(pattern_concat, "", text) + + strings = [] + for s in pattern_lua_s.findall(text): + strings.append(s[1]) + for s in pattern_lua_bracketed_s.findall(text): + strings.append(s) + for s in pattern_lua_fs.findall(text): + strings.append(s[1]) + for s in pattern_lua_bracketed_fs.findall(text): + strings.append(s) + + for s in strings: + s = re.sub(r'"\.\.\s+"', "", s) + s = re.sub("@[^@=0-9]", "@@", s) + s = s.replace('\\"', '"') + s = s.replace("\\'", "'") + s = s.replace("\n", "@n") + s = s.replace("\\n", "@n") + s = s.replace("=", "@=") + lOut.append(s) + return lOut + +# Gets strings from an existing translation file +# returns both a dictionary of translations +# and the full original source text so that the new text +# can be compared to it for changes. +# Returns also header comments in the third return value. +def import_tr_file(tr_file): + dOut = {} + text = None + header_comment = None + if os.path.exists(tr_file): + with open(tr_file, "r", encoding='utf-8') as existing_file : + # save the full text to allow for comparison + # of the old version with the new output + text = existing_file.read() + existing_file.seek(0) + # a running record of the current comment block + # we're inside, to allow preceeding multi-line comments + # to be retained for a translation line + latest_comment_block = None + for line in existing_file.readlines(): + line = line.rstrip('\n') + if line.startswith("###"): + if header_comment is None and not latest_comment_block is None: + # Save header comments + header_comment = latest_comment_block + # Strip textdomain line + tmp_h_c = "" + for l in header_comment.split('\n'): + if not l.startswith("# textdomain:"): + tmp_h_c += l + '\n' + header_comment = tmp_h_c + + # Reset comment block if we hit a header + latest_comment_block = None + continue + elif line.startswith("#"): + # Save the comment we're inside + if not latest_comment_block: + latest_comment_block = line + else: + latest_comment_block = latest_comment_block + "\n" + line + continue + match = pattern_tr.match(line) + if match: + # this line is a translated line + outval = {} + outval["translation"] = match.group(2) + if latest_comment_block: + # if there was a comment, record that. + outval["comment"] = latest_comment_block + latest_comment_block = None + dOut[match.group(1)] = outval + return (dOut, text, header_comment) + +# Walks all lua files in the mod folder, collects translatable strings, +# and writes it to a template.txt file +# Returns a dictionary of localized strings to source file sets +# that can be used with the strings_to_text function. +def generate_template(folder, mod_name): + dOut = {} + for root, dirs, files in os.walk(folder): + for name in files: + if fnmatch.fnmatch(name, "*.lua"): + fname = os.path.join(root, name) + found = read_lua_file_strings(fname) + if params["verbose"]: + print(f"{fname}: {str(len(found))} translatable strings") + + for s in found: + sources = dOut.get(s, set()) + sources.add(f"### {os.path.basename(fname)} ###") + dOut[s] = sources + + if len(dOut) == 0: + return None + templ_file = os.path.join(folder, "locale/template.txt") + write_template(templ_file, dOut, mod_name) + return dOut + +# Updates an existing .tr file, copying the old one to a ".old" file +# if any changes have happened +# dNew is the data used to generate the template, it has all the +# currently-existing localized strings +def update_tr_file(dNew, mod_name, tr_file): + if params["verbose"]: + print(f"updating {tr_file}") + + tr_import = import_tr_file(tr_file) + dOld = tr_import[0] + textOld = tr_import[1] + + textNew = strings_to_text(dNew, dOld, mod_name, tr_import[2]) + + if textOld and textOld != textNew: + print(f"{tr_file} has changed.") + if not params["no-old-file"]: + shutil.copyfile(tr_file, f"{tr_file}.old") + + with open(tr_file, "w", encoding='utf-8') as new_tr_file: + new_tr_file.write(textNew) + +# Updates translation files for the mod in the given folder +def update_mod(folder): + modname = get_modname(folder) + if modname is not None: + process_po_files(folder, modname) + print(f"Updating translations for {modname}") + data = generate_template(folder, modname) + if data == None: + print(f"No translatable strings found in {modname}") + else: + for tr_file in get_existing_tr_files(folder): + update_tr_file(data, modname, os.path.join(folder, "locale/", tr_file)) + else: + print(f"\033[31mUnable to find modname in folder {folder}.\033[0m", file=_stderr) + exit(1) + +# Determines if the folder being pointed to is a mod or a mod pack +# and then runs update_mod accordingly +def update_folder(folder): + is_modpack = os.path.exists(os.path.join(folder, "modpack.txt")) or os.path.exists(os.path.join(folder, "modpack.conf")) + if is_modpack: + subfolders = [f.path for f in os.scandir(folder) if f.is_dir() and not f.name.startswith('.')] + for subfolder in subfolders: + update_mod(subfolder) + else: + update_mod(folder) + print("Done.") + +def run_all_subfolders(folder): + for modfolder in [f.path for f in os.scandir(folder) if f.is_dir() and not f.name.startswith('.')]: + update_folder(modfolder) + + +main() + diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr new file mode 100644 index 0000000..3ec51ab --- /dev/null +++ b/locale/replacer.de.tr @@ -0,0 +1,46 @@ +# textdomain: replacer +History= +Choose mode= +Both= +Node= +Rotation= +Replace node and apply orientation.= +Replace node without changing orientation.= +Apply orientation without changing node type.= +Single= +Field= +Crust= +Replace single node.= + +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= + +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= + +Protected at %s= +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= +You have no further "%s". Replacement failed.= +Unknown node: "%s"= +Unknown node to place: "%s"= +Could not dig "%s" properly.= +Could not place "%s".= +Error: "%s" is not a node.= +Target node not yet loaded. Please wait a moment for the server to catch up.= +Nothing to replace.= +Not enough charge to use this mode.= +Aborted, too many nodes detected.= +Need %s charge to replace %s nodes.= +%s nodes replaced.= +Mode changed to %s: %s= +Error: No node selected.= +Item not in creative invenotry: "%s".= +Item not in your inventory: "%s".= +Node replacement tool set to:@n%s.= +Node replacement tool= +Node replacement tool (technic)= +Time-limit reached.= + +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= + +Valid parameter is either "%s" or "%s"= +on= +off= diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr new file mode 100644 index 0000000..3ec51ab --- /dev/null +++ b/locale/replacer.es.tr @@ -0,0 +1,46 @@ +# textdomain: replacer +History= +Choose mode= +Both= +Node= +Rotation= +Replace node and apply orientation.= +Replace node without changing orientation.= +Apply orientation without changing node type.= +Single= +Field= +Crust= +Replace single node.= + +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= + +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= + +Protected at %s= +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= +You have no further "%s". Replacement failed.= +Unknown node: "%s"= +Unknown node to place: "%s"= +Could not dig "%s" properly.= +Could not place "%s".= +Error: "%s" is not a node.= +Target node not yet loaded. Please wait a moment for the server to catch up.= +Nothing to replace.= +Not enough charge to use this mode.= +Aborted, too many nodes detected.= +Need %s charge to replace %s nodes.= +%s nodes replaced.= +Mode changed to %s: %s= +Error: No node selected.= +Item not in creative invenotry: "%s".= +Item not in your inventory: "%s".= +Node replacement tool set to:@n%s.= +Node replacement tool= +Node replacement tool (technic)= +Time-limit reached.= + +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= + +Valid parameter is either "%s" or "%s"= +on= +off= diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr new file mode 100644 index 0000000..3ec51ab --- /dev/null +++ b/locale/replacer.fi.tr @@ -0,0 +1,46 @@ +# textdomain: replacer +History= +Choose mode= +Both= +Node= +Rotation= +Replace node and apply orientation.= +Replace node without changing orientation.= +Apply orientation without changing node type.= +Single= +Field= +Crust= +Replace single node.= + +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= + +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= + +Protected at %s= +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= +You have no further "%s". Replacement failed.= +Unknown node: "%s"= +Unknown node to place: "%s"= +Could not dig "%s" properly.= +Could not place "%s".= +Error: "%s" is not a node.= +Target node not yet loaded. Please wait a moment for the server to catch up.= +Nothing to replace.= +Not enough charge to use this mode.= +Aborted, too many nodes detected.= +Need %s charge to replace %s nodes.= +%s nodes replaced.= +Mode changed to %s: %s= +Error: No node selected.= +Item not in creative invenotry: "%s".= +Item not in your inventory: "%s".= +Node replacement tool set to:@n%s.= +Node replacement tool= +Node replacement tool (technic)= +Time-limit reached.= + +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= + +Valid parameter is either "%s" or "%s"= +on= +off= diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr new file mode 100644 index 0000000..3ec51ab --- /dev/null +++ b/locale/replacer.fr.tr @@ -0,0 +1,46 @@ +# textdomain: replacer +History= +Choose mode= +Both= +Node= +Rotation= +Replace node and apply orientation.= +Replace node without changing orientation.= +Apply orientation without changing node type.= +Single= +Field= +Crust= +Replace single node.= + +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= + +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= + +Protected at %s= +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= +You have no further "%s". Replacement failed.= +Unknown node: "%s"= +Unknown node to place: "%s"= +Could not dig "%s" properly.= +Could not place "%s".= +Error: "%s" is not a node.= +Target node not yet loaded. Please wait a moment for the server to catch up.= +Nothing to replace.= +Not enough charge to use this mode.= +Aborted, too many nodes detected.= +Need %s charge to replace %s nodes.= +%s nodes replaced.= +Mode changed to %s: %s= +Error: No node selected.= +Item not in creative invenotry: "%s".= +Item not in your inventory: "%s".= +Node replacement tool set to:@n%s.= +Node replacement tool= +Node replacement tool (technic)= +Time-limit reached.= + +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= + +Valid parameter is either "%s" or "%s"= +on= +off= diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr new file mode 100644 index 0000000..3ec51ab --- /dev/null +++ b/locale/replacer.it.tr @@ -0,0 +1,46 @@ +# textdomain: replacer +History= +Choose mode= +Both= +Node= +Rotation= +Replace node and apply orientation.= +Replace node without changing orientation.= +Apply orientation without changing node type.= +Single= +Field= +Crust= +Replace single node.= + +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= + +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= + +Protected at %s= +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= +You have no further "%s". Replacement failed.= +Unknown node: "%s"= +Unknown node to place: "%s"= +Could not dig "%s" properly.= +Could not place "%s".= +Error: "%s" is not a node.= +Target node not yet loaded. Please wait a moment for the server to catch up.= +Nothing to replace.= +Not enough charge to use this mode.= +Aborted, too many nodes detected.= +Need %s charge to replace %s nodes.= +%s nodes replaced.= +Mode changed to %s: %s= +Error: No node selected.= +Item not in creative invenotry: "%s".= +Item not in your inventory: "%s".= +Node replacement tool set to:@n%s.= +Node replacement tool= +Node replacement tool (technic)= +Time-limit reached.= + +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= + +Valid parameter is either "%s" or "%s"= +on= +off= diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr new file mode 100644 index 0000000..3ec51ab --- /dev/null +++ b/locale/replacer.pt.tr @@ -0,0 +1,46 @@ +# textdomain: replacer +History= +Choose mode= +Both= +Node= +Rotation= +Replace node and apply orientation.= +Replace node without changing orientation.= +Apply orientation without changing node type.= +Single= +Field= +Crust= +Replace single node.= + +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= + +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= + +Protected at %s= +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= +You have no further "%s". Replacement failed.= +Unknown node: "%s"= +Unknown node to place: "%s"= +Could not dig "%s" properly.= +Could not place "%s".= +Error: "%s" is not a node.= +Target node not yet loaded. Please wait a moment for the server to catch up.= +Nothing to replace.= +Not enough charge to use this mode.= +Aborted, too many nodes detected.= +Need %s charge to replace %s nodes.= +%s nodes replaced.= +Mode changed to %s: %s= +Error: No node selected.= +Item not in creative invenotry: "%s".= +Item not in your inventory: "%s".= +Node replacement tool set to:@n%s.= +Node replacement tool= +Node replacement tool (technic)= +Time-limit reached.= + +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= + +Valid parameter is either "%s" or "%s"= +on= +off= diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr new file mode 100644 index 0000000..3ec51ab --- /dev/null +++ b/locale/replacer.ru.tr @@ -0,0 +1,46 @@ +# textdomain: replacer +History= +Choose mode= +Both= +Node= +Rotation= +Replace node and apply orientation.= +Replace node without changing orientation.= +Apply orientation without changing node type.= +Single= +Field= +Crust= +Replace single node.= + +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= + +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= + +Protected at %s= +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= +You have no further "%s". Replacement failed.= +Unknown node: "%s"= +Unknown node to place: "%s"= +Could not dig "%s" properly.= +Could not place "%s".= +Error: "%s" is not a node.= +Target node not yet loaded. Please wait a moment for the server to catch up.= +Nothing to replace.= +Not enough charge to use this mode.= +Aborted, too many nodes detected.= +Need %s charge to replace %s nodes.= +%s nodes replaced.= +Mode changed to %s: %s= +Error: No node selected.= +Item not in creative invenotry: "%s".= +Item not in your inventory: "%s".= +Node replacement tool set to:@n%s.= +Node replacement tool= +Node replacement tool (technic)= +Time-limit reached.= + +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= + +Valid parameter is either "%s" or "%s"= +on= +off= diff --git a/locale/template.txt b/locale/template.txt new file mode 100644 index 0000000..3ec51ab --- /dev/null +++ b/locale/template.txt @@ -0,0 +1,46 @@ +# textdomain: replacer +History= +Choose mode= +Both= +Node= +Rotation= +Replace node and apply orientation.= +Replace node without changing orientation.= +Apply orientation without changing node type.= +Single= +Field= +Crust= +Replace single node.= + +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= + +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= + +Protected at %s= +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= +You have no further "%s". Replacement failed.= +Unknown node: "%s"= +Unknown node to place: "%s"= +Could not dig "%s" properly.= +Could not place "%s".= +Error: "%s" is not a node.= +Target node not yet loaded. Please wait a moment for the server to catch up.= +Nothing to replace.= +Not enough charge to use this mode.= +Aborted, too many nodes detected.= +Need %s charge to replace %s nodes.= +%s nodes replaced.= +Mode changed to %s: %s= +Error: No node selected.= +Item not in creative invenotry: "%s".= +Item not in your inventory: "%s".= +Node replacement tool set to:@n%s.= +Node replacement tool= +Node replacement tool (technic)= +Time-limit reached.= + +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= + +Valid parameter is either "%s" or "%s"= +on= +off= diff --git a/replacer_blabla.lua b/replacer_blabla.lua index 78dbf24..0d1f325 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -1,44 +1,84 @@ +if not minetest.translate then + function minetest.translate(textdomain, str, ...) + local arg = { n = select('#', ...), ... } + return str:gsub('@(.)', function(matched) + local c = string.byte(matched) + if string.byte('1') <= c and c <= string.byte('9') then + return arg[c - string.byte('0')] + else + return matched + end + end) + end + + function core.get_translator(textdomain) + return function(str, ...) return core.translate(textdomain or '', str, ...) end + end +end -- backward compatibility +local S = minetest.get_translator('replacer') + replacer.blabla = {} local rb = replacer.blabla -rb.log = '[replacer] %s: %s' -rb.mode_single = 'Replace single node.' -rb.mode_field = 'Left click: Replace field of nodes of a kind where a translucent node is in front of it. Right click: Replace field of air where no translucent node is behind the air.' -rb.mode_crust = 'Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air. Right click: Replace air nodes which touch the crust' -rb.protected_at = 'Protected at %s' -rb.deny_listed = 'Replacing nodes of type "%s" is not allowed on this server. Replacement failed.' -rb.run_out = 'You have no further "%s". Replacement failed.' -rb.attempt_unknown_replace = 'Unknown node: "%s"' -rb.attempt_unknown_place = 'Unknown node to place: "%s"' -rb.can_not_dig = 'Could not dig "%s" properly.' -rb.can_not_place = 'Could not place "%s".' -rb.not_a_node = 'Error: "%s" is not a node.' -rb.wait_for_load = 'Target node not yet loaded. Please wait a moment for the server to catch up.' -rb.nothing_to_replace = 'Nothing to replace.' -rb.need_more_charge = 'Not enough charge to use this mode.' -rb.too_many_nodes_detected = 'Aborted, too many nodes detected.' -rb.charge_required = 'Need %d charge to replace %d nodes.' -rb.count_replaced = '%s nodes replaced.' -rb.mode_changed = 'Mode changed to %s: %s' -rb.none_selected = 'Error: No node selected.' -rb.not_in_creative = 'Item not in creative invenotry: "%s".' -rb.not_in_inventory = 'Item not in your inventory: "%s".' -rb.set_to = 'Node replacement tool set to:\n%s.' -rb.description_basic = 'Node replacement tool' -rb.description_technic = 'Node replacement tool (technic)' -rb.limit_override = 'Setting already set node-limit for "%s" was %d.' -rb.limit_insert = 'Setting node-limit for "%s" to %d.' -rb.deny_list_insert = 'Added "%s" to deny list.' -rb.timed_out = 'Time-limit reached.' +rb.log_messages = '[replacer] %s: %s' +rb.choose_history = S('History') +rb.choose_mode = S('Choose mode') +rb.mode_minor1 = S('Both') +rb.mode_minor2 = S('Node') +rb.mode_minor3 = S('Rotation') +rb.mode_minor1_info = S('Replace node and apply orientation.') +rb.mode_minor2_info = S('Replace node without changing orientation.') +rb.mode_minor3_info = S('Apply orientation without changing node type.') +rb.mode_single = S('Single') +rb.mode_field = S('Field') +rb.mode_crust = S('Crust') +rb.mode_single_tooltip = S('Replace single node.') +rb.mode_field_tooltip = S('Left click: Replace field of nodes of a kind where a ' + .. 'translucent node is in front of it.@nRight click: Replace field of air ' + .. 'where no translucent node is behind the air.') +rb.mode_crust_tooltip = S('Left click: Replace nodes which touch another one of ' + .. 'its kind and a translucent node, e.g. air.@nRight click: Replace air nodes ' + .. 'which touch the crust.') +rb.protected_at = S('Protected at %s') +rb.deny_listed = S('Replacing nodes of type "%s" is not allowed on this server. ' + .. 'Replacement failed.') +rb.run_out = S('You have no further "%s". Replacement failed.') +rb.attempt_unknown_replace = S('Unknown node: "%s"') +rb.attempt_unknown_place = S('Unknown node to place: "%s"') +rb.can_not_dig = S('Could not dig "%s" properly.') +rb.can_not_place = S('Could not place "%s".') +rb.not_a_node = S('Error: "%s" is not a node.') +rb.wait_for_load = S('Target node not yet loaded. Please wait a moment for the ' + .. 'server to catch up.') +rb.nothing_to_replace = S('Nothing to replace.') +rb.need_more_charge = S('Not enough charge to use this mode.') +rb.too_many_nodes_detected = S('Aborted, too many nodes detected.') +rb.charge_required = S('Need %s charge to replace %s nodes.') +rb.count_replaced = S('%s nodes replaced.') +rb.mode_changed = S('Mode changed to %s: %s') +rb.none_selected = S('Error: No node selected.') +rb.not_in_creative = S('Item not in creative invenotry: "%s".') +rb.not_in_inventory = S('Item not in your inventory: "%s".') +rb.set_to = S('Node replacement tool set to:\n%s.') +rb.description_basic = S('Node replacement tool') +rb.description_technic = S('Node replacement tool (technic)') +rb.log_limit_override = '[replacer] Setting already set node-limit for "%s" was %d.' +rb.log_limit_insert = '[replacer] Setting node-limit for "%s" to %d.' +rb.log_deny_list_insert = '[replacer] Added "%s" to deny list.' +rb.timed_out = S('Time-limit reached.') rb.tool_short_description = '(%s %s%s) %s' rb.tool_long_description = '%s\n%s\n%s' -rb.ccm_params = '[ on | off ]' -rb.ccm_description = 'Toggles mute of replacer tool.\nWhen on, no ' - .. 'messages are posted to chat. If off, verbose mode is on.' +rb.ccm_params = '[ %s | %s ]' +rb.ccm_description = S('Toggles verbosity.\nWhen on, ' + .. 'messages are posted to chat. When off, replacer is silent.') rb.ccm_player_not_found = 'Player not found' rb.ccm_player_meta_error = 'Player meta not existant' -rb.ccm_hint = 'Valid parameter is either "on" or "off"' -rb.reg_rot_exception_override = 'replacer.register_rotation_exception ' - .. 'for "%s" already exists.' -rb.reg_rot_exception = 'replacer.registered exception for "%s" to "%s"' -rb.reg_exception_callback = 'replacer.registered after on_place callback for "%s"' +rb.ccm_hint = S('Valid parameter is either "%s" or "%s"') +rb.on_yes = S('on') +rb.off_no = S('off') +rb.log_reg_exception_override = '[replacer] register_rotation_exception ' + .. 'for "%s" already exists.' +rb.log_reg_exception = '[replacer] registered exception for "%s" to "%s"' +rb.log_reg_exception_callback = '[replacer] registered after on_place callback for "%s"' +rb.formspec_error = '[replacer] formspec error, user "%s" attempting to change history. Fields: %s' +rb.formspec_hacker = '[replacer] formspec forge? By user "%s" Fields: %s' diff --git a/replacer_constrain.lua b/replacer_constrain.lua index 969acd2..6866143 100644 --- a/replacer_constrain.lua +++ b/replacer_constrain.lua @@ -91,15 +91,15 @@ end -- permit_replace function replacer.register_exception(node_name, drop_name, callback) if r.exception_map[node_name] then - minetest.log('info', rb.reg_rot_exception_override:format(node_name)) + minetest.log('info', rb.log_reg_exception_override:format(node_name)) end r.exception_map[node_name] = drop_name - minetest.log('info', rb.reg_rot_exception:format(node_name, drop_name)) + minetest.log('info', rb.log_reg_exception:format(node_name, drop_name)) if 'function' ~= type(callback) then return end r.exception_callbacks[node_name] = callback - minetest.log('info', rb.reg_exception_callback:format(node_name)) + minetest.log('info', rb.log_reg_exception_callback:format(node_name)) end -- register_exception local function is_positive_int(value) @@ -113,16 +113,16 @@ function replacer.register_limit(node_name, node_max) -- add to deny_list if limit is zero if 0 == node_max then - minetest.log('info', rb.deny_list_insert:format(node_name)) r.deny_list[node_name] = true + minetest.log('info', rb.log_deny_list_insert:format(node_name)) return end -- log info if already limited if nil ~= r.limit_list[node_name] then - minetest.log('info', rb.limit_override:format(node_name, r.limit_list[node_name])) + minetest.log('info', rb.log_limit_override:format(node_name, r.limit_list[node_name])) end r.limit_list[node_name] = node_max - minetest.log('info', rb.limit_insert:format(node_name, node_max)) + minetest.log('info', rb.log_limit_insert:format(node_name, node_max)) end -- register_limit From ca0ff56da0ac1237f43bb975337d32b4632b60dd Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 18 Jan 2022 13:48:47 +0100 Subject: [PATCH 120/366] changelog and comments --- CHANGELOG | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ init.lua | 47 +++++-------------------------------------- replacer.lua | 7 +++++++ 3 files changed, 69 insertions(+), 42 deletions(-) create mode 100644 CHANGELOG diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..b2471a0 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,57 @@ +20220118 * SwissalpS cleaned up more code, giving more discriptive variable names and + cleaning out ugly modes table that had both number and string indexes + * Don't allow replacer to be set to deny_list nodes + * History works for users with priv. Various settings added to + fine-tune how it behaves. + * Implemented minor-modes with more colours ;) + * Added non-formspec way to cycle minor modes: Special+Sneak+right-click + * Especially in functions with tight loops, local references to global functions was added. +20220117 * SwissalpS changed mode storage in tool meta to major.minor format + * Added version 4 formspec that enables changing minor mode + and has prepared history selector. + * Moved changelog and cleaned it up adding some dates + * Moved formspec code to separate file. + * Started implementing translations and history. +20220115 * SwissalpS refactored constraints and renamed blacklist to deny_list +20220114 * SwissalpS added support for cable plates and similar nodes +20220113 * SwissalpS worked in HybridDog's nicer pattern algorithm, modifying a little. + Also cleaned up some code and give-priv does not grant modes anymore, + creative still does. +20220112 * SwissalpS improved field mode: when replacing also check for same param2 + improved crust mode: when placing also allow vacuum instead of only air +20211202 * SwissalpS added /replacer_mute command +20210930 * SwissalpS merged patch provided by S-S-X to prevent a rare but possible crash with + Unknown Items in hotbar + * Also cleaned up tool change messages to blabla.lua +20201016 * HybridDog provided first documentation and SwissalpS added some more explaining modes. +20201015 * SwissalpS cleaned up inspector code and made inspector better readable on smaller screens +20200322 * HybridDog removed fourth mode and improved node search + * SwissalpS added backward compatibility for non technic servers, restored + creative/give behaviour and fixed the 'too many nodes detected' issue + * S-S-X and some players from pandorabox.io requested and inspired ideas to + implement which SwissalpS tried to satisfy. +20200131 * SwissalpS added method to change mode via formspec +20200109 * BuckarooBanzay added server-setting max_nodes, moved crafts and replacer to + separate files, added .luacheckrc and cleaned up inspection tool, fixing + some issues on the way and updated readme to look nice +20191217 * OgelGames fixed digging to be simulated properly +20191212 * coil0 made modes available as technic tool and added limits + * SwissalpS merged Sokomine's and HybridDog's versions + * HybridDog added modes for creative mode +20190628 * coil0 fixed issue by using buildable_to +20171209 * Got rid of outdated minetest.env + * Fixed error in protection function. + * Fixed minor bugs. + * Added blacklist +20141002 * Some more improvements for inspect-tool. Added craft-guide. +20141001 * Added inspect-tool. +20130112 * If digging the node was unsuccessful, then the replacement will now fail + (instead of destroying the old node with its metadata; i.e. chests with content) +20131120 * if the server version is new enough, minetest.is_protected is used + in order to check if the replacement is allowed +20130424 * param1 and param2 are now stored + * hold sneak + right click to store new pattern + * right click: place one of the itmes + * receipe changed + * inventory image added + diff --git a/init.lua b/init.lua index 72928ec..c67d71a 100644 --- a/init.lua +++ b/init.lua @@ -1,6 +1,9 @@ --[[ - Copyright (C) 2013 Sokomine Replacement tool for creative building (Mod for MineTest) + Copyright (C) 2013 Sokomine + Copyright (C) 2019 coil0 + Copyright (C) 2019 HybridDog + Copyright (C) 2019-2022 SwissalpS This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,47 +21,7 @@ -- Version 3.5 (20220115) --- Changelog: --- 15.01.2022 * SwissalpS refactored constraints and renamed blacklist to deny_list --- 14.01.2022 * SwissalpS added support for cable plates and similar nodes --- 13.01.2022 * SwissalpS worked in HybridDog's nicer pattern algorithm, modifying a little. --- Also cleaned up some code and give-priv does not grant modes anymore, --- creative still does. --- 12.01.2022 * SwissalpS improved field mode: when replacing also check for same param2 --- improved crust mode: when placing also allow vacuum instead of only air --- 02.12.2021 * SwissalpS added /replacer_mute command --- 30.09.2021 * SwissalpS merged patch provided by S-S-X to prevent a rare but possible crash with --- Unknown Items in hotbar --- * Also cleaned up tool change messages to blabla.lua --- 15.10.2020 * SwissalpS cleaned up inspector code and made inspector better readable on smaller screens --- * SwissalpS added backward compatibility for non technic servers, restored --- creative/give behaviour and fixed the 'too many nodes detected' issue --- * S-S-X and some players from pandorabox.io requested and inspired ideas to --- implement which SwissalpS tried to satisfy. --- * SwissalpS added method to change mode via formspec --- * BuckarooBanzay added server-setting max_nodes, moved crafts and replacer to --- separate files, added .luacheckrc and cleaned up inspection tool, fixing --- some issues on the way and updated readme to look nice --- * coil0 made modes available as technic tool and added limits --- * OgelGames fixed digging to be simulated properly --- * SwissalpS merged Sokomine's and HybridDog's versions --- * HybridDog added modes for creative mode --- * coil0 fixed issue by using buildable_to --- 09.12.2017 * Got rid of outdated minetest.env --- * Fixed error in protection function. --- * Fixed minor bugs. --- * Added blacklist --- 02.10.2014 * Some more improvements for inspect-tool. Added craft-guide. --- 01.10.2014 * Added inspect-tool. --- 12.01.2013 * If digging the node was unsuccessful, then the replacement will now fail --- (instead of destroying the old node with its metadata; i.e. chests with content) --- 20.11.2013 * if the server version is new enough, minetest.is_protected is used --- in order to check if the replacement is allowed --- 24.04.2013 * param1 and param2 are now stored --- * hold sneak + right click to store new pattern --- * right click: place one of the itmes --- * receipe changed --- * inventory image added +-- Changelog: see CHANGELOG file replacer = {} replacer.version = 20220115 diff --git a/replacer.lua b/replacer.lua index 4751cea..0c0a53c 100644 --- a/replacer.lua +++ b/replacer.lua @@ -159,6 +159,7 @@ function replacer.replace_single_node(pos, node_old, node_new, player, return true end + -- map exception local inv_name = r.exception_map[node_new.name] or node_new.name -- does the player carry at least one of the desired nodes with him? if (not creative) and (not inv:contains_item('main', inv_name)) then @@ -234,6 +235,7 @@ function replacer.replace_single_node(pos, node_old, node_new, player, end -- replace_single_node -- the function which happens when the replacer is used +-- also called by on_place if sneak isn't pressed function replacer.on_use(itemstack, player, pt, right_clicked) if (not player) or (not pt) then return @@ -312,6 +314,8 @@ function replacer.on_use(itemstack, player, pt, right_clicked) return end + -- figure out how many nodes we can modify before we reach + -- either the count or charge limit local max_nodes = r.limit_list[node_new.name] or r.max_nodes local charge = r.get_charge(itemstack) if not has_creative_or_give then @@ -413,6 +417,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) rp.reset_nodes_cache() + -- at least do the one that was clicked on if 0 == found_count then succ, error = r.replace_single_node(pos, node_old, node_new, player, name, inv, has_creative_or_give) @@ -449,6 +454,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) }) local actual_node_count = 0 while not found_positions:is_empty() do + -- Take the position nearest to the start position pos = found_positions:take() node_old = core_get_node(pos) adjust_new_to_minor(minor, node_old, node_new) @@ -465,6 +471,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) r.inform(name, rb.too_many_nodes_detected) break end + -- time-out check if us_time() - t_start > max_time_us then r.inform(name, rb.timed_out) break From a6f62addb1a888ffc6bf4eda5e95c87216c6a3a4 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 18 Jan 2022 13:49:13 +0100 Subject: [PATCH 121/366] add priv and xp protectors to deny-list --- replacer_constrain.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/replacer_constrain.lua b/replacer_constrain.lua index 6866143..c830ad4 100644 --- a/replacer_constrain.lua +++ b/replacer_constrain.lua @@ -29,8 +29,10 @@ replacer.deny_list['tnt:gunpowder_burning'] = true replacer.deny_list['tnt:tnt'] = true -- prevent accidental replacement of your protector +replacer.deny_list['priv_protector:protector'] = true replacer.deny_list['protector:protect'] = true replacer.deny_list['protector:protect2'] = true +replacer.deny_list['xp_redo:protector'] = true -- charge limits replacer.max_charge = 30000 From 9607db7eb88b8c50e9067b24c64d3939ea3849bc Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 18 Jan 2022 13:49:43 +0100 Subject: [PATCH 122/366] refuse to set replacer to denied nodes --- replacer.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/replacer.lua b/replacer.lua index 0c0a53c..08261d0 100644 --- a/replacer.lua +++ b/replacer.lua @@ -541,6 +541,11 @@ function replacer.on_place(itemstack, player, pt) local node, mode = r.get_data(itemstack) node = core_get_node_or_nil(pt.under) or node + -- don't allow setting replacer to denied nodes + if r.deny_list[node.name] then + r.inform(name, rb.deny_listed:format(node.name)) + return + end if not modes_are_available then mode = { major = 1, minor = 1 } From e0d0c0642dea082be7e331fe3253d654ee735ccd Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 18 Jan 2022 13:50:17 +0100 Subject: [PATCH 123/366] will we regret this? --- replacer.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replacer.lua b/replacer.lua index 08261d0..a14db00 100644 --- a/replacer.lua +++ b/replacer.lua @@ -321,7 +321,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) if not has_creative_or_give then if charge < r.charge_per_node then r.inform(name, rb.need_more_charge) - return + --return end -- clamp so it works as single mode even without charge From 9f5655fe7122b90f959dbff3ad253089437d5b1a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 18 Jan 2022 14:10:12 +0100 Subject: [PATCH 124/366] oops, oops & oopsies syntax errors --- replacer.lua | 4 ++-- unifieddyes.lua | 4 ++-- utils.lua | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/replacer.lua b/replacer.lua index a14db00..d74e98d 100644 --- a/replacer.lua +++ b/replacer.lua @@ -284,8 +284,8 @@ function replacer.on_use(itemstack, player, pt, right_clicked) -- minor mode overrides to node_new if 2 == minor then -- node only - node_new.param1 = node.old.param1 - node_new.param2 = node.old.param2 + node_new.param1 = node_old.param1 + node_new.param2 = node_old.param2 elseif 3 == minor then -- rotation only node_new.name = node_old.name diff --git a/unifieddyes.lua b/unifieddyes.lua index 4f0eeb4..a040109 100644 --- a/unifieddyes.lua +++ b/unifieddyes.lua @@ -1,7 +1,5 @@ replacer.unifieddyes = {} local ud = replacer.unifieddyes -local make_readable_color = unifieddyes.make_readable_color -local colour_to_name = unifieddyes.color_to_name if not replacer.has_unifieddyes_mod then function ud.colour_name(param2, node_def) return '' end @@ -9,6 +7,8 @@ if not replacer.has_unifieddyes_mod then return end +local make_readable_color = unifieddyes.make_readable_color +local colour_to_name = unifieddyes.color_to_name -- for inspector formspec function replacer.unifieddyes.add_recipe(param2, node_name, recipes) diff --git a/utils.lua b/utils.lua index 02c6246..fdf8f30 100644 --- a/utils.lua +++ b/utils.lua @@ -1,6 +1,6 @@ local rb = replacer.blabla local chat_send_player = minetest.chat_send_player -local get_player_name = minetest.get_player_by_name +local get_player_by_name = minetest.get_player_by_name local log = minetest.log function replacer.inform(name, message) From 9ae724ed65226153ea76a251d9efd742be235c1a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 18 Jan 2022 14:32:47 +0100 Subject: [PATCH 125/366] version bump 3.6 --- init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index c67d71a..f480d77 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 3.5 (20220115) +-- Version 3.6 (20220118) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220115 +replacer.version = 20220118 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From 4d3d06887bf6c96cb4d2963e65413a94fa578ae9 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 04:12:59 +0100 Subject: [PATCH 126/366] formspec adjustments wider and bigger buttons --- replacer_formspecs.lua | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/replacer_formspecs.lua b/replacer_formspecs.lua index 5fa4e0a..50c3ca9 100644 --- a/replacer_formspecs.lua +++ b/replacer_formspecs.lua @@ -15,13 +15,25 @@ function replacer.get_form_modes_4(player, mode) local major, minor = mode.major, mode.minor local name = player:get_player_name() local has_history_priv = check_player_privs(name, r.history_priv) - local form_height = has_history_priv and '4.39' or '3' + local form_dimensions = '5.375,4.25' + local button_height = '1' + local button_single_dimensions = '.33,.77;2,' + local button_field_dimensions = '2.9,.77;2,' + local button_crust_dimensions = '1.44,2.1;2,' + local minor_dimensions = '.38,3.42;4.5,.55' + if has_history_priv then + form_dimensions = '8.375,4.39' + button_single_dimensions = '0.33,0.77;2.3,' + button_field_dimensions = '3.04,0.77;2.3,' + button_crust_dimensions = '5.75,0.77;2.3,' + minor_dimensions = '1.88,2.12;4.5,0.60' + end local tmp_name = '_' local formspec = 'formspec_version[4]' - .. 'size[5.375,' .. form_height + .. 'size[' .. form_dimensions .. ']padding[0.375,0.375]' .. 'label[0.33,0.44;' .. mfe(rb.choose_mode) - .. ']button_exit[0.33,0.77;2,0.5;' + .. ']button_exit[' .. button_single_dimensions .. button_height .. ';' if 1 == major then formspec = formspec .. '_;< ' .. mfe(rb.mode_single) .. ' >' else @@ -29,7 +41,8 @@ function replacer.get_form_modes_4(player, mode) formspec = formspec .. 'mode1;' .. mfe(rb.mode_single) end formspec = formspec .. ']tooltip[' .. tmp_name .. ';' - .. mfe(rb.mode_single_tooltip) .. ']button_exit[2.9,0.77;2,0.5;' + .. mfe(rb.mode_single_tooltip) .. ']button_exit[' + .. button_field_dimensions .. button_height .. ';' if 2 == major then tmp_name = '_' formspec = formspec .. '_;< ' .. mfe(rb.mode_field) .. ' >' @@ -38,7 +51,8 @@ function replacer.get_form_modes_4(player, mode) formspec = formspec .. 'mode2;' .. mfe(rb.mode_field) end formspec = formspec .. ']tooltip[' .. tmp_name .. ';' - .. mfe(rb.mode_field_tooltip) .. ']button_exit[1.44,1.55;2,0.5;' + .. mfe(rb.mode_field_tooltip) .. ']button_exit[' + .. button_crust_dimensions .. button_height .. ';' if 3 == major then tmp_name = '_' formspec = formspec .. '_;< ' .. mfe(rb.mode_crust) .. ' >' @@ -46,7 +60,6 @@ function replacer.get_form_modes_4(player, mode) tmp_name = 'mode3' formspec = formspec .. 'mode3;' .. mfe(rb.mode_crust) end - local minor_dimensions = '0.38,2.22;4.5,0.55' formspec = formspec .. ']tooltip[' .. tmp_name .. ';' .. mfe(rb.mode_crust_tooltip) .. ']dropdown[' .. minor_dimensions .. ';minor;' .. mfe(rb.mode_minor1) .. ',' .. mfe(rb.mode_minor2) .. ',' .. mfe(rb.mode_minor3) @@ -57,7 +70,7 @@ function replacer.get_form_modes_4(player, mode) if not has_history_priv then return formspec end formspec = formspec .. 'label[0.33,3.22;' .. mfe(rb.choose_history) - .. ']dropdown[0.38,3.55;4.5,0.55;history;' + .. ']dropdown[0.38,3.55;7.5,0.6;history;' local db = r.history.get_player_table(player) for i, data in ipairs(db) do if r.history_include_mode then From de855c7b3483c2edf910e6bade70892130cfe03d Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 04:48:57 +0100 Subject: [PATCH 127/366] added new settings to settingtypes.txt --- settingtypes.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/settingtypes.txt b/settingtypes.txt index 921b64a..b470bc2 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -9,6 +9,18 @@ replacer.max_time (Time limit when putting nodes) float 1.0 # Radius limit factor when more possible positions are found than either max_nodes or charge # Set to 0 or less for behaviour of before version 3.3 replacer.radius_factor (A factor to adjust size limit) float 0.4 +# You can make history available to users with this priv. By default it is set to creative +# as non-creative users can make several replacers. +replacer.history_priv (Priv needed to allow using history) string creative +# When set, does not save history over sessions. Reason might be old MT version. +replacer.history_disable_persistancy (Disable saving history) bool false +# How frequently history is saved to player-meta. Only users with the priv are affected. +replacer.history_save_interval (Interval in minutes at which history is saved) int 7 +# When set, changes the replacer's major and minor modes when picking an item from history. +# The modes are stored either way. +replacer.history_include_mode (Should picking from history also set mode) bool false +# Limit history length. Duplicates are removed so there isn't much need for long histories. +replacer.history_max (Maximum amount of history items) int 7 2 55555 # You may choose to hide basic recipe but then make sure to enable the technic direct one replacer.hide_recipe_basic (Hide basic recipe) bool false # Hide the upgrade recipe. Only available if technic is installed. From 9a381406693f411e1255ff20fb488d7320f3715f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 05:32:25 +0100 Subject: [PATCH 128/366] typo fix --- replacer_blabla.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replacer_blabla.lua b/replacer_blabla.lua index 0d1f325..8d79904 100644 --- a/replacer_blabla.lua +++ b/replacer_blabla.lua @@ -56,7 +56,7 @@ rb.charge_required = S('Need %s charge to replace %s nodes.') rb.count_replaced = S('%s nodes replaced.') rb.mode_changed = S('Mode changed to %s: %s') rb.none_selected = S('Error: No node selected.') -rb.not_in_creative = S('Item not in creative invenotry: "%s".') +rb.not_in_creative = S('Item not in creative inventory: "%s".') rb.not_in_inventory = S('Item not in your inventory: "%s".') rb.set_to = S('Node replacement tool set to:\n%s.') rb.description_basic = S('Node replacement tool') From 0ef4181fb31eb66cc96449e37147d799cf341a72 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 05:33:02 +0100 Subject: [PATCH 129/366] German translation --- locale/replacer.de.tr | 80 +++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index 3ec51ab..831411e 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -1,46 +1,46 @@ # textdomain: replacer -History= -Choose mode= -Both= -Node= -Rotation= -Replace node and apply orientation.= -Replace node without changing orientation.= -Apply orientation without changing node type.= -Single= -Field= -Crust= -Replace single node.= +History=Verlauf +Choose mode=Wähle Modus +Both=Beide +Node=Node +Rotation=Drehung +Replace node and apply orientation.=Ersetze Node und Ausrichtung. +Replace node without changing orientation.=Ersetze Node ohne zu drehen. +Apply orientation without changing node type.=Nur Ausrichtung anwenden ohne Nodetyp zu ändern. +Single=Einzel +Field=Feld +Crust=Kruste +Replace single node.=Ersetze einzelnen Node -Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.=Links Klick: Ersetzt ein Feld gleichartiger Node welche durchsichtige Nachbarnode haben.@@Rechts Klick: Ersetzt die Luft vor dem Feld undurchsichtiger Node. -Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Links Klick: Ersetzt benachbarte, gleichartige Node welche gleichzeitig durchsichtige (nicht feste) Node berühren.@@Rechts Klick: Ersetzt Luft an der Kruste. +Protected at %s=Geschützt bei %s +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=Node des Typs „%s“ dürfen auf diesem Server nicht ersetzt werden. Versuch fehlgeschlagen. +You have no further "%s". Replacement failed.=Du hast keine weitere „%s“. Ersetzung fehlgeschlagen. +Unknown node: "%s"=Unbekannter Node: „%s“ +Unknown node to place: "%s"=Unbekant zu setzender Node: „%s“ +Could not dig "%s" properly.=Kann „%s“ nicht richtig graben. +Could not place "%s".=Konnte „%s“ nicht platzieren. +Error: "%s" is not a node.=Fehler: „%s“ ist kein Node. +Target node not yet loaded. Please wait a moment for the server to catch up.=Zielnode is noch nicht geladen. Bitte warte einen Moment damit der Server aufholen kann. +Nothing to replace.=Nichts zu ersetzen. +Not enough charge to use this mode.=Nicht genug Ladung, um diesen Modus zu verwenden. +Aborted, too many nodes detected.=Abgebrochen, zu viele Knoten gefunden. +Need %s charge to replace %s nodes.=Es wird eine Ladung von %s benötigt um %s Node auszutauschen. +%s nodes replaced.=%s Node ersetzt. +Mode changed to %s: %s=Modus gewechselt auf: %s +Error: No node selected.=Fehler: Kein Knoten ausgwählt. +Item not in creative inventory: "%s".=Artikel befindet sich nicht im Kreativ-Inventar: „%s“. +Item not in your inventory: "%s".=Artikel befindet sich nicht in deinem Inventar: „%s“. +Node replacement tool set to:@n%s.=Nodeersetzer konfiguriert auf:@n%s. +Node replacement tool=Nodeersetzer +Node replacement tool (technic)=Knotenersetzer (Technik) +Time-limit reached.=Zeitbegrenzung erreicht. -Protected at %s= -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= -You have no further "%s". Replacement failed.= -Unknown node: "%s"= -Unknown node to place: "%s"= -Could not dig "%s" properly.= -Could not place "%s".= -Error: "%s" is not a node.= -Target node not yet loaded. Please wait a moment for the server to catch up.= -Nothing to replace.= -Not enough charge to use this mode.= -Aborted, too many nodes detected.= -Need %s charge to replace %s nodes.= -%s nodes replaced.= -Mode changed to %s: %s= -Error: No node selected.= -Item not in creative invenotry: "%s".= -Item not in your inventory: "%s".= -Node replacement tool set to:@n%s.= -Node replacement tool= -Node replacement tool (technic)= -Time-limit reached.= +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Schaltet die Ausführlichkeit um.@nWenn diese Option aktiviert ist, werden Nachrichten im Chat ausgegeben. Im ausgeschalteten Zustand ist der Ersetzer stumm. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= +Valid parameter is either "%s" or "%s"=Gültige Parameter sind entweder „%s“ oder „%s“. +on=an +off=aus -Valid parameter is either "%s" or "%s"= -on= -off= From badabcce405081d3e672877ca2499e2cda26a000 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 05:34:41 +0100 Subject: [PATCH 130/366] typo update --- locale/replacer.de.tr | 1 + locale/replacer.es.tr | 2 +- locale/replacer.fi.tr | 2 +- locale/replacer.fr.tr | 2 +- locale/replacer.it.tr | 2 +- locale/replacer.pt.tr | 2 +- locale/replacer.ru.tr | 2 +- locale/template.txt | 2 +- 8 files changed, 8 insertions(+), 7 deletions(-) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index 831411e..fb1b8d3 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -15,6 +15,7 @@ Replace single node.=Ersetze einzelnen Node Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.=Links Klick: Ersetzt ein Feld gleichartiger Node welche durchsichtige Nachbarnode haben.@@Rechts Klick: Ersetzt die Luft vor dem Feld undurchsichtiger Node. Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Links Klick: Ersetzt benachbarte, gleichartige Node welche gleichzeitig durchsichtige (nicht feste) Node berühren.@@Rechts Klick: Ersetzt Luft an der Kruste. + Protected at %s=Geschützt bei %s Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=Node des Typs „%s“ dürfen auf diesem Server nicht ersetzt werden. Versuch fehlgeschlagen. You have no further "%s". Replacement failed.=Du hast keine weitere „%s“. Ersetzung fehlgeschlagen. diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 3ec51ab..5f0a32b 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -32,7 +32,7 @@ Need %s charge to replace %s nodes.= %s nodes replaced.= Mode changed to %s: %s= Error: No node selected.= -Item not in creative invenotry: "%s".= +Item not in creative inventory: "%s".= Item not in your inventory: "%s".= Node replacement tool set to:@n%s.= Node replacement tool= diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index 3ec51ab..5f0a32b 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -32,7 +32,7 @@ Need %s charge to replace %s nodes.= %s nodes replaced.= Mode changed to %s: %s= Error: No node selected.= -Item not in creative invenotry: "%s".= +Item not in creative inventory: "%s".= Item not in your inventory: "%s".= Node replacement tool set to:@n%s.= Node replacement tool= diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index 3ec51ab..5f0a32b 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -32,7 +32,7 @@ Need %s charge to replace %s nodes.= %s nodes replaced.= Mode changed to %s: %s= Error: No node selected.= -Item not in creative invenotry: "%s".= +Item not in creative inventory: "%s".= Item not in your inventory: "%s".= Node replacement tool set to:@n%s.= Node replacement tool= diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index 3ec51ab..5f0a32b 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -32,7 +32,7 @@ Need %s charge to replace %s nodes.= %s nodes replaced.= Mode changed to %s: %s= Error: No node selected.= -Item not in creative invenotry: "%s".= +Item not in creative inventory: "%s".= Item not in your inventory: "%s".= Node replacement tool set to:@n%s.= Node replacement tool= diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index 3ec51ab..5f0a32b 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -32,7 +32,7 @@ Need %s charge to replace %s nodes.= %s nodes replaced.= Mode changed to %s: %s= Error: No node selected.= -Item not in creative invenotry: "%s".= +Item not in creative inventory: "%s".= Item not in your inventory: "%s".= Node replacement tool set to:@n%s.= Node replacement tool= diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index 3ec51ab..5f0a32b 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -32,7 +32,7 @@ Need %s charge to replace %s nodes.= %s nodes replaced.= Mode changed to %s: %s= Error: No node selected.= -Item not in creative invenotry: "%s".= +Item not in creative inventory: "%s".= Item not in your inventory: "%s".= Node replacement tool set to:@n%s.= Node replacement tool= diff --git a/locale/template.txt b/locale/template.txt index 3ec51ab..5f0a32b 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -32,7 +32,7 @@ Need %s charge to replace %s nodes.= %s nodes replaced.= Mode changed to %s: %s= Error: No node selected.= -Item not in creative invenotry: "%s".= +Item not in creative inventory: "%s".= Item not in your inventory: "%s".= Node replacement tool set to:@n%s.= Node replacement tool= From a12630eb05ac9350e8b90d03415a151e8b649d3b Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 05:52:24 +0100 Subject: [PATCH 131/366] Portuguese translation --- chat_commands.lua | 4 +-- locale/replacer.pt.tr | 81 ++++++++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/chat_commands.lua b/chat_commands.lua index e7af86a..701357c 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -3,8 +3,8 @@ local rb = replacer.blabla -- let's hope there isn't a yes that means no in another language :/ -- TODO: better option would be to simply toggle (see postool) -local lOn = { 'on', 'yes', 'an', 'ja', 'si', 'sí', 'да', 'oui', 'joo', 'juu', 'kyllä', 'sim' } -local lOff = { 'off', 'no', 'aus', 'nein', 'non', 'нет', 'ei', 'fora', 'não' } +local lOn = { 'on', 'yes', 'an', 'ja', 'si', 'sí', 'да', 'oui', 'joo', 'juu', 'kyllä', 'sim', 'em' } +local lOff = { 'off', 'no', 'aus', 'nein', 'non', 'нет', 'ei', 'fora', 'não', 'desligado' } local tOn, tOff = {}, {} for _, s in ipairs(lOn) do tOn[s] = true end for _, s in ipairs(lOff) do tOff[s] = true end diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index 5f0a32b..a1970b2 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -1,46 +1,47 @@ # textdomain: replacer -History= -Choose mode= -Both= -Node= -Rotation= -Replace node and apply orientation.= -Replace node without changing orientation.= -Apply orientation without changing node type.= -Single= -Field= -Crust= -Replace single node.= +History=Histórico +Choose mode=Escolha o modo +Both=Ambos +Node=Nó +Rotation=Rotação +Replace node and apply orientation.=Substitua o nó e aplique a orientação. +Replace node without changing orientation.=Substitua o nó sem alterar a orientação. +Apply orientation without changing node type.=Aplique a orientação sem alterar o tipo de nó. +Single=Único +Field=Campo +Crust=Crosta +Replace single node.=Substitua um único nó. -Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.=Clique com o botão esquerdo: Substitui o campo de nós de um tipo onde um nó translúcido está na frente dele.@@Clique com o botão direito: Substitui o campo de ar onde nenhum nó translúcido está atrás do ar. -Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Clique com o botão esquerdo: Substitui os nós que tocam em outro de seu tipo e um nó translúcido, por exemplo air.@@Clique com o botão direito: Substitua os nós de ar que tocam a crosta. -Protected at %s= -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= -You have no further "%s". Replacement failed.= -Unknown node: "%s"= -Unknown node to place: "%s"= -Could not dig "%s" properly.= -Could not place "%s".= -Error: "%s" is not a node.= -Target node not yet loaded. Please wait a moment for the server to catch up.= -Nothing to replace.= -Not enough charge to use this mode.= -Aborted, too many nodes detected.= -Need %s charge to replace %s nodes.= -%s nodes replaced.= -Mode changed to %s: %s= -Error: No node selected.= -Item not in creative inventory: "%s".= -Item not in your inventory: "%s".= -Node replacement tool set to:@n%s.= -Node replacement tool= -Node replacement tool (technic)= -Time-limit reached.= +Protected at %s=Protegido em %s +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=A substituição de nós do tipo "%s" não é permitida neste servidor. Falha na substituição. +You have no further "%s". Replacement failed.=Você não tem mais "%s". Falha na substituição. +Unknown node: "%s"=Nó desconhecido: "%s" +Unknown node to place: "%s"=Nó desconhecido para colocar: "%s" +Could not dig "%s" properly.=Não foi possível cavar "%s" corretamente. +Could not place "%s".=Não foi possível colocar "%s". +Error: "%s" is not a node.=Erro: "%s" não é um nó. +Target node not yet loaded. Please wait a moment for the server to catch up.=O nó de destino ainda não foi carregado. Aguarde um momento para o servidor recuperar o atraso. +Nothing to replace.=Nada para substituir. +Not enough charge to use this mode.=Carga insuficiente para usar este modo. +Aborted, too many nodes detected.=Abortado, muitos nós detectados. +Need %s charge to replace %s nodes.=Precisa de %s carga para substituir %s nós. +%s nodes replaced.=%s nós substituídos. +Mode changed to %s: %s=Modo alterado para %s: %s +Error: No node selected.=Erro: Nenhum nó selecionado. +Item not in creative inventory: "%s".=Item não no inventário do criativo: "%s". +Item not in your inventory: "%s".=Item que não está em seu inventário: "%s". +Node replacement tool set to:@n%s.=Ferramenta de substituição de nó definida como:@n%s. +Node replacement tool=Ferramenta de substituição de nós +Node replacement tool (technic)=Ferramenta de substituição de nós (técnica) +Time-limit reached.=Limite de tempo atingido. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Alterna a verbosidade.@nQuando ativado, as mensagens são postadas no bate-papo. Quando desligado, o substituto fica silencioso. + +Valid parameter is either "%s" or "%s"=O parâmetro válido é "%s" ou "%s" +on=em +off=não -Valid parameter is either "%s" or "%s"= -on= -off= From f6a76ff05216db102d8a07a604cc35586f6dd1de Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 06:05:17 +0100 Subject: [PATCH 132/366] Russian translation --- locale/replacer.ru.tr | 81 ++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index 5f0a32b..db8efff 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -1,46 +1,47 @@ # textdomain: replacer -History= -Choose mode= -Both= -Node= -Rotation= -Replace node and apply orientation.= -Replace node without changing orientation.= -Apply orientation without changing node type.= -Single= -Field= -Crust= -Replace single node.= +History=История +Choose mode=Выберите режим +Both=Оба +Node=Узел +Rotation=Вращение +Replace node and apply orientation.=Замените узел и примените ориентацию. +Replace node without changing orientation.=Заменить узел без изменения ориентации. +Apply orientation without changing node type.=Применить ориентацию без изменения типа узла. +Single=Один +Field=Поле +Crust=Корка +Replace single node.=Заменить один узел. -Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.=Щелчок левой кнопкой мыши: заменить поле узлов такого типа, перед которым находится полупрозрачный узел. Щелчок правой кнопкой мыши: заменить поле воздуха там, где за воздухом не находится полупрозрачный узел. -Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Щелкните левой кнопкой мыши: замените узлы, которые соприкасаются с другим в своем роде и полупрозрачным узлом, например. воздух.@@Щелкните правой кнопкой мыши: замените воздушные узлы, которые касаются корки. -Protected at %s= -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= -You have no further "%s". Replacement failed.= -Unknown node: "%s"= -Unknown node to place: "%s"= -Could not dig "%s" properly.= -Could not place "%s".= -Error: "%s" is not a node.= -Target node not yet loaded. Please wait a moment for the server to catch up.= -Nothing to replace.= -Not enough charge to use this mode.= -Aborted, too many nodes detected.= -Need %s charge to replace %s nodes.= -%s nodes replaced.= -Mode changed to %s: %s= -Error: No node selected.= -Item not in creative inventory: "%s".= -Item not in your inventory: "%s".= -Node replacement tool set to:@n%s.= -Node replacement tool= -Node replacement tool (technic)= -Time-limit reached.= +Protected at %s=Защищено в %s +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=Замена узлов типа "%s" на этом сервере запрещена. Замена не удалась. +You have no further "%s". Replacement failed.=У вас больше нет "%s". Замена не удалась. +Unknown node: "%s"=Неизвестный узел: "%s" +Unknown node to place: "%s"=Неизвестный узел для размещения: "%s" +Could not dig "%s" properly.=Не удалось правильно раскопать "%s". +Could not place "%s".=Не удалось разместить "%s". +Error: "%s" is not a node.=Ошибка: "%s" не является узлом. +Target node not yet loaded. Please wait a moment for the server to catch up.=Целевой узел еще не загружен. Пожалуйста, подождите, пока сервер наверстает упущенное. +Nothing to replace.=Нечем заменить. +Not enough charge to use this mode.=Недостаточно заряда для использования этого режима. +Aborted, too many nodes detected.=Прервано, обнаружено слишком много узлов. +Need %s charge to replace %s nodes.=Требуется заряд %s для замены узлов %s. +%s nodes replaced.=Заменено узлов: %s. +Mode changed to %s: %s=Режим изменен на %s: %s +Error: No node selected.=Ошибка: узел не выбран. +Item not in creative inventory: "%s".=Предмета нет в творческом инвентаре: "%s". +Item not in your inventory: "%s".=Предмета нет в вашем инвентаре: "%s". +Node replacement tool set to:@n%s.=Инструмент замены узлов установлен на:@n%s. +Node replacement tool=Инструмент замены узлов +Node replacement tool (technic)=Инструмент замены узла (техника) +Time-limit reached.=Достигнут лимит времени. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Включает многословие. @nКогда включено, сообщения отправляются в чат. Когда выключено, заменитель молчит. + +Valid parameter is either "%s" or "%s"=Допустимый параметр: "%s" или "%s" +on=да +off=нет -Valid parameter is either "%s" or "%s"= -on= -off= From ff5a6d80d9b14fedcfd3bcb465c18041d2c0d261 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 06:17:24 +0100 Subject: [PATCH 133/366] Italian translation also added 1/0 as valid toggles --- chat_commands.lua | 4 +-- locale/replacer.it.tr | 81 ++++++++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/chat_commands.lua b/chat_commands.lua index 701357c..1c9a8c4 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -3,8 +3,8 @@ local rb = replacer.blabla -- let's hope there isn't a yes that means no in another language :/ -- TODO: better option would be to simply toggle (see postool) -local lOn = { 'on', 'yes', 'an', 'ja', 'si', 'sí', 'да', 'oui', 'joo', 'juu', 'kyllä', 'sim', 'em' } -local lOff = { 'off', 'no', 'aus', 'nein', 'non', 'нет', 'ei', 'fora', 'não', 'desligado' } +local lOn = { '1', 'on', 'yes', 'an', 'ja', 'si', 'sí', 'да', 'oui', 'joo', 'juu', 'kyllä', 'sim', 'em' } +local lOff = { '0', 'off', 'no', 'aus', 'nein', 'non', 'нет', 'ei', 'fora', 'não', 'desligado' } local tOn, tOff = {}, {} for _, s in ipairs(lOn) do tOn[s] = true end for _, s in ipairs(lOff) do tOff[s] = true end diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index 5f0a32b..c154a3c 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -1,46 +1,47 @@ # textdomain: replacer -History= -Choose mode= -Both= -Node= -Rotation= -Replace node and apply orientation.= -Replace node without changing orientation.= -Apply orientation without changing node type.= -Single= -Field= -Crust= -Replace single node.= +History=Storia +Choose mode=Scegli modalità +Both=Entrambi +Node=Nodo +Rotation=Rotazione +Replace node and apply orientation.=Sostituisci il nodo e applica l'orientamento. +Replace node without changing orientation.=Sostituisci il nodo senza modificare l'orientamento. +Apply orientation without changing node type.=Applicare l'orientamento senza modificare il tipo di nodo. +Single=Singolo +Field=Campo +Crust=Crosta +Replace single node.=Sostituisci singolo nodo. -Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.=Clic sinistro: Sostituisci il campo di nodi di un tipo in cui un nodo traslucido è davanti ad esso.@@Clic destro: Sostituisci il campo d'aria dove nessun nodo traslucido è dietro l'aria. -Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Clic sinistro: Sostituisci i nodi che toccano un altro del suo genere e un nodo traslucido, ad es. air.@@Clic destro: Sostituisci i nodi d'aria che toccano la crosta. -Protected at %s= -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= -You have no further "%s". Replacement failed.= -Unknown node: "%s"= -Unknown node to place: "%s"= -Could not dig "%s" properly.= -Could not place "%s".= -Error: "%s" is not a node.= -Target node not yet loaded. Please wait a moment for the server to catch up.= -Nothing to replace.= -Not enough charge to use this mode.= -Aborted, too many nodes detected.= -Need %s charge to replace %s nodes.= -%s nodes replaced.= -Mode changed to %s: %s= -Error: No node selected.= -Item not in creative inventory: "%s".= -Item not in your inventory: "%s".= -Node replacement tool set to:@n%s.= -Node replacement tool= -Node replacement tool (technic)= -Time-limit reached.= +Protected at %s=Protetto a %s +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=La sostituzione dei nodi di tipo "%s" non è consentita su questo server. Sostituzione non riuscita. +You have no further "%s". Replacement failed.=Non hai più "%s". Sostituzione non riuscita. +Unknown node: "%s"=Nodo sconosciuto: "%s" +Unknown node to place: "%s"=Nodo sconosciuto da posizionare: "%s" +Could not dig "%s" properly.=Impossibile scavare correttamente "%s". +Could not place "%s".=Impossibile posizionare "%s". +Error: "%s" is not a node.=Errore: "%s" non è un nodo. +Target node not yet loaded. Please wait a moment for the server to catch up.=Nodo di destinazione non ancora caricato. Si prega di attendere un momento affinché il server raggiunga. +Nothing to replace.=Niente da sostituire. +Not enough charge to use this mode.=Carica insufficiente per utilizzare questa modalità. +Aborted, too many nodes detected.=Interrotto, troppi nodi rilevati. +Need %s charge to replace %s nodes.=Sono necessari %s addebito per sostituire %s nodi. +%s nodes replaced.=%s nodi sostituiti. +Mode changed to %s: %s=Modalità modificata in %s: %s +Error: No node selected.=Errore: nessun nodo selezionato. +Item not in creative inventory: "%s".=Articolo non nell'inventario della creatività: "%s". +Item not in your inventory: "%s".=Articolo non nel tuo inventario: "%s". +Node replacement tool set to:@n%s.=Strumento di sostituzione del nodo impostato su:@n%s. +Node replacement tool=Strumento di sostituzione del nodo +Node replacement tool (technic)=Strumento di sostituzione del nodo (tecnico) +Time-limit reached.=Tempo limite raggiunto. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Attiva o disattiva la verbosità.@nQuando è attiva, i messaggi vengono inviati alla chat. Quando è spento, il sostituto è silenzioso. + +Valid parameter is either "%s" or "%s"=Il parametro valido è "%s" o "%s" +on=1 +off=0 -Valid parameter is either "%s" or "%s"= -on= -off= From 79c310077488d4d53b3e1c206e77272c06c5f919 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 06:30:39 +0100 Subject: [PATCH 134/366] French translation --- locale/replacer.fr.tr | 81 ++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index 5f0a32b..882faa7 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -1,46 +1,47 @@ # textdomain: replacer -History= -Choose mode= -Both= -Node= -Rotation= -Replace node and apply orientation.= -Replace node without changing orientation.= -Apply orientation without changing node type.= -Single= -Field= -Crust= -Replace single node.= +History=Historique +Choose mode=Choisi le mode +Both=Les deux +Node=Nœud +Rotation=Rotation +Replace node and apply orientation.=Remplacer le nœud et appliquer l'orientation. +Replace node without changing orientation.=Remplacer le nœud sans changer l'orientation. +Apply orientation without changing node type.=Appliquer l'orientation sans changer le type de nœud. +Single=Unique +Field=Champ +Crust=Croûte +Replace single node.=Remplacer un nœud unique. -Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.=Clic gauche : Remplacer le champ de nœuds d'un type où un nœud translucide est devant.@@Clic droit : Remplacer le champ d'air où aucun nœud translucide n'est derrière l'air. -Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Clic gauche : Remplacer les nœuds qui touchent un autre du même genre et un nœud translucide, par ex. air.@@Clic droit : Remplacer les nœuds d'air qui touchent la croûte. -Protected at %s= -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= -You have no further "%s". Replacement failed.= -Unknown node: "%s"= -Unknown node to place: "%s"= -Could not dig "%s" properly.= -Could not place "%s".= -Error: "%s" is not a node.= -Target node not yet loaded. Please wait a moment for the server to catch up.= -Nothing to replace.= -Not enough charge to use this mode.= -Aborted, too many nodes detected.= -Need %s charge to replace %s nodes.= -%s nodes replaced.= -Mode changed to %s: %s= -Error: No node selected.= -Item not in creative inventory: "%s".= -Item not in your inventory: "%s".= -Node replacement tool set to:@n%s.= -Node replacement tool= -Node replacement tool (technic)= -Time-limit reached.= +Protected at %s=Protégé à %s +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=Le remplacement de nœuds de type "%s" n'est pas autorisé sur ce serveur. Échec du remplacement. +You have no further "%s". Replacement failed.=Tu n'as plus de "%s". Échec du remplacement. +Unknown node: "%s"=Nœud inconnu : "%s" +Unknown node to place: "%s"=Nœud inconnu à placer : "%s" +Could not dig "%s" properly.=Impossible de creuser "%s" correctement. +Could not place "%s".=Impossible de placer "%s". +Error: "%s" is not a node.=Erreur : "%s" n'est pas un nœud. +Target node not yet loaded. Please wait a moment for the server to catch up.=Le nœud cible n'est pas encore chargé. Patienter quelques instants, que le serveur rattrape. +Nothing to replace.=Rien à remplacer. +Not enough charge to use this mode.=Pas assez de charge pour utiliser ce mode. +Aborted, too many nodes detected.=Abandonné, trop de nœuds détectés. +Need %s charge to replace %s nodes.=Besoin de %s charge pour remplacer %s nœuds. +%s nodes replaced.=%s nœuds remplacés. +Mode changed to %s: %s=Mode changé en %s : %s +Error: No node selected.=Erreur : Aucun nœud sélectionné. +Item not in creative inventory: "%s".=L'article n'est pas dans l'inventaire de la création : "%s". +Item not in your inventory: "%s".=Objet pas dans tu inventaire : "%s". +Node replacement tool set to:@n%s.=Remplaçant défini sur :@n%s. +Node replacement tool=Remplaçant +Node replacement tool (technic)=Remplaçant (technique) +Time-limit reached.=Délai atteint. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Active/désactive la verbosité.@nLorsque cette option est activée, les messages sont publiés sur le chat. Lorsqu'il est désactivé, le remplaçant est silencieux. + +Valid parameter is either "%s" or "%s"=Le paramètre valide est "%s" ou "%s" +on=1 +off=0 -Valid parameter is either "%s" or "%s"= -on= -off= From c8b6288c35dedf08932cbd3269561b66b2efa311 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 06:42:23 +0100 Subject: [PATCH 135/366] Finnish translation at least an attempt ;) --- locale/replacer.fi.tr | 81 ++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index 5f0a32b..0e5fa37 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -1,46 +1,47 @@ # textdomain: replacer -History= -Choose mode= -Both= -Node= -Rotation= -Replace node and apply orientation.= -Replace node without changing orientation.= -Apply orientation without changing node type.= -Single= -Field= -Crust= -Replace single node.= +History=Historia +Choose mode=Valitse tila +Both=Molemmat +Node=Solmu +Rotation=Kierto +Replace node and apply orientation.=Korvaa solmu ja käytä suuntaa. +Replace node without changing orientation.=Vaihda solmu suuntaa muuttamatta. +Apply orientation without changing node type.=Käytä suuntaa muuttamatta solmun tyyppiä. +Single=Single +Field=Kenttä +Crust=Kuori +Replace single node.=Korvaa yksi solmu. -Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.=Vasen napsautus: Korvaa sellaisten solmujen kenttä, joissa läpikuultava solmu on sen edessä.@@Oikea napsautus: Korvaa ilmakenttä, jossa ilman takana ei ole läpikuultavaa solmua. -Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Vasen napsautus: Vaihda solmut, jotka koskettavat toista laatuaan ja läpikuultavaa solmua, esim. air.@@Kakkosnapsautus: Vaihda kuorta koskettavat ilmasolmut. -Protected at %s= -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= -You have no further "%s". Replacement failed.= -Unknown node: "%s"= -Unknown node to place: "%s"= -Could not dig "%s" properly.= -Could not place "%s".= -Error: "%s" is not a node.= -Target node not yet loaded. Please wait a moment for the server to catch up.= -Nothing to replace.= -Not enough charge to use this mode.= -Aborted, too many nodes detected.= -Need %s charge to replace %s nodes.= -%s nodes replaced.= -Mode changed to %s: %s= -Error: No node selected.= -Item not in creative inventory: "%s".= -Item not in your inventory: "%s".= -Node replacement tool set to:@n%s.= -Node replacement tool= -Node replacement tool (technic)= -Time-limit reached.= +Protected at %s=Suojattu %s +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=Tyypin "%s" solmujen korvaaminen ei ole sallittua tässä palvelimessa. Vaihto epäonnistui. +You have no further "%s". Replacement failed.=Sinulla ei ole enempää "%s". Vaihto epäonnistui. +Unknown node: "%s"=Tuntematon solmu: "%s" +Unknown node to place: "%s"=Tuntematon sijoitettava solmu: "%s" +Could not dig "%s" properly.=Ei voitu kaivaa "%s" oikein. +Could not place "%s".=Ei voitu sijoittaa "%s". +Error: "%s" is not a node.=Virhe: "%s" ei ole solmu. +Target node not yet loaded. Please wait a moment for the server to catch up.=Kohdesolmua ei ole vielä ladattu. Odota hetki, että palvelin ottaa kiinni. +Nothing to replace.=Ei mitään korvattavaa. +Not enough charge to use this mode.=Lataus ei riitä tämän tilan käyttämiseen. +Aborted, too many nodes detected.=Keskeytetty, liian monta solmua havaittu. +Need %s charge to replace %s nodes.=Tarvitset %s-latauksen korvataksesi %s solmun. +%s nodes replaced.=%s solmua vaihdettu. +Mode changed to %s: %s=Tila muutettu tilaksi %s: %s +Error: No node selected.=Virhe: solmua ei ole valittu. +Item not in creative inventory: "%s".=Kohde ei ole mainosjakaumassa: "%s". +Item not in your inventory: "%s".=Tuote, joka ei ole varastossa: "%s". +Node replacement tool set to:@n%s.=Solmun korvaustyökalu asetettu arvoon:@n%s. +Node replacement tool=Solmun vaihtotyökalu +Node replacement tool (technic)=Solmun vaihtotyökalu (tekninen) +Time-limit reached.=Aikaraja saavutettu. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Vaihtaa verbosity.@nKun käytössä, viestit lähetetään chattiin. Kun se on pois päältä, korvaaja on äänetön. + +Valid parameter is either "%s" or "%s"=Kelvollinen parametri on joko "%s" tai "%s" +on=kyllä +off=fora -Valid parameter is either "%s" or "%s"= -on= -off= From bf199c087c30be13de31533a705b11d9c03c1dd4 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 06:56:56 +0100 Subject: [PATCH 136/366] Spanish translation --- locale/replacer.es.tr | 81 ++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 5f0a32b..0fcfc24 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -1,46 +1,47 @@ # textdomain: replacer -History= -Choose mode= -Both= -Node= -Rotation= -Replace node and apply orientation.= -Replace node without changing orientation.= -Apply orientation without changing node type.= -Single= -Field= -Crust= -Replace single node.= +History=Historia +Choose mode=Elegir modo +Both=Ambos +Node=Nodo +Rotation=Rotación +Replace node and apply orientation.=Reemplazar nodo y aplicar orientación. +Replace node without changing orientation.=Reemplazar nodo sin cambiar la orientación. +Apply orientation without changing node type.=Aplicar orientación sin cambiar el tipo de nodo. +Single=Único +Field=Campo +Crust=Corteza +Replace single node.=Reemplazar nodo único. -Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.= +Left click: Replace field of nodes of a kind where a translucent node is in front of it.@@Right click: Replace field of air where no translucent node is behind the air.=Clic izquierdo: Reemplazar campo de nodos de un tipo donde hay un nodo translúcido frente a él.@@ Clic derecho: Reemplazar campo de aire donde no hay un nodo translúcido detrás del aire. -Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= +Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Clic izquierdo: reemplaza los nodos que tocan otro de su tipo y un nodo translúcido, p. aire.@@Clic derecho: Reemplazar los nodos de aire que tocan la corteza. -Protected at %s= -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= -You have no further "%s". Replacement failed.= -Unknown node: "%s"= -Unknown node to place: "%s"= -Could not dig "%s" properly.= -Could not place "%s".= -Error: "%s" is not a node.= -Target node not yet loaded. Please wait a moment for the server to catch up.= -Nothing to replace.= -Not enough charge to use this mode.= -Aborted, too many nodes detected.= -Need %s charge to replace %s nodes.= -%s nodes replaced.= -Mode changed to %s: %s= -Error: No node selected.= -Item not in creative inventory: "%s".= -Item not in your inventory: "%s".= -Node replacement tool set to:@n%s.= -Node replacement tool= -Node replacement tool (technic)= -Time-limit reached.= +Protected at %s=Protegido en %s +Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=No se permite reemplazar nodos de tipo "%s" en este servidor. Reemplazo fallido. +You have no further "%s". Replacement failed.=No tienes más "%s". Reemplazo fallido. +Unknown node: "%s"=Nodo desconocido: "%s" +Unknown node to place: "%s"=Nodo desconocido a colocar: "%s" +Could not dig "%s" properly.=No se pudo excavar "%s" correctamente. +Could not place "%s".=No se pudo colocar "%s". +Error: "%s" is not a node.=Error: "%s" no es un nodo. +Target node not yet loaded. Please wait a moment for the server to catch up.=Nodo de destino aún no cargado. Espere un momento a que el servidor se ponga al día. +Nothing to replace.=Nada para reemplazar. +Not enough charge to use this mode.=No hay suficiente carga para usar este modo. +Aborted, too many nodes detected.=Anulado, demasiados nodos detectados. +Need %s charge to replace %s nodes.=Necesita %s carga para reemplazar %s nodos. +%s nodes replaced.=%s nodos reemplazados. +Mode changed to %s: %s=Modo cambiado a %s: %s +Error: No node selected.=Error: No se seleccionó ningún nodo. +Item not in creative inventory: "%s".=Artículo no está en el inventario creativo: "%s". +Item not in your inventory: "%s".=Artículo no está en su inventario: "%s". +Node replacement tool set to:@n%s.=Intercambiador establecida en:@n%s. +Node replacement tool=Intercambiador +Node replacement tool (technic)=Intercambiador (técnica) +Time-limit reached.=Límite de tiempo alcanzado. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= +Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Alterna verbosidad.@nCuando está activado, los mensajes se publican en el chat. Cuando está apagado, el intercambiador está en silencio. + +Valid parameter is either "%s" or "%s"=El parámetro válido es "%s" o "%s" +on=1 +off=0 -Valid parameter is either "%s" or "%s"= -on= -off= From 999370558fb8e01e2ad756b918e1467e1c6abc3f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 06:59:24 +0100 Subject: [PATCH 137/366] German tuning Ersetzer or Austauscher are easier to say --- locale/replacer.de.tr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index fb1b8d3..03422f0 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -34,9 +34,9 @@ Mode changed to %s: %s=Modus gewechselt auf: %s Error: No node selected.=Fehler: Kein Knoten ausgwählt. Item not in creative inventory: "%s".=Artikel befindet sich nicht im Kreativ-Inventar: „%s“. Item not in your inventory: "%s".=Artikel befindet sich nicht in deinem Inventar: „%s“. -Node replacement tool set to:@n%s.=Nodeersetzer konfiguriert auf:@n%s. -Node replacement tool=Nodeersetzer -Node replacement tool (technic)=Knotenersetzer (Technik) +Node replacement tool set to:@n%s.=Ersetzer konfiguriert auf:@n%s. +Node replacement tool=Ersetzer +Node replacement tool (technic)=Ersetzer (Technik) Time-limit reached.=Zeitbegrenzung erreicht. Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Schaltet die Ausführlichkeit um.@nWenn diese Option aktiviert ist, werden Nachrichten im Chat ausgegeben. Im ausgeschalteten Zustand ist der Ersetzer stumm. From ef2c3fc50e699793f287028a31103442967f3fe8 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 07:01:38 +0100 Subject: [PATCH 138/366] version bump 3.7 --- CHANGELOG | 1 + init.lua | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b2471a0..f6a11bd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +20220119 * SwissalpS added first draft of de,es,fi,fr,it,pt,ru locales. 20220118 * SwissalpS cleaned up more code, giving more discriptive variable names and cleaning out ugly modes table that had both number and string indexes * Don't allow replacer to be set to deny_list nodes diff --git a/init.lua b/init.lua index f480d77..6f8d3bb 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 3.6 (20220118) +-- Version 3.7 (20220119) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220118 +replacer.version = 20220119 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From ed53a03132c4ea0618976a02f9bf3eecde45c840 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 15:57:43 +0100 Subject: [PATCH 139/366] moving files to folders no code change in this commit except init.lua adjusting to paths --- compat_technic.lua => compat/technic.lua | 0 unifieddyes.lua => compat/unifieddyes.lua | 0 init.lua | 18 +++++++++--------- replacer_blabla.lua => replacer/blabla.lua | 0 .../constrain.lua | 0 .../datastructures.lua | 0 .../formspecs.lua | 0 replacer_history.lua => replacer/history.lua | 0 replacer_patterns.lua => replacer/patterns.lua | 0 replacer.lua => replacer/replacer.lua | 0 10 files changed, 9 insertions(+), 9 deletions(-) rename compat_technic.lua => compat/technic.lua (100%) rename unifieddyes.lua => compat/unifieddyes.lua (100%) rename replacer_blabla.lua => replacer/blabla.lua (100%) rename replacer_constrain.lua => replacer/constrain.lua (100%) rename datastructures.lua => replacer/datastructures.lua (100%) rename replacer_formspecs.lua => replacer/formspecs.lua (100%) rename replacer_history.lua => replacer/history.lua (100%) rename replacer_patterns.lua => replacer/patterns.lua (100%) rename replacer.lua => replacer/replacer.lua (100%) diff --git a/compat_technic.lua b/compat/technic.lua similarity index 100% rename from compat_technic.lua rename to compat/technic.lua diff --git a/unifieddyes.lua b/compat/unifieddyes.lua similarity index 100% rename from unifieddyes.lua rename to compat/unifieddyes.lua diff --git a/init.lua b/init.lua index 6f8d3bb..e8e21bf 100644 --- a/init.lua +++ b/init.lua @@ -43,24 +43,24 @@ replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') local path = minetest.get_modpath('replacer') .. '/' -- strings for translation -dofile(path .. 'replacer_blabla.lua') +dofile(path .. 'replacer/blabla.lua') -- utilities dofile(path .. 'utils.lua') -- unifiedddyes support functions -dofile(path .. 'unifieddyes.lua') -replacer.datastructures = dofile(path .. 'datastructures.lua') +dofile(path .. 'compat/unifieddyes.lua') +replacer.datastructures = dofile(path .. 'replacer/datastructures.lua') -- adds a tool for inspecting nodes and entities dofile(path .. 'inspect.lua') -dofile(path .. 'replacer_constrain.lua') -dofile(path .. 'replacer_formspecs.lua') -dofile(path .. 'replacer_history.lua') -dofile(path .. 'replacer_patterns.lua') -dofile(path .. 'replacer.lua') +dofile(path .. 'replacer/constrain.lua') +dofile(path .. 'replacer/formspecs.lua') +dofile(path .. 'replacer/history.lua') +dofile(path .. 'replacer/patterns.lua') +dofile(path .. 'replacer/replacer.lua') dofile(path .. 'crafts.lua') dofile(path .. 'chat_commands.lua') -- add cable plate exceptions if replacer.has_technic_mod then - dofile(path .. 'compat_technic.lua') + dofile(path .. 'compat/technic.lua') end -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- diff --git a/replacer_blabla.lua b/replacer/blabla.lua similarity index 100% rename from replacer_blabla.lua rename to replacer/blabla.lua diff --git a/replacer_constrain.lua b/replacer/constrain.lua similarity index 100% rename from replacer_constrain.lua rename to replacer/constrain.lua diff --git a/datastructures.lua b/replacer/datastructures.lua similarity index 100% rename from datastructures.lua rename to replacer/datastructures.lua diff --git a/replacer_formspecs.lua b/replacer/formspecs.lua similarity index 100% rename from replacer_formspecs.lua rename to replacer/formspecs.lua diff --git a/replacer_history.lua b/replacer/history.lua similarity index 100% rename from replacer_history.lua rename to replacer/history.lua diff --git a/replacer_patterns.lua b/replacer/patterns.lua similarity index 100% rename from replacer_patterns.lua rename to replacer/patterns.lua diff --git a/replacer.lua b/replacer/replacer.lua similarity index 100% rename from replacer.lua rename to replacer/replacer.lua From 851ca48bde7357bc38e3cdf2dd694861c840bdff Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 20:10:02 +0100 Subject: [PATCH 140/366] improve saw item detection also make detection public so replacer, inspect and other mods can use it --- compat/moreblocks.lua | 61 +++++++++++++++++++++++++++++++++++++++++++ init.lua | 1 + inspect.lua | 27 +++---------------- 3 files changed, 65 insertions(+), 24 deletions(-) create mode 100644 compat/moreblocks.lua diff --git a/compat/moreblocks.lua b/compat/moreblocks.lua new file mode 100644 index 0000000..068a5b0 --- /dev/null +++ b/compat/moreblocks.lua @@ -0,0 +1,61 @@ +local r = replacer +if not r.has_circular_saw then + function replacer.is_saw_output() return nil end + return +end + +local core_registered_nodes = minetest.registered_nodes +local shapes_list_sorted = nil + +function replacer.is_saw_output(node_name) + if not node_name or 'moreblocks:circular_saw' == node_name then + return nil + end + -- first time this function is called + -- make a copy and sort so longest postfixes are used first + if nil == shapes_list_sorted then + shapes_list_sorted = table.copy(stairsplus.shapes_list) + table.sort(shapes_list_sorted, function(a, b) return #a[2] > #b[2] end) + end + -- now iterate looking for match + local mod_name, material, found + for i, t in ipairs(shapes_list_sorted) do + mod_name, material = string.match(node_name, + '^([^:]+):' .. t[1] .. '(.*)' .. t[2] .. '$') + if mod_name and material then + -- double check + if circular_saw.known_nodes[mod_name .. ':' .. material] then + break + elseif circular_saw.known_nodes['default:' .. material] then + -- many are from default + mod_name = 'default' + break + else + -- need to try the long way + found = false + for itemstring, t in pairs(circular_saw.known_nodes) do + if t[1] == mod_name and t[2] == material then + mod_name = itemstring:match('^([^:]+)') or '' + found = true + break + end + end + if found then break end + -- make sure we don't accidently have a false-positive + mod_name = nil + end -- double check + end -- match found + end -- loop shapes_list_sorted + if not (mod_name and material) then + return nil + end + + local basic_node_name = mod_name .. ':' .. material + -- final check + if not core_registered_nodes[basic_node_name] then + return nil + end + + return basic_node_name +end -- is_saw_output + diff --git a/init.lua b/init.lua index e8e21bf..5808e46 100644 --- a/init.lua +++ b/init.lua @@ -49,6 +49,7 @@ dofile(path .. 'utils.lua') -- unifiedddyes support functions dofile(path .. 'compat/unifieddyes.lua') replacer.datastructures = dofile(path .. 'replacer/datastructures.lua') +dofile(path .. 'compat/moreblocks.lua') -- adds a tool for inspecting nodes and entities dofile(path .. 'inspect.lua') dofile(path .. 'replacer/constrain.lua') diff --git a/inspect.lua b/inspect.lua index 92a9b5f..61319fe 100644 --- a/inspect.lua +++ b/inspect.lua @@ -244,30 +244,9 @@ replacer.image_button_link = function(stack_string) end replacer.add_circular_saw_recipe = function(node_name, recipes) - if not node_name - or not replacer.has_circular_saw - or 'moreblocks:circular_saw' == node_name - then - return - end - local help = node_name:split(':') - if not help or 2 ~= #help or 'stairs' == help[1] then - return - end - local help2 = help[2]:split('_') - if not help2 or 2 > #help2 - or ('micro' ~= help2[1] and 'panel' ~= help2[1] and 'stair' ~= help2[1] - and 'slab' ~= help2[1]) - then - return - end --- for i,v in ipairs(circular_saw.names) do --- modname..":"..v[1].."_"..material..v[2] + local basic_node_name = replacer.is_saw_output(node_name) + if not basic_node_name then return end --- TODO: write better and more correct method of getting the names of the materials --- TODO: make sure only nodes produced by the saw are listed here - help[1] = 'default' - local basic_node_name = help[1] .. ':' .. help2[2] -- node found that fits into the saw recipes[#recipes + 1] = { method = 'saw', @@ -276,7 +255,7 @@ replacer.add_circular_saw_recipe = function(node_name, recipes) output = node_name } return recipes -end +end -- add_circular_saw_recipe replacer.add_colormachine_recipe = function(node_name, recipes) From a967d2caa44acf2ee7c487b7735ec56450b88b73 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 20:12:02 +0100 Subject: [PATCH 141/366] keep init.lua flat --- compat/technic.lua | 3 +++ init.lua | 7 +++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/compat/technic.lua b/compat/technic.lua index 034f053..4f5599f 100644 --- a/compat/technic.lua +++ b/compat/technic.lua @@ -1,3 +1,6 @@ +-- skip if technic isn't loaded at all +if not replacer.has_technic_mod then retun end + -- adds exceptions for technic cable plates local lTiers = { 'lv', 'mv', 'hv' } local lPlates = { '_digi_cable_plate_', '_cable_plate_' } diff --git a/init.lua b/init.lua index 5808e46..1bd4123 100644 --- a/init.lua +++ b/init.lua @@ -59,10 +59,9 @@ dofile(path .. 'replacer/patterns.lua') dofile(path .. 'replacer/replacer.lua') dofile(path .. 'crafts.lua') dofile(path .. 'chat_commands.lua') --- add cable plate exceptions -if replacer.has_technic_mod then - dofile(path .. 'compat/technic.lua') -end +-- add cable plate exceptions (uses replacer/constrain.lua) +dofile(path .. 'compat/technic.lua') + -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- print('[replacer] loaded') From 5c062ba1c55366fdcbddd0c05b1c5f85a20f0603 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 20:12:46 +0100 Subject: [PATCH 142/366] reorder called sub-files --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 1bd4123..907488b 100644 --- a/init.lua +++ b/init.lua @@ -48,10 +48,10 @@ dofile(path .. 'replacer/blabla.lua') dofile(path .. 'utils.lua') -- unifiedddyes support functions dofile(path .. 'compat/unifieddyes.lua') -replacer.datastructures = dofile(path .. 'replacer/datastructures.lua') dofile(path .. 'compat/moreblocks.lua') -- adds a tool for inspecting nodes and entities dofile(path .. 'inspect.lua') +replacer.datastructures = dofile(path .. 'replacer/datastructures.lua') dofile(path .. 'replacer/constrain.lua') dofile(path .. 'replacer/formspecs.lua') dofile(path .. 'replacer/history.lua') From 786eda023a8231af9fb564897bfa887b4ef9e5cc Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 20:14:41 +0100 Subject: [PATCH 143/366] move nice_pos_string to utils.lua and improve it while we are at it - better rounding --- inspect.lua | 8 +------- utils.lua | 11 +++++++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/inspect.lua b/inspect.lua index 61319fe..3bb427f 100644 --- a/inspect.lua +++ b/inspect.lua @@ -35,13 +35,7 @@ minetest.register_tool('replacer:inspect', { end, }) -local function nice_pos_string(pos) - local no_info = '' - if 'table' ~= type(pos) then return no_info end - if not (pos.x and pos.y and pos.z) then return no_info end - pos = { x = math.floor(pos.x), y = math.floor(pos.y), z = math.floor(pos.z) } - return minetest.pos_to_string(pos) -end +local nice_pos_string = replacer.nice_pos_string replacer.inspect = function(_, user, pointed_thing, mode) if nil == user or nil == pointed_thing then diff --git a/utils.lua b/utils.lua index fdf8f30..b394e71 100644 --- a/utils.lua +++ b/utils.lua @@ -2,6 +2,8 @@ local rb = replacer.blabla local chat_send_player = minetest.chat_send_player local get_player_by_name = minetest.get_player_by_name local log = minetest.log +local floor = math.floor +local pos_to_string = minetest.pos_to_string function replacer.inform(name, message) if (not message) or ('' == message) then return end @@ -17,6 +19,15 @@ function replacer.inform(name, message) end -- inform +function replacer.nice_pos_string(pos) + local no_info = '' + if 'table' ~= type(pos) then return no_info end + if not (pos.x and pos.y and pos.z) then return no_info end + + pos = { x = floor(pos.x + .5), y = floor(pos.y + .5), z = floor(pos.z + .5) } + return pos_to_string(pos) +end -- nice_pos_string + -- from: http://lua-users.org/wiki/StringRecipes function replacer.titleCase(str) local function titleCaseHelper(first, rest) From af9a818a02ef43cb998fb5564f61070a64c8cc25 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 20:14:51 +0100 Subject: [PATCH 144/366] whitespace --- utils.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.lua b/utils.lua index b394e71..05614e7 100644 --- a/utils.lua +++ b/utils.lua @@ -15,8 +15,8 @@ function replacer.inform(name, message) local meta = player:get_meta() if not meta then return end if 0 < meta:get_int('replacer_mute') then return end - chat_send_player(name, message) + chat_send_player(name, message) end -- inform function replacer.nice_pos_string(pos) From f7b7ad8509ae046493ffcc83501011d6de4245dc Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 21:08:00 +0100 Subject: [PATCH 145/366] cache known saw items --- compat/moreblocks.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compat/moreblocks.lua b/compat/moreblocks.lua index 068a5b0..d087c0b 100644 --- a/compat/moreblocks.lua +++ b/compat/moreblocks.lua @@ -6,11 +6,15 @@ end local core_registered_nodes = minetest.registered_nodes local shapes_list_sorted = nil +local confirmed_saw_items = {} function replacer.is_saw_output(node_name) if not node_name or 'moreblocks:circular_saw' == node_name then return nil end + -- if we already confirmed this item, let's take the shortcut + if confirmed_saw_items[node_name] then return confirmed_saw_items[node_name] end + -- first time this function is called -- make a copy and sort so longest postfixes are used first if nil == shapes_list_sorted then @@ -56,6 +60,8 @@ function replacer.is_saw_output(node_name) return nil end + -- cache to speed up next call + confirmed_saw_items[node_name] = basic_node_name return basic_node_name end -- is_saw_output From abf81276b2951e5ba6b7f3eaf1f6513d69453edd Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 21:09:38 +0100 Subject: [PATCH 146/366] add compat for saw items and beacon beams --- compat/beacon.lua | 7 +++++++ init.lua | 5 ++++- replacer/replacer.lua | 8 +++++--- 3 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 compat/beacon.lua diff --git a/compat/beacon.lua b/compat/beacon.lua new file mode 100644 index 0000000..43e3cdb --- /dev/null +++ b/compat/beacon.lua @@ -0,0 +1,7 @@ +function replacer.is_beacon_beam_or_base(node_name) + if 'string' ~= type(node_name) then return nil end + if node_name:match('^beacon:(.*)beam$') then return true end + if node_name:match('^beacon:(.*)base$') then return true end + return false +end -- is_beacon_beam_or_base + diff --git a/init.lua b/init.lua index 907488b..b5a813e 100644 --- a/init.lua +++ b/init.lua @@ -46,9 +46,12 @@ local path = minetest.get_modpath('replacer') .. '/' dofile(path .. 'replacer/blabla.lua') -- utilities dofile(path .. 'utils.lua') +-- beacon beam support +dofile(path .. 'compat/beacon.lua') +-- circular saw support +dofile(path .. 'compat/moreblocks.lua') -- unifiedddyes support functions dofile(path .. 'compat/unifieddyes.lua') -dofile(path .. 'compat/moreblocks.lua') -- adds a tool for inspecting nodes and entities dofile(path .. 'inspect.lua') replacer.datastructures = dofile(path .. 'replacer/datastructures.lua') diff --git a/replacer/replacer.lua b/replacer/replacer.lua index d74e98d..a32dc31 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -552,9 +552,11 @@ function replacer.on_place(itemstack, player, pt) end local inv = player:get_inventory() - if (not (creative_enabled and has_give)) and - (not inv:contains_item('main', node.name)) and - (not r.exception_map[node.name]) + if (not (creative_enabled and has_give)) + and (not inv:contains_item('main', node.name)) + and (not r.exception_map[node.name]) + and (not r.is_beacon_beam_or_base(node.name)) + and (not r.is_saw_output(node.name)) then -- not in inv and not (creative and give) local found_item = false From 565e8121c4c072df2dbdd04c3639583977317502 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 21:10:46 +0100 Subject: [PATCH 147/366] oops, typo --- compat/technic.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compat/technic.lua b/compat/technic.lua index 4f5599f..0069940 100644 --- a/compat/technic.lua +++ b/compat/technic.lua @@ -1,5 +1,5 @@ -- skip if technic isn't loaded at all -if not replacer.has_technic_mod then retun end +if not replacer.has_technic_mod then return end -- adds exceptions for technic cable plates local lTiers = { 'lv', 'mv', 'hv' } From b3e188408d7d0b8c28a4bb030e75e80679a680c5 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 19 Jan 2022 21:25:19 +0100 Subject: [PATCH 148/366] version bump 3.8 --- CHANGELOG | 3 +++ init.lua | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f6a11bd..979cd93 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +20220120 * SwissalpS made folder structure to create easier overview. + * Improved circular saw item detection for inspect and replacer. + * Added beacon beam and base support (no longer needed to be in inv when setting). 20220119 * SwissalpS added first draft of de,es,fi,fr,it,pt,ru locales. 20220118 * SwissalpS cleaned up more code, giving more discriptive variable names and cleaning out ugly modes table that had both number and string indexes diff --git a/init.lua b/init.lua index b5a813e..cfdf354 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 3.7 (20220119) +-- Version 3.8 (20220120) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220119 +replacer.version = 20220120 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From 8c5a73fa4e0ddbcb792d40f7b2bc14a97a521e98 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 02:17:09 +0100 Subject: [PATCH 149/366] add group:vines placeholder --- inspect.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/inspect.lua b/inspect.lua index 3bb427f..23b2f0e 100644 --- a/inspect.lua +++ b/inspect.lua @@ -172,6 +172,7 @@ replacer.group_placeholder['group:stick'] = 'default:stick' replacer.group_placeholder['group:stone'] = 'default:cobble' replacer.group_placeholder['group:sand'] = 'default:sand' replacer.group_placeholder['group:leaves'] = 'default:leaves' +replacer.group_placeholder['group:vines'] = 'vines:vines' replacer.group_placeholder['group:wood_slab'] = 'stairs:slab_wood' replacer.group_placeholder['group:wool'] = 'wool:white' replacer.group_placeholder['group:coal'] = 'default:coal_lump' From f5d23e73fe8806bda22c5d7b664b9627ee8535f4 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 02:18:19 +0100 Subject: [PATCH 150/366] order group placeholders alphabetically --- inspect.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/inspect.lua b/inspect.lua index 23b2f0e..bdf8a72 100644 --- a/inspect.lua +++ b/inspect.lua @@ -164,18 +164,18 @@ end -- some common groups replacer.group_placeholder = {} -replacer.group_placeholder['group:wood'] = 'default:wood' -replacer.group_placeholder['group:tree'] = 'default:tree' +replacer.group_placeholder['group:coal'] = 'default:coal_lump' +replacer.group_placeholder['group:leaves'] = 'default:leaves' +replacer.group_placeholder['group:sand'] = 'default:sand' replacer.group_placeholder['group:sapling']= 'default:sapling' replacer.group_placeholder['group:stick'] = 'default:stick' -- 'default:stone' point people to the cheaper cobble replacer.group_placeholder['group:stone'] = 'default:cobble' -replacer.group_placeholder['group:sand'] = 'default:sand' -replacer.group_placeholder['group:leaves'] = 'default:leaves' +replacer.group_placeholder['group:tree'] = 'default:tree' replacer.group_placeholder['group:vines'] = 'vines:vines' +replacer.group_placeholder['group:wood'] = 'default:wood' replacer.group_placeholder['group:wood_slab'] = 'stairs:slab_wood' replacer.group_placeholder['group:wool'] = 'wool:white' -replacer.group_placeholder['group:coal'] = 'default:coal_lump' -- add default game dyes for _, color in pairs(dye.dyes) do From d2aa5ab221ac9a3ca33bd0bf647648d7c8b55a4c Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 02:26:50 +0100 Subject: [PATCH 151/366] avoid ]] as this makes multiline commenting out difficult in Lua --- inspect.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inspect.lua b/inspect.lua index bdf8a72..fe1c6cb 100644 --- a/inspect.lua +++ b/inspect.lua @@ -179,7 +179,7 @@ replacer.group_placeholder['group:wool'] = 'wool:white' -- add default game dyes for _, color in pairs(dye.dyes) do - replacer.group_placeholder['group:dye,color_' .. color[1]] = 'dye:' .. color[1] + replacer.group_placeholder['group:dye,color_' .. color[1] ] = 'dye:' .. color[1] end -- add default game flowers From 0dd6904e308ab2e26f9dcee2c153fb6206ce78db Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 02:40:24 +0100 Subject: [PATCH 152/366] cobweb fix --- compat/mobs.lua | 7 +++++++ init.lua | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 compat/mobs.lua diff --git a/compat/mobs.lua b/compat/mobs.lua new file mode 100644 index 0000000..c6e676d --- /dev/null +++ b/compat/mobs.lua @@ -0,0 +1,7 @@ +-- for some reason cobwebs need this [mobs_animal] +-- probably because they drop string when dug and string +-- is only a craft item. +if minetest.get_modpath('mobs_animal') then + replacer.register_exception('mobs:cobweb', 'mobs:cobweb') +end + diff --git a/init.lua b/init.lua index cfdf354..5b174e7 100644 --- a/init.lua +++ b/init.lua @@ -62,7 +62,9 @@ dofile(path .. 'replacer/patterns.lua') dofile(path .. 'replacer/replacer.lua') dofile(path .. 'crafts.lua') dofile(path .. 'chat_commands.lua') --- add cable plate exceptions (uses replacer/constrain.lua) +-- these use replacer/constrain.lua +dofile(path .. 'compat/mobs.lua') +-- add cable plate exceptions dofile(path .. 'compat/technic.lua') -------------------------------------------------------------------------------- From 9beaea01287883a141bd572b4035e62b41ffb046 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 02:59:13 +0100 Subject: [PATCH 153/366] RealTest moved to compat I would have added these to replacer.group_placeholder table, it's something inherited and I haven't bothered yet to figure it out. --- compat/realTest.lua | 18 ++++++++++++++++++ init.lua | 3 +++ inspect.lua | 19 ------------------- 3 files changed, 21 insertions(+), 19 deletions(-) create mode 100644 compat/realTest.lua diff --git a/compat/realTest.lua b/compat/realTest.lua new file mode 100644 index 0000000..efc46c0 --- /dev/null +++ b/compat/realTest.lua @@ -0,0 +1,18 @@ +-- overrides for replacer:inspect +-- support for RealTest +if minetest.get_modpath('trees') + and minetest.get_modpath('core') + and minetest.get_modpath('instruments') + and minetest.get_modpath('anvil') + and minetest.get_modpath('scribing_table') +then + replacer.image_replacements['group:planks'] = 'trees:pine_planks' + replacer.image_replacements['group:plank'] = 'trees:pine_plank' + replacer.image_replacements['group:wood'] = 'trees:pine_planks' + replacer.image_replacements['group:tree'] = 'trees:pine_log' + replacer.image_replacements['group:sapling'] = 'trees:pine_sapling' + replacer.image_replacements['group:leaves'] = 'trees:pine_leaves' + replacer.image_replacements['default:furnace'] = 'oven:oven' + replacer.image_replacements['default:furnace_active'] = 'oven:oven_active' +end + diff --git a/init.lua b/init.lua index 5b174e7..d2fc6f8 100644 --- a/init.lua +++ b/init.lua @@ -41,6 +41,7 @@ replacer.has_technic_mod = minetest.get_modpath('technic') replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') and minetest.global_exists('unifieddyes') +replacer.image_replacements = {} local path = minetest.get_modpath('replacer') .. '/' -- strings for translation dofile(path .. 'replacer/blabla.lua') @@ -51,6 +52,8 @@ dofile(path .. 'compat/beacon.lua') -- circular saw support dofile(path .. 'compat/moreblocks.lua') -- unifiedddyes support functions +-- RealTest overrides (i) +dofile(path .. 'compat/realTest.lua') dofile(path .. 'compat/unifieddyes.lua') -- adds a tool for inspecting nodes and entities dofile(path .. 'inspect.lua') diff --git a/inspect.lua b/inspect.lua index fe1c6cb..fa66e96 100644 --- a/inspect.lua +++ b/inspect.lua @@ -1,23 +1,4 @@ -replacer.image_replacements = {} - --- support for RealTest -if minetest.get_modpath('trees') - and minetest.get_modpath('core') - and minetest.get_modpath('instruments') - and minetest.get_modpath('anvil') - and minetest.get_modpath('scribing_table') -then - replacer.image_replacements['group:planks'] = 'trees:pine_planks' - replacer.image_replacements['group:plank'] = 'trees:pine_plank' - replacer.image_replacements['group:wood'] = 'trees:pine_planks' - replacer.image_replacements['group:tree'] = 'trees:pine_log' - replacer.image_replacements['group:sapling'] = 'trees:pine_sapling' - replacer.image_replacements['group:leaves'] = 'trees:pine_leaves' - replacer.image_replacements['default:furnace'] = 'oven:oven' - replacer.image_replacements['default:furnace_active'] = 'oven:oven_active' -end - minetest.register_tool('replacer:inspect', { description = 'Node inspection tool', groups = {}, From 61877bbdd8d8f9a7d5792503308f31e250bd9300 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 03:00:19 +0100 Subject: [PATCH 154/366] move to init for flexibility --- init.lua | 3 +++ inspect.lua | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index d2fc6f8..c3db6d6 100644 --- a/init.lua +++ b/init.lua @@ -41,7 +41,10 @@ replacer.has_technic_mod = minetest.get_modpath('technic') replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') and minetest.global_exists('unifieddyes') +-- image mapping tables for replacer:inspect +replacer.group_placeholder = {} replacer.image_replacements = {} + local path = minetest.get_modpath('replacer') .. '/' -- strings for translation dofile(path .. 'replacer/blabla.lua') diff --git a/inspect.lua b/inspect.lua index fa66e96..1800f54 100644 --- a/inspect.lua +++ b/inspect.lua @@ -144,7 +144,6 @@ replacer.inspect = function(_, user, pointed_thing, mode) end -- some common groups -replacer.group_placeholder = {} replacer.group_placeholder['group:coal'] = 'default:coal_lump' replacer.group_placeholder['group:leaves'] = 'default:leaves' replacer.group_placeholder['group:sand'] = 'default:sand' From b473cce08612fa604ca187c9ae60505e1b92e091 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 03:01:15 +0100 Subject: [PATCH 155/366] whitespace and comments --- init.lua | 13 +++++++------ inspect.lua | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/init.lua b/init.lua index c3db6d6..603da2d 100644 --- a/init.lua +++ b/init.lua @@ -46,17 +46,17 @@ replacer.group_placeholder = {} replacer.image_replacements = {} local path = minetest.get_modpath('replacer') .. '/' --- strings for translation +-- strings for translation (r) dofile(path .. 'replacer/blabla.lua') --- utilities +-- utilities (i+r) dofile(path .. 'utils.lua') --- beacon beam support +-- beacon beam support (r) dofile(path .. 'compat/beacon.lua') --- circular saw support +-- circular saw support (i+r) dofile(path .. 'compat/moreblocks.lua') --- unifiedddyes support functions -- RealTest overrides (i) dofile(path .. 'compat/realTest.lua') +-- unifiedddyes support functions (i+r) dofile(path .. 'compat/unifieddyes.lua') -- adds a tool for inspecting nodes and entities dofile(path .. 'inspect.lua') @@ -69,8 +69,9 @@ dofile(path .. 'replacer/replacer.lua') dofile(path .. 'crafts.lua') dofile(path .. 'chat_commands.lua') -- these use replacer/constrain.lua +-- cobweb (r) dofile(path .. 'compat/mobs.lua') --- add cable plate exceptions +-- add cable plate exceptions (r) dofile(path .. 'compat/technic.lua') -------------------------------------------------------------------------------- diff --git a/inspect.lua b/inspect.lua index 1800f54..964724c 100644 --- a/inspect.lua +++ b/inspect.lua @@ -4,7 +4,7 @@ minetest.register_tool('replacer:inspect', { groups = {}, inventory_image = 'replacer_inspect.png', wield_image = '', - wield_scale = { x = 1,y = 1,z = 1 }, + wield_scale = { x = 1, y = 1, z = 1 }, liquids_pointable = true, -- it is ok to request information about liquids on_use = function(itemstack, user, pointed_thing) From 0360e93ec3f1b29e333e9f3ba19b6b9f8b7cff83 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 03:01:43 +0100 Subject: [PATCH 156/366] vines moved to compat --- compat/vines.lua | 4 ++++ init.lua | 3 +++ inspect.lua | 1 - 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 compat/vines.lua diff --git a/compat/vines.lua b/compat/vines.lua new file mode 100644 index 0000000..afa567a --- /dev/null +++ b/compat/vines.lua @@ -0,0 +1,4 @@ +if minetest.get_modpath('vines') then + replacer.group_placeholder['group:vines'] = 'vines:vines' +end + diff --git a/init.lua b/init.lua index 603da2d..14c999e 100644 --- a/init.lua +++ b/init.lua @@ -58,6 +58,9 @@ dofile(path .. 'compat/moreblocks.lua') dofile(path .. 'compat/realTest.lua') -- unifiedddyes support functions (i+r) dofile(path .. 'compat/unifieddyes.lua') +-- vines group support (i) +dofile(path .. 'compat/vines.lua') + -- adds a tool for inspecting nodes and entities dofile(path .. 'inspect.lua') replacer.datastructures = dofile(path .. 'replacer/datastructures.lua') diff --git a/inspect.lua b/inspect.lua index 964724c..6a219a6 100644 --- a/inspect.lua +++ b/inspect.lua @@ -152,7 +152,6 @@ replacer.group_placeholder['group:stick'] = 'default:stick' -- 'default:stone' point people to the cheaper cobble replacer.group_placeholder['group:stone'] = 'default:cobble' replacer.group_placeholder['group:tree'] = 'default:tree' -replacer.group_placeholder['group:vines'] = 'vines:vines' replacer.group_placeholder['group:wood'] = 'default:wood' replacer.group_placeholder['group:wood_slab'] = 'stairs:slab_wood' replacer.group_placeholder['group:wool'] = 'wool:white' From ef80dd4d7f0c5d4ae37eda23e27c9d0286b768af Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 03:08:51 +0100 Subject: [PATCH 157/366] move default support to compat --- compat/default.lua | 31 +++++++++++++++++++++++++++++++ init.lua | 2 ++ inspect.lua | 32 -------------------------------- 3 files changed, 33 insertions(+), 32 deletions(-) create mode 100644 compat/default.lua diff --git a/compat/default.lua b/compat/default.lua new file mode 100644 index 0000000..7537a01 --- /dev/null +++ b/compat/default.lua @@ -0,0 +1,31 @@ +-- replacer has default mod as hard dependancy, so no checking +-- some common groups +replacer.group_placeholder['group:coal'] = 'default:coal_lump' +replacer.group_placeholder['group:leaves'] = 'default:leaves' +replacer.group_placeholder['group:sand'] = 'default:sand' +replacer.group_placeholder['group:sapling']= 'default:sapling' +replacer.group_placeholder['group:stick'] = 'default:stick' +-- 'default:stone' point people to the cheaper cobble +replacer.group_placeholder['group:stone'] = 'default:cobble' +replacer.group_placeholder['group:tree'] = 'default:tree' +replacer.group_placeholder['group:wood'] = 'default:wood' +replacer.group_placeholder['group:wood_slab'] = 'stairs:slab_wood' +replacer.group_placeholder['group:wool'] = 'wool:white' + +-- add default game dyes +for _, color in pairs(dye.dyes) do + replacer.group_placeholder['group:dye,color_' .. color[1] ] = 'dye:' .. color[1] +end + +-- add default game flowers +local name, groups +for _, flower in pairs(flowers.datas) do + name = flower[1] + groups = flower[4] + for k, _ in pairs(groups) do + if 1 == k:find('color_') then + replacer.group_placeholder['group:flower,' .. k] = 'flowers:' .. name + end + end +end + diff --git a/init.lua b/init.lua index 14c999e..f415f42 100644 --- a/init.lua +++ b/init.lua @@ -52,6 +52,8 @@ dofile(path .. 'replacer/blabla.lua') dofile(path .. 'utils.lua') -- beacon beam support (r) dofile(path .. 'compat/beacon.lua') +-- default support (i) +dofile(path .. 'compat/default.lua') -- circular saw support (i+r) dofile(path .. 'compat/moreblocks.lua') -- RealTest overrides (i) diff --git a/inspect.lua b/inspect.lua index 6a219a6..a76cb7f 100644 --- a/inspect.lua +++ b/inspect.lua @@ -143,38 +143,6 @@ replacer.inspect = function(_, user, pointed_thing, mode) return nil -- no item shall be removed from inventory end --- some common groups -replacer.group_placeholder['group:coal'] = 'default:coal_lump' -replacer.group_placeholder['group:leaves'] = 'default:leaves' -replacer.group_placeholder['group:sand'] = 'default:sand' -replacer.group_placeholder['group:sapling']= 'default:sapling' -replacer.group_placeholder['group:stick'] = 'default:stick' --- 'default:stone' point people to the cheaper cobble -replacer.group_placeholder['group:stone'] = 'default:cobble' -replacer.group_placeholder['group:tree'] = 'default:tree' -replacer.group_placeholder['group:wood'] = 'default:wood' -replacer.group_placeholder['group:wood_slab'] = 'stairs:slab_wood' -replacer.group_placeholder['group:wool'] = 'wool:white' - --- add default game dyes -for _, color in pairs(dye.dyes) do - replacer.group_placeholder['group:dye,color_' .. color[1] ] = 'dye:' .. color[1] -end - --- add default game flowers -do - local name, groups - for _, flower in pairs(flowers.datas) do - name = flower[1] - groups = flower[4] - for k, _ in pairs(groups) do - if 1 == k:find('color_') then - replacer.group_placeholder['group:flower,' .. k] = 'flowers:' .. name - end - end - end -end - -- add bakedclay items if replacer.has_bakedclay then replacer.group_placeholder['group:bakedclay'] = 'bakedclay:natural' From 2065b871a8ec7687ba818115b7318d5a69571ab8 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 03:09:15 +0100 Subject: [PATCH 158/366] whitespace --- inspect.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inspect.lua b/inspect.lua index a76cb7f..20931a0 100644 --- a/inspect.lua +++ b/inspect.lua @@ -18,7 +18,7 @@ minetest.register_tool('replacer:inspect', { local nice_pos_string = replacer.nice_pos_string -replacer.inspect = function(_, user, pointed_thing, mode) +function replacer.inspect(_, user, pointed_thing, mode) if nil == user or nil == pointed_thing then return nil end @@ -141,7 +141,7 @@ replacer.inspect = function(_, user, pointed_thing, mode) protected_info = protected_info }) return nil -- no item shall be removed from inventory -end +end -- replacer.inspect -- add bakedclay items if replacer.has_bakedclay then From bd57008b407f880c1c012dfd769e7cada1f17da3 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 03:12:30 +0100 Subject: [PATCH 159/366] bakedclay to compat --- compat/bakedclay.lua | 12 ++++++++++++ init.lua | 2 ++ inspect.lua | 12 ------------ 3 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 compat/bakedclay.lua diff --git a/compat/bakedclay.lua b/compat/bakedclay.lua new file mode 100644 index 0000000..7f7d977 --- /dev/null +++ b/compat/bakedclay.lua @@ -0,0 +1,12 @@ +-- add bakedclay items +if replacer.has_bakedclay then + replacer.group_placeholder['group:bakedclay'] = 'bakedclay:natural' + -- unfortunately bakedclay does not expose anything, so we have to manually + -- maintain the list + local rgp = replacer.group_placeholder + rgp['group:flower,color_cyan'] = 'bakedclay:delphinium' + rgp['group:flower,color_pink'] = 'bakedclay:lazarus' + rgp['group:flower,color_dark_green'] = 'bakedclay:mannagrass' + rgp['group:flower,color_magenta'] = 'bakedclay:thistle' +end + diff --git a/init.lua b/init.lua index f415f42..c726308 100644 --- a/init.lua +++ b/init.lua @@ -50,6 +50,8 @@ local path = minetest.get_modpath('replacer') .. '/' dofile(path .. 'replacer/blabla.lua') -- utilities (i+r) dofile(path .. 'utils.lua') +-- bakedclay support (i) +dofile(path .. 'compat/bakedclay.lua') -- beacon beam support (r) dofile(path .. 'compat/beacon.lua') -- default support (i) diff --git a/inspect.lua b/inspect.lua index 20931a0..e28f2d2 100644 --- a/inspect.lua +++ b/inspect.lua @@ -143,18 +143,6 @@ function replacer.inspect(_, user, pointed_thing, mode) return nil -- no item shall be removed from inventory end -- replacer.inspect --- add bakedclay items -if replacer.has_bakedclay then - replacer.group_placeholder['group:bakedclay'] = 'bakedclay:natural' - -- unfortunately bakedclay does not expose anything, so we have to manually - -- maintain the list - local rgp = replacer.group_placeholder - rgp['group:flower,color_cyan'] = 'bakedclay:delphinium' - rgp['group:flower,color_pink'] = 'bakedclay:lazarus' - rgp['group:flower,color_dark_green'] = 'bakedclay:mannagrass' - rgp['group:flower,color_magenta'] = 'bakedclay:thistle' -end - -- handle the standard dye color groups if replacer.has_basic_dyes then for i, color in ipairs(dye.basecolors) do From 544fac381ab78c6a8373b5d5e984cf5bd5d1623f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 03:21:41 +0100 Subject: [PATCH 160/366] basic dyes to compat --- compat/default.lua | 15 +++++++++++++++ init.lua | 2 +- inspect.lua | 14 -------------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/compat/default.lua b/compat/default.lua index 7537a01..c77bc17 100644 --- a/compat/default.lua +++ b/compat/default.lua @@ -29,3 +29,18 @@ for _, flower in pairs(flowers.datas) do end end +-- handle the standard dye color groups +if replacer.has_basic_dyes then + for i, color in ipairs(dye.basecolors) do + local def = minetest.registered_items['dye:' .. color] + if def and def.groups then + for k, v in pairs(def.groups) do + if 'dye' ~= k then + replacer.group_placeholder['group:dye,' .. k] = 'dye:' .. color + end + end + replacer.group_placeholder['group:flower,color_' .. color] = 'dye:' .. color + end + end +end + diff --git a/init.lua b/init.lua index c726308..140136c 100644 --- a/init.lua +++ b/init.lua @@ -54,7 +54,7 @@ dofile(path .. 'utils.lua') dofile(path .. 'compat/bakedclay.lua') -- beacon beam support (r) dofile(path .. 'compat/beacon.lua') --- default support (i) +-- default & basic dyes support (i) dofile(path .. 'compat/default.lua') -- circular saw support (i+r) dofile(path .. 'compat/moreblocks.lua') diff --git a/inspect.lua b/inspect.lua index e28f2d2..1d3ba52 100644 --- a/inspect.lua +++ b/inspect.lua @@ -143,20 +143,6 @@ function replacer.inspect(_, user, pointed_thing, mode) return nil -- no item shall be removed from inventory end -- replacer.inspect --- handle the standard dye color groups -if replacer.has_basic_dyes then - for i, color in ipairs(dye.basecolors) do - local def = minetest.registered_items['dye:' .. color] - if def and def.groups then - for k, v in pairs(def.groups) do - if 'dye' ~= k then - replacer.group_placeholder['group:dye,' .. k] = 'dye:' .. color - end - end - replacer.group_placeholder['group:flower,color_' .. color] = 'dye:' .. color - end - end -end replacer.image_button_link = function(stack_string) local group = '' From b6afa6702a5aa411385fbb93534f5c5348258a24 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 03:22:12 +0100 Subject: [PATCH 161/366] whitespace --- inspect.lua | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/inspect.lua b/inspect.lua index 1d3ba52..a6f9a95 100644 --- a/inspect.lua +++ b/inspect.lua @@ -143,8 +143,7 @@ function replacer.inspect(_, user, pointed_thing, mode) return nil -- no item shall be removed from inventory end -- replacer.inspect - -replacer.image_button_link = function(stack_string) +function replacer.image_button_link(stack_string) local group = '' if replacer.image_replacements[stack_string] then stack_string = replacer.image_replacements[stack_string] @@ -157,7 +156,8 @@ replacer.image_button_link = function(stack_string) local stack = ItemStack(stack_string) local new_node_name = stack:get_name() return stack_string .. ';' .. new_node_name .. ';' .. group -end +end -- image_button_link + replacer.add_circular_saw_recipe = function(node_name, recipes) local basic_node_name = replacer.is_saw_output(node_name) @@ -174,7 +174,7 @@ replacer.add_circular_saw_recipe = function(node_name, recipes) end -- add_circular_saw_recipe -replacer.add_colormachine_recipe = function(node_name, recipes) +function replacer.add_colormachine_recipe(node_name, recipes) if not replacer.has_colormachine_mod then return end @@ -191,10 +191,10 @@ replacer.add_colormachine_recipe = function(node_name, recipes) output = node_name } return recipes -end +end -- add_colormachine_recipe -replacer.inspect_show_crafting = function(player_name, node_name, fields) +function replacer.inspect_show_crafting(player_name, node_name, fields) if not player_name then return end @@ -404,10 +404,11 @@ replacer.inspect_show_crafting = function(player_name, node_name, fields) end end minetest.show_formspec(player_name, 'replacer:crafting', formspec) -end +end -- inspect_show_crafting + -- translate general formspec calls back to specific calls -replacer.form_input_handler = function(player, formname, fields) +function replacer.form_input_handler(player, formname, fields) if formname and 'replacer:crafting' == formname and player and not fields.quit then From b439d5cad5b843a926bd14f982a748c5422b5d4f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 03:29:01 +0100 Subject: [PATCH 162/366] oopsie --- compat/mobs.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compat/mobs.lua b/compat/mobs.lua index c6e676d..ca4c5a8 100644 --- a/compat/mobs.lua +++ b/compat/mobs.lua @@ -1,7 +1,7 @@ --- for some reason cobwebs need this [mobs_animal] +-- for some reason cobwebs need this [mobs_monster] -- probably because they drop string when dug and string -- is only a craft item. -if minetest.get_modpath('mobs_animal') then +if minetest.get_modpath('mobs_monster') then replacer.register_exception('mobs:cobweb', 'mobs:cobweb') end From 683478880318a95b5d89797a2b19e7c3f82740c7 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 04:00:15 +0100 Subject: [PATCH 163/366] show accurate light and differentiate rc/lc right click now shows info about 'above' node of pointed_thing --- inspect.lua | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/inspect.lua b/inspect.lua index a6f9a95..20eb0c2 100644 --- a/inspect.lua +++ b/inspect.lua @@ -1,4 +1,9 @@ - +-- a crafting guide wanabe. Better than nothing for servers without +-- unified_inventory installed. +-- most useful feature is probably light measuring. +-- when punching (lc), info about the node that was punched is presented +-- when placing (rc), info about the node to the side that was clicked is +-- presented. Mostly air. minetest.register_tool('replacer:inspect', { description = 'Node inspection tool', groups = {}, @@ -12,13 +17,13 @@ minetest.register_tool('replacer:inspect', { end, on_place = function(itemstack, placer, pointed_thing) - return replacer.inspect(itemstack, placer, pointed_thing) + return replacer.inspect(itemstack, placer, pointed_thing, true) end, }) local nice_pos_string = replacer.nice_pos_string -function replacer.inspect(_, user, pointed_thing, mode) +function replacer.inspect(_, user, pointed_thing, right_clicked) if nil == user or nil == pointed_thing then return nil end @@ -113,7 +118,7 @@ function replacer.inspect(_, user, pointed_thing, mode) return nil end - local pos = minetest.get_pointed_thing_position(pointed_thing, mode) + local pos = minetest.get_pointed_thing_position(pointed_thing, right_clicked) local node = minetest.get_node_or_nil(pos) if not node then @@ -131,9 +136,6 @@ function replacer.inspect(_, user, pointed_thing, mode) -- get light of the node at the current time local light = minetest.get_node_light(pos, nil) - if 0 == light then - light = minetest.get_node_light({ x = pos.x, y = pos.y + 1, z = pos.z }) - end -- the fields part is used here to provide additional -- information about the node replacer.inspect_show_crafting(name, node.name, { From 831402421e1c2dd807544fd2edf606d69cb597fc Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 04:22:29 +0100 Subject: [PATCH 164/366] don't show button when there is no drop --- inspect.lua | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/inspect.lua b/inspect.lua index 20eb0c2..82b554d 100644 --- a/inspect.lua +++ b/inspect.lua @@ -317,9 +317,14 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) then local drop = minetest.registered_nodes[node_name].drop if 'string' == type(drop) and drop ~= node_name then - formspec = formspec .. 'label[2,1.6;Drops on dig:]' - .. 'item_image_button[2,2;1.0,1.0;' - .. replacer.image_button_link(drop) .. ']' + formspec = formspec .. 'label[2,1.6;Drops on dig:' + if '' == drop then + formspec = formspec .. 'nothing]' + else + formspec = formspec + .. ']item_image_button[2,2;1.0,1.0;' + .. replacer.image_button_link(drop) .. ']' + end elseif 'table' == type(drop) and drop.items then local droplist = {} for _, drops in ipairs(drop.items) do From c0d0f3984b416f4798ad8109011ce859b976b80a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 04:39:34 +0100 Subject: [PATCH 165/366] moved constrain up so compat can be looped later --- init.lua | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/init.lua b/init.lua index 140136c..42bbc11 100644 --- a/init.lua +++ b/init.lua @@ -48,18 +48,26 @@ replacer.image_replacements = {} local path = minetest.get_modpath('replacer') .. '/' -- strings for translation (r) dofile(path .. 'replacer/blabla.lua') +-- more settings and functions +dofile(path .. 'replacer/constrain.lua') -- utilities (i+r) dofile(path .. 'utils.lua') + +-- TODO: just loop through compat dir -- bakedclay support (i) dofile(path .. 'compat/bakedclay.lua') -- beacon beam support (r) dofile(path .. 'compat/beacon.lua') -- default & basic dyes support (i) dofile(path .. 'compat/default.lua') +-- cobweb (r) +dofile(path .. 'compat/mobs.lua') -- circular saw support (i+r) dofile(path .. 'compat/moreblocks.lua') -- RealTest overrides (i) dofile(path .. 'compat/realTest.lua') +-- add cable plate exceptions (r) +dofile(path .. 'compat/technic.lua') -- unifiedddyes support functions (i+r) dofile(path .. 'compat/unifieddyes.lua') -- vines group support (i) @@ -68,19 +76,12 @@ dofile(path .. 'compat/vines.lua') -- adds a tool for inspecting nodes and entities dofile(path .. 'inspect.lua') replacer.datastructures = dofile(path .. 'replacer/datastructures.lua') -dofile(path .. 'replacer/constrain.lua') dofile(path .. 'replacer/formspecs.lua') dofile(path .. 'replacer/history.lua') dofile(path .. 'replacer/patterns.lua') dofile(path .. 'replacer/replacer.lua') dofile(path .. 'crafts.lua') dofile(path .. 'chat_commands.lua') --- these use replacer/constrain.lua --- cobweb (r) -dofile(path .. 'compat/mobs.lua') --- add cable plate exceptions (r) -dofile(path .. 'compat/technic.lua') - -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- print('[replacer] loaded') From 67a1da4c424dd44c9a5a3c328a40f900a6d4b61e Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 04:40:19 +0100 Subject: [PATCH 166/366] added replacer vines support --- compat/vines.lua | 10 ++++++++-- init.lua | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/compat/vines.lua b/compat/vines.lua index afa567a..87b5e62 100644 --- a/compat/vines.lua +++ b/compat/vines.lua @@ -1,4 +1,10 @@ -if minetest.get_modpath('vines') then - replacer.group_placeholder['group:vines'] = 'vines:vines' +if not minetest.get_modpath('vines') then return end + +replacer.group_placeholder['group:vines'] = 'vines:vines' +local vines = { 'jungle', 'root', 'side', 'vine', 'willow' } +local node_name +for _, name in ipairs(vines) do + node_name = 'vines:' .. name .. '_end' + replacer.register_exception(node_name, node_name) end diff --git a/init.lua b/init.lua index 42bbc11..5510ed9 100644 --- a/init.lua +++ b/init.lua @@ -70,7 +70,7 @@ dofile(path .. 'compat/realTest.lua') dofile(path .. 'compat/technic.lua') -- unifiedddyes support functions (i+r) dofile(path .. 'compat/unifieddyes.lua') --- vines group support (i) +-- vines group support (i+r) dofile(path .. 'compat/vines.lua') -- adds a tool for inspecting nodes and entities From 7bea45de0f7fa80994f15292e303020ba800a1d5 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 05:59:04 +0100 Subject: [PATCH 167/366] added alias mapping for non creative users --- replacer/blabla.lua | 7 +++++-- replacer/constrain.lua | 21 +++++++++++++++++++++ replacer/replacer.lua | 10 ++++++++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/replacer/blabla.lua b/replacer/blabla.lua index 8d79904..0b43a78 100644 --- a/replacer/blabla.lua +++ b/replacer/blabla.lua @@ -75,10 +75,13 @@ rb.ccm_player_meta_error = 'Player meta not existant' rb.ccm_hint = S('Valid parameter is either "%s" or "%s"') rb.on_yes = S('on') rb.off_no = S('off') -rb.log_reg_exception_override = '[replacer] register_rotation_exception ' - .. 'for "%s" already exists.' +rb.log_reg_exception_override = '[replacer] register_exception: ' + .. 'exception for "%s" already exists.' rb.log_reg_exception = '[replacer] registered exception for "%s" to "%s"' rb.log_reg_exception_callback = '[replacer] registered after on_place callback for "%s"' +rb.log_reg_alias_override = '[replacer] register_non_creative_alias: ' + .. ' alias for "%s" already exists.' +rb.log_reg_alias = '[replacer] registered alias for "%s" to "%s"' rb.formspec_error = '[replacer] formspec error, user "%s" attempting to change history. Fields: %s' rb.formspec_hacker = '[replacer] formspec forge? By user "%s" Fields: %s' diff --git a/replacer/constrain.lua b/replacer/constrain.lua index c830ad4..cd1a224 100644 --- a/replacer/constrain.lua +++ b/replacer/constrain.lua @@ -15,8 +15,21 @@ replacer.limit_list = {} -- In order to register only a callback, pass two identical itemstrings. -- Generally the callback is not needed as on_place() is called on the placed node -- callback signature is: (pos, old_node_def, new_node_def, player_ref) +-- Examples: +-- 1) Technic cable plate 'technic:lv_cable_plate_4' needs to consume 'technic:lv_cable_plate_1' +-- r.register_exception('technic:lv_cable_plate_4', 'technic:lv_cable_plate_1') +-- 2) Cobwebs don't drop cobwebs, to enable setting replacer to them without having any in +-- user's inventory, register like so: +-- r.register_exception('mobs:cobweb', 'mobs:cobweb') replacer.exception_map = {} replacer.exception_callbacks = {} +-- sometimes you want a reverse exception, for that you use: +-- replacer.register_non_creative_alias(name_sibling, name_placed) +-- Example vines have middle and end parts. To enable setting replacer on middle part +-- to then place an end part in world (only when player does not have creative priv) +-- register like so: +-- replacer.register_non_creative_alias('vines:jungle_middle', 'vines:jungle_end') +replacer.alias_map = {} -- don't allow these at all replacer.deny_list = {} @@ -128,3 +141,11 @@ function replacer.register_limit(node_name, node_max) minetest.log('info', rb.log_limit_insert:format(node_name, node_max)) end -- register_limit +function replacer.register_non_creative_alias(name_sibling, name_placed) + if r.alias_map[name_sibling] then + minetest.log('info', rb.log_reg_alias_override:format(name_sibling)) + end + r.alias_map[name_sibling] = name_placed + minetest.log('info', rb.log_reg_alias:format(name_sibling, name_placed)) +end -- register_non_creative_alias + diff --git a/replacer/replacer.lua b/replacer/replacer.lua index a32dc31..70bc4c9 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -552,7 +552,11 @@ function replacer.on_place(itemstack, player, pt) end local inv = player:get_inventory() - if (not (creative_enabled and has_give)) + + if (not creative_enabled) and r.reverse_exception_map[node.name] then + -- apply reverse exception (alias) if not a creatvie user + node.name = r.reverse_exception_map[node.name] + elseif (not (creative_enabled and has_give)) and (not inv:contains_item('main', node.name)) and (not r.exception_map[node.name]) and (not r.is_beacon_beam_or_base(node.name)) @@ -617,9 +621,11 @@ function replacer.on_place(itemstack, player, pt) end end + -- set the params to tool local short_description = r.set_data(itemstack, node, mode) + -- add to history r.history.add_item(player, mode, node, short_description) - + -- inform player about successful setting r.inform(name, rb.set_to:format(short_description)) return itemstack --data changed From 4e0f7e88abe3038e124a483b2c98db2370342176 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 06:00:42 +0100 Subject: [PATCH 168/366] adding first use of alias map --- compat/vines.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/compat/vines.lua b/compat/vines.lua index 87b5e62..d8244ff 100644 --- a/compat/vines.lua +++ b/compat/vines.lua @@ -2,9 +2,12 @@ if not minetest.get_modpath('vines') then return end replacer.group_placeholder['group:vines'] = 'vines:vines' local vines = { 'jungle', 'root', 'side', 'vine', 'willow' } -local node_name +local name_base, name_end, name_middle for _, name in ipairs(vines) do - node_name = 'vines:' .. name .. '_end' - replacer.register_exception(node_name, node_name) + name_base = 'vines:' .. name + name_end = name_base .. '_end' + name_middle = name_base .. '_middle' + replacer.register_exception(name_end, name_end) + replacer.register_non_creative_alias(name_middle, name_end) end From c01aa1dbd6b229ebda59427e83c35210101cab8d Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 06:07:29 +0100 Subject: [PATCH 169/366] oopsa daisy --- replacer/replacer.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 70bc4c9..1fdfa9a 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -553,9 +553,9 @@ function replacer.on_place(itemstack, player, pt) local inv = player:get_inventory() - if (not creative_enabled) and r.reverse_exception_map[node.name] then + if (not creative_enabled) and r.alias_map[node.name] then -- apply reverse exception (alias) if not a creatvie user - node.name = r.reverse_exception_map[node.name] + node.name = r.alias_map[node.name] elseif (not (creative_enabled and has_give)) and (not inv:contains_item('main', node.name)) and (not r.exception_map[node.name]) From abb250805b4a7fe40e632a1b6c80529871d4f5f2 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 06:16:59 +0100 Subject: [PATCH 170/366] adding ropes support --- compat/ropes.lua | 4 ++++ init.lua | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 compat/ropes.lua diff --git a/compat/ropes.lua b/compat/ropes.lua new file mode 100644 index 0000000..6c742b7 --- /dev/null +++ b/compat/ropes.lua @@ -0,0 +1,4 @@ +if not minetest.get_modpath('ropes') then return end + +replacer.register_non_creative_alias('ropes:ropeladder', 'ropes:ropeladder_top') + diff --git a/init.lua b/init.lua index 5510ed9..65a4b9f 100644 --- a/init.lua +++ b/init.lua @@ -66,6 +66,8 @@ dofile(path .. 'compat/mobs.lua') dofile(path .. 'compat/moreblocks.lua') -- RealTest overrides (i) dofile(path .. 'compat/realTest.lua') +-- ropes support (r) +dofile(path .. 'compat/ropes.lua') -- add cable plate exceptions (r) dofile(path .. 'compat/technic.lua') -- unifiedddyes support functions (i+r) From f5decde21bd705c515cfe001fe7ec867b3839a34 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 06:17:21 +0100 Subject: [PATCH 171/366] whitespace --- compat/beacon.lua | 8 ++++---- compat/vines.lua | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compat/beacon.lua b/compat/beacon.lua index 43e3cdb..b888a3d 100644 --- a/compat/beacon.lua +++ b/compat/beacon.lua @@ -1,7 +1,7 @@ function replacer.is_beacon_beam_or_base(node_name) - if 'string' ~= type(node_name) then return nil end - if node_name:match('^beacon:(.*)beam$') then return true end - if node_name:match('^beacon:(.*)base$') then return true end - return false + if 'string' ~= type(node_name) then return nil end + if node_name:match('^beacon:(.*)beam$') then return true end + if node_name:match('^beacon:(.*)base$') then return true end + return false end -- is_beacon_beam_or_base diff --git a/compat/vines.lua b/compat/vines.lua index d8244ff..5b43699 100644 --- a/compat/vines.lua +++ b/compat/vines.lua @@ -4,9 +4,9 @@ replacer.group_placeholder['group:vines'] = 'vines:vines' local vines = { 'jungle', 'root', 'side', 'vine', 'willow' } local name_base, name_end, name_middle for _, name in ipairs(vines) do - name_base = 'vines:' .. name - name_end = name_base .. '_end' - name_middle = name_base .. '_middle' + name_base = 'vines:' .. name + name_end = name_base .. '_end' + name_middle = name_base .. '_middle' replacer.register_exception(name_end, name_end) replacer.register_non_creative_alias(name_middle, name_end) end From 10ce7fdf68a48b466b58385d61edd4e83d12fab5 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 06:50:08 +0100 Subject: [PATCH 172/366] support frozen dirt and dirt with grass since user can craft/freeze them, only makes sense that replacer can place them too --- compat/default.lua | 3 +++ compat/technic.lua | 3 +++ 2 files changed, 6 insertions(+) diff --git a/compat/default.lua b/compat/default.lua index c77bc17..e64e641 100644 --- a/compat/default.lua +++ b/compat/default.lua @@ -44,3 +44,6 @@ if replacer.has_basic_dyes then end end +-- can be crafted, so let it be placed +replacer.register_exception('default:dirt_with_grass', 'default:dirt_with_grass') + diff --git a/compat/technic.lua b/compat/technic.lua index 0069940..1941733 100644 --- a/compat/technic.lua +++ b/compat/technic.lua @@ -15,3 +15,6 @@ for _, sTier in ipairs(lTiers) do end end +-- can be frozen, so let it be placed +replacer.register_exception('default:dirt_with_snow', 'default:dirt_with_snow') + From 7dc00115b6ec5e5ea4e405158b62ad27dacf9ae7 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 07:48:12 +0100 Subject: [PATCH 173/366] biofuel support --- compat/biofuel.lua | 4 ++++ init.lua | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 compat/biofuel.lua diff --git a/compat/biofuel.lua b/compat/biofuel.lua new file mode 100644 index 0000000..a6704a9 --- /dev/null +++ b/compat/biofuel.lua @@ -0,0 +1,4 @@ +if not minetest.get_modpath('biofuel') then return end + +replacer.register_non_creative_alias('biofuel:refinery_active', 'biofuel:refinery') + diff --git a/init.lua b/init.lua index 65a4b9f..4a98be5 100644 --- a/init.lua +++ b/init.lua @@ -58,6 +58,8 @@ dofile(path .. 'utils.lua') dofile(path .. 'compat/bakedclay.lua') -- beacon beam support (r) dofile(path .. 'compat/beacon.lua') +-- biofuel (r) +dofile(path .. 'compat/biofuel.lua') -- default & basic dyes support (i) dofile(path .. 'compat/default.lua') -- cobweb (r) From af4c15701da354715f6d51477a9f96d7a644297c Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 07:50:07 +0100 Subject: [PATCH 174/366] prefab compat --- compat/prefab.lua | 7 +++++++ init.lua | 2 ++ 2 files changed, 9 insertions(+) create mode 100644 compat/prefab.lua diff --git a/compat/prefab.lua b/compat/prefab.lua new file mode 100644 index 0000000..d690816 --- /dev/null +++ b/compat/prefab.lua @@ -0,0 +1,7 @@ +if not minetest.get_modpath('prefab') then return end + +local name = 'prefab:concrete_with_grass' +replacer.register_exception(name, name) +-- not adding the inverted slabs as they can't be rotated +-- anyway, and there are the table-saw slabs too. + diff --git a/init.lua b/init.lua index 4a98be5..7a266c7 100644 --- a/init.lua +++ b/init.lua @@ -66,6 +66,8 @@ dofile(path .. 'compat/default.lua') dofile(path .. 'compat/mobs.lua') -- circular saw support (i+r) dofile(path .. 'compat/moreblocks.lua') +-- prefab (r) +dofile(path .. 'compat/prefab.lua') -- RealTest overrides (i) dofile(path .. 'compat/realTest.lua') -- ropes support (r) From 01a742c87dcf241e15cf7339ee7ce96a63763dde Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 08:20:16 +0100 Subject: [PATCH 175/366] add optional depends beacon is not needed as any mod can add more and we check dynamically during runtime --- mod.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod.conf b/mod.conf index feff229..34e7e70 100644 --- a/mod.conf +++ b/mod.conf @@ -1,5 +1,5 @@ name = replacer description = Replacement tool for creative building and tool to inspect nodes. depends = default -optional_depends = bakedclay, colormachine, dye, moreblocks, technic, unifieddyes +optional_depends = bakedclay, biofuel, colormachine, dye, mobs_monster, moreblocks, prefab, ropes, technic, unifieddyes, vines From 19f56091bece5912737475365ecd08f9fbb65b89 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 08:21:04 +0100 Subject: [PATCH 176/366] add TODO file --- TODO | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 0000000..71d4257 --- /dev/null +++ b/TODO @@ -0,0 +1,21 @@ +-- known incompat replacer ------------------------ +most of the coloured nodes work, just not setting without +at least one in inventory +these should be solve-able with a general lookup similar to what +inspect already does, but return an itemstring for correct +consumption node +-- framed steel obsidian glass tinted +-- new glass +-- unified bricks bricks and clay (coloured) +-- sci-fi plastic coloured +-- stained glass coloured (normal and trap) + +-- telemosaic extenders (coloured) probably will need a compat like beacon beams +-- default clay (baked works) + +-- doors in general (low priority) +-- elphabet:xx (lowest priority) +---------- known incompat inspect ----------- +-- soundblock recipe does not correctly show mesecon wires +-- same for fpga and delayer (works with gates though also eeprom and some others) + From 0fe19e620ee957e0e9b003275006a850e3166144 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 16:15:22 +0100 Subject: [PATCH 177/366] move blabla.lua to mod dir since it's going to have inspection tool strings too --- replacer/blabla.lua => blabla.lua | 0 init.lua | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename replacer/blabla.lua => blabla.lua (100%) diff --git a/replacer/blabla.lua b/blabla.lua similarity index 100% rename from replacer/blabla.lua rename to blabla.lua diff --git a/init.lua b/init.lua index 7a266c7..991a18e 100644 --- a/init.lua +++ b/init.lua @@ -46,8 +46,8 @@ replacer.group_placeholder = {} replacer.image_replacements = {} local path = minetest.get_modpath('replacer') .. '/' --- strings for translation (r) -dofile(path .. 'replacer/blabla.lua') +-- strings for translation (i+r) +dofile(path .. 'blabla.lua') -- more settings and functions dofile(path .. 'replacer/constrain.lua') -- utilities (i+r) From cbc4c9e16b4cef65ea66303d383d6dbf898bea40 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 16:16:46 +0100 Subject: [PATCH 178/366] better description for inspection tool --- inspect.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inspect.lua b/inspect.lua index 82b554d..bce87d4 100644 --- a/inspect.lua +++ b/inspect.lua @@ -5,7 +5,8 @@ -- when placing (rc), info about the node to the side that was clicked is -- presented. Mostly air. minetest.register_tool('replacer:inspect', { - description = 'Node inspection tool', + description = 'Node Inspection Tool\nUse to inspect target node.\n' + .. 'Place to inspect the adjacent node.', groups = {}, inventory_image = 'replacer_inspect.png', wield_image = '', From 49f5db7be7525067e14d2355962dfbdee0879fab Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 18:56:49 +0100 Subject: [PATCH 179/366] prepared inspection tool for translations --- blabla.lua | 39 ++++++++++++ inspect.lua | 171 ++++++++++++++++++++++++++-------------------------- 2 files changed, 126 insertions(+), 84 deletions(-) diff --git a/blabla.lua b/blabla.lua index 0b43a78..f3b052f 100644 --- a/blabla.lua +++ b/blabla.lua @@ -18,7 +18,10 @@ end -- backward compatibility local S = minetest.get_translator('replacer') replacer.blabla = {} +replacer.blabla.inspect = {} local rb = replacer.blabla +local rbi = replacer.blabla.inspect + rb.log_messages = '[replacer] %s: %s' rb.choose_history = S('History') rb.choose_mode = S('Choose mode') @@ -85,3 +88,39 @@ rb.log_reg_alias = '[replacer] registered alias for "%s" to "%s"' rb.formspec_error = '[replacer] formspec error, user "%s" attempting to change history. Fields: %s' rb.formspec_hacker = '[replacer] formspec forge? By user "%s" Fields: %s' +----------------- replacer:inspect ----------------- +rbi.description = S('Inspection Tool\nUse to inspect target node or entity.\n' + .. 'Place to inspect the adjacent node.') +rbi.broken_object = S('This is a broken object. We have no further information about it. It is located') +rbi.this_is_player = S('This is your fellow player "%s"') +rbi.this_is_entity = S('This is an entity "%s"') +rbi.dropped_ago = S(', dropped %s minutes ago') +rbi.owned_protected_locked = S('owned, protected and locked') +rbi.owned_protected = S('owned and protected') +rbi.owned_locked = S('owned and locked') +rbi.by_owner = S('by "%s"') +rbi.with_order_to = S('with order to %s') +rbi.has_x_types = S('Has %s different types of items,') +rbi.total_in_inv = S('total of %s items in inventory.') +rbi.this_is_object_type = S('This is an object "%s"') +rbi.this_is_object = S('This is an object') +rbi.at = S('at %s') +rbi.sorry_no_info = S('Sorry, this is an unkown something of type "%s". No information available.') +rbi.is_protected = S('WARNING: You can\'t dig this node. It is protected.') +rbi.you_can_dig = S('INFO: You can dig this node, but others can\'t.') +rbi.no_desc = S('~ no description provided ~') +rbi.no_node_desc = S('~ no node description provided ~') +rbi.no_item_desc = S('~ no item description provided ~') +rbi.located_at = S('Located at %s') +rbi.with_param2 = S('with param2 of %s') +rbi.and_light = S('and receiving %s light') +rbi.prev = S('prev') +rbi.next = S('next') +rbi.no_recipes = S('No recipes.') +rbi.drops_on_dig = S('Drops on dig:') +rbi.nothing = S('nothing') +rbi.may_drop_on_dig = S('May drop on dig:') +rbi.alternate_x_of_y = S('Alternate %s/%s') +rbi.can_be_fuel = S('This can be used as a fuel.') +rbi.unkown_recipe = S('Error: Unkown recipe.') + diff --git a/inspect.lua b/inspect.lua index bce87d4..8bc5517 100644 --- a/inspect.lua +++ b/inspect.lua @@ -1,12 +1,20 @@ -- a crafting guide wanabe. Better than nothing for servers without -- unified_inventory installed. -- most useful feature is probably light measuring. --- when punching (lc), info about the node that was punched is presented --- when placing (rc), info about the node to the side that was clicked is +-- when using (lc), info about the node that was punched is presented +-- when placing (rc), info about the adjacent node that was clicked is -- presented. Mostly air. + +local r = replacer +local rb = replacer.blabla +local rbi = replacer.blabla.inspect +local nice_pos_string = replacer.nice_pos_string +local floor = math.floor +local chat = minetest.chat_send_player +local mfe = minetest.formspec_escape + minetest.register_tool('replacer:inspect', { - description = 'Node Inspection Tool\nUse to inspect target node.\n' - .. 'Place to inspect the adjacent node.', + description = rbi.description, groups = {}, inventory_image = 'replacer_inspect.png', wield_image = '', @@ -22,7 +30,6 @@ minetest.register_tool('replacer:inspect', { end, }) -local nice_pos_string = replacer.nice_pos_string function replacer.inspect(_, user, pointed_thing, right_clicked) if nil == user or nil == pointed_thing then @@ -33,17 +40,16 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) if 'object' == pointed_thing.type then local inventory_text = nil - local text = 'This is ' + local text = '' local ref = pointed_thing.ref if not ref then - text = text .. 'a broken object. We have no further information ' - .. 'about it. It is located' + text = rbi.broken_object elseif ref:is_player() then - text = text .. 'your fellow player "' .. ref:get_player_name() .. '"' + text = rbi.this_is_player:format(ref:get_player_name()) else local luaob = ref:get_luaentity() if luaob and luaob.get_staticdata then - text = text .. 'an entity "' .. luaob.name .. '"' + text = rbi.this_is_entity:format(luaob.name) local sdata = luaob:get_staticdata() if 0 < #sdata then sdata = minetest.deserialize(sdata) or {} @@ -52,34 +58,32 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) if show_recipe then -- the fields part is used here to provide -- additional information about the entity - replacer.inspect_show_crafting( + r.inspect_show_crafting( name, sdata.itemstring, { luaob = luaob }) end end if sdata.age then - text = text .. ', dropped ' - .. tostring(math.floor(sdata.age / 60)) - .. ' minutes ago' + text = text .. rbi.dropped_ago:format( + tostring(floor((sdata.age / 60) + .5))) end if sdata.owner then - text = text .. ' owned' if true == sdata.protected then if true == sdata.locked then - text = text .. ', protected and locked' + text = text .. ' ' .. rbi.owned_protected_locked else - text = text .. ' and protected' + text = text .. ' ' .. rbi.owned_protected end else if true == sdata.locked then - text = text .. ' and locked' + text = text .. ' ' .. rbi.owned_locked end end - text = text .. ' by ' .. sdata.owner + text = text .. ' ' .. rbi.by_owner:format(sdata.owner) end if 'string' == type(sdata.order) then - text = text .. ' with order to ' .. sdata.order + text = text .. ' ' .. rbi.with_order_to:format(sdata.order) end if 'table' == type(sdata.inv) then local item_count = 0 @@ -89,33 +93,31 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) item_count = item_count + v end if 0 < type_count then - inventory_text = '\nHas ' + inventory_text = '\n' if 1 < type_count then - inventory_text = inventory_text .. type_count - .. ' different types of items, ' + inventory_text = inventory_text + .. rbi.has_x_types:format(tostring(type_count)) .. ' ' end - inventory_text = inventory_text .. 'total of ' - .. item_count .. ' items in inventory.' + inventory_text = inventory_text + .. rbi.total_in_inv:format(tostring(item_count)) end end end elseif luaob then - text = text .. 'an object "' .. luaob.name .. '"' + text = rbi.this_is_object_type:format(luaob.name) else - text = text .. 'an object' + text = rbi.this_is_object end end if ref then - text = text .. ' at ' .. nice_pos_string(ref:getpos()) + text = text .. ' ' .. rbi.at:format(nice_pos_string(ref:getpos())) end if inventory_text then text = text .. inventory_text end - minetest.chat_send_player(name, text) + chat(name, text) return nil elseif 'node' ~= pointed_thing.type then - minetest.chat_send_player(name, 'Sorry, this is an unkown something ' - .. 'of type "' .. pointed_thing.type .. '". ' - .. 'No information available.') + chat(name, rbi.sorry_no_info:format(pointed_thing.type)) return nil end @@ -123,23 +125,22 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) local node = minetest.get_node_or_nil(pos) if not node then - minetest.chat_send_player(name, 'Error: Target node not yet loaded. ' - .. 'Please wait a moment for the server to catch up.') + chat(name, rb.wait_for_load) return nil end local protected_info = '' if minetest.is_protected(pos, name) then - protected_info = 'WARNING: You can\'t dig this node. It is protected.' + protected_info = rbi.is_protected elseif minetest.is_protected(pos, '_THIS_NAME_DOES_NOT_EXIST_') then - protected_info = 'INFO: You can dig this node, but others can\'t.' + protected_info = rbi.you_can_dig end -- get light of the node at the current time local light = minetest.get_node_light(pos, nil) -- the fields part is used here to provide additional -- information about the node - replacer.inspect_show_crafting(name, node.name, { + r.inspect_show_crafting(name, node.name, { pos = pos, param2 = node.param2, light = light, protected_info = protected_info }) @@ -148,11 +149,11 @@ end -- replacer.inspect function replacer.image_button_link(stack_string) local group = '' - if replacer.image_replacements[stack_string] then - stack_string = replacer.image_replacements[stack_string] + if r.image_replacements[stack_string] then + stack_string = r.image_replacements[stack_string] end - if replacer.group_placeholder[stack_string] then - stack_string = replacer.group_placeholder[stack_string] + if r.group_placeholder[stack_string] then + stack_string = r.group_placeholder[stack_string] group = 'G' end -- TODO: show information about other groups not handled above @@ -162,8 +163,8 @@ function replacer.image_button_link(stack_string) end -- image_button_link -replacer.add_circular_saw_recipe = function(node_name, recipes) - local basic_node_name = replacer.is_saw_output(node_name) +function replacer.add_circular_saw_recipe(node_name, recipes) + local basic_node_name = r.is_saw_output(node_name) if not basic_node_name then return end -- node found that fits into the saw @@ -178,7 +179,7 @@ end -- add_circular_saw_recipe function replacer.add_colormachine_recipe(node_name, recipes) - if not replacer.has_colormachine_mod then + if not r.has_colormachine_mod then return end local res = colormachine.get_node_name_painted(node_name, '') @@ -236,9 +237,9 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) -- -- add special recipes for nodes created by machines - replacer.add_circular_saw_recipe(node_name, res) - replacer.add_colormachine_recipe(node_name, res) - replacer.unifieddyes.add_recipe(fields.param2, node_name, res) + r.add_circular_saw_recipe(node_name, res) + r.add_colormachine_recipe(node_name, res) + r.unifieddyes.add_recipe(fields.param2, node_name, res) -- offer all alternate creafting recipes thrugh prev/next buttons if fields and fields.prev_recipe and 1 < recipe_nr then @@ -247,7 +248,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) recipe_nr = recipe_nr + 1 end - local desc = ' - no description provided - ' + local desc = ' ' .. rbi.no_desc .. ' ' if minetest.registered_nodes[node_name] then if minetest.registered_nodes[node_name].description and '' ~= minetest.registered_nodes[node_name].description @@ -256,7 +257,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) elseif minetest.registered_nodes[node_name].name then desc = minetest.registered_nodes[node_name].name else - desc = ' - no node description provided - ' + desc = ' ' .. rbi.no_node_desc .. ' ' end elseif minetest.registered_items[node_name] then if minetest.registered_items[node_name].description @@ -266,15 +267,15 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) elseif minetest.registered_items[node_name].name then desc = minetest.registered_items[node_name].name else - desc = ' - no item description provided - ' + desc = ' ' .. rbi.no_item_desc .. ' ' end end local formspec = 'size[6,6]' .. 'label[0,0;Name: ' .. node_name .. ']' .. 'item_image_button[5,2;1.0,1.0;' .. node_name .. ';normal;]' - .. 'button_exit[5.0,4.3;1,0.5;quit;Exit]' - .. 'label[0,5.5;This is: ' .. minetest.formspec_escape(desc) .. ']' + .. 'button_exit[5.0,4.3;1,0.5;quit;' .. mfe('Exit') .. ']' + .. 'label[0,5.5;This is: ' .. mfe(desc) .. ']' -- invisible field for passing on information .. 'field[20,20;0.1,0.1;node_name;node_name;' .. node_name .. ']' -- another invisible field @@ -284,70 +285,72 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) -- that has been inspected formspec = formspec .. 'label[0.0,0.3;' if fields.pos then - formspec = formspec .. 'Located at ' - .. minetest.formspec_escape(minetest.pos_to_string(fields.pos)) + formspec = formspec .. mfe(rbi.located_at:format(nice_pos_string(fields.pos))) end if fields.param2 then - formspec = formspec .. ' with param2 of ' .. tostring(fields.param2) + formspec = formspec .. ' ' + .. mfe(rbi.with_param2:format(tostring(fields.param2))) end formspec = formspec .. ']' if fields.light then - formspec = formspec .. 'label[0.0,0.6;and receiving ' - .. tostring(fields.light) .. ' light]' + formspec = formspec .. 'label[0.0,0.6;' + .. mfe(rbi.and_light:format(tostring(fields.light))) .. ']' end -- show information about protection if fields.protected_info and '' ~= fields.protected_info then formspec = formspec .. 'label[0.0,4.5;' - .. minetest.formspec_escape(fields.protected_info) .. ']' + .. mfe(fields.protected_info) .. ']' end if #res < recipe_nr or 1 > recipe_nr then recipe_nr = 1 end if 1 < recipe_nr then - formspec = formspec .. 'button[3.8,5;1,0.5;prev_recipe;prev]' + formspec = formspec .. 'button[3.8,5;1,0.5;prev_recipe;' + .. mfe(rbi.prev) .. ']' end if #res > recipe_nr then - formspec = formspec .. 'button[5.0,5.0;1,0.5;next_recipe;next]' + formspec = formspec .. 'button[5.0,5.0;1,0.5;next_recipe;' + .. mfe(rbi.next) .. ']' end if 1 > #res then - formspec = formspec .. 'label[3,1;No recipes.]' + formspec = formspec .. 'label[3,1;' .. mfe(rbi.no_recipes) .. ']' if minetest.registered_nodes[node_name] and minetest.registered_nodes[node_name].drop then local drop = minetest.registered_nodes[node_name].drop if 'string' == type(drop) and drop ~= node_name then - formspec = formspec .. 'label[2,1.6;Drops on dig:' + formspec = formspec .. 'label[2,1.6;' .. mfe(rbi.drops_on_dig) .. ' ' if '' == drop then - formspec = formspec .. 'nothing]' + formspec = formspec .. mfe(rbi.nothing) .. ']' else formspec = formspec .. ']item_image_button[2,2;1.0,1.0;' - .. replacer.image_button_link(drop) .. ']' + .. r.image_button_link(drop) .. ']' end elseif 'table' == type(drop) and drop.items then local droplist = {} for _, drops in ipairs(drop.items) do - for _,item in ipairs(drops.items) do - -- avoid duplicates; but include the item itshelf + for _, item in ipairs(drops.items) do + -- avoid duplicates; but include the item itself droplist[item] = 1 end end local i = 1 - formspec = formspec .. 'label[2,1.6;May drop on dig:]' + formspec = formspec .. 'label[2,1.6;' .. mfe(rbi.may_drop_on_dig) .. ']' for k, v in pairs(droplist) do formspec = formspec .. 'item_image_button[' .. (((i - 1) % 3) + 1) .. ',' - .. tostring(math.floor(((i - 1) / 3) + 2)) - .. ';1.0,1.0;' .. replacer.image_button_link(k) .. ']' + .. tostring(floor(((i - 1) / 3) + 2)) + .. ';1.0,1.0;' .. r.image_button_link(k) .. ']' i = i + 1 end end end else - formspec = formspec .. 'label[1,5;Alternate ' .. tostring(recipe_nr) - .. '/' .. tostring(#res) .. ']' + formspec = formspec .. 'label[1,5;' + .. mfe(rbi.alternate_x_of_y:format(tostring(recipe_nr), tostring(#res))) .. ']' -- reverse order; default recipes (and thus the most intresting ones) -- are usually the oldest local recipe = res[#res + 1 - recipe_nr] @@ -361,9 +364,9 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) if recipe.items[i] then formspec = formspec .. 'item_image_button[' .. (((i - 1) % width) + 1) .. ',' - .. tostring(math.floor((i - 1) / width) + 1) + .. tostring(floor((i - 1) / width) + 1) .. ';1.0,1.0;' - .. replacer.image_button_link(recipe.items[i]) .. ']' + .. r.image_button_link(recipe.items[i]) .. ']' end end elseif 'cooking' == recipe.type @@ -372,37 +375,37 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) and '' == recipe.output then formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' - .. replacer.image_button_link('default:furnace_active') .. ']' + .. r.image_button_link('default:furnace_active') .. ']' .. 'item_image_button[2.9,2.7;1.0,1.0;' - .. replacer.image_button_link(recipe.items[1]) .. ']' + .. r.image_button_link(recipe.items[1]) .. ']' .. 'label[1.0,0;' .. tostring(recipe.items[1]) .. ']' - .. 'label[0,0.5;This can be used as a fuel.' .. ']' + .. 'label[0,0.5;' .. mfe(rbi.can_be_fuel) .. ']' elseif 'cooking' == recipe.type and recipe.items and 1 == #recipe.items then formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' - .. replacer.image_button_link('default:furnace') .. ']' + .. r.image_button_link('default:furnace') .. ']' .. 'item_image_button[2.9,2.7;1.0,1.0;' - .. replacer.image_button_link(recipe.items[1]) .. ']' + .. r.image_button_link(recipe.items[1]) .. ']' elseif 'colormachine' == recipe.type and recipe.items and 1 == #recipe.items then formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' - .. replacer.image_button_link('colormachine:colormachine') .. ']' + .. r.image_button_link('colormachine:colormachine') .. ']' .. 'item_image_button[2,2;1.0,1.0;' - .. replacer.image_button_link(recipe.items[1]) .. ']' + .. r.image_button_link(recipe.items[1]) .. ']' elseif 'saw' == recipe.type and recipe.items and 1 == #recipe.items then formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' - .. replacer.image_button_link('moreblocks:circular_saw') .. ']' + .. r.image_button_link('moreblocks:circular_saw') .. ']' .. 'item_image_button[2,0.6;1.0,1.0;' - .. replacer.image_button_link(recipe.items[1]) .. ']' + .. r.image_button_link(recipe.items[1]) .. ']' else - formspec = formspec .. 'label[3,1;Error: Unkown recipe.]' + formspec = formspec .. 'label[3,1;' .. mfe(rbi.unkown_recipe) .. ']' end -- show how many of the items the recipe will yield local outstack = ItemStack(recipe.output) @@ -420,7 +423,7 @@ function replacer.form_input_handler(player, formname, fields) if formname and 'replacer:crafting' == formname and player and not fields.quit then - replacer.inspect_show_crafting(player:get_player_name(), nil, fields) + r.inspect_show_crafting(player:get_player_name(), nil, fields) return end end From a633b1050c5226d93a0c7da8621cffaa8c3cea62 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 19:29:00 +0100 Subject: [PATCH 180/366] small adjustment to text --- blabla.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blabla.lua b/blabla.lua index f3b052f..30ef71f 100644 --- a/blabla.lua +++ b/blabla.lua @@ -107,7 +107,7 @@ rbi.this_is_object = S('This is an object') rbi.at = S('at %s') rbi.sorry_no_info = S('Sorry, this is an unkown something of type "%s". No information available.') rbi.is_protected = S('WARNING: You can\'t dig this node. It is protected.') -rbi.you_can_dig = S('INFO: You can dig this node, but others can\'t.') +rbi.you_can_dig = S('INFO: You can dig this node, others can\'t.') rbi.no_desc = S('~ no description provided ~') rbi.no_node_desc = S('~ no node description provided ~') rbi.no_item_desc = S('~ no item description provided ~') From 777a9c82b738e01dcc00fbf80eaf6dd7ba8ca383 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 19:32:46 +0100 Subject: [PATCH 181/366] German translation --- locale/replacer.de.tr | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index 03422f0..5e98d1c 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -45,3 +45,38 @@ Valid parameter is either "%s" or "%s"=Gültige Parameter sind entweder „%s“ on=an off=aus +Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Inspektionswerkzeug@nSchlagen zum Inspizieren der Zielnode oder der Entität.@nPlatzieren zum Inspizieren der angrenzenden Node. + +This is a broken object. We have no further information about it. It is located=Dies ist ein kaputtes Objekt. Wir haben keine weiteren Informationen darüber. Es befindet sich +This is your fellow player "%s"=Dies ist dein Mitspieler „%s“ +This is an entity "%s"=Das ist eine Entität „%s“ +, dropped %s minutes ago=, vor %s Minuten gefallen +owned, protected and locked=hat einen Besitzer, ist geschützt und ist gesperrt +owned and protected=hat einen Besitzer und ist geschützt +owned and locked=hat einen Besitzer und ist gesperrt +by "%s"=von „%s“ +with order to %s=mit Befehl zu „%s“ +Has %s different types of items,=Hat %s verschiedene Arten von Gegenständen, +total of %s items in inventory.=insgesamt %s Artikel im Inventar. +This is an object "%s"=Dies ist ein „%s“ Objekt +This is an object=Dies ist ein Objekt +at %s=bei %s +Sorry, this is an unkown something of type "%s". No information available.=Tut mir leid, das ist etwas unbekanntes vom Typ „%s“. Keine Informationen verfügbar. +WARNING: You can't dig this node. It is protected.=WARNUNG: Du kannst diesen Node nicht graben. Es ist geschützt. +INFO: You can dig this node, others can't.=INFO: Du kannst diese Node graben, andere nicht. +~ no description provided ~=~ keine Beschreibung vorhanden ~ +~ no node description provided ~=~ keine Nodebeschreibung vorhanden ~ +~ no item description provided ~=~ keine Artikelbeschreibung vorhanden ~ +Located at %s=Befindet sich bei %s +with param2 of %s=mit param2 von %s +and receiving %s light=und empfängt %s licht +prev=zurück +next=weiter +No recipes.=Keine Rezepte. +Drops on dig:=Lässt fallen beim Graben: +nothing=nichts +May drop on dig:=Kann beim Graben fallen lassen: +Alternate %s/%s=Alternative %s/%s +This can be used as a fuel.=Dies kann als Brennstoff verwendet werden. +Error: Unkown recipe.=Fehler: Unbekanntes Rezept. + From 2196d02daca8d212b2e5375929526ddf39428d86 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 19:50:14 +0100 Subject: [PATCH 182/366] Finnish translation --- locale/replacer.fi.tr | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index 0e5fa37..825fc88 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -45,3 +45,38 @@ Valid parameter is either "%s" or "%s"=Kelvollinen parametri on joko "%s" tai "% on=kyllä off=fora +Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Tarkastustyökalu@nTarkista kohdesolmu tai entiteetti.@nTarkista viereinen solmu. + +This is a broken object. We have no further information about it. It is located=Tämä on rikkinäinen esine. Meillä ei ole asiasta enempää tietoa. Se sijaitsee +This is your fellow player "%s"=Tämä on pelikaverisi "%s" +This is an entity "%s"=Tämä on entiteetti "%s" +, dropped %s minutes ago=, pudonnut %s minuuttia sitten +owned, protected and locked=omistettu, suojattu ja lukittu +owned and protected=omistettu ja suojattu +owned and locked=omistettu ja lukittu +by "%s"=kirjoittaja "%s" +with order to %s=tilauksella %s +Has %s different types of items,=Sisältää %s erityyppistä tuotetta, +total of %s items in inventory.=yhteensä %s tuotetta varastossa. +This is an object "%s"=Tämä on objekti "%s" +This is an object=Tämä on objekti +at %s=osoitteessa %s +Sorry, this is an unkown something of type "%s". No information available.=Anteeksi, tämä on tuntematon asia, jonka tyyppi on "%s". Tietoja ei ole saatavilla. +WARNING: You can't dig this node. It is protected.=VAROITUS: Et voi kaivaa tätä solmua. Se on suojattu. +INFO: You can dig this node, others can't.=INFO: Voit kaivaa tämän solmun, mutta muut eivät. +~ no description provided ~=~ ei kuvausta ~ +~ no node description provided ~=~ solmun kuvausta ei ole annettu ~ +~ no item description provided ~=~ ei tuotekuvausta ~ +Located at %s=Sijaitsee %s +with param2 of %s=param2 %s +and receiving %s light=ja vastaanottaa %s valoa +prev=edellinen +next=seuraava +No recipes.=Ei reseptejä. +Drops on dig:=Pudotukset kaivamaan: +nothing=ei mitään +May drop on dig:=Saattaa pudota kaivamaan: +Alternate %s/%s=Vaihtoehtoinen %s/%s +This can be used as a fuel.=Tätä voidaan käyttää polttoaineena. +Error: Unkown recipe.=Virhe: Tuntematon resepti. + From c0c43f6714e70a9fa27f73906be70b7b969c3a8f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 19:57:37 +0100 Subject: [PATCH 183/366] Russian translation --- locale/replacer.ru.tr | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index db8efff..a05a108 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -45,3 +45,38 @@ Valid parameter is either "%s" or "%s"=Допустимый параметр: "% on=да off=нет +Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Inspection Tool@nИспользуйте для проверки целевого узла или объекта. @nPlace для проверки соседнего узла. + +This is a broken object. We have no further information about it. It is located=Это сломанный объект. У нас нет никакой дополнительной информации об этом. Он расположен. +This is your fellow player "%s"=Это ваш товарищ по игре "%s" +This is an entity "%s"=Это сущность "%s" +, dropped %s minutes ago=, выпало %s минут назад +owned, protected and locked=принадлежит, защищено и заблокировано +owned and protected=в собственности и под защитой +owned and locked=принадлежит и заблокирован +by "%s"=по "%s" +with order to %s=с заказом на "%s" +Has %s different types of items,=Имеет %s различных типов предметов, +total of %s items in inventory.=всего %s предметов в инвентаре. +This is an object "%s"=Это объект "%s" +This is an object=Это объект +at %s=в %s +Sorry, this is an unkown something of type "%s". No information available.=Извините, это неизвестное что-то типа "%s". Информация отсутствует. +WARNING: You can't dig this node. It is protected.=ВНИМАНИЕ: Вы не можете копать этот узел. Он защищен. +INFO: You can dig this node, others can't.=ИНФОРМАЦИЯ: Вы можете копать этот узел, а другие нет. +~ no description provided ~=~ описание не предоставлено ~ +~ no node description provided ~=~ описание узла не предоставлено ~ +~ no item description provided ~=~ описание предмета не предоставлено ~ +Located at %s=Находится по адресу %s +with param2 of %s=с параметром2 из %s +and receiving %s light=и получаю %s свет +prev=предыдущая +next=следующий +No recipes.=Нет рецептов. +Drops on dig:=Выпадает при раскопках: +nothing=ничего +May drop on dig:=Может выпасть при раскопках: +Alternate %s/%s=Альтернативный %s/%s +This can be used as a fuel.=Это можно использовать в качестве топлива. +Error: Unkown recipe.=Ошибка: Неизвестный рецепт. + From 3a24a3673e9f8b3b324701f4c534d3352d705594 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 20:10:47 +0100 Subject: [PATCH 184/366] Portuguese translation --- locale/replacer.pt.tr | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index a1970b2..541c3aa 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -45,3 +45,39 @@ Valid parameter is either "%s" or "%s"=O parâmetro válido é "%s" ou "%s" on=em off=não +Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Ferramenta de Inspeção@nUse para inspecionar o nó ou entidade de destino.@nPlace para inspecionar o nó adjacente. + +This is a broken object. We have no further information about it. It is located=Este é um objeto quebrado. Não temos mais informações a respeito. está localizado +This is your fellow player "%s"=Este é seu colega jogador "%s" +This is an entity "%s"=Esta é uma entidade "%s" +, dropped %s minutes ago=, caiu %s minutos atrás +owned, protected and locked=possuído, protegido e bloqueado +owned and protected=possuído e protegido +owned and locked=possuído e bloqueado +by "%s"=por "%s" +with order to %s=com ordem para %s +Has %s different types of items,=Tem %s tipos diferentes de itens, +total of %s items in inventory.=total de %s itens no inventário. +This is an object "%s"=Este é um objeto "%s" +This is an object=Este é um objeto +at %s=em %s +Sorry, this is an unkown something of type "%s". No information available.=Desculpe, isso é algo desconhecido do tipo "%s". Nenhuma informação disponível. + +WARNING: You can't dig this node. It is protected.=AVISO: você não pode cavar este nó. Está protegido. +INFO: You can dig this node, others can't.=INFO: Você pode cavar este nó, mas outros não podem. +~ no description provided ~=~ nenhuma descrição fornecida ~ +~ no node description provided ~=~ nenhuma descrição do nó fornecida ~ +~ no item description provided ~=~ nenhuma descrição do item fornecida ~ +Located at %s=Localizado em %s +with param2 of %s=com param2 de %s +and receiving %s light=e recebendo %s luz +prev=anterior +next=próximo +No recipes.=Sem receitas. +Drops on dig:=Gotas na escavação: +nothing=nada +May drop on dig:=Pode cair na escavação: +Alternate %s/%s=alternativo %s/%s +This can be used as a fuel.=Isso pode ser usado como combustível. +Error: Unkown recipe.=Erro: receita desconhecida. + From 9d4636b2ac459c486a47e07412e94403e36a310d Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 20:21:33 +0100 Subject: [PATCH 185/366] Italian translation --- locale/replacer.it.tr | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index c154a3c..800a94c 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -45,3 +45,39 @@ Valid parameter is either "%s" or "%s"=Il parametro valido è "%s" o "%s" on=1 off=0 +Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Strumento di ispezione@nUtilizzare per ispezionare il nodo o l'entità di destinazione.@nPosizionare per ispezionare il nodo adiacente. + +This is a broken object. We have no further information about it. It is located=Questo è un oggetto rotto. Non abbiamo ulteriori informazioni a riguardo. Si trova +This is your fellow player "%s"=Questo è il tuo compagno di gioco "%s" +This is an entity "%s"=Questa è un'entità "%s" +, dropped %s minutes ago=, caduto %s minuti fa +owned, protected and locked=posseduto, protetto e bloccato +owned and protected=posseduto e protetto +owned and locked=posseduto e bloccato +by "%s"=per "%s" +with order to %s=con ordine a %s +Has %s different types of items,=Ha %s diversi tipi di elementi, +total of %s items in inventory.=totale di %s articoli nell'inventario. +This is an object "%s"=Questo è un oggetto "%s" +This is an object=Questo è un oggetto +at %s=alle %s +Sorry, this is an unkown something of type "%s". No information available.=Siamo spiacenti, questo è un qualcosa sconosciuto di tipo "%s". Nessuna informazione disponibile. + +WARNING: You can't dig this node. It is protected.=ATTENZIONE: non puoi scavare questo nodo. È protetto. +INFO: You can dig this node, others can't.=INFO: puoi scavare questo nodo, ma altri no. +~ no description provided ~=~ nessuna descrizione fornita ~ +~ no node description provided ~=~ nessuna descrizione del nodo fornita ~ +~ no item description provided ~=~ nessuna descrizione dell'oggetto fornita ~ +Located at %s=Situato a %s +with param2 of %s=con param2 di %s +and receiving %s light=e ricevendo %s luce +prev=precedente +next=successivo +No recipes.=Nessuna ricetta. +Drops on dig:=Gocce allo scavo: +nothing=niente +May drop on dig:=Può cadere durante lo scavo: +Alternate %s/%s=%s/%s= alternativo +This can be used as a fuel.=Questo può essere usato come carburante. +Error: Unkown recipe.=Errore: ricetta sconosciuta. + From 717a5e7febeae759f299dbb41767808b1b482930 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 20:31:29 +0100 Subject: [PATCH 186/366] French translation --- locale/replacer.fr.tr | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index 882faa7..5b10283 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -45,3 +45,39 @@ Valid parameter is either "%s" or "%s"=Le paramètre valide est "%s" ou "%s" on=1 off=0 +Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Outil d'inspection@nUtiliser pour inspecter le nœud ou l'entité cible.@nPlacer pour inspecter le nœud adjacent. + +This is a broken object. We have no further information about it. It is located=Ceci est un objet cassé. Nous n'avons pas d'autres informations à ce sujet. Il est situé +This is your fellow player "%s"=C'est votre coéquipier "%s" +This is an entity "%s"=Ceci est une entité "%s" +, dropped %s minutes ago=, déposé il y a %s minutes +owned, protected and locked=possédé, protégé et verrouillé +owned and protected=possédé et protégé +owned and locked=possédé et verrouillé +by "%s"=par "%s" +with order to %s=avec l'ordre de "%s" +Has %s different types of items,=A %s différents types d'éléments, +total of %s items in inventory.=total de %s articles dans l'inventaire. +This is an object "%s"=Ceci est un objet "%s" +This is an object=Ceci est un objet +at %s=à %s +Sorry, this is an unkown something of type "%s". No information available.=Désolé, c'est quelque chose d'inconnu de type "%s". Aucune information disponible. + +WARNING: You can't dig this node. It is protected.=AVERTISSEMENT: Tu ne peux pas creuser ce nœud. Il est protégé. +INFO: You can dig this node, others can't.=INFO: Tu peux creuser ce nœud, mais les autres ne le peuvent pas. +~ no description provided ~=~ aucune description fournie ~ +~ no node description provided ~=~ aucune description de nœud fournie ~ +~ no item description provided ~=~ aucune description d'article fournie ~ +Located at %s=Situé à %s +with param2 of %s=avec param2 de %s +and receiving %s light=et recevant %s lumière +prev=préc +next=suivant +No recipes.=Aucune recette. +Drops on dig:=Gouttes sur creuser: +nothing=rien +May drop on dig:=Peut tomber en creusant: +Alternate %s/%s=Autre %s/%s +This can be used as a fuel.=Cela peut être utilisé comme carburant. +Error: Unkown recipe.=Erreur : recette inconnue. + From 8db802e8fb952b22524ca47113ad5770f193cdd1 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 20:33:02 +0100 Subject: [PATCH 187/366] put untranslated order in quotes --- locale/replacer.fi.tr | 2 +- locale/replacer.it.tr | 2 +- locale/replacer.pt.tr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index 825fc88..c54fb38 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -55,7 +55,7 @@ owned, protected and locked=omistettu, suojattu ja lukittu owned and protected=omistettu ja suojattu owned and locked=omistettu ja lukittu by "%s"=kirjoittaja "%s" -with order to %s=tilauksella %s +with order to %s=tilauksella "%s" Has %s different types of items,=Sisältää %s erityyppistä tuotetta, total of %s items in inventory.=yhteensä %s tuotetta varastossa. This is an object "%s"=Tämä on objekti "%s" diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index 800a94c..a70de5b 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -55,7 +55,7 @@ owned, protected and locked=posseduto, protetto e bloccato owned and protected=posseduto e protetto owned and locked=posseduto e bloccato by "%s"=per "%s" -with order to %s=con ordine a %s +with order to %s=con ordine a "%s" Has %s different types of items,=Ha %s diversi tipi di elementi, total of %s items in inventory.=totale di %s articoli nell'inventario. This is an object "%s"=Questo è un oggetto "%s" diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index 541c3aa..c95c1e9 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -55,7 +55,7 @@ owned, protected and locked=possuído, protegido e bloqueado owned and protected=possuído e protegido owned and locked=possuído e bloqueado by "%s"=por "%s" -with order to %s=com ordem para %s +with order to %s=com ordem para "%s" Has %s different types of items,=Tem %s tipos diferentes de itens, total of %s items in inventory.=total de %s itens no inventário. This is an object "%s"=Este é um objeto "%s" From d618a97802ca51d666a0775f2bbc21989fae4dff Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 20:51:45 +0100 Subject: [PATCH 188/366] Spanish translation --- locale/replacer.es.tr | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 0fcfc24..466bc74 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -45,3 +45,39 @@ Valid parameter is either "%s" or "%s"=El parámetro válido es "%s" o "%s" on=1 off=0 +Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Herramienta de inspección@nUsar para inspeccionar el nodo o la entidad de destino.@Colocar para inspeccionar el nodo adyacente. + +This is a broken object. We have no further information about it. It is located=Este es un objeto roto. No tenemos más información al respecto. se encuentra +This is your fellow player "%s"=Este es tu compañero de juego "%s" +This is an entity "%s"=Esta es una entidad "%s" +, dropped %s minutes ago=, caído hace %s minutos +owned, protected and locked=propietario, protegido y cerrado +owned and protected=propietario y protegido +owned and locked=propietario y bloqueado +by "%s"=por "%s" +with order to %s=con pedido a "%s" +Has %s different types of items,=Tiene %s tipos diferentes de artículos, +total of %s items in inventory.=total de %s artículos en inventario. +This is an object "%s"=Este es un objeto "%s" +This is an object=Este es un objeto +at %s=en %s +Sorry, this is an unkown something of type "%s". No information available.=Lo sentimos, esto es algo desconocido de tipo "%s". No hay información disponible. + +WARNING: You can't dig this node. It is protected.=ADVERTENCIA: No puedes excavar este nodo. Está protegido. +INFO: You can dig this node, others can't.=INFO: Puedes excavar este nodo, pero otros no. +~ no description provided ~=~ no se proporciona descripción ~ +~ no node description provided ~=~ no se proporcionó una descripción del nodo ~ +~ no item description provided ~=~ no se proporciona descripción del artículo ~ +Located at %s=Ubicado en %s +with param2 of %s=con param2 de %s +and receiving %s light=y recibiendo %s luz +prev=anterior +next=siguiente +No recipes.=Sin recetas. +Drops on dig:=Cae en excavación: +nothing=nada +May drop on dig:=Puede caer en excavación: +Alternate %s/%s=alternativo %s/%s +This can be used as a fuel.=Esto se puede usar como combustible. +Error: Unkown recipe.=Error: Receta desconocida. + From c8e1326c6a95f1959098f483f009e7aa9d3b4914 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 20:52:05 +0100 Subject: [PATCH 189/366] updated locale template --- locale/template.txt | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/locale/template.txt b/locale/template.txt index 5f0a32b..a876668 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -44,3 +44,38 @@ Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is Valid parameter is either "%s" or "%s"= on= off= + +Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.= + +This is a broken object. We have no further information about it. It is located= +This is your fellow player "%s"= +This is an entity "%s"= +, dropped %s minutes ago= +owned, protected and locked= +owned and protected= +owned and locked= +by "%s"= +with order to %s= +Has %s different types of items,= +total of %s items in inventory.= +This is an object "%s"= +This is an object= +at %s= +Sorry, this is an unkown something of type "%s". No information available.= +WARNING: You can't dig this node. It is protected.= +INFO: You can dig this node, others can't.= +~ no description provided ~= +~ no node description provided ~= +~ no item description provided ~= +Located at %s= +with param2 of %s= +and receiving %s light= +prev= +next= +No recipes.= +Drops on dig:= +nothing= +May drop on dig:= +Alternate %s/%s= +This can be used as a fuel.= +Error: Unkown recipe.= From 11ee69dd75249ba1343be5377f87d2f400f2cb15 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 21:35:47 +0100 Subject: [PATCH 190/366] fix out of bounds error --- locale/replacer.es.tr | 1 + 1 file changed, 1 insertion(+) diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 466bc74..dfda4b1 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -80,4 +80,5 @@ May drop on dig:=Puede caer en excavación: Alternate %s/%s=alternativo %s/%s This can be used as a fuel.=Esto se puede usar como combustible. Error: Unkown recipe.=Error: Receta desconocida. +Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Herramienta de inspección@nUsar para inspeccionar el nodo o la entidad de destino.@nColocar para inspeccionar el nodo adyacente. From e7788a786c6f98421218f984236b8af1259656ea Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 21:36:37 +0100 Subject: [PATCH 191/366] shorten next/prev to fit in button still needs doing in ru and fi Signed-off-by: Luke aka SwissalpS --- locale/replacer.es.tr | 4 ++-- locale/replacer.fr.tr | 2 +- locale/replacer.it.tr | 4 ++-- locale/replacer.pt.tr | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index dfda4b1..bae7c24 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -71,8 +71,8 @@ INFO: You can dig this node, others can't.=INFO: Puedes excavar este nodo, pero Located at %s=Ubicado en %s with param2 of %s=con param2 de %s and receiving %s light=y recibiendo %s luz -prev=anterior -next=siguiente +prev=ant. +next=sig. No recipes.=Sin recetas. Drops on dig:=Cae en excavación: nothing=nada diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index 5b10283..18d4966 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -72,7 +72,7 @@ Located at %s=Situé à %s with param2 of %s=avec param2 de %s and receiving %s light=et recevant %s lumière prev=préc -next=suivant +next=suiv. No recipes.=Aucune recette. Drops on dig:=Gouttes sur creuser: nothing=rien diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index a70de5b..f30cd20 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -71,8 +71,8 @@ INFO: You can dig this node, others can't.=INFO: puoi scavare questo nodo, ma al Located at %s=Situato a %s with param2 of %s=con param2 di %s and receiving %s light=e ricevendo %s luce -prev=precedente -next=successivo +prev=pre. +next=suc. No recipes.=Nessuna ricetta. Drops on dig:=Gocce allo scavo: nothing=niente diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index c95c1e9..7b75923 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -71,8 +71,8 @@ INFO: You can dig this node, others can't.=INFO: Você pode cavar este nó, mas Located at %s=Localizado em %s with param2 of %s=com param2 de %s and receiving %s light=e recebendo %s luz -prev=anterior -next=próximo +prev=ant. +next=pró. No recipes.=Sem receitas. Drops on dig:=Gotas na escavação: nothing=nada From 16be1e0d73db9771a2eb0bd35774b7d7dad07b6a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 20 Jan 2022 23:38:04 +0100 Subject: [PATCH 192/366] bugfix es --- locale/replacer.es.tr | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index bae7c24..5f53016 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -45,7 +45,7 @@ Valid parameter is either "%s" or "%s"=El parámetro válido es "%s" o "%s" on=1 off=0 -Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Herramienta de inspección@nUsar para inspeccionar el nodo o la entidad de destino.@Colocar para inspeccionar el nodo adyacente. +Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Herramienta de inspección@nUsar para inspeccionar el nodo o la entidad de destino.@nColocar para inspeccionar el nodo adyacente. This is a broken object. We have no further information about it. It is located=Este es un objeto roto. No tenemos más información al respecto. se encuentra This is your fellow player "%s"=Este es tu compañero de juego "%s" @@ -80,5 +80,4 @@ May drop on dig:=Puede caer en excavación: Alternate %s/%s=alternativo %s/%s This can be used as a fuel.=Esto se puede usar como combustible. Error: Unkown recipe.=Error: Receta desconocida. -Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Herramienta de inspección@nUsar para inspeccionar el nodo o la entidad de destino.@nColocar para inspeccionar el nodo adyacente. From 500c4e6387446d2b2a8b9017813df850ba448f34 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 21 Jan 2022 01:23:55 +0100 Subject: [PATCH 193/366] language overhaul --- blabla.lua | 36 ++++-------------------- chat_commands.lua | 3 +- inspect.lua | 42 +++++++++++++++------------- locale/replacer.de.tr | 61 +++++++++++++++++++++-------------------- locale/replacer.es.tr | 62 +++++++++++++++++++++--------------------- locale/replacer.fi.tr | 61 +++++++++++++++++++++-------------------- locale/replacer.fr.tr | 62 +++++++++++++++++++++--------------------- locale/replacer.it.tr | 62 +++++++++++++++++++++--------------------- locale/replacer.pt.tr | 62 +++++++++++++++++++++--------------------- locale/replacer.ru.tr | 61 +++++++++++++++++++++-------------------- locale/template.txt | 60 ++++++++++++++++++++-------------------- replacer/constrain.lua | 3 +- replacer/replacer.lua | 29 +++++++++++--------- 13 files changed, 296 insertions(+), 308 deletions(-) diff --git a/blabla.lua b/blabla.lua index 30ef71f..e300570 100644 --- a/blabla.lua +++ b/blabla.lua @@ -15,7 +15,8 @@ if not minetest.translate then return function(str, ...) return core.translate(textdomain or '', str, ...) end end end -- backward compatibility -local S = minetest.get_translator('replacer') +replacer.S = minetest.get_translator('replacer') +local S = replacer.S replacer.blabla = {} replacer.blabla.inspect = {} @@ -41,27 +42,12 @@ rb.mode_field_tooltip = S('Left click: Replace field of nodes of a kind where a rb.mode_crust_tooltip = S('Left click: Replace nodes which touch another one of ' .. 'its kind and a translucent node, e.g. air.@nRight click: Replace air nodes ' .. 'which touch the crust.') -rb.protected_at = S('Protected at %s') -rb.deny_listed = S('Replacing nodes of type "%s" is not allowed on this server. ' - .. 'Replacement failed.') -rb.run_out = S('You have no further "%s". Replacement failed.') -rb.attempt_unknown_replace = S('Unknown node: "%s"') -rb.attempt_unknown_place = S('Unknown node to place: "%s"') -rb.can_not_dig = S('Could not dig "%s" properly.') -rb.can_not_place = S('Could not place "%s".') -rb.not_a_node = S('Error: "%s" is not a node.') rb.wait_for_load = S('Target node not yet loaded. Please wait a moment for the ' .. 'server to catch up.') rb.nothing_to_replace = S('Nothing to replace.') rb.need_more_charge = S('Not enough charge to use this mode.') rb.too_many_nodes_detected = S('Aborted, too many nodes detected.') -rb.charge_required = S('Need %s charge to replace %s nodes.') -rb.count_replaced = S('%s nodes replaced.') -rb.mode_changed = S('Mode changed to %s: %s') rb.none_selected = S('Error: No node selected.') -rb.not_in_creative = S('Item not in creative inventory: "%s".') -rb.not_in_inventory = S('Item not in your inventory: "%s".') -rb.set_to = S('Node replacement tool set to:\n%s.') rb.description_basic = S('Node replacement tool') rb.description_technic = S('Node replacement tool (technic)') rb.log_limit_override = '[replacer] Setting already set node-limit for "%s" was %d.' @@ -75,7 +61,6 @@ rb.ccm_description = S('Toggles verbosity.\nWhen on, ' .. 'messages are posted to chat. When off, replacer is silent.') rb.ccm_player_not_found = 'Player not found' rb.ccm_player_meta_error = 'Player meta not existant' -rb.ccm_hint = S('Valid parameter is either "%s" or "%s"') rb.on_yes = S('on') rb.off_no = S('off') rb.log_reg_exception_override = '[replacer] register_exception: ' @@ -92,35 +77,24 @@ rb.formspec_hacker = '[replacer] formspec forge? By user "%s" Fields: %s' rbi.description = S('Inspection Tool\nUse to inspect target node or entity.\n' .. 'Place to inspect the adjacent node.') rbi.broken_object = S('This is a broken object. We have no further information about it. It is located') -rbi.this_is_player = S('This is your fellow player "%s"') -rbi.this_is_entity = S('This is an entity "%s"') -rbi.dropped_ago = S(', dropped %s minutes ago') rbi.owned_protected_locked = S('owned, protected and locked') rbi.owned_protected = S('owned and protected') rbi.owned_locked = S('owned and locked') -rbi.by_owner = S('by "%s"') -rbi.with_order_to = S('with order to %s') -rbi.has_x_types = S('Has %s different types of items,') -rbi.total_in_inv = S('total of %s items in inventory.') -rbi.this_is_object_type = S('This is an object "%s"') rbi.this_is_object = S('This is an object') -rbi.at = S('at %s') -rbi.sorry_no_info = S('Sorry, this is an unkown something of type "%s". No information available.') rbi.is_protected = S('WARNING: You can\'t dig this node. It is protected.') rbi.you_can_dig = S('INFO: You can dig this node, others can\'t.') rbi.no_desc = S('~ no description provided ~') rbi.no_node_desc = S('~ no node description provided ~') rbi.no_item_desc = S('~ no item description provided ~') -rbi.located_at = S('Located at %s') -rbi.with_param2 = S('with param2 of %s') -rbi.and_light = S('and receiving %s light') +rbi.name = S('Name:') +rbi.exit = S('Exit') +rbi.this_is = S('This is:') rbi.prev = S('prev') rbi.next = S('next') rbi.no_recipes = S('No recipes.') rbi.drops_on_dig = S('Drops on dig:') rbi.nothing = S('nothing') rbi.may_drop_on_dig = S('May drop on dig:') -rbi.alternate_x_of_y = S('Alternate %s/%s') rbi.can_be_fuel = S('This can be used as a fuel.') rbi.unkown_recipe = S('Error: Unkown recipe.') diff --git a/chat_commands.lua b/chat_commands.lua index 1c9a8c4..8355b35 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -1,5 +1,6 @@ local rb = replacer.blabla +local S = replacer.S -- let's hope there isn't a yes that means no in another language :/ -- TODO: better option would be to simply toggle (see postool) @@ -29,7 +30,7 @@ replacer.chatcommand_mute = { elseif tOn[lower] then meta:set_int('replacer_mute', 0) else - return false, rb.ccm_hint:format(rb.on_yes, rb.off_no) + return false, S('Valid parameter is either "@1" or "@2"', rb.on_yes, rb.off_no) end return true, '' diff --git a/inspect.lua b/inspect.lua index 8bc5517..5174308 100644 --- a/inspect.lua +++ b/inspect.lua @@ -9,6 +9,7 @@ local r = replacer local rb = replacer.blabla local rbi = replacer.blabla.inspect local nice_pos_string = replacer.nice_pos_string +local S = replacer.S local floor = math.floor local chat = minetest.chat_send_player local mfe = minetest.formspec_escape @@ -45,11 +46,11 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) if not ref then text = rbi.broken_object elseif ref:is_player() then - text = rbi.this_is_player:format(ref:get_player_name()) + text = S('This is your fellow player "@1"', ref:get_player_name()) else local luaob = ref:get_luaentity() if luaob and luaob.get_staticdata then - text = rbi.this_is_entity:format(luaob.name) + text = S('This is an entity "@1"', luaob.name) local sdata = luaob:get_staticdata() if 0 < #sdata then sdata = minetest.deserialize(sdata) or {} @@ -65,7 +66,7 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) end end if sdata.age then - text = text .. rbi.dropped_ago:format( + text = text .. S(', dropped @1 minutes ago', tostring(floor((sdata.age / 60) + .5))) end if sdata.owner then @@ -80,10 +81,10 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) text = text .. ' ' .. rbi.owned_locked end end - text = text .. ' ' .. rbi.by_owner:format(sdata.owner) + text = text .. ' ' .. S('by "@1"', sdata.owner) end if 'string' == type(sdata.order) then - text = text .. ' ' .. rbi.with_order_to:format(sdata.order) + text = text .. ' ' .. S('with order to @1', sdata.order) end if 'table' == type(sdata.inv) then local item_count = 0 @@ -96,28 +97,31 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) inventory_text = '\n' if 1 < type_count then inventory_text = inventory_text - .. rbi.has_x_types:format(tostring(type_count)) .. ' ' + .. S('Has @1 different types of items,', + tostring(type_count)) .. ' ' end inventory_text = inventory_text - .. rbi.total_in_inv:format(tostring(item_count)) + .. S('total of @1 items in inventory.', + tostring(item_count)) end end end elseif luaob then - text = rbi.this_is_object_type:format(luaob.name) + text = S('This is an object "@1"', luaob.name) else text = rbi.this_is_object end end if ref then - text = text .. ' ' .. rbi.at:format(nice_pos_string(ref:getpos())) + text = text .. ' ' .. S('at @1', nice_pos_string(ref:getpos())) end if inventory_text then text = text .. inventory_text end chat(name, text) return nil elseif 'node' ~= pointed_thing.type then - chat(name, rbi.sorry_no_info:format(pointed_thing.type)) + chat(name, S('Sorry, this is an unkown something of type "@1". ' + .. 'No information available.', pointed_thing.type)) return nil end @@ -272,10 +276,10 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) end local formspec = 'size[6,6]' - .. 'label[0,0;Name: ' .. node_name .. ']' + .. 'label[0,0;' .. mfe(rbi.name) .. ' ' .. node_name .. ']' .. 'item_image_button[5,2;1.0,1.0;' .. node_name .. ';normal;]' - .. 'button_exit[5.0,4.3;1,0.5;quit;' .. mfe('Exit') .. ']' - .. 'label[0,5.5;This is: ' .. mfe(desc) .. ']' + .. 'button_exit[5.0,4.3;1,0.5;quit;' .. mfe(rbi.exit) .. ']' + .. 'label[0,5.5;' .. mfe(rbi.this_is) .. ' ' .. mfe(desc) .. ']' -- invisible field for passing on information .. 'field[20,20;0.1,0.1;node_name;node_name;' .. node_name .. ']' -- another invisible field @@ -285,16 +289,16 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) -- that has been inspected formspec = formspec .. 'label[0.0,0.3;' if fields.pos then - formspec = formspec .. mfe(rbi.located_at:format(nice_pos_string(fields.pos))) + formspec = formspec .. mfe(S('Located at @1', nice_pos_string(fields.pos))) end if fields.param2 then formspec = formspec .. ' ' - .. mfe(rbi.with_param2:format(tostring(fields.param2))) + .. mfe(S('with param2 of @1', tostring(fields.param2))) end formspec = formspec .. ']' if fields.light then formspec = formspec .. 'label[0.0,0.6;' - .. mfe(rbi.and_light:format(tostring(fields.light))) .. ']' + .. mfe(S('and receiving @1 light', tostring(fields.light))) .. ']' end -- show information about protection @@ -307,11 +311,11 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) recipe_nr = 1 end if 1 < recipe_nr then - formspec = formspec .. 'button[3.8,5;1,0.5;prev_recipe;' + formspec = formspec .. 'button[3.8,5;1,0.75;prev_recipe;' .. mfe(rbi.prev) .. ']' end if #res > recipe_nr then - formspec = formspec .. 'button[5.0,5.0;1,0.5;next_recipe;' + formspec = formspec .. 'button[5.0,5.0;1,0.75;next_recipe;' .. mfe(rbi.next) .. ']' end if 1 > #res then @@ -350,7 +354,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) end else formspec = formspec .. 'label[1,5;' - .. mfe(rbi.alternate_x_of_y:format(tostring(recipe_nr), tostring(#res))) .. ']' + .. mfe(S('Alternate @1/@2', tostring(recipe_nr), tostring(#res))) .. ']' -- reverse order; default recipes (and thus the most intresting ones) -- are usually the oldest local recipe = res[#res + 1 - recipe_nr] diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index 5e98d1c..712ac32 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -16,67 +16,68 @@ Left click: Replace field of nodes of a kind where a translucent node is in fron Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Links Klick: Ersetzt benachbarte, gleichartige Node welche gleichzeitig durchsichtige (nicht feste) Node berühren.@@Rechts Klick: Ersetzt Luft an der Kruste. -Protected at %s=Geschützt bei %s -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=Node des Typs „%s“ dürfen auf diesem Server nicht ersetzt werden. Versuch fehlgeschlagen. -You have no further "%s". Replacement failed.=Du hast keine weitere „%s“. Ersetzung fehlgeschlagen. -Unknown node: "%s"=Unbekannter Node: „%s“ -Unknown node to place: "%s"=Unbekant zu setzender Node: „%s“ -Could not dig "%s" properly.=Kann „%s“ nicht richtig graben. -Could not place "%s".=Konnte „%s“ nicht platzieren. -Error: "%s" is not a node.=Fehler: „%s“ ist kein Node. Target node not yet loaded. Please wait a moment for the server to catch up.=Zielnode is noch nicht geladen. Bitte warte einen Moment damit der Server aufholen kann. Nothing to replace.=Nichts zu ersetzen. Not enough charge to use this mode.=Nicht genug Ladung, um diesen Modus zu verwenden. Aborted, too many nodes detected.=Abgebrochen, zu viele Knoten gefunden. -Need %s charge to replace %s nodes.=Es wird eine Ladung von %s benötigt um %s Node auszutauschen. -%s nodes replaced.=%s Node ersetzt. -Mode changed to %s: %s=Modus gewechselt auf: %s Error: No node selected.=Fehler: Kein Knoten ausgwählt. -Item not in creative inventory: "%s".=Artikel befindet sich nicht im Kreativ-Inventar: „%s“. -Item not in your inventory: "%s".=Artikel befindet sich nicht in deinem Inventar: „%s“. -Node replacement tool set to:@n%s.=Ersetzer konfiguriert auf:@n%s. Node replacement tool=Ersetzer Node replacement tool (technic)=Ersetzer (Technik) Time-limit reached.=Zeitbegrenzung erreicht. Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Schaltet die Ausführlichkeit um.@nWenn diese Option aktiviert ist, werden Nachrichten im Chat ausgegeben. Im ausgeschalteten Zustand ist der Ersetzer stumm. -Valid parameter is either "%s" or "%s"=Gültige Parameter sind entweder „%s“ oder „%s“. on=an off=aus Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Inspektionswerkzeug@nSchlagen zum Inspizieren der Zielnode oder der Entität.@nPlatzieren zum Inspizieren der angrenzenden Node. This is a broken object. We have no further information about it. It is located=Dies ist ein kaputtes Objekt. Wir haben keine weiteren Informationen darüber. Es befindet sich -This is your fellow player "%s"=Dies ist dein Mitspieler „%s“ -This is an entity "%s"=Das ist eine Entität „%s“ -, dropped %s minutes ago=, vor %s Minuten gefallen owned, protected and locked=hat einen Besitzer, ist geschützt und ist gesperrt owned and protected=hat einen Besitzer und ist geschützt owned and locked=hat einen Besitzer und ist gesperrt -by "%s"=von „%s“ -with order to %s=mit Befehl zu „%s“ -Has %s different types of items,=Hat %s verschiedene Arten von Gegenständen, -total of %s items in inventory.=insgesamt %s Artikel im Inventar. -This is an object "%s"=Dies ist ein „%s“ Objekt This is an object=Dies ist ein Objekt -at %s=bei %s -Sorry, this is an unkown something of type "%s". No information available.=Tut mir leid, das ist etwas unbekanntes vom Typ „%s“. Keine Informationen verfügbar. WARNING: You can't dig this node. It is protected.=WARNUNG: Du kannst diesen Node nicht graben. Es ist geschützt. INFO: You can dig this node, others can't.=INFO: Du kannst diese Node graben, andere nicht. ~ no description provided ~=~ keine Beschreibung vorhanden ~ ~ no node description provided ~=~ keine Nodebeschreibung vorhanden ~ ~ no item description provided ~=~ keine Artikelbeschreibung vorhanden ~ -Located at %s=Befindet sich bei %s -with param2 of %s=mit param2 von %s -and receiving %s light=und empfängt %s licht +Name:=Name: +Exit=Schliessen +This is:=Dies ist: prev=zurück next=weiter No recipes.=Keine Rezepte. Drops on dig:=Lässt fallen beim Graben: nothing=nichts May drop on dig:=Kann beim Graben fallen lassen: -Alternate %s/%s=Alternative %s/%s This can be used as a fuel.=Dies kann als Brennstoff verwendet werden. Error: Unkown recipe.=Fehler: Unbekanntes Rezept. - +Valid parameter is either "@1" or "@2"=Gültige Parameter sind entweder „@1“ oder „@2“. +Protected at @1=Geschützt bei @1 +This is your fellow player "@1"=Dies ist dein Mitspieler „@1“ +This is an entity "@1"=Das ist eine Entität „@1“ +, dropped @1 minutes ago=, vor @1 Minuten gefallen +by "@1"=von „@1“ +with order to @1=mit Befehl zu „@1“ +Has @1 different types of items,=Hat %s verschiedene Arten von Gegenständen, +total of @1 items in inventory.=insgesamt @1 Artikel im Inventar. +This is an object "@1"=Dies ist ein „@1“ Objekt +at @1=bei @1 +Sorry, this is an unkown something of type "@1". No information available.=Tut mir leid, das ist etwas unbekanntes vom Typ „@1“. Keine Informationen verfügbar. +Located at @1=Befindet sich bei @1 +with param2 of @1=mit param2 von @1 +and receiving @1 light=und empfängt @1 licht +Alternate @1/@2=Alternative @1/@2 +You have no further "@1". Replacement failed.=Du hast keine weitere „@1“. Ersetzung fehlgeschlagen. +Unknown node: "@1"=Unbekannter Node: „@1“ +Unknown node to place: "@1"=Unbekant zu setzender Node: „@1“ +Could not dig "@1" properly.=Kann „@1“ nicht richtig graben. +Could not place "@1".=Konnte „@1“ nicht platzieren. +Error: "@1" is not a node.=Fehler: „@1“ ist kein Node. +@1 nodes replaced.=@1 Node ersetzt. +Mode changed to @1: @2=Modus gewechselt auf @1: @2 +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Node des Typs „@1“ dürfen auf diesem Server nicht ersetzt werden. Versuch fehlgeschlagen. +Item not in creative inventory: "@1".=Artikel befindet sich nicht im Kreativ-Inventar: „@1“. +Item not in your inventory: "@1".=Artikel befindet sich nicht in deinem Inventar: „@1“. +Node replacement tool set to:@n@1.=Ersetzer konfiguriert auf:@n@1. diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 5f53016..531c302 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -16,68 +16,68 @@ Left click: Replace field of nodes of a kind where a translucent node is in fron Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Clic izquierdo: reemplaza los nodos que tocan otro de su tipo y un nodo translúcido, p. aire.@@Clic derecho: Reemplazar los nodos de aire que tocan la corteza. -Protected at %s=Protegido en %s -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=No se permite reemplazar nodos de tipo "%s" en este servidor. Reemplazo fallido. -You have no further "%s". Replacement failed.=No tienes más "%s". Reemplazo fallido. -Unknown node: "%s"=Nodo desconocido: "%s" -Unknown node to place: "%s"=Nodo desconocido a colocar: "%s" -Could not dig "%s" properly.=No se pudo excavar "%s" correctamente. -Could not place "%s".=No se pudo colocar "%s". -Error: "%s" is not a node.=Error: "%s" no es un nodo. Target node not yet loaded. Please wait a moment for the server to catch up.=Nodo de destino aún no cargado. Espere un momento a que el servidor se ponga al día. Nothing to replace.=Nada para reemplazar. Not enough charge to use this mode.=No hay suficiente carga para usar este modo. Aborted, too many nodes detected.=Anulado, demasiados nodos detectados. -Need %s charge to replace %s nodes.=Necesita %s carga para reemplazar %s nodos. -%s nodes replaced.=%s nodos reemplazados. -Mode changed to %s: %s=Modo cambiado a %s: %s Error: No node selected.=Error: No se seleccionó ningún nodo. -Item not in creative inventory: "%s".=Artículo no está en el inventario creativo: "%s". -Item not in your inventory: "%s".=Artículo no está en su inventario: "%s". -Node replacement tool set to:@n%s.=Intercambiador establecida en:@n%s. Node replacement tool=Intercambiador Node replacement tool (technic)=Intercambiador (técnica) Time-limit reached.=Límite de tiempo alcanzado. Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Alterna verbosidad.@nCuando está activado, los mensajes se publican en el chat. Cuando está apagado, el intercambiador está en silencio. -Valid parameter is either "%s" or "%s"=El parámetro válido es "%s" o "%s" on=1 off=0 Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Herramienta de inspección@nUsar para inspeccionar el nodo o la entidad de destino.@nColocar para inspeccionar el nodo adyacente. This is a broken object. We have no further information about it. It is located=Este es un objeto roto. No tenemos más información al respecto. se encuentra -This is your fellow player "%s"=Este es tu compañero de juego "%s" -This is an entity "%s"=Esta es una entidad "%s" -, dropped %s minutes ago=, caído hace %s minutos owned, protected and locked=propietario, protegido y cerrado owned and protected=propietario y protegido owned and locked=propietario y bloqueado -by "%s"=por "%s" -with order to %s=con pedido a "%s" -Has %s different types of items,=Tiene %s tipos diferentes de artículos, -total of %s items in inventory.=total de %s artículos en inventario. -This is an object "%s"=Este es un objeto "%s" This is an object=Este es un objeto -at %s=en %s -Sorry, this is an unkown something of type "%s". No information available.=Lo sentimos, esto es algo desconocido de tipo "%s". No hay información disponible. - WARNING: You can't dig this node. It is protected.=ADVERTENCIA: No puedes excavar este nodo. Está protegido. INFO: You can dig this node, others can't.=INFO: Puedes excavar este nodo, pero otros no. ~ no description provided ~=~ no se proporciona descripción ~ ~ no node description provided ~=~ no se proporcionó una descripción del nodo ~ ~ no item description provided ~=~ no se proporciona descripción del artículo ~ -Located at %s=Ubicado en %s -with param2 of %s=con param2 de %s -and receiving %s light=y recibiendo %s luz +Name:=Nombre: +Exit=Salir +This is:=Esto es: prev=ant. next=sig. No recipes.=Sin recetas. Drops on dig:=Cae en excavación: nothing=nada May drop on dig:=Puede caer en excavación: -Alternate %s/%s=alternativo %s/%s This can be used as a fuel.=Esto se puede usar como combustible. Error: Unkown recipe.=Error: Receta desconocida. - +Valid parameter is either "@1" or "@2"=El parámetro válido es "@1" o "@2" +Protected at @1=Protegido en @1 +This is your fellow player "@1"=Este es tu compañero de juego "@1" +This is an entity "@1"=Esta es una entidad "@1" +, dropped @1 minutes ago=, caído hace @1 minutos +by "@1"=por "@1" +with order to @1=con pedido a "@1" +Has @1 different types of items,=Tiene @1 tipos diferentes de artículos, +total of @1 items in inventory.=total de @1 artículos en inventario. +This is an object "@1"=Este es un objeto "@1" +at @1=en @1 +Sorry, this is an unkown something of type "@1". No information available.=Lo sentimos, esto es algo desconocido de tipo "%s". No hay información disponible. +Located at @1=Ubicado en @1 +with param2 of @1=con param2 de @1 +and receiving @1 light=y recibiendo @1 luz +Alternate @1/@2=Alternativo @1/@2 +You have no further "@1". Replacement failed.=No tienes más "@1". Reemplazo fallido. +Unknown node: "@1"=Nodo desconocido: "@1" +Unknown node to place: "@1"=Nodo desconocido a colocar: "@1" +Could not dig "@1" properly.=No se pudo excavar "@1" correctamente. +Could not place "@1".=No se pudo colocar "@1". +Error: "@1" is not a node.=Error: "@1" no es un nodo. +@1 nodes replaced.=@1 nodos reemplazados. +Mode changed to @1: @2=Modo cambiado a @1: @2 +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=No se permite reemplazar nodos de tipo "@1" en este servidor. Reemplazo fallido. +Item not in creative inventory: "@1".=Artículo no está en el inventario creativo: "@1". +Item not in your inventory: "@1".=Artículo no está en su inventario: "@1". +Node replacement tool set to:@n@1.=Intercambiador establecida en:@n@1. diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index c54fb38..14a6866 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -16,67 +16,68 @@ Left click: Replace field of nodes of a kind where a translucent node is in fron Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Vasen napsautus: Vaihda solmut, jotka koskettavat toista laatuaan ja läpikuultavaa solmua, esim. air.@@Kakkosnapsautus: Vaihda kuorta koskettavat ilmasolmut. -Protected at %s=Suojattu %s -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=Tyypin "%s" solmujen korvaaminen ei ole sallittua tässä palvelimessa. Vaihto epäonnistui. -You have no further "%s". Replacement failed.=Sinulla ei ole enempää "%s". Vaihto epäonnistui. -Unknown node: "%s"=Tuntematon solmu: "%s" -Unknown node to place: "%s"=Tuntematon sijoitettava solmu: "%s" -Could not dig "%s" properly.=Ei voitu kaivaa "%s" oikein. -Could not place "%s".=Ei voitu sijoittaa "%s". -Error: "%s" is not a node.=Virhe: "%s" ei ole solmu. Target node not yet loaded. Please wait a moment for the server to catch up.=Kohdesolmua ei ole vielä ladattu. Odota hetki, että palvelin ottaa kiinni. Nothing to replace.=Ei mitään korvattavaa. Not enough charge to use this mode.=Lataus ei riitä tämän tilan käyttämiseen. Aborted, too many nodes detected.=Keskeytetty, liian monta solmua havaittu. -Need %s charge to replace %s nodes.=Tarvitset %s-latauksen korvataksesi %s solmun. -%s nodes replaced.=%s solmua vaihdettu. -Mode changed to %s: %s=Tila muutettu tilaksi %s: %s Error: No node selected.=Virhe: solmua ei ole valittu. -Item not in creative inventory: "%s".=Kohde ei ole mainosjakaumassa: "%s". -Item not in your inventory: "%s".=Tuote, joka ei ole varastossa: "%s". -Node replacement tool set to:@n%s.=Solmun korvaustyökalu asetettu arvoon:@n%s. Node replacement tool=Solmun vaihtotyökalu Node replacement tool (technic)=Solmun vaihtotyökalu (tekninen) Time-limit reached.=Aikaraja saavutettu. Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Vaihtaa verbosity.@nKun käytössä, viestit lähetetään chattiin. Kun se on pois päältä, korvaaja on äänetön. -Valid parameter is either "%s" or "%s"=Kelvollinen parametri on joko "%s" tai "%s" on=kyllä off=fora Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Tarkastustyökalu@nTarkista kohdesolmu tai entiteetti.@nTarkista viereinen solmu. This is a broken object. We have no further information about it. It is located=Tämä on rikkinäinen esine. Meillä ei ole asiasta enempää tietoa. Se sijaitsee -This is your fellow player "%s"=Tämä on pelikaverisi "%s" -This is an entity "%s"=Tämä on entiteetti "%s" -, dropped %s minutes ago=, pudonnut %s minuuttia sitten owned, protected and locked=omistettu, suojattu ja lukittu owned and protected=omistettu ja suojattu owned and locked=omistettu ja lukittu -by "%s"=kirjoittaja "%s" -with order to %s=tilauksella "%s" -Has %s different types of items,=Sisältää %s erityyppistä tuotetta, -total of %s items in inventory.=yhteensä %s tuotetta varastossa. -This is an object "%s"=Tämä on objekti "%s" This is an object=Tämä on objekti -at %s=osoitteessa %s -Sorry, this is an unkown something of type "%s". No information available.=Anteeksi, tämä on tuntematon asia, jonka tyyppi on "%s". Tietoja ei ole saatavilla. WARNING: You can't dig this node. It is protected.=VAROITUS: Et voi kaivaa tätä solmua. Se on suojattu. INFO: You can dig this node, others can't.=INFO: Voit kaivaa tämän solmun, mutta muut eivät. ~ no description provided ~=~ ei kuvausta ~ ~ no node description provided ~=~ solmun kuvausta ei ole annettu ~ ~ no item description provided ~=~ ei tuotekuvausta ~ -Located at %s=Sijaitsee %s -with param2 of %s=param2 %s -and receiving %s light=ja vastaanottaa %s valoa +Name:=Nimi: +Exit=Poistu +This is:=Tämä on: prev=edellinen next=seuraava No recipes.=Ei reseptejä. Drops on dig:=Pudotukset kaivamaan: nothing=ei mitään May drop on dig:=Saattaa pudota kaivamaan: -Alternate %s/%s=Vaihtoehtoinen %s/%s This can be used as a fuel.=Tätä voidaan käyttää polttoaineena. Error: Unkown recipe.=Virhe: Tuntematon resepti. - +Valid parameter is either "@1" or "@2"=Kelvollinen parametri on joko "@1" tai "@2" +Protected at @1=Suojattu @1 +This is your fellow player "@1"=Tämä on pelikaverisi "@1" +This is an entity "@1"=Tämä on entiteetti "@1" +, dropped @1 minutes ago=, pudonnut @1 minuuttia sitten +by "@1"=kirjoittaja "@1" +with order to @1=tilauksella "@1" +Has @1 different types of items,=Sisältää @1 erityyppistä tuotetta, +total of @1 items in inventory.=yhteensä @1 tuotetta varastossa. +This is an object "@1"=Tämä on objekti "@1" +at @1=osoitteessa @1 +Sorry, this is an unkown something of type "@1". No information available.=Anteeksi, tämä on tuntematon asia, jonka tyyppi on "@1". Tietoja ei ole saatavilla. +Located at @1=Sijaitsee @1 +with param2 of @1=param2 @1 +and receiving @1 light=ja vastaanottaa @1 valoa +Alternate @1/@2=Vaihtoehto @1/@2 +You have no further "@1". Replacement failed.=Sinulla ei ole enempää "@1". Vaihto epäonnistui. +Unknown node: "@1"=Tuntematon solmu: "@1" +Unknown node to place: "@1"=Tuntematon sijoitettava solmu: "@1" +Could not dig "@1" properly.=Ei voitu kaivaa "@1" oikein. +Could not place "@1".=Ei voitu sijoittaa "@1". +Error: "@1" is not a node.=Virhe: "@1" ei ole solmu. +@1 nodes replaced.=@1 solmua vaihdettu. +Mode changed to @1: @2=Tila muutettu tilaksi @1: @2 +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Tyypin "@1" solmujen korvaaminen ei ole sallittua tässä palvelimessa. Vaihto epäonnistui. +Item not in creative inventory: "@1".=Kohde ei ole mainosjakaumassa: "@1". +Item not in your inventory: "@1".=Tuote, joka ei ole varastossa: "@1". +Node replacement tool set to:@n@1.=Solmun korvaustyökalu asetettu arvoon:@n@1. diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index 18d4966..d81032b 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -16,68 +16,68 @@ Left click: Replace field of nodes of a kind where a translucent node is in fron Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Clic gauche : Remplacer les nœuds qui touchent un autre du même genre et un nœud translucide, par ex. air.@@Clic droit : Remplacer les nœuds d'air qui touchent la croûte. -Protected at %s=Protégé à %s -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=Le remplacement de nœuds de type "%s" n'est pas autorisé sur ce serveur. Échec du remplacement. -You have no further "%s". Replacement failed.=Tu n'as plus de "%s". Échec du remplacement. -Unknown node: "%s"=Nœud inconnu : "%s" -Unknown node to place: "%s"=Nœud inconnu à placer : "%s" -Could not dig "%s" properly.=Impossible de creuser "%s" correctement. -Could not place "%s".=Impossible de placer "%s". -Error: "%s" is not a node.=Erreur : "%s" n'est pas un nœud. Target node not yet loaded. Please wait a moment for the server to catch up.=Le nœud cible n'est pas encore chargé. Patienter quelques instants, que le serveur rattrape. Nothing to replace.=Rien à remplacer. Not enough charge to use this mode.=Pas assez de charge pour utiliser ce mode. Aborted, too many nodes detected.=Abandonné, trop de nœuds détectés. -Need %s charge to replace %s nodes.=Besoin de %s charge pour remplacer %s nœuds. -%s nodes replaced.=%s nœuds remplacés. -Mode changed to %s: %s=Mode changé en %s : %s Error: No node selected.=Erreur : Aucun nœud sélectionné. -Item not in creative inventory: "%s".=L'article n'est pas dans l'inventaire de la création : "%s". -Item not in your inventory: "%s".=Objet pas dans tu inventaire : "%s". -Node replacement tool set to:@n%s.=Remplaçant défini sur :@n%s. Node replacement tool=Remplaçant Node replacement tool (technic)=Remplaçant (technique) Time-limit reached.=Délai atteint. Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Active/désactive la verbosité.@nLorsque cette option est activée, les messages sont publiés sur le chat. Lorsqu'il est désactivé, le remplaçant est silencieux. -Valid parameter is either "%s" or "%s"=Le paramètre valide est "%s" ou "%s" on=1 off=0 Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Outil d'inspection@nUtiliser pour inspecter le nœud ou l'entité cible.@nPlacer pour inspecter le nœud adjacent. This is a broken object. We have no further information about it. It is located=Ceci est un objet cassé. Nous n'avons pas d'autres informations à ce sujet. Il est situé -This is your fellow player "%s"=C'est votre coéquipier "%s" -This is an entity "%s"=Ceci est une entité "%s" -, dropped %s minutes ago=, déposé il y a %s minutes owned, protected and locked=possédé, protégé et verrouillé owned and protected=possédé et protégé owned and locked=possédé et verrouillé -by "%s"=par "%s" -with order to %s=avec l'ordre de "%s" -Has %s different types of items,=A %s différents types d'éléments, -total of %s items in inventory.=total de %s articles dans l'inventaire. -This is an object "%s"=Ceci est un objet "%s" This is an object=Ceci est un objet -at %s=à %s -Sorry, this is an unkown something of type "%s". No information available.=Désolé, c'est quelque chose d'inconnu de type "%s". Aucune information disponible. - WARNING: You can't dig this node. It is protected.=AVERTISSEMENT: Tu ne peux pas creuser ce nœud. Il est protégé. INFO: You can dig this node, others can't.=INFO: Tu peux creuser ce nœud, mais les autres ne le peuvent pas. ~ no description provided ~=~ aucune description fournie ~ ~ no node description provided ~=~ aucune description de nœud fournie ~ ~ no item description provided ~=~ aucune description d'article fournie ~ -Located at %s=Situé à %s -with param2 of %s=avec param2 de %s -and receiving %s light=et recevant %s lumière +Name:=Nom: +Exit=Sortir +This is:=C'est: prev=préc next=suiv. No recipes.=Aucune recette. Drops on dig:=Gouttes sur creuser: nothing=rien May drop on dig:=Peut tomber en creusant: -Alternate %s/%s=Autre %s/%s This can be used as a fuel.=Cela peut être utilisé comme carburant. Error: Unkown recipe.=Erreur : recette inconnue. - +Valid parameter is either "@1" or "@2"=Le paramètre valide est "@1" ou "@2" +Protected at @1=Protégé à @1 +This is your fellow player "@1"=C'est votre coéquipier "@1" +This is an entity "@1"=Ceci est une entité "@1" +, dropped @1 minutes ago=, déposé il y a @1 minutes +by "@1"=par "@1" +with order to @1=avec l'ordre de "@1" +Has @1 different types of items,=A @1 différents types d'éléments, +total of @1 items in inventory.=total de @1 articles dans l'inventaire. +This is an object "@1"=Ceci est un objet "@1" +at @1=à @1 +Sorry, this is an unkown something of type "@1". No information available.=Désolé, c'est quelque chose d'inconnu de type "@1". Aucune information disponible. +Located at @1=Situé à @1 +with param2 of @1=avec param2 de @1 +and receiving @1 light=et recevant @1 lumière +Alternate @1/@2=Alternance @1/@2 +You have no further "@1". Replacement failed.=Tu n'as plus de "@1". Échec du remplacement. +Unknown node: "@1"=Nœud inconnu : "@1" +Unknown node to place: "@1"=Nœud inconnu à placer : "@1" +Could not dig "@1" properly.=Impossible de creuser "@1" correctement. +Could not place "@1".=Impossible de placer "@1". +Error: "@1" is not a node.=Erreur : "@1" n'est pas un nœud. +@1 nodes replaced.=@1 nœuds remplacés. +Mode changed to @1: @2=Mode changé en @1 : @2 +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Le remplacement de nœuds de type "@1" n'est pas autorisé sur ce serveur. Échec du remplacement. +Item not in creative inventory: "@1".=L'article n'est pas dans l'inventaire de la création : "@1". +Item not in your inventory: "@1".=Objet pas dans tu inventaire : "@1". +Node replacement tool set to:@n@1.=Remplaçant défini sur :@n@1. diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index f30cd20..37e1be6 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -16,68 +16,68 @@ Left click: Replace field of nodes of a kind where a translucent node is in fron Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Clic sinistro: Sostituisci i nodi che toccano un altro del suo genere e un nodo traslucido, ad es. air.@@Clic destro: Sostituisci i nodi d'aria che toccano la crosta. -Protected at %s=Protetto a %s -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=La sostituzione dei nodi di tipo "%s" non è consentita su questo server. Sostituzione non riuscita. -You have no further "%s". Replacement failed.=Non hai più "%s". Sostituzione non riuscita. -Unknown node: "%s"=Nodo sconosciuto: "%s" -Unknown node to place: "%s"=Nodo sconosciuto da posizionare: "%s" -Could not dig "%s" properly.=Impossibile scavare correttamente "%s". -Could not place "%s".=Impossibile posizionare "%s". -Error: "%s" is not a node.=Errore: "%s" non è un nodo. Target node not yet loaded. Please wait a moment for the server to catch up.=Nodo di destinazione non ancora caricato. Si prega di attendere un momento affinché il server raggiunga. Nothing to replace.=Niente da sostituire. Not enough charge to use this mode.=Carica insufficiente per utilizzare questa modalità. Aborted, too many nodes detected.=Interrotto, troppi nodi rilevati. -Need %s charge to replace %s nodes.=Sono necessari %s addebito per sostituire %s nodi. -%s nodes replaced.=%s nodi sostituiti. -Mode changed to %s: %s=Modalità modificata in %s: %s Error: No node selected.=Errore: nessun nodo selezionato. -Item not in creative inventory: "%s".=Articolo non nell'inventario della creatività: "%s". -Item not in your inventory: "%s".=Articolo non nel tuo inventario: "%s". -Node replacement tool set to:@n%s.=Strumento di sostituzione del nodo impostato su:@n%s. Node replacement tool=Strumento di sostituzione del nodo Node replacement tool (technic)=Strumento di sostituzione del nodo (tecnico) Time-limit reached.=Tempo limite raggiunto. Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Attiva o disattiva la verbosità.@nQuando è attiva, i messaggi vengono inviati alla chat. Quando è spento, il sostituto è silenzioso. -Valid parameter is either "%s" or "%s"=Il parametro valido è "%s" o "%s" on=1 off=0 Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Strumento di ispezione@nUtilizzare per ispezionare il nodo o l'entità di destinazione.@nPosizionare per ispezionare il nodo adiacente. This is a broken object. We have no further information about it. It is located=Questo è un oggetto rotto. Non abbiamo ulteriori informazioni a riguardo. Si trova -This is your fellow player "%s"=Questo è il tuo compagno di gioco "%s" -This is an entity "%s"=Questa è un'entità "%s" -, dropped %s minutes ago=, caduto %s minuti fa owned, protected and locked=posseduto, protetto e bloccato owned and protected=posseduto e protetto owned and locked=posseduto e bloccato -by "%s"=per "%s" -with order to %s=con ordine a "%s" -Has %s different types of items,=Ha %s diversi tipi di elementi, -total of %s items in inventory.=totale di %s articoli nell'inventario. -This is an object "%s"=Questo è un oggetto "%s" This is an object=Questo è un oggetto -at %s=alle %s -Sorry, this is an unkown something of type "%s". No information available.=Siamo spiacenti, questo è un qualcosa sconosciuto di tipo "%s". Nessuna informazione disponibile. - WARNING: You can't dig this node. It is protected.=ATTENZIONE: non puoi scavare questo nodo. È protetto. INFO: You can dig this node, others can't.=INFO: puoi scavare questo nodo, ma altri no. ~ no description provided ~=~ nessuna descrizione fornita ~ ~ no node description provided ~=~ nessuna descrizione del nodo fornita ~ ~ no item description provided ~=~ nessuna descrizione dell'oggetto fornita ~ -Located at %s=Situato a %s -with param2 of %s=con param2 di %s -and receiving %s light=e ricevendo %s luce +Name:=Nome: +Exit=Uscita +This is:=Questo è: prev=pre. next=suc. No recipes.=Nessuna ricetta. Drops on dig:=Gocce allo scavo: nothing=niente May drop on dig:=Può cadere durante lo scavo: -Alternate %s/%s=%s/%s= alternativo This can be used as a fuel.=Questo può essere usato come carburante. Error: Unkown recipe.=Errore: ricetta sconosciuta. - +Valid parameter is either "@1" or "@2"=Il parametro valido è "@1" o "@2" +Protected at @1=Protetto a @1 +This is your fellow player "@1"=Questo è il tuo compagno di gioco "@1" +This is an entity "@1"=Questa è un'entità "@1" +, dropped @1 minutes ago=, caduto @1 minuti fa +by "@1"=per "@1" +with order to @1=con ordine a "@1" +Has @1 different types of items,=Ha @1 diversi tipi di elementi, +total of @1 items in inventory.=totale di @1 articoli nell'inventario. +This is an object "@1"=Questo è un oggetto "@1" +at @1=alle @1 +Sorry, this is an unkown something of type "@1". No information available.=Siamo spiacenti, questo è un qualcosa sconosciuto di tipo "@1". Nessuna informazione disponibile. +Located at @1=Situato a @1 +with param2 of @1=con param2 di @1 +and receiving @1 light=e ricevendo @1 luce +Alternate @1/@2=Alternativo @1/@2 +You have no further "@1". Replacement failed.=Non hai più "@1". Sostituzione non riuscita. +Unknown node: "@1"=Nodo sconosciuto: "@1" +Unknown node to place: "@1"=Nodo sconosciuto da posizionare: "@1" +Could not dig "@1" properly.=Impossibile scavare correttamente "@1". +Could not place "@1".=Impossibile posizionare "@1". +Error: "@1" is not a node.=Errore: "@1" non è un nodo. +@1 nodes replaced.=@1 nodi sostituiti. +Mode changed to @1: @2=Modalità modificata in @1: @2 +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=La sostituzione dei nodi di tipo "@1" non è consentita su questo server. Sostituzione non riuscita. +Item not in creative inventory: "@1".=Articolo non nell'inventario della creatività: "@1". +Item not in your inventory: "@1".=Articolo non nel tuo inventario: "@1". +Node replacement tool set to:@n@1.=Strumento di sostituzione del nodo impostato su:@n@1. diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index 7b75923..a687cfd 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -16,68 +16,68 @@ Left click: Replace field of nodes of a kind where a translucent node is in fron Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Clique com o botão esquerdo: Substitui os nós que tocam em outro de seu tipo e um nó translúcido, por exemplo air.@@Clique com o botão direito: Substitua os nós de ar que tocam a crosta. -Protected at %s=Protegido em %s -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=A substituição de nós do tipo "%s" não é permitida neste servidor. Falha na substituição. -You have no further "%s". Replacement failed.=Você não tem mais "%s". Falha na substituição. -Unknown node: "%s"=Nó desconhecido: "%s" -Unknown node to place: "%s"=Nó desconhecido para colocar: "%s" -Could not dig "%s" properly.=Não foi possível cavar "%s" corretamente. -Could not place "%s".=Não foi possível colocar "%s". -Error: "%s" is not a node.=Erro: "%s" não é um nó. Target node not yet loaded. Please wait a moment for the server to catch up.=O nó de destino ainda não foi carregado. Aguarde um momento para o servidor recuperar o atraso. Nothing to replace.=Nada para substituir. Not enough charge to use this mode.=Carga insuficiente para usar este modo. Aborted, too many nodes detected.=Abortado, muitos nós detectados. -Need %s charge to replace %s nodes.=Precisa de %s carga para substituir %s nós. -%s nodes replaced.=%s nós substituídos. -Mode changed to %s: %s=Modo alterado para %s: %s Error: No node selected.=Erro: Nenhum nó selecionado. -Item not in creative inventory: "%s".=Item não no inventário do criativo: "%s". -Item not in your inventory: "%s".=Item que não está em seu inventário: "%s". -Node replacement tool set to:@n%s.=Ferramenta de substituição de nó definida como:@n%s. Node replacement tool=Ferramenta de substituição de nós Node replacement tool (technic)=Ferramenta de substituição de nós (técnica) Time-limit reached.=Limite de tempo atingido. Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Alterna a verbosidade.@nQuando ativado, as mensagens são postadas no bate-papo. Quando desligado, o substituto fica silencioso. -Valid parameter is either "%s" or "%s"=O parâmetro válido é "%s" ou "%s" on=em off=não Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Ferramenta de Inspeção@nUse para inspecionar o nó ou entidade de destino.@nPlace para inspecionar o nó adjacente. This is a broken object. We have no further information about it. It is located=Este é um objeto quebrado. Não temos mais informações a respeito. está localizado -This is your fellow player "%s"=Este é seu colega jogador "%s" -This is an entity "%s"=Esta é uma entidade "%s" -, dropped %s minutes ago=, caiu %s minutos atrás owned, protected and locked=possuído, protegido e bloqueado owned and protected=possuído e protegido owned and locked=possuído e bloqueado -by "%s"=por "%s" -with order to %s=com ordem para "%s" -Has %s different types of items,=Tem %s tipos diferentes de itens, -total of %s items in inventory.=total de %s itens no inventário. -This is an object "%s"=Este é um objeto "%s" This is an object=Este é um objeto -at %s=em %s -Sorry, this is an unkown something of type "%s". No information available.=Desculpe, isso é algo desconhecido do tipo "%s". Nenhuma informação disponível. - WARNING: You can't dig this node. It is protected.=AVISO: você não pode cavar este nó. Está protegido. INFO: You can dig this node, others can't.=INFO: Você pode cavar este nó, mas outros não podem. ~ no description provided ~=~ nenhuma descrição fornecida ~ ~ no node description provided ~=~ nenhuma descrição do nó fornecida ~ ~ no item description provided ~=~ nenhuma descrição do item fornecida ~ -Located at %s=Localizado em %s -with param2 of %s=com param2 de %s -and receiving %s light=e recebendo %s luz +Name:=Nome: +Exit=Saída +This is:=Isto é: prev=ant. next=pró. No recipes.=Sem receitas. Drops on dig:=Gotas na escavação: nothing=nada May drop on dig:=Pode cair na escavação: -Alternate %s/%s=alternativo %s/%s This can be used as a fuel.=Isso pode ser usado como combustível. Error: Unkown recipe.=Erro: receita desconhecida. - +Valid parameter is either "@1" or "@2"=O parâmetro válido é "@1" ou "@2" +Protected at @1=Protegido em @1 +This is your fellow player "@1"=Este é seu colega jogador "@1" +This is an entity "@1"=Esta é uma entidade "@1" +, dropped @1 minutes ago=, caiu @1 minutos atrás +by "@1"=por "@1" +with order to @1=com ordem para "@1" +Has @1 different types of items,=Tem @1 tipos diferentes de itens, +total of @1 items in inventory.=total de @1 itens no inventário. +This is an object "@1"=Este é um objeto "@1" +at @1=em @1 +Sorry, this is an unkown something of type "@1". No information available.=Desculpe, isso é algo desconhecido do tipo "@1". Nenhuma informação disponível. +Located at @1=Localizado em @1 +with param2 of @1=com param2 de @1 +and receiving @1 light=e recebendo @1 luz +Alternate @1/@2=Alternativo @1/@2 +You have no further "@1". Replacement failed.=Você não tem mais "@1". Falha na substituição. +Unknown node: "@1"=Nó desconhecido: "@1" +Unknown node to place: "@1"=Nó desconhecido para colocar: "@1" +Could not dig "@1" properly.=Não foi possível cavar "@1" corretamente. +Could not place "@1".=Não foi possível colocar "@1". +Error: "@1" is not a node.=Erro: "@1" não é um nó. +@1 nodes replaced.=@1 nós substituídos. +Mode changed to @1: @2=Modo alterado para @1: @2 +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=A substituição de nós do tipo "@1" não é permitida neste servidor. Falha na substituição. +Item not in creative inventory: "@1".=Item não no inventário do criativo: "@1". +Item not in your inventory: "@1".=Item que não está em seu inventário: "@1". +Node replacement tool set to:@n@1.=Ferramenta de substituição de nó definida como:@n@1. diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index a05a108..8770be4 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -16,67 +16,68 @@ Left click: Replace field of nodes of a kind where a translucent node is in fron Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.=Щелкните левой кнопкой мыши: замените узлы, которые соприкасаются с другим в своем роде и полупрозрачным узлом, например. воздух.@@Щелкните правой кнопкой мыши: замените воздушные узлы, которые касаются корки. -Protected at %s=Защищено в %s -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.=Замена узлов типа "%s" на этом сервере запрещена. Замена не удалась. -You have no further "%s". Replacement failed.=У вас больше нет "%s". Замена не удалась. -Unknown node: "%s"=Неизвестный узел: "%s" -Unknown node to place: "%s"=Неизвестный узел для размещения: "%s" -Could not dig "%s" properly.=Не удалось правильно раскопать "%s". -Could not place "%s".=Не удалось разместить "%s". -Error: "%s" is not a node.=Ошибка: "%s" не является узлом. Target node not yet loaded. Please wait a moment for the server to catch up.=Целевой узел еще не загружен. Пожалуйста, подождите, пока сервер наверстает упущенное. Nothing to replace.=Нечем заменить. Not enough charge to use this mode.=Недостаточно заряда для использования этого режима. Aborted, too many nodes detected.=Прервано, обнаружено слишком много узлов. -Need %s charge to replace %s nodes.=Требуется заряд %s для замены узлов %s. -%s nodes replaced.=Заменено узлов: %s. -Mode changed to %s: %s=Режим изменен на %s: %s Error: No node selected.=Ошибка: узел не выбран. -Item not in creative inventory: "%s".=Предмета нет в творческом инвентаре: "%s". -Item not in your inventory: "%s".=Предмета нет в вашем инвентаре: "%s". -Node replacement tool set to:@n%s.=Инструмент замены узлов установлен на:@n%s. Node replacement tool=Инструмент замены узлов Node replacement tool (technic)=Инструмент замены узла (техника) Time-limit reached.=Достигнут лимит времени. Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Включает многословие. @nКогда включено, сообщения отправляются в чат. Когда выключено, заменитель молчит. -Valid parameter is either "%s" or "%s"=Допустимый параметр: "%s" или "%s" on=да off=нет Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Inspection Tool@nИспользуйте для проверки целевого узла или объекта. @nPlace для проверки соседнего узла. This is a broken object. We have no further information about it. It is located=Это сломанный объект. У нас нет никакой дополнительной информации об этом. Он расположен. -This is your fellow player "%s"=Это ваш товарищ по игре "%s" -This is an entity "%s"=Это сущность "%s" -, dropped %s minutes ago=, выпало %s минут назад owned, protected and locked=принадлежит, защищено и заблокировано owned and protected=в собственности и под защитой owned and locked=принадлежит и заблокирован -by "%s"=по "%s" -with order to %s=с заказом на "%s" -Has %s different types of items,=Имеет %s различных типов предметов, -total of %s items in inventory.=всего %s предметов в инвентаре. -This is an object "%s"=Это объект "%s" This is an object=Это объект -at %s=в %s -Sorry, this is an unkown something of type "%s". No information available.=Извините, это неизвестное что-то типа "%s". Информация отсутствует. WARNING: You can't dig this node. It is protected.=ВНИМАНИЕ: Вы не можете копать этот узел. Он защищен. INFO: You can dig this node, others can't.=ИНФОРМАЦИЯ: Вы можете копать этот узел, а другие нет. ~ no description provided ~=~ описание не предоставлено ~ ~ no node description provided ~=~ описание узла не предоставлено ~ ~ no item description provided ~=~ описание предмета не предоставлено ~ -Located at %s=Находится по адресу %s -with param2 of %s=с параметром2 из %s -and receiving %s light=и получаю %s свет +Name:=Имя: +Exit=Выход +This is:=Это: prev=предыдущая next=следующий No recipes.=Нет рецептов. Drops on dig:=Выпадает при раскопках: nothing=ничего May drop on dig:=Может выпасть при раскопках: -Alternate %s/%s=Альтернативный %s/%s This can be used as a fuel.=Это можно использовать в качестве топлива. Error: Unkown recipe.=Ошибка: Неизвестный рецепт. - +Valid parameter is either "@1" or "@2"=Допустимый параметр: "@1" или "@2" +Protected at @1=Защищено в @1 +This is your fellow player "@1"=Это ваш товарищ по игре "@1" +This is an entity "@1"=Это сущность "@1" +, dropped @1 minutes ago=, выпало @1 минут назад +by "@1"=по "@1" +with order to @1=с заказом на "@1" +Has @1 different types of items,=Имеет @1 различных типов предметов, +total of @1 items in inventory.=всего @1 предметов в инвентаре. +This is an object "@1"=Это объект "@1" +at @1=в @1 +Sorry, this is an unkown something of type "@1". No information available.=Извините, это неизвестное что-то типа "@1". Информация отсутствует. +Located at @1=Находится по адресу @1 +with param2 of @1=с параметром2 из @1 +and receiving @1 light=и получаю @1 свет +Alternate @1/@2=Альтернатива @1/@2 +You have no further "@1". Replacement failed.=У вас больше нет "@1". Замена не удалась. +Unknown node: "@1"=Неизвестный узел: "@1" +Unknown node to place: "@1"=Неизвестный узел для размещения: "@1" +Could not dig "@1" properly.=Не удалось правильно раскопать "@1". +Could not place "@1".=Не удалось разместить "@1". +Error: "@1" is not a node.=Ошибка: "@1" не является узлом. +@1 nodes replaced.=Заменено узлов: @1. +Mode changed to @1: @2=Режим изменен на @1: @2 +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Замена узлов типа "@1" на этом сервере запрещена. Замена не удалась. +Item not in creative inventory: "@1".=Предмета нет в творческом инвентаре: "@1". +Item not in your inventory: "@1".=Предмета нет в вашем инвентаре: "@1". +Node replacement tool set to:@n@1.=Инструмент замены узлов установлен на:@n@1. diff --git a/locale/template.txt b/locale/template.txt index a876668..af0eefc 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -16,66 +16,68 @@ Left click: Replace field of nodes of a kind where a translucent node is in fron Left click: Replace nodes which touch another one of its kind and a translucent node, e.g. air.@@Right click: Replace air nodes which touch the crust.= -Protected at %s= -Replacing nodes of type "%s" is not allowed on this server. Replacement failed.= -You have no further "%s". Replacement failed.= -Unknown node: "%s"= -Unknown node to place: "%s"= -Could not dig "%s" properly.= -Could not place "%s".= -Error: "%s" is not a node.= Target node not yet loaded. Please wait a moment for the server to catch up.= Nothing to replace.= Not enough charge to use this mode.= Aborted, too many nodes detected.= -Need %s charge to replace %s nodes.= -%s nodes replaced.= -Mode changed to %s: %s= Error: No node selected.= -Item not in creative inventory: "%s".= -Item not in your inventory: "%s".= -Node replacement tool set to:@n%s.= Node replacement tool= Node replacement tool (technic)= Time-limit reached.= Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= -Valid parameter is either "%s" or "%s"= on= off= Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.= This is a broken object. We have no further information about it. It is located= -This is your fellow player "%s"= -This is an entity "%s"= -, dropped %s minutes ago= owned, protected and locked= owned and protected= owned and locked= -by "%s"= -with order to %s= -Has %s different types of items,= -total of %s items in inventory.= -This is an object "%s"= This is an object= -at %s= -Sorry, this is an unkown something of type "%s". No information available.= WARNING: You can't dig this node. It is protected.= INFO: You can dig this node, others can't.= ~ no description provided ~= ~ no node description provided ~= ~ no item description provided ~= -Located at %s= -with param2 of %s= -and receiving %s light= +Name:= +Exit= +This is:= prev= next= No recipes.= Drops on dig:= nothing= May drop on dig:= -Alternate %s/%s= This can be used as a fuel.= Error: Unkown recipe.= +Valid parameter is either "@1" or "@2"= +Protected at @1= +This is your fellow player "@1"= +This is an entity "@1"= +, dropped @1 minutes ago= +by "@1"= +with order to @1= +Has @1 different types of items,= +total of @1 items in inventory.= +This is an object "@1"= +at @1= +Sorry, this is an unkown something of type "@1". No information available.= +Located at @1= +with param2 of @1= +and receiving @1 light= +Alternate @1/@2= +You have no further "@1". Replacement failed.= +Unknown node: "@1"= +Unknown node to place: "@1"= +Could not dig "@1" properly.= +Could not place "@1".= +Error: "@1" is not a node.= +@1 nodes replaced.= +Mode changed to @1: @2= +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.= +Item not in creative inventory: "@1".= +Item not in your inventory: "@1".= +Node replacement tool set to:@n@1.= diff --git a/replacer/constrain.lua b/replacer/constrain.lua index cd1a224..745a2fa 100644 --- a/replacer/constrain.lua +++ b/replacer/constrain.lua @@ -1,5 +1,6 @@ local r = replacer local rb = replacer.blabla +local S = replacer.S local is_protected = minetest.is_protected local pos_to_string = minetest.pos_to_string @@ -98,7 +99,7 @@ function replacer.permit_replace(pos, old_node_def, new_node_def, end if is_protected(pos, player_name) then - return false, rb.protected_at:format(pos_to_string(pos)) + return false, S('Protected at @1', pos_to_string(pos)) end return true diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 1fdfa9a..df899bf 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -7,6 +7,7 @@ local r = replacer local rb = replacer.blabla local rp = replacer.patterns local rud = replacer.unifieddyes +local S = replacer.S -- math local max, min, floor = math.max, math.min, math.floor local core_check_player_privs = minetest.check_player_privs @@ -163,16 +164,17 @@ function replacer.replace_single_node(pos, node_old, node_new, player, local inv_name = r.exception_map[node_new.name] or node_new.name -- does the player carry at least one of the desired nodes with him? if (not creative) and (not inv:contains_item('main', inv_name)) then - return false, rb.run_out:format(node_new.name or '?') + return false, S('You have no further "@1". Replacement failed.', + node_new.name or '?') end local node_old_def = core_registered_nodes[node_old.name] if not node_old_def then - return false, rb.attempt_unknown_replace:format(node_old.name) + return false, S('Unknown node: "@1"', node_old.name) end local node_new_def = core_registered_nodes[node_new.name] if not node_new_def then - return false, rb.attempt_unknown_place:format(node_new.name) + return false, S('Unknown node to place: "@1"', node_new.name) end -- dig the current node if needed @@ -183,7 +185,7 @@ function replacer.replace_single_node(pos, node_old, node_new, player, local dug_node = core_get_node_or_nil(pos) if (not dug_node) or (not core_registered_nodes[dug_node.name].buildable_to) then - return false, rb.can_not_dig:format(node_old.name) + return false, S('Could not dig "@1" properly.', node_old.name) end end @@ -196,7 +198,7 @@ function replacer.replace_single_node(pos, node_old, node_new, player, -- this allows users to dig nodes, I don't see reason to stop that -- as long as no crash occurs - SwissalpS if (false == succ) or (nil == new_item) then - return false, rb.can_not_place:format(node_new.name) + return false, S('Could not place "@1".', node_new.name) end -- update inventory in survival mode @@ -262,7 +264,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) end if 'node' ~= pt.type then - r.inform(name, rb.not_a_node:format(pt.type)) + r.inform(name, S('Error: "@1" is not a node.', pt.type)) return end @@ -480,7 +482,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) r.discharge(itemstack, charge, actual_node_count, has_creative_or_give) if has_creative_or_give then - r.inform(name, rb.count_replaced:format(actual_node_count)) + r.inform(name, S('@1 nodes replaced.', actual_node_count)) end return itemstack end -- on_use @@ -512,13 +514,13 @@ function replacer.on_place(itemstack, player, pt) -- increment and roll-over minor mode mode.minor = mode.minor % 3 + 1 -- spam chat - r.inform(name, rb.mode_changed:format( + r.inform(name, S('Mode changed to @1: @2', r.mode_minor_names[mode.minor], r.mode_minor_infos[mode.minor])) else -- increment and roll-over major mode mode.major = mode.major % 3 + 1 -- spam chat - r.inform(name, rb.mode_changed:format( + r.inform(name, S('Mode changed to @1: @2', r.mode_major_names[mode.major], r.mode_major_infos[mode.major])) end -- update tool @@ -543,7 +545,8 @@ function replacer.on_place(itemstack, player, pt) -- don't allow setting replacer to denied nodes if r.deny_list[node.name] then - r.inform(name, rb.deny_listed:format(node.name)) + r.inform(name, S('Replacing nodes of type "@1" is not allowed on this server. ' + .. 'Replacement failed.', node.name)) return end @@ -582,7 +585,7 @@ function replacer.on_place(itemstack, player, pt) end end if not found_item then - r.inform(name, rb.not_in_creative:format(node.name)) + r.inform(name, S('Item not in creative inventory: "@1".', node.name)) return end end @@ -615,7 +618,7 @@ function replacer.on_place(itemstack, player, pt) end end if (not found_item) and (not has_give) then - r.inform(name, rb.not_in_inventory:format(node.name)) + r.inform(name, S('Item not in your inventory: "@1".', node.name)) return end end @@ -626,7 +629,7 @@ function replacer.on_place(itemstack, player, pt) -- add to history r.history.add_item(player, mode, node, short_description) -- inform player about successful setting - r.inform(name, rb.set_to:format(short_description)) + r.inform(name, S('Node replacement tool set to:\n@1.', short_description)) return itemstack --data changed end -- on_place From ba51e61fe074385d84ef739ffe618a8903fb634b Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 21 Jan 2022 01:48:01 +0100 Subject: [PATCH 194/366] version bump 3.8.1 --- CHANGELOG | 2 ++ init.lua | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 979cd93..510eb19 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ 20220120 * SwissalpS made folder structure to create easier overview. * Improved circular saw item detection for inspect and replacer. * Added beacon beam and base support (no longer needed to be in inv when setting). + * Inspection tool now inspects light correctly and respects right-click. + * Added locale for inspection tool. 20220119 * SwissalpS added first draft of de,es,fi,fr,it,pt,ru locales. 20220118 * SwissalpS cleaned up more code, giving more discriptive variable names and cleaning out ugly modes table that had both number and string indexes diff --git a/init.lua b/init.lua index 991a18e..7d961c1 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 3.8 (20220120) +-- Version 3.8.1 (20220120) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220120 +replacer.version = 20220120.1 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From 871e959b7ef3d741e358779e3956afd5fbd5173c Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:25:57 +0100 Subject: [PATCH 195/366] new log strings --- blabla.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/blabla.lua b/blabla.lua index e300570..ef0ca6d 100644 --- a/blabla.lua +++ b/blabla.lua @@ -70,6 +70,7 @@ rb.log_reg_exception_callback = '[replacer] registered after on_place callback f rb.log_reg_alias_override = '[replacer] register_non_creative_alias: ' .. ' alias for "%s" already exists.' rb.log_reg_alias = '[replacer] registered alias for "%s" to "%s"' +rb.log_reg_set_callback_fail = '[replacer] register_set_enabler called without passing function.' rb.formspec_error = '[replacer] formspec error, user "%s" attempting to change history. Fields: %s' rb.formspec_hacker = '[replacer] formspec forge? By user "%s" Fields: %s' @@ -97,4 +98,7 @@ rbi.nothing = S('nothing') rbi.may_drop_on_dig = S('May drop on dig:') rbi.can_be_fuel = S('This can be used as a fuel.') rbi.unkown_recipe = S('Error: Unkown recipe.') +rbi.log_reg_craft_method_wrong_arguments = '[replacer] register_craft_method invalid arguments given.' +rbi.log_reg_craft_method_overriding_method = '[replacer] register_craft_method overriding existing method ' +rbi.log_reg_craft_method_added = '[replacer] register_craft_method method added: %s %s' From 3a74cf843c79fb719951d7d0f1e529709cd45c5a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:28:01 +0100 Subject: [PATCH 196/366] load compat files by scanning dir --- init.lua | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/init.lua b/init.lua index 7d961c1..8022105 100644 --- a/init.lua +++ b/init.lua @@ -52,35 +52,17 @@ dofile(path .. 'blabla.lua') dofile(path .. 'replacer/constrain.lua') -- utilities (i+r) dofile(path .. 'utils.lua') - --- TODO: just loop through compat dir --- bakedclay support (i) -dofile(path .. 'compat/bakedclay.lua') --- beacon beam support (r) -dofile(path .. 'compat/beacon.lua') --- biofuel (r) -dofile(path .. 'compat/biofuel.lua') --- default & basic dyes support (i) -dofile(path .. 'compat/default.lua') --- cobweb (r) -dofile(path .. 'compat/mobs.lua') --- circular saw support (i+r) -dofile(path .. 'compat/moreblocks.lua') --- prefab (r) -dofile(path .. 'compat/prefab.lua') --- RealTest overrides (i) -dofile(path .. 'compat/realTest.lua') --- ropes support (r) -dofile(path .. 'compat/ropes.lua') --- add cable plate exceptions (r) -dofile(path .. 'compat/technic.lua') --- unifiedddyes support functions (i+r) -dofile(path .. 'compat/unifieddyes.lua') --- vines group support (i+r) -dofile(path .. 'compat/vines.lua') - -- adds a tool for inspecting nodes and entities dofile(path .. 'inspect.lua') + +-- loop through compat dir +local path_compat = path .. 'compat/' +for _, file in ipairs(minetest.get_dir_list(path_compat, false)) do + if file:find('^[^._].+[.]lua$') then + dofile(path_compat .. file) + end +end + replacer.datastructures = dofile(path .. 'replacer/datastructures.lua') dofile(path .. 'replacer/formspecs.lua') dofile(path .. 'replacer/history.lua') From 4854f6786fecede0986424c9f2c533ef71c75859 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:33:49 +0100 Subject: [PATCH 197/366] splitting constrain and enabler functions --- init.lua | 6 ++- replacer/constrain.lua | 44 ---------------------- replacer/enable.lua | 84 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 46 deletions(-) create mode 100644 replacer/enable.lua diff --git a/init.lua b/init.lua index 8022105..988945a 100644 --- a/init.lua +++ b/init.lua @@ -48,10 +48,12 @@ replacer.image_replacements = {} local path = minetest.get_modpath('replacer') .. '/' -- strings for translation (i+r) dofile(path .. 'blabla.lua') --- more settings and functions -dofile(path .. 'replacer/constrain.lua') -- utilities (i+r) dofile(path .. 'utils.lua') +-- more settings and functions +dofile(path .. 'replacer/constrain.lua') +-- register set enable functions +dofile(path .. 'replacer/enable.lua') -- adds a tool for inspecting nodes and entities dofile(path .. 'inspect.lua') diff --git a/replacer/constrain.lua b/replacer/constrain.lua index 745a2fa..93bc508 100644 --- a/replacer/constrain.lua +++ b/replacer/constrain.lua @@ -7,30 +7,6 @@ local pos_to_string = minetest.pos_to_string -- limit by node, use replacer.register_limit(sName, iMax) replacer.limit_list = {} --- some nodes don't rotate using param2. They can be added --- using replacer.register_exception(node_name, inv_node_name[, callback_function]) --- where: node_name is the itemstring of node when placed in world --- inv_node_name the itemstring of item in inventory to consume --- callback_function is optional and will be called after node is placed. --- It must return true on success and false, error_message on fail. --- In order to register only a callback, pass two identical itemstrings. --- Generally the callback is not needed as on_place() is called on the placed node --- callback signature is: (pos, old_node_def, new_node_def, player_ref) --- Examples: --- 1) Technic cable plate 'technic:lv_cable_plate_4' needs to consume 'technic:lv_cable_plate_1' --- r.register_exception('technic:lv_cable_plate_4', 'technic:lv_cable_plate_1') --- 2) Cobwebs don't drop cobwebs, to enable setting replacer to them without having any in --- user's inventory, register like so: --- r.register_exception('mobs:cobweb', 'mobs:cobweb') -replacer.exception_map = {} -replacer.exception_callbacks = {} --- sometimes you want a reverse exception, for that you use: --- replacer.register_non_creative_alias(name_sibling, name_placed) --- Example vines have middle and end parts. To enable setting replacer on middle part --- to then place an end part in world (only when player does not have creative priv) --- register like so: --- replacer.register_non_creative_alias('vines:jungle_middle', 'vines:jungle_end') -replacer.alias_map = {} -- don't allow these at all replacer.deny_list = {} @@ -105,18 +81,6 @@ function replacer.permit_replace(pos, old_node_def, new_node_def, return true end -- permit_replace -function replacer.register_exception(node_name, drop_name, callback) - if r.exception_map[node_name] then - minetest.log('info', rb.log_reg_exception_override:format(node_name)) - end - r.exception_map[node_name] = drop_name - minetest.log('info', rb.log_reg_exception:format(node_name, drop_name)) - - if 'function' ~= type(callback) then return end - - r.exception_callbacks[node_name] = callback - minetest.log('info', rb.log_reg_exception_callback:format(node_name)) -end -- register_exception local function is_positive_int(value) return (type(value) == 'number') and (math.floor(value) == value) and (0 <= value) @@ -142,11 +106,3 @@ function replacer.register_limit(node_name, node_max) minetest.log('info', rb.log_limit_insert:format(node_name, node_max)) end -- register_limit -function replacer.register_non_creative_alias(name_sibling, name_placed) - if r.alias_map[name_sibling] then - minetest.log('info', rb.log_reg_alias_override:format(name_sibling)) - end - r.alias_map[name_sibling] = name_placed - minetest.log('info', rb.log_reg_alias:format(name_sibling, name_placed)) -end -- register_non_creative_alias - diff --git a/replacer/enable.lua b/replacer/enable.lua new file mode 100644 index 0000000..ef69bcd --- /dev/null +++ b/replacer/enable.lua @@ -0,0 +1,84 @@ +local r = replacer +local rb = replacer.blabla + +-- see replacer.register_exception() +replacer.exception_map = {} +replacer.exception_callbacks = {} + +-- see replacer.register_set_enabler() +replacer.enable_set_callbacks = {} + +-- see replacer.register_non_creative_alias() +replacer.alias_map = {} + +-- some nodes don't rotate using param2. They can be added +-- using replacer.register_exception(node_name, inv_node_name[, callback_function]) +-- where: node_name is the itemstring of node when placed in world +-- inv_node_name the itemstring of item in inventory to consume +-- callback_function is optional and will be called after node is placed. +-- It must return true on success and false, error_message on fail. +-- In order to register only a callback, pass two identical itemstrings. +-- Generally the callback is not needed as on_place() is called on the placed node +-- callback signature is: (pos, old_node_def, new_node_def, player_ref) +-- Examples: +-- 1) Technic cable plate 'technic:lv_cable_plate_4' needs to consume 'technic:lv_cable_plate_1' +-- r.register_exception('technic:lv_cable_plate_4', 'technic:lv_cable_plate_1') +-- 2) Cobwebs don't drop cobwebs, to enable setting replacer to them without having any in +-- user's inventory, register like so: +-- r.register_exception('mobs:cobweb', 'mobs:cobweb') +function replacer.register_exception(node_name, drop_name, callback) + if r.exception_map[node_name] then + minetest.log('warning', rb.log_reg_exception_override:format(node_name)) + end + r.exception_map[node_name] = drop_name + minetest.log('info', rb.log_reg_exception:format(node_name, drop_name)) + + if 'function' ~= type(callback) then return end + + r.exception_callbacks[node_name] = callback + minetest.log('info', rb.log_reg_exception_callback:format(node_name)) +end -- register_exception + + +-- sometimes you want a reverse exception, for that you use: +-- replacer.register_non_creative_alias(name_sibling, name_placed) +-- Example vines have middle and end parts. To enable setting replacer on middle part +-- to then place an end part in world (only when player does not have creative priv) +-- register like so: +-- replacer.register_non_creative_alias('vines:jungle_middle', 'vines:jungle_end') +function replacer.register_non_creative_alias(name_sibling, name_placed) + if r.alias_map[name_sibling] then + minetest.log('warning', rb.log_reg_alias_override:format(name_sibling)) + end + r.alias_map[name_sibling] = name_placed + minetest.log('info', rb.log_reg_alias:format(name_sibling, name_placed)) +end -- register_non_creative_alias + + +-- The callback will be called when setting replacer and *none* of these +-- criteria are matched: +-- - user has give priv +-- - user has the item in inventory +-- - user does not have creative priv and item is in alias map +-- see register_non_creative_alias() +-- - item is in exceptions, see register_exception() +-- - the item can be obtained by crafting, cooking etc. +-- The first callback to respond with something other than false or nil +-- allows setting the replacer to node. Such a callback may also +-- modify node-table's name, param1 and param2 fields. +-- If you want all your users to be able to set replacer to any node, +-- looking @Sokomine ;), then in your custom server mod register: +-- replacer.register_set_enabler(replacer.yes) +-- although, at that point you might as well just give users creative. +-- the callback signature is f(node, player, pointed_thing) +function replacer.register_set_enabler(callback) + if 'function' ~= type(callback) then + minetest.log('error', rb.log_reg_set_callback_fail) + return + end + + table.insert(r.enable_set_callbacks, callback) +end -- register_set_enabler + +function replacer.yes() return true end + From ba076642732aa4b583f432a8465bc7d94b85dacd Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:34:13 +0100 Subject: [PATCH 198/366] use nicer pos_to_string --- replacer/constrain.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/replacer/constrain.lua b/replacer/constrain.lua index 93bc508..ca6f744 100644 --- a/replacer/constrain.lua +++ b/replacer/constrain.lua @@ -2,7 +2,7 @@ local r = replacer local rb = replacer.blabla local S = replacer.S local is_protected = minetest.is_protected -local pos_to_string = minetest.pos_to_string +local pos_to_string = replacer.nice_pos_string -- limit by node, use replacer.register_limit(sName, iMax) replacer.limit_list = {} From 8ecd022e80e15792b7360d46b2407850184eb751 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:35:47 +0100 Subject: [PATCH 199/366] move default denies to compat files --- compat/protectors.lua | 7 +++++++ compat/tnt.lua | 7 +++++++ replacer/constrain.lua | 16 ++-------------- 3 files changed, 16 insertions(+), 14 deletions(-) create mode 100644 compat/protectors.lua create mode 100644 compat/tnt.lua diff --git a/compat/protectors.lua b/compat/protectors.lua new file mode 100644 index 0000000..084cff4 --- /dev/null +++ b/compat/protectors.lua @@ -0,0 +1,7 @@ +-- prevent accidental replacement of your protectors +replacer.deny_list['priv_protector:protector'] = true +replacer.deny_list['protector:protect'] = true +replacer.deny_list['protector:protect2'] = true +replacer.deny_list['xp_redo:protector'] = true +replacer.deny_list['xp_redo:xpgate'] = true + diff --git a/compat/tnt.lua b/compat/tnt.lua new file mode 100644 index 0000000..d5aa66f --- /dev/null +++ b/compat/tnt.lua @@ -0,0 +1,7 @@ +-- playing with tnt and creative building are usually contradictory +-- (except when doing large-scale landscaping in singleplayer) +replacer.deny_list['tnt:boom'] = true +replacer.deny_list['tnt:gunpowder'] = true +replacer.deny_list['tnt:gunpowder_burning'] = true +replacer.deny_list['tnt:tnt'] = true + diff --git a/replacer/constrain.lua b/replacer/constrain.lua index ca6f744..46f583f 100644 --- a/replacer/constrain.lua +++ b/replacer/constrain.lua @@ -8,22 +8,10 @@ local pos_to_string = replacer.nice_pos_string replacer.limit_list = {} --- don't allow these at all +-- don't allow these at all, neither for placing nor replacing +-- example: r.deny_list['tnt:boom'] = true replacer.deny_list = {} --- playing with tnt and creative building are usually contradictory --- (except when doing large-scale landscaping in singleplayer) -replacer.deny_list['tnt:boom'] = true -replacer.deny_list['tnt:gunpowder'] = true -replacer.deny_list['tnt:gunpowder_burning'] = true -replacer.deny_list['tnt:tnt'] = true - --- prevent accidental replacement of your protector -replacer.deny_list['priv_protector:protector'] = true -replacer.deny_list['protector:protect'] = true -replacer.deny_list['protector:protect2'] = true -replacer.deny_list['xp_redo:protector'] = true - -- charge limits replacer.max_charge = 30000 replacer.charge_per_node = 15 From d67b09cdf6d1b2f213c453a772895535f3362a38 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:39:45 +0100 Subject: [PATCH 200/366] new tool set decision making --- replacer/constrain.lua | 3 + replacer/replacer.lua | 152 ++++++++++++++++++++++++----------------- 2 files changed, 92 insertions(+), 63 deletions(-) diff --git a/replacer/constrain.lua b/replacer/constrain.lua index 46f583f..dad2662 100644 --- a/replacer/constrain.lua +++ b/replacer/constrain.lua @@ -7,6 +7,9 @@ local pos_to_string = replacer.nice_pos_string -- limit by node, use replacer.register_limit(sName, iMax) replacer.limit_list = {} +-- don't allow items of these groups for setting replacer to +replacer.deny_groups = {} +replacer.deny_groups['seed'] = true -- don't allow these at all, neither for placing nor replacing -- example: r.deny_list['tnt:boom'] = true diff --git a/replacer/replacer.lua b/replacer/replacer.lua index df899bf..b375ad4 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -19,6 +19,7 @@ local core_registered_items = minetest.registered_items local core_registered_nodes = minetest.registered_nodes local core_swap_node = minetest.swap_node local deserialize = minetest.deserialize +local get_craft_recipe = minetest.get_craft_recipe local has_creative = creative.is_enabled_for local serialize = minetest.serialize local us_time = minetest.get_us_time @@ -540,8 +541,8 @@ function replacer.on_place(itemstack, player, pt) return end - local node, mode = r.get_data(itemstack) - node = core_get_node_or_nil(pt.under) or node + node = core_get_node_or_nil(pt.under) + if not node then return end -- don't allow setting replacer to denied nodes if r.deny_list[node.name] then @@ -550,78 +551,103 @@ function replacer.on_place(itemstack, player, pt) return end + local _, mode = r.get_data(itemstack) if not modes_are_available then mode = { major = 1, minor = 1 } end local inv = player:get_inventory() - if (not creative_enabled) and r.alias_map[node.name] then - -- apply reverse exception (alias) if not a creatvie user - node.name = r.alias_map[node.name] - elseif (not (creative_enabled and has_give)) - and (not inv:contains_item('main', node.name)) - and (not r.exception_map[node.name]) - and (not r.is_beacon_beam_or_base(node.name)) - and (not r.is_saw_output(node.name)) - then - -- not in inv and not (creative and give) - local found_item = false - local drops = core_get_node_drops(node.name) - if has_creative_or_give then - if 0 < core_get_item_group(node.name, - 'not_in_creative_inventory') - then - -- search for a drop available in creative inventory - for i = 1, #drops do - local name = drops[i] - if core_registered_nodes[name] and - 0 == core_get_item_group(name, - 'not_in_creative_inventory') - then - node.name = name - found_item = true - break - end - end - if not found_item then - r.inform(name, S('Item not in creative inventory: "@1".', node.name)) - return - end + -- helper function for valid() + local function denied_group(name) + for _, group in ipairs(r.deny_groups) do + if 0 < core_get_item_group(name, group) then + return true end - else - -- search for a drop that the player has if possible + end + return false + end + -- helper function for simpler mechanics + local function valid() + -- user with give can get and place anything available + if has_give then return true end + + -- if user has it in inventory it must be ok + if inv:contains_item('main', node.name) then return true end + + -- if there is an alias, apply and allow it + if (not creative_enabled) and r.alias_map[node.name] then + node.name = r.alias_map[node.name] return true + end + + -- it's one of those nodes that consume an item with different name + -- and/or have an after_on_place callback registered + if r.exception_map[node.name] then return true end + + local function can_be_crafted(itemstring) + local input = get_craft_recipe(itemstring) + return input and input.items and true or false + end + -- if it can be crafted, it's ok to use (includes cooking etc.) + if can_be_crafted(node.name) then return true end + + -- give callbacks a chance to allow it + -- they can also manipulate the passed node-table + for _, f in ipairs(r.enable_set_callbacks) do + -- first callback to return something other than nil or false + -- permits to setting the replacer to node + if f(node, player, pt) then return true end + end + + -- now we are scraping the bottom of the barrel + -- let's check if digging this would drop something use-able + -- TODO: check if this is list as defined or random factor incorporated already + -- SwissalpS has the suspicion that it is. When testing on grain crops + -- sometimes was set to seeds and sometimes attempted to set to the crop. + -- This could also be that the table isn't always returned with same sorting. + local drops = core_get_node_drops(node.name) + local drop_name + -- if 0 == core_get_item_group(node.name, 'not_in_creative_inventory') then for i = 1, #drops do - local name = drops[i] - if core_registered_nodes[name] and - inv:contains_item('main', name) + drop_name = drops[i] + if core_registered_nodes[drop_name] -- it's a node not an item-drop + and (not denied_group(drop_name)) + and (inv:contains_item('main', drop_name) + or (0 == core_get_item_group(drop_name, + 'not_in_creative_inventory'))) then - node.name = name - found_item = true - break + -- example dirt_with_rainforest_litter can not be + -- crafted on all servers but drops dirt, so + -- replacer would be set to dirt + node.name = drop_name + return true end + end -- loop drops + -- end -- node is in creative inventory + + if not creative_enabled then return false end + + -- creative users have access to more items + -- but it must be a dig-able node + for i = 1, #drops do + drop_name = drops[i] + if core_registered_nodes[drop_name] -- it's a node not an item-drop + and (not denied_group(drop_name)) + and (0 == core_get_item_group(drop_name, + 'not_in_creative_inventory')) + then + node.name = drop_name + return true end - if not found_item then - -- search for a drop available in creative inventory - -- that first configuring the replacer, - -- then digging the nodes works - for i = 1, #drops do - local name = drops[i] - if core_registered_nodes[name] and - 0 == core_get_item_group(name, - 'not_in_creative_inventory') - then - node.name = name - found_item = true - break - end - end - end - if (not found_item) and (not has_give) then - r.inform(name, S('Item not in your inventory: "@1".', node.name)) - return - end - end + end -- loop drops + + -- well, better luck next time + return false + end -- valid + if not valid() then + r.inform(name, S('Failed to set replacer to "@1". ' + .. 'If you had one in your inventory, it could be set.', node.name)) + return end -- set the params to tool From 7426743bd5b8a5585f914123bac4232e2ac1f1e2 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:42:10 +0100 Subject: [PATCH 201/366] test helper for developement mode places a field of all available nodes or a subset some are skipped by default as they are counter productive or even cause crashes others are just not needed. --- init.lua | 2 + test.lua | 265 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 267 insertions(+) create mode 100644 test.lua diff --git a/init.lua b/init.lua index 988945a..cf04f2d 100644 --- a/init.lua +++ b/init.lua @@ -46,6 +46,8 @@ replacer.group_placeholder = {} replacer.image_replacements = {} local path = minetest.get_modpath('replacer') .. '/' +-- for developers +dofile(path .. 'test.lua') -- strings for translation (i+r) dofile(path .. 'blabla.lua') -- utilities (i+r) diff --git a/test.lua b/test.lua new file mode 100644 index 0000000..e890a63 --- /dev/null +++ b/test.lua @@ -0,0 +1,265 @@ +-- enable developer mode +replacer.dev_mode = + minetest.settings:get_bool('replacer.dev_mode') or false +if not replacer.dev_mode then return end + +function pd(m) print(dump(m)) end +function i(m) replacer.inform('singleplayer', dump(m)) pd(m) end + +replacer.test = {} +local r = replacer +local rt = replacer.test +rt.spacing = 2 +rt.player = nil +rt.facing = vector.new(0, 0, 0) +rt.active = false +rt.no_support = false +rt.move_player = false +rt.nodes_per_step = 444 +rt.air_node = { name = 'air' } +rt.seconds_between_steps = 1.1 +rt.support_node = { name = 'default:cobble' } +-- skip these patterns that return a match with string:find(pattern) +rt.skip = { + -- these can be counter-productive and not replacer nodes + '^air$', '^ignore$', 'corium', '^tnt:', + '^technic:hv_nuclear_reactor_core_active$', + '^default:lava_source$', '^default:lava_flowing$', + '^default:.*water_source$', '^default:.*water_flowing$', + --'^default:large_cactus_seedling$', -- depends on support_node + '^digistuff:heatsink_onic$', -- depends on support_node + --'^farming:seed_', -- depends on support_node + -- these are removed right away + '^illumination:light_', '^morelights_extras:stairlight$', + '^throwing:arrow', '^vacuum:vacuum$', + -- sun matter is harmless, but not needed as not pointable + '^planetoidgen:sun$', + -- not pointable (can right-click with inspection tool to see them) + '^digistuff:piston_pusher$', '^doors:hidden$', '^elevator:placeholder$', + '^fancy_vend:display_node$', + -- these cause crashes + '^advtrains_interlocking:dtrack_npr_st', + '^advtrains_line_automation:dtrack_stop_st', + '^basic_signs:sign_', + '^default:sign_' +} + +function replacer.test.inform(message) + if not rt.player or not rt.player.get_player_name then return end + r.inform(rt.player:get_player_name(), message) +end -- inform +local rti = rt.inform + + +-- This function is quite robust but it still can happen that game crashes. +-- It has worked best if area was already generated and loaded at least once. +-- Don't be too hasty to add nodes to deny-patterns. +-- It probably helps to turn off mesecons_debug and metrics in general for this +-- kind of excercise. +-- It's also advisable to have damage turned off or to wear a hazmat suit when +-- technic is involved and move_player flag is set. +function replacer.test.chatcommand_place_all(player_name, param) + if rt.active then + return false, 'There is an active task in progress, try again later' + end + param = param or '' + local dry_run, skip_corium + local params = param:split(' ') + local patterns = {} + rt.no_support = false + rt.move_player = false + for _, param in ipairs(params) do + if 'dry-run' == param then + dry_run = true + elseif 'move_player' == param then + rt.move_player = true + elseif 'no_support_node' == param then + rt.no_support = true + else + table.insert(patterns, param) + end + end + if 0 == #patterns then table.insert(patterns, '.*') end + rt.player = minetest.get_player_by_name(player_name) + rt.pos = rt.player:get_pos()--vector.add(player:get_pos(), vector.new(1, 0, 1))-- + rt.selected = {} + rt.count = 0 + local function has_match(name, patterns) + for _, pattern in ipairs(patterns) do + if name:find(pattern) then return true end + end + return false + end -- has_match + for name, _ in pairs(minetest.registered_nodes) do + if not has_match(name, rt.skip) + and has_match(name, patterns) + then + table.insert(rt.selected, name) + rt.count = rt.count + 1 + end + end + if 0 == rt.count then + return true, 'Nothing to do.' + end + table.sort(rt.selected) + rt.side, rt.x, rt.z = math.floor((rt.count ^ .5) + .5), 0, 0 + local full_side = rt.spacing * (rt.side + 1) + local pos2 = vector.add(rt.pos, vector.new(full_side, 0, full_side)) + if dry_run then + return true, 'Required space: ' .. r.nice_pos_string(rt.pos) + .. ' to ' .. r.nice_pos_string(pos2) + end + + minetest.emerge_area(rt.pos, vector.add(pos2, vector.new(0, -1, 0))) + rt.i = 1 + rt.active = true + rt.succ_count = 0 + minetest.after(.1, rt.step) + return true, 'Started process' +end -- chatcommand_place_all + + +function replacer.test.step() + -- player may have logged off already + if not rt.active then return end + + local new_item, succ, pos_, pos__, node, name + local function move_player() + if not rt.move_player then return end + + rt.player:set_pos(vector.add(pos_, vector.new(-.25, 0, -1))) + --rt.player:set_rotation(rt.facing) + rt.player:set_look_horizontal(math.rad(0)) + rt.player:set_look_vertical(math.rad(45)) + end -- move_player + + for i = 1, rt.nodes_per_step do + name = rt.selected[rt.i] + node = minetest.registered_nodes[name] + pos_ = vector.add(rt.pos, vector.new(rt.x, 0, rt.z)) + pos__ = vector.add(pos_, vector.new(0, -1, 0)) + -- ensure area is generated and loaded + if rt.check_mapgen(pos_) then + rti('waiting for mapgen') + minetest.after(5, rt.step) + return + end + + if minetest.find_node_near(pos_, 1, 'ignore', true) then + rti('emerging area') + move_player() + minetest.emerge_area(pos_, pos__) + minetest.after(2, rt.step) + return + end + + minetest.set_node(pos_, rt.air_node) + if not rt.no_support then + minetest.set_node(pos__, rt.support_node) + end + move_player() + print(r.nice_pos_string(pos_) .. ' ' .. name) + new_item, succ = node.on_place(ItemStack(node.name), rt.player, { + type = 'node', + under = vector.new(pos_), + above = vector.add(pos_, vector.new(0, 1, 0)) + }) + if (false == succ) or (nil == new_item) then + pd('Could not place ' .. node.name .. ' at ' .. r.nice_pos_string(pos_)) + else + rt.succ_count = rt.succ_count + 1 + end + rt.x = rt.x + rt.spacing if rt.spacing * rt.side < rt.x then + rt.x = 0 + rt.z = rt.z + rt.spacing + end + rt.i = rt.i + 1 + if rt.count < rt.i then break end + end + -- keep player alive + --rt.player:set_hp(55555, { type = 'set_hp', from = 'mod' }) + minetest.do_item_eat(55555, 'farming:bread 99', ItemStack('farming:bread 99'), + rt.player, { type = 'nothing' }) + if rt.count <= rt.i then + rti(tostring(rt.succ_count) .. ' of ' .. tostring(rt.count) + .. ' nodes placed successfuly') + rt.active = false + return + end + + rti('Step ' .. tostring(rt.i) .. ' of ' .. tostring(rt.count) .. ' done') + + minetest.after(rt.seconds_between_steps, rt.step) +end -- step + + +function replacer.test.dealloc_player(player) + if not rt.player or not rt.player.get_player_name then return end + if not rt.player:get_player_name() == player:get_player_name() then return end + rt.active = false + rt.player = nil +end -- dealloc_player + + +minetest.register_on_leaveplayer(rt.dealloc_player) +minetest.register_chatcommand('place_all', { + params = '[dry-run][ move_player][ no_support_node][ [] ... [ ] ]', + description = 'Places one of all registered nodes on a grid in +x,+z plane starting ' + .. 'at player position. You can use dry-run option to detect how much space you will need. ' + .. 'Pass patterns to only place nodes whose name matches. e.g. "^beacon:" "_tinted$" ' + .. '-> only place nodes beginning with "beacon:" i.e. beacon-mod, and all nodes ending ' + .. 'with "_tinted" i.e. paintbrush nodes. To exclude patterns, edit test.lua and add to ' + .. 'rt.skip table.', + func = rt.chatcommand_place_all, + privs = { privs = true } +}) + + +-- from jumpdrive code, mapgen tracking +local events = {} -- list of { minp, maxp, time } + +-- update last mapgen event time +minetest.register_on_generated(function(minp, maxp, seed) + table.insert(events, { + minp = minp, + maxp = maxp, + time = minetest.get_us_time() + }) +end) + + +-- true = mapgen recently active in that area +function replacer.test.check_mapgen(pos) + for _, event in ipairs(events) do + if 200 > vector.distance(pos, event.minp) then + return true + end + end + + return false +end -- check_mapgen + + +-- cleanup +local timer = 0 +minetest.register_globalstep(function(dtime) + timer = timer + dtime + if 5 > timer then return end + + timer = 0 + local time = minetest.get_us_time() + local delay_seconds = 10 + + local copied_events = events + events = {} + + local count = 0 + for _, event in ipairs(copied_events) do + if event.time > (time - (delay_seconds * 1000000)) then + -- still recent + table.insert(events, event) + count = count + 1 + end + end +end) + From e5bf1bf6e6574849eae5483d71c6867385732fea Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:47:45 +0100 Subject: [PATCH 202/366] bunch of compat and improved api mods can now register their machines as crafting methods --- compat/bakedclay.lua | 22 ++++----- compat/beacon.lua | 11 ++++- compat/bridger.lua | 9 ++++ compat/colormachine.lua | 21 +++++++++ compat/default.lua | 16 ++++++- compat/digtron.lua | 7 +++ compat/drawers.lua | 5 +++ compat/farming.lua | 16 +++++++ compat/homedecor.lua | 5 +++ compat/mesecons.lua | 4 ++ compat/mobs.lua | 11 +++-- compat/moreblocks.lua | 32 +++++++++++--- compat/telemosaic.lua | 7 +++ compat/travelnet.lua | 5 +++ compat/unifieddyes.lua | 22 +++++---- inspect.lua | 98 ++++++++++++++++++++--------------------- 16 files changed, 206 insertions(+), 85 deletions(-) create mode 100644 compat/bridger.lua create mode 100644 compat/colormachine.lua create mode 100644 compat/digtron.lua create mode 100644 compat/drawers.lua create mode 100644 compat/farming.lua create mode 100644 compat/homedecor.lua create mode 100644 compat/mesecons.lua create mode 100644 compat/telemosaic.lua create mode 100644 compat/travelnet.lua diff --git a/compat/bakedclay.lua b/compat/bakedclay.lua index 7f7d977..4d9fadd 100644 --- a/compat/bakedclay.lua +++ b/compat/bakedclay.lua @@ -1,12 +1,12 @@ --- add bakedclay items -if replacer.has_bakedclay then - replacer.group_placeholder['group:bakedclay'] = 'bakedclay:natural' - -- unfortunately bakedclay does not expose anything, so we have to manually - -- maintain the list - local rgp = replacer.group_placeholder - rgp['group:flower,color_cyan'] = 'bakedclay:delphinium' - rgp['group:flower,color_pink'] = 'bakedclay:lazarus' - rgp['group:flower,color_dark_green'] = 'bakedclay:mannagrass' - rgp['group:flower,color_magenta'] = 'bakedclay:thistle' -end +if not replacer.has_bakedclay then return end + +-- add bakedclay items for inspection tool +replacer.group_placeholder['group:bakedclay'] = 'bakedclay:natural' +-- unfortunately bakedclay does not expose anything, so we have to manually +-- maintain the list +local rgp = replacer.group_placeholder +rgp['group:flower,color_cyan'] = 'bakedclay:delphinium' +rgp['group:flower,color_pink'] = 'bakedclay:lazarus' +rgp['group:flower,color_dark_green'] = 'bakedclay:mannagrass' +rgp['group:flower,color_magenta'] = 'bakedclay:thistle' diff --git a/compat/beacon.lua b/compat/beacon.lua index b888a3d..1172a12 100644 --- a/compat/beacon.lua +++ b/compat/beacon.lua @@ -1,7 +1,16 @@ -function replacer.is_beacon_beam_or_base(node_name) +if not minetest.get_modpath('beacon') then return end + +local function is_beacon_beam_or_base(node_name) if 'string' ~= type(node_name) then return nil end if node_name:match('^beacon:(.*)beam$') then return true end if node_name:match('^beacon:(.*)base$') then return true end return false end -- is_beacon_beam_or_base +replacer.register_set_enabler(function(node) + return node and node.name and is_beacon_beam_or_base(node.name) +end) + +-- for inspection tool +replacer.group_placeholder['group:beacon'] = 'beacon:white' + diff --git a/compat/bridger.lua b/compat/bridger.lua new file mode 100644 index 0000000..4a70c8e --- /dev/null +++ b/compat/bridger.lua @@ -0,0 +1,9 @@ +if not minetest.get_modpath('bridger') then return end + +local rir = replacer.image_replacements +rir['bridger:corrugated_steelgreen'] = 'bridger:corrugated_steel_green' +rir['bridger:corrugated_steelwhite'] = 'bridger:corrugated_steel_white' +rir['bridger:corrugated_steelred'] = 'bridger:corrugated_steel_red' +rir['bridger:corrugated_steelsteel'] = 'bridger:corrugated_steel_steel' +rir['bridger:corrugated_steelyellow'] = 'bridger:corrugated_steel_yellow' + diff --git a/compat/colormachine.lua b/compat/colormachine.lua new file mode 100644 index 0000000..9827851 --- /dev/null +++ b/compat/colormachine.lua @@ -0,0 +1,21 @@ +if not replacer.has_colormachine_mod then return end + +local function add_colormachine_recipe(node_name, _, recipes) + + local res = colormachine.get_node_name_painted(node_name, '') + if not res or not res.possible or 1 > #res.possible then + return + end + + -- paintable node found + recipes[#recipes + 1] = { + method = 'colormachine', + type = 'colormachine', + items = { res.possible[1] }, + output = node_name + } +end -- add_colormachine_recipe + +replacer.register_craft_method( + 'colormachine', 'colormachine:colormachine', add_colormachine_recipe) + diff --git a/compat/default.lua b/compat/default.lua index e64e641..8518c98 100644 --- a/compat/default.lua +++ b/compat/default.lua @@ -1,16 +1,26 @@ -- replacer has default mod as hard dependancy, so no checking +-- helpers for inspection tool -- some common groups +replacer.group_placeholder['group:water_bucket'] = 'bucket:bucket_river_water' replacer.group_placeholder['group:coal'] = 'default:coal_lump' +replacer.group_placeholder['group:fence'] = 'default:fence_wood' replacer.group_placeholder['group:leaves'] = 'default:leaves' +replacer.group_placeholder['group:marble']= 'technic:marble' -- building_blocks:Marble replacer.group_placeholder['group:sand'] = 'default:sand' replacer.group_placeholder['group:sapling']= 'default:sapling' replacer.group_placeholder['group:stick'] = 'default:stick' -- 'default:stone' point people to the cheaper cobble replacer.group_placeholder['group:stone'] = 'default:cobble' +replacer.group_placeholder['group:tar_block'] = 'building_blocks:Tar' replacer.group_placeholder['group:tree'] = 'default:tree' +replacer.group_placeholder['group:vessel'] = 'fireflies:firefly_bottle' replacer.group_placeholder['group:wood'] = 'default:wood' replacer.group_placeholder['group:wood_slab'] = 'stairs:slab_wood' replacer.group_placeholder['group:wool'] = 'wool:white' +-- pickaxes +local picks = { 'diamond', 'bronze', 'mese', 'steel', 'stone', 'wood' } +table.shuffle(picks) +replacer.group_placeholder['group:pickaxe'] = 'default:pick_' .. picks[1] -- add default game dyes for _, color in pairs(dye.dyes) do @@ -44,6 +54,8 @@ if replacer.has_basic_dyes then end end --- can be crafted, so let it be placed -replacer.register_exception('default:dirt_with_grass', 'default:dirt_with_grass') +-- fix dandelion +replacer.image_replacements['flowers:dandelion'] = 'flowers:dandelion_white' +-- fix pink +replacer.group_placeholder['group:dye,unicolor_light_red'] = 'dye:pink' diff --git a/compat/digtron.lua b/compat/digtron.lua new file mode 100644 index 0000000..e5d38e0 --- /dev/null +++ b/compat/digtron.lua @@ -0,0 +1,7 @@ +if not minetest.get_modpath('digtron') then return end + +-- prevent accidental replacement of digtron crates +-- also placing isn't a good idea either +replacer.deny_list['digtron:loaded_crate'] = true +replacer.deny_list['digtron:loaded_locked_crate'] = true + diff --git a/compat/drawers.lua b/compat/drawers.lua new file mode 100644 index 0000000..a9a5529 --- /dev/null +++ b/compat/drawers.lua @@ -0,0 +1,5 @@ +if not minetest.get_modpath('drawers') then return end + +local rgp = replacer.group_placeholder +rgp['group:drawer'] = 'drawers:wood2' + diff --git a/compat/farming.lua b/compat/farming.lua new file mode 100644 index 0000000..56a202e --- /dev/null +++ b/compat/farming.lua @@ -0,0 +1,16 @@ +if not minetest.get_modpath('farming') then return end + +local rgp = replacer.group_placeholder +rgp['group:food_cheese'] = 'farming:cheese_vegan' +rgp['group:food_meat'] = 'farming:tofu_cooked' +rgp['group:food_saucepan'] = 'farming:saucepan' +rgp['group:food_coffee'] = 'farming:coffee_beans' +rgp['group:food_pot'] = 'farming:pot' +rgp['group:food_corn'] = 'farming:corn' +rgp['group:food_sunflower_seeds'] = 'farming:seed_sunflower' +rgp['group:food_vanilla'] = 'farming:vanilla' +rgp['group:food_peppercorn'] = 'farming:peppercorn' +rgp['group:food_soy'] = 'farming:soy_beans' +rgp['group:food_salt'] = 'farming:salt' +rgp['group:food_juicer'] = 'farming:juicer' + diff --git a/compat/homedecor.lua b/compat/homedecor.lua new file mode 100644 index 0000000..5306578 --- /dev/null +++ b/compat/homedecor.lua @@ -0,0 +1,5 @@ +if not minetest.get_modpath('homedecor_kitchen') then return end + +local rir = replacer.image_replacements +rir['homedecor:kitchen_cabinet'] = 'homedecor:kitchen_cabinet_colorable' + diff --git a/compat/mesecons.lua b/compat/mesecons.lua new file mode 100644 index 0000000..2b2bac2 --- /dev/null +++ b/compat/mesecons.lua @@ -0,0 +1,4 @@ +if not minetest.get_modpath('mesecons') then return end + +replacer.group_placeholder['group:mesecon_conductor_craftable'] = 'mesecons:wire_00000000_off' + diff --git a/compat/mobs.lua b/compat/mobs.lua index ca4c5a8..bf3697d 100644 --- a/compat/mobs.lua +++ b/compat/mobs.lua @@ -1,7 +1,6 @@ --- for some reason cobwebs need this [mobs_monster] --- probably because they drop string when dug and string --- is only a craft item. -if minetest.get_modpath('mobs_monster') then - replacer.register_exception('mobs:cobweb', 'mobs:cobweb') -end +if not minetest.get_modpath('mobs') then return end + +local rgp = replacer.group_placeholder +if not rgp['group:food_cheese'] then rgp['group:food_cheese'] = 'mobs:cheese' end +if not rgp['group:food_meat'] then rgp['group:food_meat'] = 'mobs:meat' end diff --git a/compat/moreblocks.lua b/compat/moreblocks.lua index d087c0b..899e16e 100644 --- a/compat/moreblocks.lua +++ b/compat/moreblocks.lua @@ -1,17 +1,15 @@ local r = replacer -if not r.has_circular_saw then - function replacer.is_saw_output() return nil end - return -end +if not r.has_circular_saw then return end local core_registered_nodes = minetest.registered_nodes local shapes_list_sorted = nil local confirmed_saw_items = {} -function replacer.is_saw_output(node_name) +local function is_saw_output(node_name) if not node_name or 'moreblocks:circular_saw' == node_name then return nil end + -- if we already confirmed this item, let's take the shortcut if confirmed_saw_items[node_name] then return confirmed_saw_items[node_name] end @@ -65,3 +63,27 @@ function replacer.is_saw_output(node_name) return basic_node_name end -- is_saw_output + +local function add_circular_saw_recipe(node_name, _, recipes) + local basic_node_name = is_saw_output(node_name) + if not basic_node_name then return end + + -- node found that fits into the saw + recipes[#recipes + 1] = { + method = 'saw', + type = 'saw', + items = { basic_node_name }, + output = node_name + } +end -- add_circular_saw_recipe + + +-- for replacer +r.register_set_enabler(function(node) + return node and is_saw_output(node.name) +end) + + +-- for inspection tool +r.register_craft_method('saw', 'moreblocks:circular_saw', add_circular_saw_recipe) + diff --git a/compat/telemosaic.lua b/compat/telemosaic.lua new file mode 100644 index 0000000..c153fa6 --- /dev/null +++ b/compat/telemosaic.lua @@ -0,0 +1,7 @@ +if not minetest.get_modpath('telemosaic') then return end + +local rgp = replacer.group_placeholder +rgp['group:telemosaic_extender_one'] = 'telemosaic:extender_one' +rgp['group:telemosaic_extender_two'] = 'telemosaic:extender_two' +rgp['group:telemosaic_extender_three'] = 'telemosaic:extender_three' + diff --git a/compat/travelnet.lua b/compat/travelnet.lua new file mode 100644 index 0000000..1cb3e68 --- /dev/null +++ b/compat/travelnet.lua @@ -0,0 +1,5 @@ +if not minetest.get_modpath('telemosaic') then return end + +local rgp = replacer.group_placeholder +rgp['group:travelnet'] = 'travelnet:travelnet' + diff --git a/compat/unifieddyes.lua b/compat/unifieddyes.lua index a040109..7baf655 100644 --- a/compat/unifieddyes.lua +++ b/compat/unifieddyes.lua @@ -2,19 +2,17 @@ replacer.unifieddyes = {} local ud = replacer.unifieddyes if not replacer.has_unifieddyes_mod then + -- replacer uses this function ud.colour_name(param2, node_def) return '' end - function ud.add_recipe(node_name, recipes) return recipes end return end local make_readable_color = unifieddyes.make_readable_color local colour_to_name = unifieddyes.color_to_name --- for inspector formspec -function replacer.unifieddyes.add_recipe(param2, node_name, recipes) - if not param2 then - return recipes - end +-- for inspection tool formspec +local function add_recipe(node_name, param2, recipes) + if not param2 then return end local node_def = minetest.registered_items[node_name] if ud.is_airbrushed(node_def) then @@ -25,14 +23,14 @@ function replacer.unifieddyes.add_recipe(param2, node_name, recipes) first, last = t.output:find(needle) if nil ~= first then recipes[#recipes + 1] = t - return recipes + return end end end - - return recipes end -- add_recipe +replacer.register_craft_method('unifieddyes:airbrush', 'unifieddyes:airbrush', add_recipe) + function replacer.unifieddyes.colour_name(param2, node_def) param2 = tonumber(param2) @@ -69,6 +67,12 @@ function replacer.unifieddyes.is_airbrushed(node_def) if nil ~= node_def.name:find('_tinted$') then return true end + --[[ tried to fix scifi_nodes white2 ... _colored + didn't work this way even though airbrush was used to paint them + if nil ~= node_def.name:find('_colored$') then + return true + end + --]] return not node_def.airbrush_replacement_node end -- is_airbrushed diff --git a/inspect.lua b/inspect.lua index 5174308..27d79db 100644 --- a/inspect.lua +++ b/inspect.lua @@ -14,6 +14,43 @@ local floor = math.floor local chat = minetest.chat_send_player local mfe = minetest.formspec_escape +-- use r.register_craft_method() to populate +replacer.recipe_adders = {} + +-- uid: unique identifier e.g. 'saw', 'compress', 'freeze' +-- machine_itemstring: the itemstring that has registered icon texture, +-- generally the machine used. +-- func_inspect: function that manipulates recipes list with signature: +-- f(node_name, param2, recipes) +-- returns nothing, just adds recipes to recipes list +-- func_formspec: optional function that returns extra formspec elements +-- f(recipe) +-- where recipe is the recipe table func_inspect added. +-- returns a string, even if empty. +function replacer.register_craft_method(uid, machine_itemstring, func_inspect, + func_formspec) + if ('string' ~= type(uid) or '' == uid) + or ('string' ~= type(machine_itemstring) + or not minetest.registered_items[machine_itemstring]) + or 'function' ~= type(func_inspect) + then + minetest.log('warning', rbi.log_reg_craft_method_wrong_arguments) + return + end + + if r.recipe_adders[uid] then + minetest.log('warning', rbi.log_reg_craft_method_overriding_method .. uid) + end + + r.recipe_adders[uid] = { + machine = machine_itemstring, + add_recipe = func_inspect, + formspec = ('function' == type(func_formspec) and func_formspec) or nil + } + minetest.log('info', rbi.log_reg_craft_method_added:format(uid, machine_itemstring)) +end -- register_craft_method + + minetest.register_tool('replacer:inspect', { description = rbi.description, groups = {}, @@ -167,41 +204,6 @@ function replacer.image_button_link(stack_string) end -- image_button_link -function replacer.add_circular_saw_recipe(node_name, recipes) - local basic_node_name = r.is_saw_output(node_name) - if not basic_node_name then return end - - -- node found that fits into the saw - recipes[#recipes + 1] = { - method = 'saw', - type = 'saw', - items = { basic_node_name }, - output = node_name - } - return recipes -end -- add_circular_saw_recipe - - -function replacer.add_colormachine_recipe(node_name, recipes) - if not r.has_colormachine_mod then - return - end - local res = colormachine.get_node_name_painted(node_name, '') - - if not res or not res.possible or 1 > #res.possible then - return - end - -- paintable node found - recipes[#recipes + 1] = { - method = 'colormachine', - type = 'colormachine', - items = { res.possible[1] }, - output = node_name - } - return recipes -end -- add_colormachine_recipe - - function replacer.inspect_show_crafting(player_name, node_name, fields) if not player_name then return @@ -241,11 +243,11 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) -- -- add special recipes for nodes created by machines - r.add_circular_saw_recipe(node_name, res) - r.add_colormachine_recipe(node_name, res) - r.unifieddyes.add_recipe(fields.param2, node_name, res) + for _, adder in pairs(r.recipe_adders) do + adder.add_recipe(node_name, fields.param2, res) + end - -- offer all alternate creafting recipes thrugh prev/next buttons + -- offer all alternate crafting recipes through prev/next buttons if fields and fields.prev_recipe and 1 < recipe_nr then recipe_nr = recipe_nr - 1 elseif fields and fields.next_recipe and recipe_nr < #res then @@ -392,22 +394,16 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) .. r.image_button_link('default:furnace') .. ']' .. 'item_image_button[2.9,2.7;1.0,1.0;' .. r.image_button_link(recipe.items[1]) .. ']' - elseif 'colormachine' == recipe.type - and recipe.items - and 1 == #recipe.items + elseif recipe.items + and 1 == #recipe.items -- TODO: investigate if this shouldn't be 0 < #recipe.items + and r.recipe_adders[recipe.type] then + local handler = r.recipe_adders[recipe.type] formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' - .. r.image_button_link('colormachine:colormachine') .. ']' + .. r.image_button_link(handler.machine) .. ']' .. 'item_image_button[2,2;1.0,1.0;' .. r.image_button_link(recipe.items[1]) .. ']' - elseif 'saw' == recipe.type - and recipe.items - and 1 == #recipe.items - then - formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' - .. r.image_button_link('moreblocks:circular_saw') .. ']' - .. 'item_image_button[2,0.6;1.0,1.0;' - .. r.image_button_link(recipe.items[1]) .. ']' + .. (handler.formspec and handler.formspec(recipe) or '') else formspec = formspec .. 'label[3,1;' .. mfe(rbi.unkown_recipe) .. ']' end From 78e19a273d5c0bf0caff7b5e306ccfbd481ec9d3 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:48:30 +0100 Subject: [PATCH 203/366] technic 'crafting' methods --- compat/technic.lua | 186 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) diff --git a/compat/technic.lua b/compat/technic.lua index 1941733..42a0446 100644 --- a/compat/technic.lua +++ b/compat/technic.lua @@ -18,3 +18,189 @@ end -- can be frozen, so let it be placed replacer.register_exception('default:dirt_with_snow', 'default:dirt_with_snow') +-- allow cnc output nodes +replacer.register_set_enabler(function(node) + return node and node.name and node.name:find('_technic_cnc_') and true or false +end) + +------------------------------------------ +----------- for inpection tool ----------- +------------------------------------------ +-- have not tested 'other' technic mod, so just support technic.plus +--if not technic.plus then return end + +--[[ +--"cooking" is probably not needed as that is a standard method +]] + +local function add_recipe_alloy(item_name, _, recipes) +--pd(technic.recipes['alloy']) + for input_name, def in pairs(technic.recipes['alloy']['recipes']) do + if def.output and 'string' == type(def.output) + and def.output:find('^' .. item_name .. ' ?[0-9]*$') + and def.input and 'table' == type(def.input) + then + local l = {} + for k, v in pairs(def.input) do table.insert(l, k) end + local i1, i2 = l[1], l[2] + recipes[#recipes + 1] = { + method = 'alloy', + type = 'technic:alloy', + items = { i1 }, + output = item_name, + item2 = i2 + } + end + end +end -- add_recipe_alloy + +local function add_formspec_alloy(recipe) + if not recipe.item2 then return '' end + return 'item_image_button[3,2;1.0,1.0;' + .. replacer.image_button_link(recipe.item2) .. ']' +end + +replacer.register_craft_method( + 'technic:alloy', 'technic:coal_alloy_furnace', add_recipe_alloy, add_formspec_alloy) + + +local function add_recipe_cnc(item_name, _, recipes) + local base_name, program = item_name:match('^(.*)_technic_cnc_(.*)$') + if not base_name then return end + + recipes[#recipes + 1] = { + method = 'cnc', + type = 'technic:cnc', + items = { base_name }, + output = item_name, + program = program:gsub('_', ' ') + } +end -- add_recipe_freeze + +local function add_formspec_cnc(recipe) + if not recipe.program then return '' end + return 'label[3,1;' .. recipe.program .. ']' +end + +replacer.register_craft_method('technic:cnc', 'technic:cnc', add_recipe_cnc, add_formspec_cnc) + + +local function add_recipe_compress(item_name, _, recipes) +--pd(technic.recipes['compressing']) + for input_name, def in pairs(technic.recipes['compressing']['recipes']) do + if def.output and def.output == item_name then + recipes[#recipes + 1] = { + method = 'compress', + type = 'technic:compress', + items = { input_name }, + output = item_name + } + end + end +end -- add_recipe_compress + +replacer.register_craft_method('technic:compress', 'technic:lv_compressor', add_recipe_compress) + + +local function add_recipe_extract(item_name, _, recipes) +--pd(technic.recipes['extracting']) + for input_name, def in pairs(technic.recipes['extracting']['recipes']) do + if def.output and 'string' == type(def.output) + and def.output:find('^' .. item_name .. ' ?[0-9]*$') + then + recipes[#recipes + 1] = { + method = 'extract', + type = 'technic:extract', + items = { input_name }, + output = item_name + } + end + end +end -- add_recipe_extract + +replacer.register_craft_method('technic:extract', 'technic:lv_extractor', add_recipe_extract) + + +local function add_recipe_freeze(item_name, _, recipes) + for input_name, def in pairs(technic.recipes['freezing']['recipes']) do + if def.output + and (def.output == item_name + or ('table' == type(def.output) + and def.output[1] == item_name)) + then + recipes[#recipes + 1] = { + method = 'freeze', + type = 'technic:freeze', + items = { input_name }, + output = item_name + } + end + end +end -- add_recipe_freeze + +replacer.register_craft_method('technic:freeze', 'technic:mv_freezer', add_recipe_freeze) + + +local function add_recipe_grind(item_name, _, recipes) +--pd(technic.recipes['grinding']) + for input_name, def in pairs(technic.recipes['grinding']['recipes']) do + if def.output and 'string' == type(def.output) + and def.output:find('^' .. item_name .. ' ?[0-9]*$') + then + recipes[#recipes + 1] = { + method = 'grind', + type = 'technic:grind', + items = { input_name }, + output = item_name + } + end + end +end -- add_recipe_grind + +replacer.register_craft_method('technic:grind', 'technic:lv_grinder', add_recipe_grind) + + +local function add_recipe_separate(item_name, _, recipes) +--pd(technic.recipes['separating']) + for input_name, def in pairs(technic.recipes['separating']['recipes']) do + if def.output and 'table' == type(def.output) then + local clean, cleaned, found = '', {}, false + for _, output in ipairs(def.output) do + clean = output:match('^([^ ]+)') + if clean == item_name then + found = true + else + table.insert(cleaned, clean) + end + end + if found then + recipes[#recipes + 1] = { + method = 'separate', + type = 'technic:separate', + items = { input_name }, + output = item_name, + output_other = cleaned + } + end -- if found + end -- if output is table + end -- loop +end -- add_recipe_separate + +local function add_formspec_separate(recipe) + if not recipe.output_other or 0 == #recipe.output_other then + return '' + end + + local out = 'item_image_button[5,3;1.0,1.0;' + .. replacer.image_button_link(recipe.output_other[1]) .. ']' + if recipe.output_other[2] then + out = out .. 'item_image_button[5,1;1.0,1.0;' + .. replacer.image_button_link(recipe.output_other[2]) .. ']' + end + return out +end -- add_formspec_separate + +replacer.register_craft_method( + 'technic:separate', 'technic:mv_centrifuge', + add_recipe_separate, add_formspec_separate) + From 7eb4430b039e1fe2a78e2ec73b09b375a0bf9ee4 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:49:19 +0100 Subject: [PATCH 204/366] add planetoidgen:airlight to air-like nodes --- replacer/patterns.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/replacer/patterns.lua b/replacer/patterns.lua index 3fe53c0..24c1c81 100644 --- a/replacer/patterns.lua +++ b/replacer/patterns.lua @@ -38,8 +38,9 @@ function replacer.patterns.replaceable(pos, node_name, player_name, param2) -- TODO: add mechanism to register allowed types -- some servers might have other nodes like mars-lights that should be allowed too -- maybe dummy lights, on the other hand, it might be useful to be able to stop replacer with dummy lights - return (('air' == node.name) or ('vacuum:vacuum' == node.name)) - and (not is_protected(pos, player_name)) + return (('air' == node.name) or ('vacuum:vacuum' == node.name) + or 'planetoidgen:airlight' == node.name) + and (not is_protected(pos, player_name)) end -- in field mode we also check that param2 is the same as the -- initial node that was clicked on From 5c96541faa649d8baa9576678f0792b2601068f9 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:50:37 +0100 Subject: [PATCH 205/366] whitespace and comments --- compat/vines.lua | 4 ++++ inspect.lua | 1 + replacer/replacer.lua | 14 +++++++++++--- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/compat/vines.lua b/compat/vines.lua index 5b43699..10bfec6 100644 --- a/compat/vines.lua +++ b/compat/vines.lua @@ -1,6 +1,10 @@ if not minetest.get_modpath('vines') then return end +-- for inspection tool replacer.group_placeholder['group:vines'] = 'vines:vines' + +-- for replacer, so player can set to any part of vine and then replacer +-- uses the '_end' part to place local vines = { 'jungle', 'root', 'side', 'vine', 'willow' } local name_base, name_end, name_middle for _, name in ipairs(vines) do diff --git a/inspect.lua b/inspect.lua index 27d79db..3f02293 100644 --- a/inspect.lua +++ b/inspect.lua @@ -188,6 +188,7 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) return nil -- no item shall be removed from inventory end -- replacer.inspect + function replacer.image_button_link(stack_string) local group = '' if r.image_replacements[stack_string] then diff --git a/replacer/replacer.lua b/replacer/replacer.lua index b375ad4..d82fb33 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -44,6 +44,8 @@ replacer.mode_colours = { { '#38fb9a', '#21cc79', '#10bb68' }, { '#f4b755', '#d29533', '#9F6200' } } + + function replacer.get_data(stack) local meta = stack:get_meta() local data = meta:get_string('replacer'):split(' ') or {} @@ -58,6 +60,7 @@ function replacer.get_data(stack) return node, mode end -- get_data + function replacer.set_data(stack, node, mode) node = 'table' == type(node) and node or {} -- allow passing nil mode -> when ignoring mode in history @@ -103,6 +106,7 @@ function replacer.set_data(stack, node, mode) return short_description end -- set_data + if r.has_technic_mod then if technic.plus then replacer.get_charge = technic.get_RE_charge @@ -141,6 +145,7 @@ else function replacer.get_charge() return r.max_charge end end + -- replaces one node with another one and returns if it was successful function replacer.replace_single_node(pos, node_old, node_new, player, name, inv, creative) @@ -237,6 +242,7 @@ function replacer.replace_single_node(pos, node_old, node_new, player, return true end -- replace_single_node + -- the function which happens when the replacer is used -- also called by on_place if sneak isn't pressed function replacer.on_use(itemstack, player, pt, right_clicked) @@ -488,6 +494,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) return itemstack end -- on_use + -- right-click with tool -> place set node -- special+right-click -> cycle major mode (if tool/privs permit) -- special+sneak+right-click -> cycle minor mode (if tool/privs permit) @@ -505,7 +512,7 @@ function replacer.on_place(itemstack, player, pt) local is_technic = itemstack:get_name() == r.tool_name_technic local modes_are_available = is_technic or creative_enabled - -- is special-key held? (aka fast-key) + -- is special-key held? (aka fast-key) -> change mode if keys.aux1 then -- don't want anybody to think that special+rc = place if not modes_are_available then return end @@ -528,7 +535,7 @@ function replacer.on_place(itemstack, player, pt) r.set_data(itemstack, node, mode) -- return changed tool return itemstack - end + end -- change mode -- If not holding sneak key, place node(s) if not keys.sneak then @@ -555,7 +562,6 @@ function replacer.on_place(itemstack, player, pt) if not modes_are_available then mode = { major = 1, minor = 1 } end - local inv = player:get_inventory() -- helper function for valid() @@ -660,6 +666,7 @@ function replacer.on_place(itemstack, player, pt) return itemstack --data changed end -- on_place + function replacer.tool_def_basic() return { description = rb.description_basic, @@ -674,6 +681,7 @@ function replacer.tool_def_basic() } end + minetest.register_tool(r.tool_name_basic, r.tool_def_basic()) if r.has_technic_mod then From a1df009b37c81ccdb1cc6f5259bbec2923223263 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:51:05 +0100 Subject: [PATCH 206/366] changed error messages --- replacer/constrain.lua | 3 ++- replacer/replacer.lua | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/replacer/constrain.lua b/replacer/constrain.lua index dad2662..c3d94bc 100644 --- a/replacer/constrain.lua +++ b/replacer/constrain.lua @@ -62,7 +62,8 @@ function replacer.permit_replace(pos, old_node_def, new_node_def, player_ref, player_name, player_inv, creative_or_give) if r.deny_list[old_node_def.name] then - return false, rb.deny_listed:format(old_node_def.name) + return false, S('Replacing nodes of type "@1" is not allowed ' + .. 'on this server. Replacement failed.', old_node_def.name) end if is_protected(pos, player_name) then diff --git a/replacer/replacer.lua b/replacer/replacer.lua index d82fb33..00e5aac 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -553,8 +553,8 @@ function replacer.on_place(itemstack, player, pt) -- don't allow setting replacer to denied nodes if r.deny_list[node.name] then - r.inform(name, S('Replacing nodes of type "@1" is not allowed on this server. ' - .. 'Replacement failed.', node.name)) + r.inform(name, S('Placing nodes of type "@1" is not ' + .. 'allowed on this server.', node.name)) return end From c1630bcfb931df129ed79bdd9296a2eb5213af95 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:52:04 +0100 Subject: [PATCH 207/366] dev mode switching from GUI --- settingtypes.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/settingtypes.txt b/settingtypes.txt index b470bc2..6b24a67 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -27,4 +27,6 @@ replacer.hide_recipe_basic (Hide basic recipe) bool false replacer.hide_recipe_technic_upgrade (Hide upgrade recipe) bool false # Hide the direct upgrade recipe. Only available if technic is installed. replacer.hide_recipe_technic_direct (Hide direct recipe) bool true +# Enable developer mode +replacer.dev_mode (Enable developer mode) bool false From 0d5caee145708cf5af4b271ef65a11c65264ebcd Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 03:58:01 +0100 Subject: [PATCH 208/366] TODO update --- TODO | 64 ++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/TODO b/TODO index 71d4257..c1c22a4 100644 --- a/TODO +++ b/TODO @@ -1,21 +1,55 @@ --- known incompat replacer ------------------------ -most of the coloured nodes work, just not setting without -at least one in inventory -these should be solve-able with a general lookup similar to what -inspect already does, but return an itemstring for correct -consumption node --- framed steel obsidian glass tinted --- new glass --- unified bricks bricks and clay (coloured) --- sci-fi plastic coloured --- stained glass coloured (normal and trap) +-- inspection tool: add button to open unified_inventory's formspec + this may no longer be as important and isn't that practical as there are + now so many buttons. It would be hard to keep clear which item will be shown. + SwissalpS: by using player:set_inventory_formspec() unified_inventory + binds itself to the 'i'-key + https://github.com/minetest-mods/unified_inventory/blob/d6688872c84417d2f61d6f5e607aea39d78920aa/internal.lua#L302-L306 + I think you could open it by sending the formspec from + unified_inventory.get_formspec(player, page) + maybe we can use this on group buttons + +-- inspection tool: add wrap-around for prev, next buttons + +-- inspection tool: add support for letter stencil and ehlphibet machines + also fermenting barrels and shears (both vines and wool) + elphabet blocks and stickers insert ehlphi block for block and paper for sicker + canned_.*_plus items could use a 'craft'-method --- telemosaic extenders (coloured) probably will need a compat like beacon beams --- default clay (baked works) +-- inspection tool: add input/output amounts for technic machine processes +-- inspection tool: put the translated texts of prev/next buttons into tooltips and show generic icon + instead of abreviating texts. + +-- known incompat replacer ------------------------ +-- sci-fi plastic coloured -- doors in general (low priority) +-- punched letter -- elphabet:xx (lowest priority) + ---------- known incompat inspect ----------- --- soundblock recipe does not correctly show mesecon wires --- same for fpga and delayer (works with gates though also eeprom and some others) +-- no recipe for silicon lump + +---- missing icons ---- +-- fix in scifi_nodes +flowers:dandelion --> dandelion_white and dandelion_yellow would exist (*scifi_nodes:plant10 also 9) + +-- fix in homedecor_kitchen +homedecor:kitchen_cabinet --> homedecor:kitchen_cabinet_colorable * + +-- fix these in bridger mod +bridger:corrugated_steelgreen --> bridger:corrugated_steel_green * +bridger:corrugated_steelwhite +bridger:corrugated_steelred +bridger:corrugated_steelsteel +bridger:corrugated_steelyellow + +-- has unknown items in recipe -- +-- stained_glass? which one? + +-- glowlight has trouble finding base recipe, also desk_lamp, ceiling lantern, ceiling lamp, + ground lantern, hanging lantern, kitchen cabinet coloured, latice lantern, table lamp, + standing lamp, rope light/on floor, plasma lamp, plasma ball, wall lamp, +-- dvd_cd_cabinet, chains, wood_table_large_square have no recipe at all + +-- christmas presents say they don't drop anything From f9317b2a36b6742359520f68e64425f537c8c969 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 04:00:58 +0100 Subject: [PATCH 209/366] version bump 3.9 --- init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index cf04f2d..f6d69a7 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 3.8.1 (20220120) +-- Version 3.9 (20220123) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220120.1 +replacer.version = 20220123 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From 85bb9e9fe612bae57947219b2d8d2d329bf24b29 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 14:10:33 +0100 Subject: [PATCH 210/366] compat for sci-fi plastic --- compat/unifieddyes.lua | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/compat/unifieddyes.lua b/compat/unifieddyes.lua index 7baf655..df96ca5 100644 --- a/compat/unifieddyes.lua +++ b/compat/unifieddyes.lua @@ -67,12 +67,13 @@ function replacer.unifieddyes.is_airbrushed(node_def) if nil ~= node_def.name:find('_tinted$') then return true end - --[[ tried to fix scifi_nodes white2 ... _colored - didn't work this way even though airbrush was used to paint them - if nil ~= node_def.name:find('_colored$') then - return true - end - --]] return not node_def.airbrush_replacement_node end -- is_airbrushed + +-- mostly for scifi_nodes plastic. +replacer.register_set_enabler(function(node) + return node and node.name + and ud.is_airbrush_compatible(minetest.registered_nodes[node.name]) +end) + From b38faa7b7eeab83607dd534ae6b0c955525762c4 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 14:13:52 +0100 Subject: [PATCH 211/366] advtrains compat --- compat/advtrains.lua | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 compat/advtrains.lua diff --git a/compat/advtrains.lua b/compat/advtrains.lua new file mode 100644 index 0000000..bbb668f --- /dev/null +++ b/compat/advtrains.lua @@ -0,0 +1,24 @@ +local function add_advtrains_aliases() + if not minetest.get_modpath('advtrains') then return end + + local core_get_node_drops = minetest.get_node_drops + local reg = replacer.register_non_creative_alias + -- these cause crashes + local deny_list = { + ['advtrains_interlocking:dtrack_npr_st'] = true, + ['advtrains_line_automation:dtrack_stop_st'] = true, + } + local drops, drop_name + for name, _ in pairs(minetest.registered_nodes) do + if not deny_list[name] and name:find('^advtrains') then + drops = core_get_node_drops(name) + drop_name = drops and drops[1] or '' + if drop_name ~= name then + reg(name, drop_name) + end + end + end +end -- add_advtrains_aliases + +minetest.after(.2, add_advtrains_aliases) + From 5d92b77f255627aad7f774c0f687e0d61cb1c578 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 14:16:57 +0100 Subject: [PATCH 212/366] check deny group earlier --- replacer/replacer.lua | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 00e5aac..7017c93 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -552,7 +552,16 @@ function replacer.on_place(itemstack, player, pt) if not node then return end -- don't allow setting replacer to denied nodes - if r.deny_list[node.name] then + -- helper function for valid() + local function denied_group(name) + for _, group in ipairs(r.deny_groups) do + if 0 < core_get_item_group(name, group) then + return true + end + end + return false + end + if r.deny_list[node.name] or denied_group(node.name) then r.inform(name, S('Placing nodes of type "@1" is not ' .. 'allowed on this server.', node.name)) return @@ -563,17 +572,11 @@ function replacer.on_place(itemstack, player, pt) mode = { major = 1, minor = 1 } end local inv = player:get_inventory() - - -- helper function for valid() - local function denied_group(name) - for _, group in ipairs(r.deny_groups) do - if 0 < core_get_item_group(name, group) then - return true - end - end - return false + -- helper functions for simpler mechanics + local function can_be_crafted(itemstring) + local input = get_craft_recipe(itemstring) + return input and input.items and true or false end - -- helper function for simpler mechanics local function valid() -- user with give can get and place anything available if has_give then return true end @@ -590,10 +593,6 @@ function replacer.on_place(itemstack, player, pt) -- and/or have an after_on_place callback registered if r.exception_map[node.name] then return true end - local function can_be_crafted(itemstring) - local input = get_craft_recipe(itemstring) - return input and input.items and true or false - end -- if it can be crafted, it's ok to use (includes cooking etc.) if can_be_crafted(node.name) then return true end From bf8975ec2600e50e02ef7e73aed15a1f95cab85a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 15:06:13 +0100 Subject: [PATCH 213/366] prefab compat no longer needed --- compat/prefab.lua | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 compat/prefab.lua diff --git a/compat/prefab.lua b/compat/prefab.lua deleted file mode 100644 index d690816..0000000 --- a/compat/prefab.lua +++ /dev/null @@ -1,7 +0,0 @@ -if not minetest.get_modpath('prefab') then return end - -local name = 'prefab:concrete_with_grass' -replacer.register_exception(name, name) --- not adding the inverted slabs as they can't be rotated --- anyway, and there are the table-saw slabs too. - From 0cfda2363108c06bf121d557c126ae4cf30b364f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 15:06:56 +0100 Subject: [PATCH 214/366] bugfix actually check groups --- replacer/replacer.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 7017c93..5f11796 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -553,9 +553,9 @@ function replacer.on_place(itemstack, player, pt) -- don't allow setting replacer to denied nodes -- helper function for valid() - local function denied_group(name) - for _, group in ipairs(r.deny_groups) do - if 0 < core_get_item_group(name, group) then + local function denied_group(item_name) + for group, val in pairs(r.deny_groups) do + if val and 0 < core_get_item_group(item_name, group) then return true end end From ef398fc62ab73e0d1eb4e856b80b40fd295e2a1d Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 20:00:32 +0100 Subject: [PATCH 215/366] compat for canned_food incl. pickling --- TODO | 2 -- compat/canned_food.lua | 30 ++++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 compat/canned_food.lua diff --git a/TODO b/TODO index c1c22a4..bdb185b 100644 --- a/TODO +++ b/TODO @@ -13,7 +13,6 @@ -- inspection tool: add support for letter stencil and ehlphibet machines also fermenting barrels and shears (both vines and wool) elphabet blocks and stickers insert ehlphi block for block and paper for sicker - canned_.*_plus items could use a 'craft'-method -- inspection tool: add input/output amounts for technic machine processes @@ -21,7 +20,6 @@ instead of abreviating texts. -- known incompat replacer ------------------------ --- sci-fi plastic coloured -- doors in general (low priority) -- punched letter -- elphabet:xx (lowest priority) diff --git a/compat/canned_food.lua b/compat/canned_food.lua new file mode 100644 index 0000000..cb20d1a --- /dev/null +++ b/compat/canned_food.lua @@ -0,0 +1,30 @@ +if not minetest.get_modpath('canned_food') then return end + +local S = replacer.S + +-- for inspection tool +local function add_recipe(item_name, _, recipes) + local base_name = item_name:match('^(canned_food:.+)_plus$') + if not base_name then return end + + recipes[#recipes + 1] = { + method = 'ferment', + type = 'canned_food', + items = { base_name }, + output = item_name, + } +end -- add_recipe + +local function add_formspec(recipe) + return 'label[0.5,3.5;' .. S('Store near group:wood, light < 12.') .. ']' +end + +replacer.register_craft_method('canned_food', 'default:wood', add_recipe, add_formspec) + + +-- for replacer +replacer.register_set_enabler(function(node) + return node and 'string' == type(node.name) + and node.name:find('^(canned_food:.+)_plus$') and true or false +end) + From bcd7848d4309d3bb61d1a53dad0e6eb60ceee584 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 21:22:51 +0100 Subject: [PATCH 216/366] wrap around prev. next --- inspect.lua | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/inspect.lua b/inspect.lua index 3f02293..fa3aa50 100644 --- a/inspect.lua +++ b/inspect.lua @@ -249,11 +249,17 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) end -- offer all alternate crafting recipes through prev/next buttons - if fields and fields.prev_recipe and 1 < recipe_nr then + if fields and fields.prev_recipe then recipe_nr = recipe_nr - 1 - elseif fields and fields.next_recipe and recipe_nr < #res then + elseif fields and fields.next_recipe then recipe_nr = recipe_nr + 1 end + -- wrap around + if #res < recipe_nr then + recipe_nr = 1 + elseif 1 > recipe_nr then + recipe_nr = #res + end local desc = ' ' .. rbi.no_desc .. ' ' if minetest.registered_nodes[node_name] then @@ -310,15 +316,10 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) .. mfe(fields.protected_info) .. ']' end - if #res < recipe_nr or 1 > recipe_nr then - recipe_nr = 1 - end - if 1 < recipe_nr then + if 1 < #res then formspec = formspec .. 'button[3.8,5;1,0.75;prev_recipe;' .. mfe(rbi.prev) .. ']' - end - if #res > recipe_nr then - formspec = formspec .. 'button[5.0,5.0;1,0.75;next_recipe;' + .. 'button[5.0,5.0;1,0.75;next_recipe;' .. mfe(rbi.next) .. ']' end if 1 > #res then From d7c821a647d52a9346fe92019d9e528b6ac76de3 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 21:27:12 +0100 Subject: [PATCH 217/366] show next prev. buttons under 'this is' text --- inspect.lua | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/inspect.lua b/inspect.lua index fa3aa50..a6c4b77 100644 --- a/inspect.lua +++ b/inspect.lua @@ -288,6 +288,15 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) .. 'label[0,0;' .. mfe(rbi.name) .. ' ' .. node_name .. ']' .. 'item_image_button[5,2;1.0,1.0;' .. node_name .. ';normal;]' .. 'button_exit[5.0,4.3;1,0.5;quit;' .. mfe(rbi.exit) .. ']' + + if 1 < #res then + formspec = formspec .. 'button[3.8,5;1,0.75;prev_recipe;' + .. mfe(rbi.prev) .. ']' + .. 'button[5.0,5.0;1,0.75;next_recipe;' + .. mfe(rbi.next) .. ']' + end + + formspec = formspec .. 'label[0,5.5;' .. mfe(rbi.this_is) .. ' ' .. mfe(desc) .. ']' -- invisible field for passing on information .. 'field[20,20;0.1,0.1;node_name;node_name;' .. node_name .. ']' @@ -316,12 +325,6 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) .. mfe(fields.protected_info) .. ']' end - if 1 < #res then - formspec = formspec .. 'button[3.8,5;1,0.75;prev_recipe;' - .. mfe(rbi.prev) .. ']' - .. 'button[5.0,5.0;1,0.75;next_recipe;' - .. mfe(rbi.next) .. ']' - end if 1 > #res then formspec = formspec .. 'label[3,1;' .. mfe(rbi.no_recipes) .. ']' if minetest.registered_nodes[node_name] From 65ea3c29bab6955b010fedafb57a43d56b554c0a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 21:50:31 +0100 Subject: [PATCH 218/366] tooltips for better translations --- inspect.lua | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/inspect.lua b/inspect.lua index a6c4b77..bf85e8d 100644 --- a/inspect.lua +++ b/inspect.lua @@ -287,13 +287,15 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) local formspec = 'size[6,6]' .. 'label[0,0;' .. mfe(rbi.name) .. ' ' .. node_name .. ']' .. 'item_image_button[5,2;1.0,1.0;' .. node_name .. ';normal;]' - .. 'button_exit[5.0,4.3;1,0.5;quit;' .. mfe(rbi.exit) .. ']' + .. 'button_exit[5.0,4.3;1,0.5;quit;X]' + .. 'tooltip[quit;'.. mfe(rbi.exit) .. ']' if 1 < #res then - formspec = formspec .. 'button[3.8,5;1,0.75;prev_recipe;' - .. mfe(rbi.prev) .. ']' - .. 'button[5.0,5.0;1,0.75;next_recipe;' - .. mfe(rbi.next) .. ']' + formspec = formspec + .. 'button[3.8,5;1,0.75;prev_recipe;<-]' + .. 'tooltip[prev_recipe;'.. mfe(rbi.prev) .. ']' + .. 'button[5.0,5.0;1,0.75;next_recipe;->]' + .. 'tooltip[next_recipe;'.. mfe(rbi.next) .. ']' end formspec = formspec From 45a859ffb1f0fe394d482d21085a6bb95f37cc89 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 21:51:47 +0100 Subject: [PATCH 219/366] update TODO --- TODO | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/TODO b/TODO index bdb185b..fe87866 100644 --- a/TODO +++ b/TODO @@ -8,22 +8,19 @@ unified_inventory.get_formspec(player, page) maybe we can use this on group buttons --- inspection tool: add wrap-around for prev, next buttons - -- inspection tool: add support for letter stencil and ehlphibet machines also fermenting barrels and shears (both vines and wool) - elphabet blocks and stickers insert ehlphi block for block and paper for sicker + elphabet blocks and stickers insert ehlphi block for block and paper for sticker -- inspection tool: add input/output amounts for technic machine processes --- inspection tool: put the translated texts of prev/next buttons into tooltips and show generic icon - instead of abreviating texts. - -- known incompat replacer ------------------------ -- doors in general (low priority) -- punched letter -- elphabet:xx (lowest priority) +------ replacer fixes -------- + ---------- known incompat inspect ----------- -- no recipe for silicon lump From 4c37d2bf715b89bfc4c3c218b63038973d68cb00 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 22:10:33 +0100 Subject: [PATCH 220/366] fine-tuning positions --- inspect.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/inspect.lua b/inspect.lua index bf85e8d..15e4335 100644 --- a/inspect.lua +++ b/inspect.lua @@ -292,9 +292,9 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) if 1 < #res then formspec = formspec - .. 'button[3.8,5;1,0.75;prev_recipe;<-]' + .. 'button[4.1,5;1,0.75;prev_recipe;<-]' .. 'tooltip[prev_recipe;'.. mfe(rbi.prev) .. ']' - .. 'button[5.0,5.0;1,0.75;next_recipe;->]' + .. 'button[5.0,5;1,0.75;next_recipe;->]' .. 'tooltip[next_recipe;'.. mfe(rbi.next) .. ']' end @@ -351,7 +351,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) end end local i = 1 - formspec = formspec .. 'label[2,1.6;' .. mfe(rbi.may_drop_on_dig) .. ']' + formspec = formspec .. 'label[0,1.5;' .. mfe(rbi.may_drop_on_dig) .. ']' for k, v in pairs(droplist) do formspec = formspec .. 'item_image_button[' .. (((i - 1) % 3) + 1) .. ',' From b010b3a281dfbeb4a241a9f642bf22819680838f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 23:08:43 +0100 Subject: [PATCH 221/366] add group:food_potato image --- compat/farming.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/compat/farming.lua b/compat/farming.lua index 56a202e..7241e68 100644 --- a/compat/farming.lua +++ b/compat/farming.lua @@ -13,4 +13,5 @@ rgp['group:food_peppercorn'] = 'farming:peppercorn' rgp['group:food_soy'] = 'farming:soy_beans' rgp['group:food_salt'] = 'farming:salt' rgp['group:food_juicer'] = 'farming:juicer' +rgp['group:food_potato'] = 'farming:potato' From 9ccb275ee6e11c92b2798268e790f587e5bc15e6 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 23:14:06 +0100 Subject: [PATCH 222/366] sort --- compat/farming.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compat/farming.lua b/compat/farming.lua index 7241e68..c46773a 100644 --- a/compat/farming.lua +++ b/compat/farming.lua @@ -2,16 +2,16 @@ if not minetest.get_modpath('farming') then return end local rgp = replacer.group_placeholder rgp['group:food_cheese'] = 'farming:cheese_vegan' -rgp['group:food_meat'] = 'farming:tofu_cooked' -rgp['group:food_saucepan'] = 'farming:saucepan' rgp['group:food_coffee'] = 'farming:coffee_beans' -rgp['group:food_pot'] = 'farming:pot' rgp['group:food_corn'] = 'farming:corn' -rgp['group:food_sunflower_seeds'] = 'farming:seed_sunflower' -rgp['group:food_vanilla'] = 'farming:vanilla' -rgp['group:food_peppercorn'] = 'farming:peppercorn' -rgp['group:food_soy'] = 'farming:soy_beans' -rgp['group:food_salt'] = 'farming:salt' rgp['group:food_juicer'] = 'farming:juicer' +rgp['group:food_meat'] = 'farming:tofu_cooked' +rgp['group:food_peppercorn'] = 'farming:peppercorn' +rgp['group:food_pot'] = 'farming:pot' rgp['group:food_potato'] = 'farming:potato' +rgp['group:food_salt'] = 'farming:salt' +rgp['group:food_saucepan'] = 'farming:saucepan' +rgp['group:food_soy'] = 'farming:soy_beans' +rgp['group:food_sunflower_seeds'] = 'farming:seed_sunflower' +rgp['group:food_vanilla'] = 'farming:vanilla' From 30b440aff113acdde99af971dc7aa6ccc422eae2 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 24 Jan 2022 23:21:49 +0100 Subject: [PATCH 223/366] wine compat --- compat/wine.lua | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 compat/wine.lua diff --git a/compat/wine.lua b/compat/wine.lua new file mode 100644 index 0000000..c19f871 --- /dev/null +++ b/compat/wine.lua @@ -0,0 +1,44 @@ +if not minetest.get_modpath('wine') then return end + +local S = replacer.S + +-- for inspection tool +-- order preserved from wines mod +local in_out = {} +in_out['wine:glass_wine'] = 'farming:grapes' +in_out['wine:glass_beer'] = 'farming:barley' +in_out['wine:glass_mead'] = 'mobs:honey' +in_out['wine:glass_mead'] = 'xdecor:honey' +in_out['wine:glass_cider'] = 'default:apple' +in_out['wine:glass_rum'] = 'default:papyrus' +in_out['wine:glass_tequila'] = 'wine:blue_agave' +in_out['wine:glass_wheat_beer'] = 'farming:wheat' +in_out['wine:glass_sake'] = 'farming:rice' +in_out['wine:glass_bourbon'] = 'farming:corn' +in_out['wine:glass_vodka'] = 'farming:baked_potato' +in_out['wine:glass_coffee_liquor'] = 'farming:coffee_beans' +in_out['wine:glass_champagne'] = 'wine:glass_champagne_raw' + +local function add_recipe(item_name, _, recipes) + if not 'string' == type(item_name) + or not item_name:find('^wine:glass_') then return end + + -- this one is an exception + if 'wine:glass_champagne_raw' == item_name then return end + + -- allow new items to show up using air as icon + local input = in_out[item_name] or 'air' + recipes[#recipes + 1] = { + method = 'ferment', + type = 'wine:ferment', + items = { input }, + output = item_name, + } +end -- add_recipe + +local function add_formspec(recipe) + return 'label[0.5,3.5;' .. S('Ferment in barrel.') .. ']' +end + +replacer.register_craft_method('wine:ferment', 'wine:wine_barrel', add_recipe, add_formspec) + From b40bda9bd858c5ddaa34c9f6ec8023ab665a9eec Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 00:28:42 +0100 Subject: [PATCH 224/366] compat vines:shears --- compat/vines.lua | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/compat/vines.lua b/compat/vines.lua index 10bfec6..58cf6e2 100644 --- a/compat/vines.lua +++ b/compat/vines.lua @@ -1,17 +1,42 @@ if not minetest.get_modpath('vines') then return end --- for inspection tool -replacer.group_placeholder['group:vines'] = 'vines:vines' +local S = replacer.S -- for replacer, so player can set to any part of vine and then replacer -- uses the '_end' part to place +local cutables = {} local vines = { 'jungle', 'root', 'side', 'vine', 'willow' } local name_base, name_end, name_middle for _, name in ipairs(vines) do name_base = 'vines:' .. name name_end = name_base .. '_end' name_middle = name_base .. '_middle' + cutables[name_end] = name_end + cutables[name_middle] = name_end replacer.register_exception(name_end, name_end) replacer.register_non_creative_alias(name_middle, name_end) end + +-- for inspection tool +replacer.group_placeholder['group:vines'] = 'vines:vines' + + +local function add_recipe(item_name, _, recipes) + local output = cutables[item_name] + if not output then return end + + recipes[#recipes + 1] = { + method = 'cutting', + type = 'vines:cut', + items = { output }, -- not 'correct' but should do the job + output = item_name, + } +end -- add_recipe + +local function add_formspec(recipe) + return 'label[0.5,3.5;' .. S('Cut with shears.') .. ']' +end + +replacer.register_craft_method('vines:cut', 'vines:shears', add_recipe, add_formspec) + From cf3de8a5458e178ced32df75da9fa53efd318046 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 00:57:45 +0100 Subject: [PATCH 225/366] sheep compat (wool) --- compat/mobs.lua | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/compat/mobs.lua b/compat/mobs.lua index bf3697d..b21b4dc 100644 --- a/compat/mobs.lua +++ b/compat/mobs.lua @@ -4,3 +4,33 @@ local rgp = replacer.group_placeholder if not rgp['group:food_cheese'] then rgp['group:food_cheese'] = 'mobs:cheese' end if not rgp['group:food_meat'] then rgp['group:food_meat'] = 'mobs:meat' end + +if not minetest.get_modpath('mobs_animal') then return end +if not minetest.get_modpath('mobs_animal') then return end + +local S = replacer.S + +local colours = { 'black', 'blue', 'brown', 'cyan', 'dark_green', 'dark_grey', 'green', + 'grey', 'magenta', 'orange', 'pink', 'red', 'violet', 'white', 'yellow' } +local map = {} +for _, colour in ipairs(colours) do + map['wool:' .. colour] = 'mobs_animal:sheep_' .. colour +end +local function add_recipe(item_name, _, recipes) + local output = map[item_name] + if not output then return end + + recipes[#recipes + 1] = { + method = 'cutting', + type = 'sheep:cut', + items = { output }, -- tecnically input, but hey + output = item_name, + } +end -- add_recipe + +local function add_formspec(recipe) + return 'label[0.5,3.5;' .. S('Cut with shears.') .. ']' +end + +replacer.register_craft_method('sheep:cut', 'mobs:shears', add_recipe, add_formspec) + From 9303ff4c7dc516b9106bb0af1d8384ac2bb65632 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 00:58:49 +0100 Subject: [PATCH 226/366] TODO update --- TODO | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index fe87866..b0cbd1a 100644 --- a/TODO +++ b/TODO @@ -9,8 +9,12 @@ maybe we can use this on group buttons -- inspection tool: add support for letter stencil and ehlphibet machines - also fermenting barrels and shears (both vines and wool) elphabet blocks and stickers insert ehlphi block for block and paper for sticker + add info for seeds and saplings about planting + add info for plants telling when they are ripe -> allowing user to click on the ripe + stage and see possible seed drop -> showing info about planting. + don't forget wine:blue_agave when doing that + add spawning, breading etc. info for mobs -- inspection tool: add input/output amounts for technic machine processes From 9a8040d84bf4359db006a49d952792a778cae6e1 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 02:35:17 +0100 Subject: [PATCH 227/366] inspect ehlphabet compat --- compat/ehlphabet.lua | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 compat/ehlphabet.lua diff --git a/compat/ehlphabet.lua b/compat/ehlphabet.lua new file mode 100644 index 0000000..72b6037 --- /dev/null +++ b/compat/ehlphabet.lua @@ -0,0 +1,29 @@ +if not minetest.get_modpath('ehlphabet') then return end + +-- for inspection tool +replacer.group_placeholder['group:ehlphabet_block'] = 'ehlphabet:208164' + +local exceptions = { '231140', '229140', '228184', + '230157', '229141', '232165', '231171' } +local skip = {} +for _, n in ipairs(exceptions) do skip[n] = true end + +local function add_recipe(item_name, _, recipes) + if not item_name or not 'string' == type(item_name) then return end + + local number = item_name:match('^ehlphabet:([0-9]+)') + if not number or skip[number] then return end + + local sticker = item_name:find('_sticker$') and true + local input = sticker and 'default:paper' or 'ehlphabet:block' + + recipes[#recipes + 1] = { + method = 'printing', + type = 'ehlphabet', + items = { input }, + output = item_name, + } +end -- add_recipe + +replacer.register_craft_method('ehlphabet', 'ehlphabet:machine', add_recipe) + From 789cf2f6466860e336a4fa388da8a05f960bb818 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 02:50:10 +0100 Subject: [PATCH 228/366] ehlphabet replacer compat --- TODO | 6 +++--- compat/ehlphabet.lua | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/TODO b/TODO index b0cbd1a..6555cc3 100644 --- a/TODO +++ b/TODO @@ -8,20 +8,20 @@ unified_inventory.get_formspec(player, page) maybe we can use this on group buttons --- inspection tool: add support for letter stencil and ehlphibet machines - elphabet blocks and stickers insert ehlphi block for block and paper for sticker +-- inspection tool: add support for letter stencil add info for seeds and saplings about planting add info for plants telling when they are ripe -> allowing user to click on the ripe stage and see possible seed drop -> showing info about planting. don't forget wine:blue_agave when doing that add spawning, breading etc. info for mobs + add biofuel hints -- inspection tool: add input/output amounts for technic machine processes -- known incompat replacer ------------------------ -- doors in general (low priority) -- punched letter --- elphabet:xx (lowest priority) +-- elphabet: add human readable letter to shortstring mainly for history (lowest priority) ------ replacer fixes -------- diff --git a/compat/ehlphabet.lua b/compat/ehlphabet.lua index 72b6037..b7f15f0 100644 --- a/compat/ehlphabet.lua +++ b/compat/ehlphabet.lua @@ -8,15 +8,18 @@ local exceptions = { '231140', '229140', '228184', local skip = {} for _, n in ipairs(exceptions) do skip[n] = true end -local function add_recipe(item_name, _, recipes) +local function ehlphabet_number_sticker(item_name) if not item_name or not 'string' == type(item_name) then return end - local number = item_name:match('^ehlphabet:([0-9]+)') + return item_name:match('^ehlphabet:([0-9]+)'), + item_name:find('_sticker$') and true +end + +local function add_recipe(item_name, _, recipes) + local number, sticker = ehlphabet_number_sticker(item_name) if not number or skip[number] then return end - local sticker = item_name:find('_sticker$') and true local input = sticker and 'default:paper' or 'ehlphabet:block' - recipes[#recipes + 1] = { method = 'printing', type = 'ehlphabet', @@ -27,3 +30,9 @@ end -- add_recipe replacer.register_craft_method('ehlphabet', 'ehlphabet:machine', add_recipe) + +-- for replacer +replacer.register_set_enabler(function(node) + return node and node.name and ehlphabet_number_sticker(node.name) +end) + From c387f5ade2f9cb3b5f6b19140bc618b4a46e0fcb Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 03:19:09 +0100 Subject: [PATCH 229/366] compat for letters --- TODO | 10 +++++----- compat/letters.lua | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 compat/letters.lua diff --git a/TODO b/TODO index 6555cc3..4a3d023 100644 --- a/TODO +++ b/TODO @@ -8,20 +8,20 @@ unified_inventory.get_formspec(player, page) maybe we can use this on group buttons --- inspection tool: add support for letter stencil +-- inspection tool: add info for seeds and saplings about planting add info for plants telling when they are ripe -> allowing user to click on the ripe stage and see possible seed drop -> showing info about planting. don't forget wine:blue_agave when doing that add spawning, breading etc. info for mobs add biofuel hints - --- inspection tool: add input/output amounts for technic machine processes + add input/output amounts for technic machine processes -- known incompat replacer ------------------------ -- doors in general (low priority) --- punched letter --- elphabet: add human readable letter to shortstring mainly for history (lowest priority) + (lowest priority) +-- elphabet: add human readable letter to shortstring mainly for history +-- letters: similar to elphabet ------ replacer fixes -------- diff --git a/compat/letters.lua b/compat/letters.lua new file mode 100644 index 0000000..5551c3b --- /dev/null +++ b/compat/letters.lua @@ -0,0 +1,44 @@ +if not minetest.get_modpath('letters') then return end + +-- for inspection tool +local function add_recipe_u(item_name, _, recipes) + if not item_name or not 'string' == type(item_name) then return end + + local input, letter = item_name:match('^(.+)_letter_(.)u$') + if not input then return end + + recipes[#recipes + 1] = { + method = 'cutting', + type = 'letters:upper', + items = { input }, + output = item_name, + letter = letter + } +end -- add_recipe_u + +replacer.register_craft_method('letters:upper', 'letters:letter_cutter_upper', add_recipe_u) + + +local function add_recipe_l(item_name, _, recipes) + if not item_name or not 'string' == type(item_name) then return end + + local input, letter = item_name:match('^(.+)_letter_(.)l$') + if not input then return end + + recipes[#recipes + 1] = { + method = 'cutting', + type = 'letters:lower', + items = { input }, + output = item_name, + letter = letter + } +end -- add_recipe_l + +replacer.register_craft_method('letters:lower', 'letters:letter_cutter_lower', add_recipe_l) + + +-- for replacer +replacer.register_set_enabler(function(node) + return node and node.name and node.name:find('^.+_letter_(.)[lu]$') +end) + From fd3f4b1edc8a16180dda25466f99a5b40b74b328 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 03:21:36 +0100 Subject: [PATCH 230/366] cleanup comment modifier key presses are not passed on when clicking formspec buttons --- inspect.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/inspect.lua b/inspect.lua index 15e4335..330f4b2 100644 --- a/inspect.lua +++ b/inspect.lua @@ -73,9 +73,8 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) if nil == user or nil == pointed_thing then return nil end - local name = user:get_player_name() - local keys = user:get_player_control() + local name = user:get_player_name() if 'object' == pointed_thing.type then local inventory_text = nil local text = '' @@ -430,6 +429,9 @@ function replacer.form_input_handler(player, formname, fields) if formname and 'replacer:crafting' == formname and player and not fields.quit then + -- too bad keys are all false :/ could have implemented easy + -- switch to unified_inventory formspec + --local keys = player:get_player_control() r.inspect_show_crafting(player:get_player_name(), nil, fields) return end From 0c5fa75e143b2921bbdfcf69eb91d4e584f0237d Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 03:25:16 +0100 Subject: [PATCH 231/366] version bump 3.10 --- CHANGELOG | 10 ++++++++++ TODO | 2 +- init.lua | 4 ++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 510eb19..615a8ef 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,13 @@ +20220124 * SwissalpS added wrap around for recipes - yes, long due. + * Bugfix, now replacer actually checks groups. + * Compat for shears (wool & vines) also fermenting/pickling, advtrains and sci-fi plastic + * ehlphabet and letters compat. +20220123 * SwissalpS added dev-mode and /place_all chat command. + * Technic crafting methods for inspection tool, including cnc nodes. + * planetoidgen:airlight is treated as air. + * New way to determine if replacer can be set to node + implementing callbacks better. Such as group denial. + * A lot of compatibility added to many mods. 20220120 * SwissalpS made folder structure to create easier overview. * Improved circular saw item detection for inspect and replacer. * Added beacon beam and base support (no longer needed to be in inv when setting). diff --git a/TODO b/TODO index 4a3d023..3ce356e 100644 --- a/TODO +++ b/TODO @@ -9,13 +9,13 @@ maybe we can use this on group buttons -- inspection tool: + add input/output amounts for technic machine processes add info for seeds and saplings about planting add info for plants telling when they are ripe -> allowing user to click on the ripe stage and see possible seed drop -> showing info about planting. don't forget wine:blue_agave when doing that add spawning, breading etc. info for mobs add biofuel hints - add input/output amounts for technic machine processes -- known incompat replacer ------------------------ -- doors in general (low priority) diff --git a/init.lua b/init.lua index f6d69a7..e8fd2af 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 3.9 (20220123) +-- Version 3.10 (20220124) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220123 +replacer.version = 20220124 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From d90bc186e09b2476946e4c775e43dee59f3d3c3a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 17:27:56 +0100 Subject: [PATCH 232/366] update method strings --- compat/canned_food.lua | 2 +- compat/mobs.lua | 2 +- compat/moreblocks.lua | 4 ++-- compat/wine.lua | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compat/canned_food.lua b/compat/canned_food.lua index cb20d1a..ace4785 100644 --- a/compat/canned_food.lua +++ b/compat/canned_food.lua @@ -8,7 +8,7 @@ local function add_recipe(item_name, _, recipes) if not base_name then return end recipes[#recipes + 1] = { - method = 'ferment', + method = 'fermenting/pickling', type = 'canned_food', items = { base_name }, output = item_name, diff --git a/compat/mobs.lua b/compat/mobs.lua index b21b4dc..7df49f2 100644 --- a/compat/mobs.lua +++ b/compat/mobs.lua @@ -21,7 +21,7 @@ local function add_recipe(item_name, _, recipes) if not output then return end recipes[#recipes + 1] = { - method = 'cutting', + method = 'shearing', type = 'sheep:cut', items = { output }, -- tecnically input, but hey output = item_name, diff --git a/compat/moreblocks.lua b/compat/moreblocks.lua index 899e16e..bad1d12 100644 --- a/compat/moreblocks.lua +++ b/compat/moreblocks.lua @@ -9,7 +9,7 @@ local function is_saw_output(node_name) if not node_name or 'moreblocks:circular_saw' == node_name then return nil end - + -- if we already confirmed this item, let's take the shortcut if confirmed_saw_items[node_name] then return confirmed_saw_items[node_name] end @@ -70,7 +70,7 @@ local function add_circular_saw_recipe(node_name, _, recipes) -- node found that fits into the saw recipes[#recipes + 1] = { - method = 'saw', + method = 'sawing', type = 'saw', items = { basic_node_name }, output = node_name diff --git a/compat/wine.lua b/compat/wine.lua index c19f871..dc67bca 100644 --- a/compat/wine.lua +++ b/compat/wine.lua @@ -29,7 +29,7 @@ local function add_recipe(item_name, _, recipes) -- allow new items to show up using air as icon local input = in_out[item_name] or 'air' recipes[#recipes + 1] = { - method = 'ferment', + method = 'fermenting', type = 'wine:ferment', items = { input }, output = item_name, From b6c0af136d2b6ded6a2faf604c1f4f883a919c89 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 17:29:21 +0100 Subject: [PATCH 233/366] add better drop detection --- replacer/replacer.lua | 6 +----- utils.lua | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 5f11796..0c4983a 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -606,11 +606,7 @@ function replacer.on_place(itemstack, player, pt) -- now we are scraping the bottom of the barrel -- let's check if digging this would drop something use-able - -- TODO: check if this is list as defined or random factor incorporated already - -- SwissalpS has the suspicion that it is. When testing on grain crops - -- sometimes was set to seeds and sometimes attempted to set to the crop. - -- This could also be that the table isn't always returned with same sorting. - local drops = core_get_node_drops(node.name) + local drops = r.possible_node_drops(node.name, true) local drop_name -- if 0 == core_get_item_group(node.name, 'not_in_creative_inventory') then for i = 1, #drops do diff --git a/utils.lua b/utils.lua index 05614e7..23231a8 100644 --- a/utils.lua +++ b/utils.lua @@ -5,6 +5,42 @@ local log = minetest.log local floor = math.floor local pos_to_string = minetest.pos_to_string +function replacer.possible_node_drops(node_name, return_names_only) + if not minetest.registered_nodes[node_name] + or not minetest.registered_nodes[node_name].drop then return {} end + + local drop = minetest.registered_nodes[node_name].drop + if 'string' == type(drop) then + if '' == drop then return {} end + if return_names_only then + return { drop:match('^([^ ]+)') } + end + return { drop } + end + + if 'table' ~= type(drop) or not drop.items then return {} end + + local droplist = {} + local checks = {} + for _, drops in ipairs(drop.items) do + for _, item in ipairs(drops.items) do + -- avoid duplicates; but include the item itself + -- these are itemstrings so same item can appear multiple times with + -- different amounts and/or rarity + if return_names_only then + item = item:match('^([^ ]+)') + end + if not checks[item] then + checks[item] = 1 + table.insert(droplist, item) + end + end + end + checks = nil + return droplist +end -- possible_node_drops + + function replacer.inform(name, message) if (not message) or ('' == message) then return end @@ -19,6 +55,7 @@ function replacer.inform(name, message) chat_send_player(name, message) end -- inform + function replacer.nice_pos_string(pos) local no_info = '' if 'table' ~= type(pos) then return no_info end @@ -28,6 +65,7 @@ function replacer.nice_pos_string(pos) return pos_to_string(pos) end -- nice_pos_string + -- from: http://lua-users.org/wiki/StringRecipes function replacer.titleCase(str) local function titleCaseHelper(first, rest) From 7081583a09be5bfaa20387dcbfbe8041bbff2ea3 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 17:29:55 +0100 Subject: [PATCH 234/366] improved technic recipes now showing amounts --- compat/technic.lua | 134 +++++++++++++++++++++++++++++++-------------- 1 file changed, 92 insertions(+), 42 deletions(-) diff --git a/compat/technic.lua b/compat/technic.lua index 42a0446..b8100b4 100644 --- a/compat/technic.lua +++ b/compat/technic.lua @@ -41,27 +41,22 @@ local function add_recipe_alloy(item_name, _, recipes) and def.input and 'table' == type(def.input) then local l = {} - for k, v in pairs(def.input) do table.insert(l, k) end + for k, v in pairs(def.input) do + table.insert(l, k .. ' ' .. tostring(v)) + end local i1, i2 = l[1], l[2] recipes[#recipes + 1] = { - method = 'alloy', + method = 'alloying', type = 'technic:alloy', - items = { i1 }, - output = item_name, - item2 = i2 + items = { i1, i2 }, + output = def.output } end end end -- add_recipe_alloy -local function add_formspec_alloy(recipe) - if not recipe.item2 then return '' end - return 'item_image_button[3,2;1.0,1.0;' - .. replacer.image_button_link(recipe.item2) .. ']' -end - replacer.register_craft_method( - 'technic:alloy', 'technic:coal_alloy_furnace', add_recipe_alloy, add_formspec_alloy) + 'technic:alloy', 'technic:coal_alloy_furnace', add_recipe_alloy) local function add_recipe_cnc(item_name, _, recipes) @@ -69,11 +64,11 @@ local function add_recipe_cnc(item_name, _, recipes) if not base_name then return end recipes[#recipes + 1] = { - method = 'cnc', + method = 'CNC machining', type = 'technic:cnc', items = { base_name }, output = item_name, - program = program:gsub('_', ' ') + program = program --:gsub('_', ' ') } end -- add_recipe_freeze @@ -90,9 +85,9 @@ local function add_recipe_compress(item_name, _, recipes) for input_name, def in pairs(technic.recipes['compressing']['recipes']) do if def.output and def.output == item_name then recipes[#recipes + 1] = { - method = 'compress', + method = 'compressing', type = 'technic:compress', - items = { input_name }, + items = { input_name .. ' ' .. tostring(def.input[input_name]) }, output = item_name } end @@ -109,10 +104,10 @@ local function add_recipe_extract(item_name, _, recipes) and def.output:find('^' .. item_name .. ' ?[0-9]*$') then recipes[#recipes + 1] = { - method = 'extract', + method = 'extracting', type = 'technic:extract', - items = { input_name }, - output = item_name + items = { input_name .. ' ' .. tostring(def.input[input_name]) }, + output = def.output } end end @@ -122,36 +117,84 @@ replacer.register_craft_method('technic:extract', 'technic:lv_extractor', add_re local function add_recipe_freeze(item_name, _, recipes) +--pd(technic.recipes['freezing']) + local def_out_type, outputs, main_output for input_name, def in pairs(technic.recipes['freezing']['recipes']) do - if def.output - and (def.output == item_name - or ('table' == type(def.output) - and def.output[1] == item_name)) + def_out_type = type(def.output) + if 'string' == def_out_type + and def.output:find('^' .. item_name .. ' ?[0-9]*$') then recipes[#recipes + 1] = { - method = 'freeze', + method = 'freezing', type = 'technic:freeze', items = { input_name }, - output = item_name + output = def.output, } + + elseif 'table' == def_out_type then + outputs, main_output = {}, nil + for _, output_string in ipairs(def.output) do + if output_string:find('^' .. item_name .. ' ?[0-9]*$') then + main_output = output_string + else + table.insert(outputs, output_string) + end + end + if main_output then + recipes[#recipes + 1] = { + method = 'freezing', + type = 'technic:freeze', + items = { input_name .. ' '.. tostring(def.input[input_name]) }, + output = main_output, + output_other = outputs, + } + end end end end -- add_recipe_freeze -replacer.register_craft_method('technic:freeze', 'technic:mv_freezer', add_recipe_freeze) +local function add_formspec_freeze(recipe) + if not recipe.output_other or 0 == #recipe.output_other then + return '' + end + + local out = 'item_image_button[5,3;1.0,1.0;' + .. replacer.image_button_link(recipe.output_other[1]) .. ']' + if recipe.output_other[2] then + out = out .. 'item_image_button[5,1;1.0,1.0;' + .. replacer.image_button_link(recipe.output_other[2]) .. ']' + end + return out +end -- add_formspec_freeze + +replacer.register_craft_method( + 'technic:freeze', 'technic:mv_freezer', add_recipe_freeze, add_formspec_freeze) local function add_recipe_grind(item_name, _, recipes) --pd(technic.recipes['grinding']) + local inputs, input_type for input_name, def in pairs(technic.recipes['grinding']['recipes']) do - if def.output and 'string' == type(def.output) + if 'string' == type(def.output) and def.output:find('^' .. item_name .. ' ?[0-9]*$') then + input_type = type(def.input) + if 'string' == input_type then + inputs = { def.input } + elseif 'table' == input_type then + inputs = {} + -- there is only one, but that's how lua works so we need to loop + for k, v in pairs(def.input) do + table.insert(inputs, k .. ' ' .. tostring(v)) + end + else + inputs = {} + end recipes[#recipes + 1] = { - method = 'grind', + method = 'grinding', type = 'technic:grind', - items = { input_name }, - output = item_name + items = inputs, + output = def.output } end end @@ -162,24 +205,31 @@ replacer.register_craft_method('technic:grind', 'technic:lv_grinder', add_recipe local function add_recipe_separate(item_name, _, recipes) --pd(technic.recipes['separating']) + local outputs, main_output, inputs for input_name, def in pairs(technic.recipes['separating']['recipes']) do - if def.output and 'table' == type(def.output) then - local clean, cleaned, found = '', {}, false - for _, output in ipairs(def.output) do - clean = output:match('^([^ ]+)') - if clean == item_name then - found = true + if def.output and 'table' == type(def.output) + and def.input and 'table' == type(def.input) + then + outputs, main_output = {}, nil + for _, output_string in ipairs(def.output) do + if output_string:find('^' .. item_name .. ' ?[0-9]*$') then + main_output = output_string else - table.insert(cleaned, clean) + table.insert(outputs, output_string) end end - if found then + if main_output then + inputs = {} + -- there is only one, but that's how lua works so we need to loop + for k, v in pairs(def.input) do + table.insert(inputs, k .. ' ' .. tostring(v)) + end recipes[#recipes + 1] = { - method = 'separate', + method = 'separating', type = 'technic:separate', - items = { input_name }, - output = item_name, - output_other = cleaned + items = inputs, + output = main_output, + output_other = outputs, } end -- if found end -- if output is table From 93da96a0a0536f385557c385fdec785138f6edc6 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 17:30:30 +0100 Subject: [PATCH 235/366] improve airbrush method --- compat/unifieddyes.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compat/unifieddyes.lua b/compat/unifieddyes.lua index df96ca5..9c17d17 100644 --- a/compat/unifieddyes.lua +++ b/compat/unifieddyes.lua @@ -22,6 +22,8 @@ local function add_recipe(node_name, param2, recipes) for i, t in ipairs(recipes) do first, last = t.output:find(needle) if nil ~= first then + t.method = 'painting' + t.type = 'unifieddyes:airbrush' recipes[#recipes + 1] = t return end From 0e9f9552d28ed364a20fc5f9904e26d768cd7f61 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 17:33:53 +0100 Subject: [PATCH 236/366] improve dynamic methods handling and drop detection and some other minor adjustments --- inspect.lua | 107 ++++++++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 49 deletions(-) diff --git a/inspect.lua b/inspect.lua index 330f4b2..f40fddd 100644 --- a/inspect.lua +++ b/inspect.lua @@ -11,6 +11,7 @@ local rbi = replacer.blabla.inspect local nice_pos_string = replacer.nice_pos_string local S = replacer.S local floor = math.floor +local max, min = math.max, math.min local chat = minetest.chat_send_player local mfe = minetest.formspec_escape @@ -233,6 +234,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) end end + -- fetch recipes from core local res = minetest.get_all_craft_recipes(node_name) if not res then res = {} @@ -240,7 +242,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) --print(dump(res)) -- TODO: filter out invalid recipes with no items -- such as "group:flower,color_dark_grey" - -- + -- also 'normal' recipe.type uranium*_dust recipes -- add special recipes for nodes created by machines for _, adder in pairs(r.recipe_adders) do @@ -260,6 +262,8 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) recipe_nr = #res end + -- fetch description + -- when clicking unknown nodes local desc = ' ' .. rbi.no_desc .. ' ' if minetest.registered_nodes[node_name] then if minetest.registered_nodes[node_name].description @@ -283,12 +287,14 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) end end + -- base info local formspec = 'size[6,6]' + -- label on top .. 'label[0,0;' .. mfe(rbi.name) .. ' ' .. node_name .. ']' - .. 'item_image_button[5,2;1.0,1.0;' .. node_name .. ';normal;]' .. 'button_exit[5.0,4.3;1,0.5;quit;X]' .. 'tooltip[quit;'.. mfe(rbi.exit) .. ']' + -- prev. and next buttons if 1 < #res then formspec = formspec .. 'button[4.1,5;1,0.75;prev_recipe;<-]' @@ -298,14 +304,14 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) end formspec = formspec - .. 'label[0,5.5;' .. mfe(rbi.this_is) .. ' ' .. mfe(desc) .. ']' + -- description at bottom + .. 'label[0,5.7;' .. mfe(rbi.this_is) .. ' ' .. mfe(desc) .. ']' -- invisible field for passing on information .. 'field[20,20;0.1,0.1;node_name;node_name;' .. node_name .. ']' -- another invisible field .. 'field[21,21;0.1,0.1;recipe_nr;recipe_nr;' .. tostring(recipe_nr) .. ']' - -- provide additional information regarding the node in particular - -- that has been inspected + -- location and param2 formspec = formspec .. 'label[0.0,0.3;' if fields.pos then formspec = formspec .. mfe(S('Located at @1', nice_pos_string(fields.pos))) @@ -314,6 +320,8 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) formspec = formspec .. ' ' .. mfe(S('with param2 of @1', tostring(fields.param2))) end + + -- light formspec = formspec .. ']' if fields.light then formspec = formspec .. 'label[0.0,0.6;' @@ -326,43 +334,35 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) .. mfe(fields.protected_info) .. ']' end + -- if no recipes, collect drops else show current recipe if 1 > #res then formspec = formspec .. 'label[3,1;' .. mfe(rbi.no_recipes) .. ']' - if minetest.registered_nodes[node_name] - and minetest.registered_nodes[node_name].drop - then - local drop = minetest.registered_nodes[node_name].drop - if 'string' == type(drop) and drop ~= node_name then - formspec = formspec .. 'label[2,1.6;' .. mfe(rbi.drops_on_dig) .. ' ' - if '' == drop then - formspec = formspec .. mfe(rbi.nothing) .. ']' - else - formspec = formspec - .. ']item_image_button[2,2;1.0,1.0;' - .. r.image_button_link(drop) .. ']' - end - elseif 'table' == type(drop) and drop.items then - local droplist = {} - for _, drops in ipairs(drop.items) do - for _, item in ipairs(drops.items) do - -- avoid duplicates; but include the item itself - droplist[item] = 1 - end - end - local i = 1 - formspec = formspec .. 'label[0,1.5;' .. mfe(rbi.may_drop_on_dig) .. ']' - for k, v in pairs(droplist) do - formspec = formspec .. 'item_image_button[' - .. (((i - 1) % 3) + 1) .. ',' - .. tostring(floor(((i - 1) / 3) + 2)) - .. ';1.0,1.0;' .. r.image_button_link(k) .. ']' - i = i + 1 - end - end + -- always returns a table + local drops = r.possible_node_drops(node_name) + formspec = formspec .. 'label[0,1.5;' + if 0 == #drops then + formspec = formspec .. mfe(rbi.drops_on_dig) .. ' ' .. mfe(rbi.nothing) .. ']' + elseif 1 == #drops then + formspec = formspec .. mfe(rbi.drops_on_dig) .. ']' + else + formspec = formspec .. mfe(rbi.may_drop_on_dig) .. ']' + end + for i, n in ipairs(drops) do + formspec = formspec .. 'item_image_button[' + .. (((i - 1) % 3) + 1) .. ',' + .. tostring(floor(((i - 1) / 3) + 2)) + .. ';1.0,1.0;' .. r.image_button_link(n) .. ']' + i = i + 1 end + -- output item on the right + formspec = formspec + .. 'item_image_button[5,2;1.0,1.0;' .. node_name .. ';normal;]' + else - formspec = formspec .. 'label[1,5;' - .. mfe(S('Alternate @1/@2', tostring(recipe_nr), tostring(#res))) .. ']' + if 1 < #res then + formspec = formspec .. 'label[1,5;' + .. mfe(S('Alternate @1/@2', tostring(recipe_nr), tostring(#res))) .. ']' + end -- reverse order; default recipes (and thus the most intresting ones) -- are usually the oldest local recipe = res[#res + 1 - recipe_nr] @@ -381,7 +381,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) .. r.image_button_link(recipe.items[i]) .. ']' end end - elseif 'cooking' == recipe.type + elseif ('cooking' == recipe.type or 'fuel' == recipe.type) and recipe.items and 1 == #recipe.items and '' == recipe.output @@ -398,27 +398,36 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) then formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' .. r.image_button_link('default:furnace') .. ']' - .. 'item_image_button[2.9,2.7;1.0,1.0;' + .. 'item_image_button[2.2,2.2;1.0,1.0;' .. r.image_button_link(recipe.items[1]) .. ']' elseif recipe.items - and 1 == #recipe.items -- TODO: investigate if this shouldn't be 0 < #recipe.items + and 0 < #recipe.items and r.recipe_adders[recipe.type] then local handler = r.recipe_adders[recipe.type] formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' .. r.image_button_link(handler.machine) .. ']' - .. 'item_image_button[2,2;1.0,1.0;' - .. r.image_button_link(recipe.items[1]) .. ']' + .. 'label[0.1,4.3;' .. mfe(S(recipe.method)) .. ']' + local width = recipe.width or #recipe.items + width = max(1, min(3, width)) + local offsets = { 2.2, 1.7, 1.2 } + local offset = offsets[width] + for i = 1, 9 do + if not recipe.items[i] then break end + formspec = formspec .. 'item_image_button[' + .. (((i - 1) % width) + offset) .. ',' + .. tostring(floor((i - 1) / width) + offset) + .. ';1.0,1.0;' + .. r.image_button_link(recipe.items[i]) .. ']' + end + formspec = formspec .. (handler.formspec and handler.formspec(recipe) or '') else formspec = formspec .. 'label[3,1;' .. mfe(rbi.unkown_recipe) .. ']' end - -- show how many of the items the recipe will yield - local outstack = ItemStack(recipe.output) - local out_count = outstack:get_count() - if 1 < out_count then - formspec = formspec .. 'label[5.5,2.5;' .. tostring(out_count) .. ']' - end + -- output item on the right + formspec = formspec + .. 'item_image_button[5,2;1.0,1.0;' .. recipe.output .. ';normal;]' end minetest.show_formspec(player_name, 'replacer:crafting', formspec) end -- inspect_show_crafting From 7bde3644b349c598cdf89b17dbf23011cb7043ae Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 25 Jan 2022 17:34:24 +0100 Subject: [PATCH 237/366] TODO updated --- TODO | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 3ce356e..aa13762 100644 --- a/TODO +++ b/TODO @@ -9,13 +9,14 @@ maybe we can use this on group buttons -- inspection tool: - add input/output amounts for technic machine processes + filter out 'normal' recipe.type uranium*_dust recipes given by core.get_all_craft_recipes() + add bucket/cannister as method add info for seeds and saplings about planting add info for plants telling when they are ripe -> allowing user to click on the ripe stage and see possible seed drop -> showing info about planting. don't forget wine:blue_agave when doing that add spawning, breading etc. info for mobs - add biofuel hints + add biofuel hints also general 'fuel' craft types -- known incompat replacer ------------------------ -- doors in general (low priority) From 508a3616a585d93f96182d9a62df461f30cd6d1b Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 02:01:49 +0100 Subject: [PATCH 238/366] reformated chat command for more flexibility --- blabla.lua | 6 +++--- chat_commands.lua | 32 ++++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/blabla.lua b/blabla.lua index ef0ca6d..1753dad 100644 --- a/blabla.lua +++ b/blabla.lua @@ -56,9 +56,9 @@ rb.log_deny_list_insert = '[replacer] Added "%s" to deny list.' rb.timed_out = S('Time-limit reached.') rb.tool_short_description = '(%s %s%s) %s' rb.tool_long_description = '%s\n%s\n%s' -rb.ccm_params = '[ %s | %s ]' -rb.ccm_description = S('Toggles verbosity.\nWhen on, ' - .. 'messages are posted to chat. When off, replacer is silent.') +rb.ccm_params = '(chat|audio) (%s|%s)' +rb.ccm_description = S('Toggles verbosity.\nchat: When on, ' + .. 'messages are posted to chat.\naudio: When off, replacer is silent.') rb.ccm_player_not_found = 'Player not found' rb.ccm_player_meta_error = 'Player meta not existant' rb.on_yes = S('on') diff --git a/chat_commands.lua b/chat_commands.lua index 8355b35..7c112dc 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -12,7 +12,7 @@ for _, s in ipairs(lOff) do tOff[s] = true end replacer.chatcommand_mute = { - params = rb.ccm_params:format(rb.on_yes, rb.off_no), + params = rb.ccm_params:format(rb.on_yes, rb.off_no),--(chat|audio) (%s|%s) description = rb.ccm_description, func = function(name, param) local player = minetest.get_player_by_name(name) @@ -25,18 +25,34 @@ replacer.chatcommand_mute = { end local lower = string.lower(param) - if tOff[lower] then - meta:set_int('replacer_mute', 1) - elseif tOn[lower] then - meta:set_int('replacer_mute', 0) + local parts = lower:split(' ') + local usage = rb.ccm_params .. '\n' + .. rb.ccm_description + if 2 > #parts then return false, usage end + + local command, value, key = parts[1], parts[2] + if 'chat' == command then + key = 'replacer_mute' + elseif 'audio' == command then + key = 'replacer_muteS' + elseif 'version' == command then + return true, tostring(replacer.version) else - return false, S('Valid parameter is either "@1" or "@2"', rb.on_yes, rb.off_no) + return false, usage end - return true, '' + if tOff[value] then + value = 1 + elseif tOn[value] then + value = 0 + else + return false, usage + end + meta:set_int(key, value) + return true, '' end } -minetest.register_chatcommand('replacer_mute', replacer.chatcommand_mute) +minetest.register_chatcommand('replacer', replacer.chatcommand_mute) From 12eaba28eab5fbe832f1a82ae0d81c121e68f842 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 02:03:53 +0100 Subject: [PATCH 239/366] added sound feedback for errors (mainly) --- replacer/replacer.lua | 12 +++++++++++- utils.lua | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 0c4983a..8175e15 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -271,6 +271,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) end if 'node' ~= pt.type then + r.play_sound(name, true) r.inform(name, S('Error: "@1" is not a node.', pt.type)) return end @@ -279,6 +280,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) local node_old = core_get_node_or_nil(pos) if not node_old then + r.play_sound(name, true) r.inform(name, rb.wait_for_load) return end @@ -329,6 +331,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) local charge = r.get_charge(itemstack) if not has_creative_or_give then if charge < r.charge_per_node then + r.play_sound(name, true) r.inform(name, rb.need_more_charge) --return end @@ -544,12 +547,16 @@ function replacer.on_place(itemstack, player, pt) -- Select new node if 'node' ~= pt.type then + r.play_sound(name, true) r.inform(name, rb.none_selected) return end node = core_get_node_or_nil(pt.under) - if not node then return end + if not node then + r.play_sound(name, true) + return + end -- don't allow setting replacer to denied nodes -- helper function for valid() @@ -562,6 +569,7 @@ function replacer.on_place(itemstack, player, pt) return false end if r.deny_list[node.name] or denied_group(node.name) then + r.play_sound(name, true) r.inform(name, S('Placing nodes of type "@1" is not ' .. 'allowed on this server.', node.name)) return @@ -646,6 +654,7 @@ function replacer.on_place(itemstack, player, pt) return false end -- valid if not valid() then + r.play_sound(name, true) r.inform(name, S('Failed to set replacer to "@1". ' .. 'If you had one in your inventory, it could be set.', node.name)) return @@ -656,6 +665,7 @@ function replacer.on_place(itemstack, player, pt) -- add to history r.history.add_item(player, mode, node, short_description) -- inform player about successful setting + r.play_sound(name) r.inform(name, S('Node replacement tool set to:\n@1.', short_description)) return itemstack --data changed diff --git a/utils.lua b/utils.lua index 23231a8..ae4fae8 100644 --- a/utils.lua +++ b/utils.lua @@ -1,9 +1,34 @@ +local r = replacer local rb = replacer.blabla local chat_send_player = minetest.chat_send_player local get_player_by_name = minetest.get_player_by_name local log = minetest.log local floor = math.floor local pos_to_string = minetest.pos_to_string +local sound_fail = 'default_break_glass' +local sound_success = 'default_item_smoke' +local sound_gain = 0.5 +if r.has_technic_mod then + sound_fail = 'technic_prospector_miss' + --sound_success = 'technic_prospector_hit' + sound_gain = 0.1 +end + + +function replacer.play_sound(player_name, fail) + local player = get_player_by_name(player_name) + if not player then return end + + local meta = player:get_meta() if not meta then return end + + if 0 < meta:get_int('replacer_muteS') then return end + + minetest.sound_play(fail and sound_fail or sound_success, { + to_player = player_name, + max_hear_distance = 2, + gain = sound_gain }, true) +end -- play_sound + function replacer.possible_node_drops(node_name, return_names_only) if not minetest.registered_nodes[node_name] From 8c2dbcb86b1cf3c40e25e3896650c64b50ab12c5 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 02:06:03 +0100 Subject: [PATCH 240/366] added tooltips sometimes the text clips the formspec this commit allows users to have another chance of reading full text --- inspect.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/inspect.lua b/inspect.lua index f40fddd..e0c1a3d 100644 --- a/inspect.lua +++ b/inspect.lua @@ -291,6 +291,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) local formspec = 'size[6,6]' -- label on top .. 'label[0,0;' .. mfe(rbi.name) .. ' ' .. node_name .. ']' + .. 'tooltip[-1,-1;7,2;' .. mfe(rbi.name) .. ' ' .. node_name .. ']' .. 'button_exit[5.0,4.3;1,0.5;quit;X]' .. 'tooltip[quit;'.. mfe(rbi.exit) .. ']' @@ -306,6 +307,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) formspec = formspec -- description at bottom .. 'label[0,5.7;' .. mfe(rbi.this_is) .. ' ' .. mfe(desc) .. ']' + .. 'tooltip[-1,5.7;7,2;' .. mfe(rbi.this_is) .. ' ' .. mfe(desc) .. ']' -- invisible field for passing on information .. 'field[20,20;0.1,0.1;node_name;node_name;' .. node_name .. ']' -- another invisible field From caaeeb74b794a3a50c3a12c5ab6f63e31d7a4b51 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 02:08:02 +0100 Subject: [PATCH 241/366] failed attempt with textarea idea was to allow selecting of itemstring but positioning didn't work out post-poning this to when we upgrade to newer version of formspec --- inspect.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/inspect.lua b/inspect.lua index e0c1a3d..c9f4b21 100644 --- a/inspect.lua +++ b/inspect.lua @@ -290,6 +290,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) -- base info local formspec = 'size[6,6]' -- label on top + --.. 'textarea[-9,-18,6,1;;' .. mfe(rbi.name) .. ' ' .. node_name .. ';]' .. 'label[0,0;' .. mfe(rbi.name) .. ' ' .. node_name .. ']' .. 'tooltip[-1,-1;7,2;' .. mfe(rbi.name) .. ' ' .. node_name .. ']' .. 'button_exit[5.0,4.3;1,0.5;quit;X]' From c261ec3c65f3d6fed41631299eb6b22f279f820a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 02:09:19 +0100 Subject: [PATCH 242/366] experimenting with opening unified_inventory with tool --- init.lua | 2 ++ inspect.lua | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/init.lua b/init.lua index e8fd2af..950f3ad 100644 --- a/init.lua +++ b/init.lua @@ -40,6 +40,8 @@ replacer.has_technic_mod = minetest.get_modpath('technic') and minetest.global_exists('technic') replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') and minetest.global_exists('unifieddyes') +replacer.has_unified_inventory_mod = minetest.get_modpath('unified_inventory') + and true or false -- image mapping tables for replacer:inspect replacer.group_placeholder = {} diff --git a/inspect.lua b/inspect.lua index c9f4b21..64189dc 100644 --- a/inspect.lua +++ b/inspect.lua @@ -8,6 +8,7 @@ local r = replacer local rb = replacer.blabla local rbi = replacer.blabla.inspect +local ui = r.has_unified_inventory_mod and unified_inventory or false local nice_pos_string = replacer.nice_pos_string local S = replacer.S local floor = math.floor @@ -170,6 +171,20 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) return nil end + -- EXPERIMENTAL: attempt to open unified_inventory's crafting guide + if ui then + local keys = user:get_player_control() + -- while testing let's use zoom until we either drop the idea + -- or get it to work + if keys.zoom then --aux1 then ---and keys.sneak then + ui.current_item[name] = node.name + ui.current_craft_direction[name] = 'recipe' + ui.current_searchbox[name] = node.name + ui.apply_filter(user, node.name, 'recipe')--'usage' --nochange') + minetest.show_formspec(name, '', ui.get_formspec(user, 'craftguide')) + return + end + end local protected_info = '' if minetest.is_protected(pos, name) then protected_info = rbi.is_protected From 36d3d61599876fcdd4db389632493d957341fe59 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 13:10:06 +0100 Subject: [PATCH 243/366] TODO update --- TODO | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- inspect.lua | 2 +- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index aa13762..af5d574 100644 --- a/TODO +++ b/TODO @@ -9,8 +9,13 @@ maybe we can use this on group buttons -- inspection tool: + figure out how to make the itemstring selectable for copy -> do that with new formspec version + is the new drop detection hindering setting replacer to wine:blue_agave filter out 'normal' recipe.type uranium*_dust recipes given by core.get_all_craft_recipes() + add mixing method add bucket/cannister as method + add home_workshop_misc:beer_tap as method -> home_workshop_misc:beer_mug + add digging method for ores add info for seeds and saplings about planting add info for plants telling when they are ripe -> allowing user to click on the ripe stage and see possible seed drop -> showing info about planting. @@ -25,11 +30,52 @@ -- letters: similar to elphabet ------ replacer fixes -------- +-- can't be set --> no recipe +home_workshop_misc:beer_mug +homedecor:glass_table_large_square +homedecor:dvd_cd_cabinet +homedecor:chains +homedecor:wood_table_large_square +scifi_nodes:junk +scifi_nodes:engine +scifi_nodes:doomengine +scifi_nodes:crate +scifi_nodes:capsule2 +scifi_nodes:capsule3 +scifi_nodes:builder + +-- can be set but can't be placed -- need alias for inspect tool too +homedecor:desk_lamp_7 -> 14 +homedecor:ceiling_lantern_6 -> 14 +homedecor:ceiling_lamp_8|on -> 14 +homedecor:glowlight_half_8|on -> 14 +homedecor:glowlight_quarter_0|on -> 14 +homedecor:glowlight_small_cube_1|on -> 14 +homedecor:ground_lantern_0-13|on homedecor:ground_lantern_14 +homedecor:hanging_lantern_10|on -> 14 +homedecor:lattice_lantern_large_1|on -> 14 +homedecor:lattice_lantern_small_1 +homedecor:plasma_ball_off -> homedecor:plasma_ball_on -- meh +homedecor:plasma_lamp_8|on -> 14 +homedecor:speaker_open -> homedecor:speaker (cable plate overrides) +homedecor:standing_lamp_8 +homedecor:table_lamp_12 +ilights:light_off -> on +lavalamp:lavalamp_off -> lavalamp:lavalamp +ropes:ropeladder_bottom (didn't we add this?) +vines:rope + +------- need 'cable plate override' --------- +jumping:trampoline2-6 -> 1 +scifi_nodes:laptop_open -> scifi_nodes:laptop_closed ---------- known incompat inspect ----------- -- no recipe for silicon lump ---- missing icons ---- +cottages:wool;cottages:wool (used by homedecor:curtain_open) +(homedecor:stained_glass) -- cottages:glass_pane_side + -- fix in scifi_nodes flowers:dandelion --> dandelion_white and dandelion_yellow would exist (*scifi_nodes:plant10 also 9) @@ -43,9 +89,6 @@ bridger:corrugated_steelred bridger:corrugated_steelsteel bridger:corrugated_steelyellow --- has unknown items in recipe -- --- stained_glass? which one? - -- glowlight has trouble finding base recipe, also desk_lamp, ceiling lantern, ceiling lamp, ground lantern, hanging lantern, kitchen cabinet coloured, latice lantern, table lamp, standing lamp, rope light/on floor, plasma lamp, plasma ball, wall lamp, diff --git a/inspect.lua b/inspect.lua index 64189dc..860a2a5 100644 --- a/inspect.lua +++ b/inspect.lua @@ -178,7 +178,7 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) -- or get it to work if keys.zoom then --aux1 then ---and keys.sneak then ui.current_item[name] = node.name - ui.current_craft_direction[name] = 'recipe' + ui.current_craft_direction[name] = 'recipe'-- keys.x and 'usage' or 'recipe' ui.current_searchbox[name] = node.name ui.apply_filter(user, node.name, 'recipe')--'usage' --nochange') minetest.show_formspec(name, '', ui.get_formspec(user, 'craftguide')) From a7f5f746ecc869ac2cca5cf318fd1518de34764d Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 13:12:00 +0100 Subject: [PATCH 244/366] version bump 3.11 --- CHANGELOG | 10 ++++++++++ init.lua | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 615a8ef..812e0db 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,13 @@ +20220125 * SwissalpS improved sytem for showing dynamicly added crafting methods + which allowed to improve the output of technic and saw methods. + * Better drop detection method. + * Added sound playback for setting replacer errors, mainly. + * Change /replacer_mute to /replacer and changed the arguments + so sound can be muted separately. + * Added tooltips so users have more chance of reading long lines. Adding + textarea to make itemstring selectable failed and is post-poned to when + new version of formspec is being used for inspection tool as well. + * Added experimental hold zoom+click with inspection tool to open unified_inventory. 20220124 * SwissalpS added wrap around for recipes - yes, long due. * Bugfix, now replacer actually checks groups. * Compat for shears (wool & vines) also fermenting/pickling, advtrains and sci-fi plastic diff --git a/init.lua b/init.lua index 950f3ad..4a31c0d 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 3.10 (20220124) +-- Version 3.11 (20220125) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220124 +replacer.version = 20220125 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From e1a36a9c0953775af8ae2026c74551b459c74893 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 13:22:21 +0100 Subject: [PATCH 245/366] fix vines:rope --- TODO | 1 - compat/vines.lua | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index af5d574..4546d6d 100644 --- a/TODO +++ b/TODO @@ -63,7 +63,6 @@ homedecor:table_lamp_12 ilights:light_off -> on lavalamp:lavalamp_off -> lavalamp:lavalamp ropes:ropeladder_bottom (didn't we add this?) -vines:rope ------- need 'cable plate override' --------- jumping:trampoline2-6 -> 1 diff --git a/compat/vines.lua b/compat/vines.lua index 58cf6e2..864abd3 100644 --- a/compat/vines.lua +++ b/compat/vines.lua @@ -16,6 +16,8 @@ for _, name in ipairs(vines) do replacer.register_exception(name_end, name_end) replacer.register_non_creative_alias(name_middle, name_end) end +replacer.register_non_creative_alias('vines:rope', 'vines:rope_block') +replacer.register_non_creative_alias('vines:rope_end', 'vines:rope_block') -- for inspection tool From 1c0692b54f3ef8a107fc8d7a9aca733a2b6049a3 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 13:38:59 +0100 Subject: [PATCH 246/366] 'fix' ropes --- TODO | 1 - compat/ropes.lua | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 4546d6d..6b431c2 100644 --- a/TODO +++ b/TODO @@ -62,7 +62,6 @@ homedecor:standing_lamp_8 homedecor:table_lamp_12 ilights:light_off -> on lavalamp:lavalamp_off -> lavalamp:lavalamp -ropes:ropeladder_bottom (didn't we add this?) ------- need 'cable plate override' --------- jumping:trampoline2-6 -> 1 diff --git a/compat/ropes.lua b/compat/ropes.lua index 6c742b7..fa1c4ad 100644 --- a/compat/ropes.lua +++ b/compat/ropes.lua @@ -1,4 +1,9 @@ if not minetest.get_modpath('ropes') then return end replacer.register_non_creative_alias('ropes:ropeladder', 'ropes:ropeladder_top') +replacer.register_non_creative_alias('ropes:ropeladder_bottom', 'ropes:ropeladder_top') +-- for these there are multiple targets. For now, alias to cheapest one +replacer.register_non_creative_alias('ropes:rope', 'ropes:wood1rope_block') +-- for these there are multiple targets. For now, alias to longest one +replacer.register_non_creative_alias('ropes:rope_bottom', 'ropes:steel9rope_block') From 493fc5381fdafa85124a22c9da5999bb270ae8ac Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 13:46:13 +0100 Subject: [PATCH 247/366] jumping compat --- TODO | 3 +-- compat/jumping.lua | 8 ++++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 compat/jumping.lua diff --git a/TODO b/TODO index 6b431c2..6bc7597 100644 --- a/TODO +++ b/TODO @@ -57,15 +57,14 @@ homedecor:lattice_lantern_large_1|on -> 14 homedecor:lattice_lantern_small_1 homedecor:plasma_ball_off -> homedecor:plasma_ball_on -- meh homedecor:plasma_lamp_8|on -> 14 -homedecor:speaker_open -> homedecor:speaker (cable plate overrides) homedecor:standing_lamp_8 homedecor:table_lamp_12 ilights:light_off -> on lavalamp:lavalamp_off -> lavalamp:lavalamp ------- need 'cable plate override' --------- -jumping:trampoline2-6 -> 1 scifi_nodes:laptop_open -> scifi_nodes:laptop_closed +homedecor:speaker_open -> homedecor:speaker (cable plate overrides) ---------- known incompat inspect ----------- -- no recipe for silicon lump diff --git a/compat/jumping.lua b/compat/jumping.lua new file mode 100644 index 0000000..9ace6d9 --- /dev/null +++ b/compat/jumping.lua @@ -0,0 +1,8 @@ +if not minetest.get_modpath('jumping') then return end + +local sBaseName = 'jumping:trampoline' +local sDropName = sBaseName .. '1' +for i = 2, 6 do + replacer.register_exception(sBaseName .. tostring(i), sDropName) +end + From 912dfffd3715b93c93e6e4dcb1f94428aa3146aa Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 13:54:41 +0100 Subject: [PATCH 248/366] scifi_nodes laptop --- TODO | 1 - compat/scifi_nodes.lua | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 compat/scifi_nodes.lua diff --git a/TODO b/TODO index 6bc7597..807d8c0 100644 --- a/TODO +++ b/TODO @@ -63,7 +63,6 @@ ilights:light_off -> on lavalamp:lavalamp_off -> lavalamp:lavalamp ------- need 'cable plate override' --------- -scifi_nodes:laptop_open -> scifi_nodes:laptop_closed homedecor:speaker_open -> homedecor:speaker (cable plate overrides) ---------- known incompat inspect ----------- diff --git a/compat/scifi_nodes.lua b/compat/scifi_nodes.lua new file mode 100644 index 0000000..edb7252 --- /dev/null +++ b/compat/scifi_nodes.lua @@ -0,0 +1,4 @@ +if not minetest.get_modpath('scifi_nodes') then return end + +replacer.register_exception('scifi_nodes:laptop_open', 'scifi_nodes:laptop_closed') + From 2e95ce74854a2e2f41fae08f8f348ad3d7377437 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 14:07:17 +0100 Subject: [PATCH 249/366] TODO update these seem to work --- TODO | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/TODO b/TODO index 807d8c0..2ea132e 100644 --- a/TODO +++ b/TODO @@ -59,8 +59,6 @@ homedecor:plasma_ball_off -> homedecor:plasma_ball_on -- meh homedecor:plasma_lamp_8|on -> 14 homedecor:standing_lamp_8 homedecor:table_lamp_12 -ilights:light_off -> on -lavalamp:lavalamp_off -> lavalamp:lavalamp ------- need 'cable plate override' --------- homedecor:speaker_open -> homedecor:speaker (cable plate overrides) @@ -69,7 +67,7 @@ homedecor:speaker_open -> homedecor:speaker (cable plate overrides) -- no recipe for silicon lump ---- missing icons ---- -cottages:wool;cottages:wool (used by homedecor:curtain_open) +cottages:wool;cottages:wool (used by homedecor:curtain_open) -- meh, there is working recipe (homedecor:stained_glass) -- cottages:glass_pane_side -- fix in scifi_nodes From b6d3bfa696f9d3ee044639f3e99c36345d9715fc Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 14:34:34 +0100 Subject: [PATCH 250/366] TODO update --- TODO | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/TODO b/TODO index 2ea132e..25c354d 100644 --- a/TODO +++ b/TODO @@ -45,6 +45,7 @@ scifi_nodes:capsule3 scifi_nodes:builder -- can be set but can't be placed -- need alias for inspect tool too +-- these seem to work now, maybe placing them with place_all isn't good simulation? homedecor:desk_lamp_7 -> 14 homedecor:ceiling_lantern_6 -> 14 homedecor:ceiling_lamp_8|on -> 14 @@ -61,7 +62,7 @@ homedecor:standing_lamp_8 homedecor:table_lamp_12 ------- need 'cable plate override' --------- -homedecor:speaker_open -> homedecor:speaker (cable plate overrides) +homedecor:speaker_open -> homedecor:speaker (cable plate overrides) -- not fixing as user can have both in inventory ---------- known incompat inspect ----------- -- no recipe for silicon lump @@ -83,10 +84,5 @@ bridger:corrugated_steelred bridger:corrugated_steelsteel bridger:corrugated_steelyellow --- glowlight has trouble finding base recipe, also desk_lamp, ceiling lantern, ceiling lamp, - ground lantern, hanging lantern, kitchen cabinet coloured, latice lantern, table lamp, - standing lamp, rope light/on floor, plasma lamp, plasma ball, wall lamp, --- dvd_cd_cabinet, chains, wood_table_large_square have no recipe at all - -- christmas presents say they don't drop anything From 26d3c37a1e69c8a3775417ad5f4f79899ebf9c00 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 14:35:51 +0100 Subject: [PATCH 251/366] prepare for better translatable strings detection --- compat/advtrains.lua | 4 ++-- compat/canned_food.lua | 2 +- compat/ehlphabet.lua | 3 ++- compat/letters.lua | 5 +++-- compat/mobs.lua | 2 +- compat/moreblocks.lua | 4 ++-- compat/technic.lua | 15 ++++++++------- compat/unifieddyes.lua | 3 ++- compat/wine.lua | 2 +- inspect.lua | 2 +- 10 files changed, 23 insertions(+), 19 deletions(-) diff --git a/compat/advtrains.lua b/compat/advtrains.lua index bbb668f..7598918 100644 --- a/compat/advtrains.lua +++ b/compat/advtrains.lua @@ -1,6 +1,6 @@ -local function add_advtrains_aliases() - if not minetest.get_modpath('advtrains') then return end +if not minetest.get_modpath('advtrains') then return end +local function add_advtrains_aliases() local core_get_node_drops = minetest.get_node_drops local reg = replacer.register_non_creative_alias -- these cause crashes diff --git a/compat/canned_food.lua b/compat/canned_food.lua index ace4785..7cd09c4 100644 --- a/compat/canned_food.lua +++ b/compat/canned_food.lua @@ -8,7 +8,7 @@ local function add_recipe(item_name, _, recipes) if not base_name then return end recipes[#recipes + 1] = { - method = 'fermenting/pickling', + method = S('fermenting/pickling'), type = 'canned_food', items = { base_name }, output = item_name, diff --git a/compat/ehlphabet.lua b/compat/ehlphabet.lua index b7f15f0..775c3eb 100644 --- a/compat/ehlphabet.lua +++ b/compat/ehlphabet.lua @@ -1,6 +1,7 @@ if not minetest.get_modpath('ehlphabet') then return end -- for inspection tool +local S = replacer.S replacer.group_placeholder['group:ehlphabet_block'] = 'ehlphabet:208164' local exceptions = { '231140', '229140', '228184', @@ -21,7 +22,7 @@ local function add_recipe(item_name, _, recipes) local input = sticker and 'default:paper' or 'ehlphabet:block' recipes[#recipes + 1] = { - method = 'printing', + method = S('printing'), type = 'ehlphabet', items = { input }, output = item_name, diff --git a/compat/letters.lua b/compat/letters.lua index 5551c3b..5e8fced 100644 --- a/compat/letters.lua +++ b/compat/letters.lua @@ -1,6 +1,7 @@ if not minetest.get_modpath('letters') then return end -- for inspection tool +local S = replacer.S local function add_recipe_u(item_name, _, recipes) if not item_name or not 'string' == type(item_name) then return end @@ -8,7 +9,7 @@ local function add_recipe_u(item_name, _, recipes) if not input then return end recipes[#recipes + 1] = { - method = 'cutting', + method = S('cutting'), type = 'letters:upper', items = { input }, output = item_name, @@ -26,7 +27,7 @@ local function add_recipe_l(item_name, _, recipes) if not input then return end recipes[#recipes + 1] = { - method = 'cutting', + method = S('cutting'), type = 'letters:lower', items = { input }, output = item_name, diff --git a/compat/mobs.lua b/compat/mobs.lua index 7df49f2..208d7b5 100644 --- a/compat/mobs.lua +++ b/compat/mobs.lua @@ -21,7 +21,7 @@ local function add_recipe(item_name, _, recipes) if not output then return end recipes[#recipes + 1] = { - method = 'shearing', + method = S('shearing'), type = 'sheep:cut', items = { output }, -- tecnically input, but hey output = item_name, diff --git a/compat/moreblocks.lua b/compat/moreblocks.lua index bad1d12..cc97a74 100644 --- a/compat/moreblocks.lua +++ b/compat/moreblocks.lua @@ -63,14 +63,14 @@ local function is_saw_output(node_name) return basic_node_name end -- is_saw_output - +local S = replacer.S local function add_circular_saw_recipe(node_name, _, recipes) local basic_node_name = is_saw_output(node_name) if not basic_node_name then return end -- node found that fits into the saw recipes[#recipes + 1] = { - method = 'sawing', + method = S('sawing'), type = 'saw', items = { basic_node_name }, output = node_name diff --git a/compat/technic.lua b/compat/technic.lua index b8100b4..748971a 100644 --- a/compat/technic.lua +++ b/compat/technic.lua @@ -32,6 +32,7 @@ end) --[[ --"cooking" is probably not needed as that is a standard method ]] +local S = replacer.S local function add_recipe_alloy(item_name, _, recipes) --pd(technic.recipes['alloy']) @@ -46,7 +47,7 @@ local function add_recipe_alloy(item_name, _, recipes) end local i1, i2 = l[1], l[2] recipes[#recipes + 1] = { - method = 'alloying', + method = S('alloying'), type = 'technic:alloy', items = { i1, i2 }, output = def.output @@ -64,7 +65,7 @@ local function add_recipe_cnc(item_name, _, recipes) if not base_name then return end recipes[#recipes + 1] = { - method = 'CNC machining', + method = S('CNC machining'), type = 'technic:cnc', items = { base_name }, output = item_name, @@ -85,7 +86,7 @@ local function add_recipe_compress(item_name, _, recipes) for input_name, def in pairs(technic.recipes['compressing']['recipes']) do if def.output and def.output == item_name then recipes[#recipes + 1] = { - method = 'compressing', + method = S('compressing'), type = 'technic:compress', items = { input_name .. ' ' .. tostring(def.input[input_name]) }, output = item_name @@ -104,7 +105,7 @@ local function add_recipe_extract(item_name, _, recipes) and def.output:find('^' .. item_name .. ' ?[0-9]*$') then recipes[#recipes + 1] = { - method = 'extracting', + method = S('extracting'), type = 'technic:extract', items = { input_name .. ' ' .. tostring(def.input[input_name]) }, output = def.output @@ -125,7 +126,7 @@ local function add_recipe_freeze(item_name, _, recipes) and def.output:find('^' .. item_name .. ' ?[0-9]*$') then recipes[#recipes + 1] = { - method = 'freezing', + method = S('freezing'), type = 'technic:freeze', items = { input_name }, output = def.output, @@ -191,7 +192,7 @@ local function add_recipe_grind(item_name, _, recipes) inputs = {} end recipes[#recipes + 1] = { - method = 'grinding', + method = S('grinding'), type = 'technic:grind', items = inputs, output = def.output @@ -225,7 +226,7 @@ local function add_recipe_separate(item_name, _, recipes) table.insert(inputs, k .. ' ' .. tostring(v)) end recipes[#recipes + 1] = { - method = 'separating', + method = S('separating'), type = 'technic:separate', items = inputs, output = main_output, diff --git a/compat/unifieddyes.lua b/compat/unifieddyes.lua index 9c17d17..10760fe 100644 --- a/compat/unifieddyes.lua +++ b/compat/unifieddyes.lua @@ -11,6 +11,7 @@ local make_readable_color = unifieddyes.make_readable_color local colour_to_name = unifieddyes.color_to_name -- for inspection tool formspec +local S = replacer.S local function add_recipe(node_name, param2, recipes) if not param2 then return end @@ -22,7 +23,7 @@ local function add_recipe(node_name, param2, recipes) for i, t in ipairs(recipes) do first, last = t.output:find(needle) if nil ~= first then - t.method = 'painting' + t.method = S('painting') t.type = 'unifieddyes:airbrush' recipes[#recipes + 1] = t return diff --git a/compat/wine.lua b/compat/wine.lua index dc67bca..bc96a46 100644 --- a/compat/wine.lua +++ b/compat/wine.lua @@ -29,7 +29,7 @@ local function add_recipe(item_name, _, recipes) -- allow new items to show up using air as icon local input = in_out[item_name] or 'air' recipes[#recipes + 1] = { - method = 'fermenting', + method = S('fermenting'), type = 'wine:ferment', items = { input }, output = item_name, diff --git a/inspect.lua b/inspect.lua index 860a2a5..9aed0aa 100644 --- a/inspect.lua +++ b/inspect.lua @@ -425,7 +425,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) local handler = r.recipe_adders[recipe.type] formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' .. r.image_button_link(handler.machine) .. ']' - .. 'label[0.1,4.3;' .. mfe(S(recipe.method)) .. ']' + .. 'label[0.1,4.3;' .. mfe(recipe.method) .. ']' local width = recipe.width or #recipe.items width = max(1, min(3, width)) local offsets = { 2.2, 1.7, 1.2 } From e2911ef22a6c2ffe342930349cce29e38034d0dd Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 26 Jan 2022 15:49:37 +0100 Subject: [PATCH 252/366] translations update --- blabla.lua | 4 +--- chat_commands.lua | 2 +- locale/replacer.de.tr | 29 +++++++++++++++++++++-------- locale/replacer.es.tr | 29 +++++++++++++++++++++-------- locale/replacer.fi.tr | 29 +++++++++++++++++++++-------- locale/replacer.fr.tr | 29 +++++++++++++++++++++-------- locale/replacer.it.tr | 29 +++++++++++++++++++++-------- locale/replacer.pt.tr | 29 +++++++++++++++++++++-------- locale/replacer.ru.tr | 29 +++++++++++++++++++++-------- locale/template.txt | 29 +++++++++++++++++++++-------- replacer/replacer.lua | 2 +- 11 files changed, 171 insertions(+), 69 deletions(-) diff --git a/blabla.lua b/blabla.lua index 1753dad..adcb4fc 100644 --- a/blabla.lua +++ b/blabla.lua @@ -56,13 +56,11 @@ rb.log_deny_list_insert = '[replacer] Added "%s" to deny list.' rb.timed_out = S('Time-limit reached.') rb.tool_short_description = '(%s %s%s) %s' rb.tool_long_description = '%s\n%s\n%s' -rb.ccm_params = '(chat|audio) (%s|%s)' +rb.ccm_params = '(chat|audio) (0|1)' rb.ccm_description = S('Toggles verbosity.\nchat: When on, ' .. 'messages are posted to chat.\naudio: When off, replacer is silent.') rb.ccm_player_not_found = 'Player not found' rb.ccm_player_meta_error = 'Player meta not existant' -rb.on_yes = S('on') -rb.off_no = S('off') rb.log_reg_exception_override = '[replacer] register_exception: ' .. 'exception for "%s" already exists.' rb.log_reg_exception = '[replacer] registered exception for "%s" to "%s"' diff --git a/chat_commands.lua b/chat_commands.lua index 7c112dc..1def2df 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -12,7 +12,7 @@ for _, s in ipairs(lOff) do tOff[s] = true end replacer.chatcommand_mute = { - params = rb.ccm_params:format(rb.on_yes, rb.off_no),--(chat|audio) (%s|%s) + params = rb.ccm_params,--(chat|audio) (0|1) description = rb.ccm_description, func = function(name, param) local player = minetest.get_player_by_name(name) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index 712ac32..7c35391 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -25,10 +25,7 @@ Node replacement tool=Ersetzer Node replacement tool (technic)=Ersetzer (Technik) Time-limit reached.=Zeitbegrenzung erreicht. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Schaltet die Ausführlichkeit um.@nWenn diese Option aktiviert ist, werden Nachrichten im Chat ausgegeben. Im ausgeschalteten Zustand ist der Ersetzer stumm. - -on=an -off=aus +Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Schaltet die Ausführlichkeit um.@nchat: Wenn eingeschaltet, werden Nachrichten im Chat ausgegeben.@audio: Wenn ausgeschaltet, ist der Ersetzer stumm. Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Inspektionswerkzeug@nSchlagen zum Inspizieren der Zielnode oder der Entität.@nPlatzieren zum Inspizieren der angrenzenden Node. @@ -53,8 +50,11 @@ nothing=nichts May drop on dig:=Kann beim Graben fallen lassen: This can be used as a fuel.=Dies kann als Brennstoff verwendet werden. Error: Unkown recipe.=Fehler: Unbekanntes Rezept. -Valid parameter is either "@1" or "@2"=Gültige Parameter sind entweder „@1“ oder „@2“. +fermenting/pickling=Gären +Store near group:wood, light < 12.=In der Nähe der Holzgruppe@n(group:wood) lagern, Licht < 12. +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Node des Typs „@1“ dürfen auf diesem Server nicht ersetzt werden. Versuch fehlgeschlagen. Protected at @1=Geschützt bei @1 +printing=Drucken This is your fellow player "@1"=Dies ist dein Mitspieler „@1“ This is an entity "@1"=Das ist eine Entität „@1“ , dropped @1 minutes ago=, vor @1 Minuten gefallen @@ -69,6 +69,10 @@ Located at @1=Befindet sich bei @1 with param2 of @1=mit param2 von @1 and receiving @1 light=und empfängt @1 licht Alternate @1/@2=Alternative @1/@2 +cutting=Schneiden +shearing=Scheren +Cut with shears.=Mit Schere schneiden. +sawing=Sägen You have no further "@1". Replacement failed.=Du hast keine weitere „@1“. Ersetzung fehlgeschlagen. Unknown node: "@1"=Unbekannter Node: „@1“ Unknown node to place: "@1"=Unbekant zu setzender Node: „@1“ @@ -77,7 +81,16 @@ Could not place "@1".=Konnte „@1“ nicht platzieren. Error: "@1" is not a node.=Fehler: „@1“ ist kein Node. @1 nodes replaced.=@1 Node ersetzt. Mode changed to @1: @2=Modus gewechselt auf @1: @2 -Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Node des Typs „@1“ dürfen auf diesem Server nicht ersetzt werden. Versuch fehlgeschlagen. -Item not in creative inventory: "@1".=Artikel befindet sich nicht im Kreativ-Inventar: „@1“. -Item not in your inventory: "@1".=Artikel befindet sich nicht in deinem Inventar: „@1“. +Placing nodes of type "@1" is not allowed on this server.=Das Platzieren von Node vom Typ "@1" ist auf diesem Server nicht erlaubt. +Failed to set replacer to "@1". If there was one in your inventory, then maybe.=Ersetzer konnte nicht auf "@1" gesetzt werden. Wenn es einen in deinem Inventar gäbe, dann vielleicht. Node replacement tool set to:@n@1.=Ersetzer konfiguriert auf:@n@1. +alloying=Legieren +CNC machining=CNC-Bearbeitung +compressing=Komprimieren +extracting=Extrahieren +freezing=Einfrieren +grinding=Mahlen +separating=Trennen +painting=Malen +fermenting=Fermentieren +Ferment in barrel.=Gärung im Fass. diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 531c302..f207514 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -25,10 +25,7 @@ Node replacement tool=Intercambiador Node replacement tool (technic)=Intercambiador (técnica) Time-limit reached.=Límite de tiempo alcanzado. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Alterna verbosidad.@nCuando está activado, los mensajes se publican en el chat. Cuando está apagado, el intercambiador está en silencio. - -on=1 -off=0 +Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Alterna la verbosidad. @nchat: cuando está activado, los mensajes se publican en el chat. @naudio: cuando está desactivado, el intercambiador está en silencio. Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Herramienta de inspección@nUsar para inspeccionar el nodo o la entidad de destino.@nColocar para inspeccionar el nodo adyacente. @@ -53,8 +50,11 @@ nothing=nada May drop on dig:=Puede caer en excavación: This can be used as a fuel.=Esto se puede usar como combustible. Error: Unkown recipe.=Error: Receta desconocida. -Valid parameter is either "@1" or "@2"=El parámetro válido es "@1" o "@2" +fermenting/pickling=fermentación/decapado +Store near group:wood, light < 12.=Almacenar cerca del grupo de madera@n(group:wood), luz < 12. +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=No se permite reemplazar nodos de tipo "@1" en este servidor. Reemplazo fallido. Protected at @1=Protegido en @1 +printing=impresión This is your fellow player "@1"=Este es tu compañero de juego "@1" This is an entity "@1"=Esta es una entidad "@1" , dropped @1 minutes ago=, caído hace @1 minutos @@ -69,6 +69,10 @@ Located at @1=Ubicado en @1 with param2 of @1=con param2 de @1 and receiving @1 light=y recibiendo @1 luz Alternate @1/@2=Alternativo @1/@2 +cutting=corte +shearing=cizallamiento +Cut with shears.=Cortar con tijeras. +sawing=aserradura You have no further "@1". Replacement failed.=No tienes más "@1". Reemplazo fallido. Unknown node: "@1"=Nodo desconocido: "@1" Unknown node to place: "@1"=Nodo desconocido a colocar: "@1" @@ -77,7 +81,16 @@ Could not place "@1".=No se pudo colocar "@1". Error: "@1" is not a node.=Error: "@1" no es un nodo. @1 nodes replaced.=@1 nodos reemplazados. Mode changed to @1: @2=Modo cambiado a @1: @2 -Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=No se permite reemplazar nodos de tipo "@1" en este servidor. Reemplazo fallido. -Item not in creative inventory: "@1".=Artículo no está en el inventario creativo: "@1". -Item not in your inventory: "@1".=Artículo no está en su inventario: "@1". +Placing nodes of type "@1" is not allowed on this server.=No se permite colocar nodos de tipo "@1" en este servidor. +Failed to set replacer to "@1". If there was one in your inventory, then maybe.=No se pudo establecer el intercambiador en "@1". Si habías uno en tu inventario, entonces tal vez. Node replacement tool set to:@n@1.=Intercambiador establecida en:@n@1. +alloying=aleación +CNC machining=Mecanizado CNC +compressing=comprimiendo +extracting=extrayendo +freezing=congelación +grinding=molienda +separating=separando +painting=pintaando +fermenting=fermentando +Ferment in barrel.=Fermentación en barrica. diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index 14a6866..dd29e06 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -25,10 +25,7 @@ Node replacement tool=Solmun vaihtotyökalu Node replacement tool (technic)=Solmun vaihtotyökalu (tekninen) Time-limit reached.=Aikaraja saavutettu. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Vaihtaa verbosity.@nKun käytössä, viestit lähetetään chattiin. Kun se on pois päältä, korvaaja on äänetön. - -on=kyllä -off=fora +Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Vaihtaa verbosity.@nchat: Kun päällä, viestit lähetetään chat.@naudio: Kun pois päältä, korvaaja on äänetön. Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Tarkastustyökalu@nTarkista kohdesolmu tai entiteetti.@nTarkista viereinen solmu. @@ -53,8 +50,11 @@ nothing=ei mitään May drop on dig:=Saattaa pudota kaivamaan: This can be used as a fuel.=Tätä voidaan käyttää polttoaineena. Error: Unkown recipe.=Virhe: Tuntematon resepti. -Valid parameter is either "@1" or "@2"=Kelvollinen parametri on joko "@1" tai "@2" +fermenting/pickling=käyminen/peittaus +Store near group:wood, light < 12.=Varasto lähellä group:wood,@nkevyt < 12. +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Tyypin "@1" solmujen korvaaminen ei ole sallittua tässä palvelimessa. Vaihto epäonnistui. Protected at @1=Suojattu @1 +printing=painatus This is your fellow player "@1"=Tämä on pelikaverisi "@1" This is an entity "@1"=Tämä on entiteetti "@1" , dropped @1 minutes ago=, pudonnut @1 minuuttia sitten @@ -69,6 +69,10 @@ Located at @1=Sijaitsee @1 with param2 of @1=param2 @1 and receiving @1 light=ja vastaanottaa @1 valoa Alternate @1/@2=Vaihtoehto @1/@2 +cutting=leikkaus +shearing=leikkaus +Cut with shears.=Leikkaa saksilla. +sawing=sahaus You have no further "@1". Replacement failed.=Sinulla ei ole enempää "@1". Vaihto epäonnistui. Unknown node: "@1"=Tuntematon solmu: "@1" Unknown node to place: "@1"=Tuntematon sijoitettava solmu: "@1" @@ -77,7 +81,16 @@ Could not place "@1".=Ei voitu sijoittaa "@1". Error: "@1" is not a node.=Virhe: "@1" ei ole solmu. @1 nodes replaced.=@1 solmua vaihdettu. Mode changed to @1: @2=Tila muutettu tilaksi @1: @2 -Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Tyypin "@1" solmujen korvaaminen ei ole sallittua tässä palvelimessa. Vaihto epäonnistui. -Item not in creative inventory: "@1".=Kohde ei ole mainosjakaumassa: "@1". -Item not in your inventory: "@1".=Tuote, joka ei ole varastossa: "@1". +Placing nodes of type "@1" is not allowed on this server.=Tyypin "@1" solmujen sijoittaminen ei ole sallittua tälle palvelimelle. +Failed to set replacer to "@1". If there was one in your inventory, then maybe.=Korvaajan asettaminen arvoon "@1" epäonnistui. Jos sellainen oli varastossasi, niin ehkä. Node replacement tool set to:@n@1.=Solmun korvaustyökalu asetettu arvoon:@n@1. +alloying=seostus +CNC machining=CNC-työstö +compressing=pakkaaminen +extracting=purkaminen +freezing=jäätyminen +grinding=hionta +separating=erottava +painting=maalaus +fermenting=käyminen +Ferment in barrel.=Fermentoida tynnyrissä. diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index d81032b..3357e74 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -25,10 +25,7 @@ Node replacement tool=Remplaçant Node replacement tool (technic)=Remplaçant (technique) Time-limit reached.=Délai atteint. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Active/désactive la verbosité.@nLorsque cette option est activée, les messages sont publiés sur le chat. Lorsqu'il est désactivé, le remplaçant est silencieux. - -on=1 -off=0 +Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Active/désactive la verbosité.@nchat : lorsque cette option est activée, les messages sont publiés sur le chat.@naudio : lorsqu'elle est désactivée, le remplaçant est silencieux. Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Outil d'inspection@nUtiliser pour inspecter le nœud ou l'entité cible.@nPlacer pour inspecter le nœud adjacent. @@ -53,8 +50,11 @@ nothing=rien May drop on dig:=Peut tomber en creusant: This can be used as a fuel.=Cela peut être utilisé comme carburant. Error: Unkown recipe.=Erreur : recette inconnue. -Valid parameter is either "@1" or "@2"=Le paramètre valide est "@1" ou "@2" +fermenting/pickling=fermentation/marinage +Store near group:wood, light < 12.=Entreposer près du groupe @ngroup:wood, lumière < 12. +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Le remplacement de nœuds de type "@1" n'est pas autorisé sur ce serveur. Échec du remplacement. Protected at @1=Protégé à @1 +printing=impression This is your fellow player "@1"=C'est votre coéquipier "@1" This is an entity "@1"=Ceci est une entité "@1" , dropped @1 minutes ago=, déposé il y a @1 minutes @@ -69,6 +69,10 @@ Located at @1=Situé à @1 with param2 of @1=avec param2 de @1 and receiving @1 light=et recevant @1 lumière Alternate @1/@2=Alternance @1/@2 +cutting=Coupe +shearing=Tonte +Cut with shears.=Couper avec des cisailles. +sawing=Sciage You have no further "@1". Replacement failed.=Tu n'as plus de "@1". Échec du remplacement. Unknown node: "@1"=Nœud inconnu : "@1" Unknown node to place: "@1"=Nœud inconnu à placer : "@1" @@ -77,7 +81,16 @@ Could not place "@1".=Impossible de placer "@1". Error: "@1" is not a node.=Erreur : "@1" n'est pas un nœud. @1 nodes replaced.=@1 nœuds remplacés. Mode changed to @1: @2=Mode changé en @1 : @2 -Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Le remplacement de nœuds de type "@1" n'est pas autorisé sur ce serveur. Échec du remplacement. -Item not in creative inventory: "@1".=L'article n'est pas dans l'inventaire de la création : "@1". -Item not in your inventory: "@1".=Objet pas dans tu inventaire : "@1". +Placing nodes of type "@1" is not allowed on this server.=Le placement de nœuds de type "@1" n'est pas autorisé sur ce serveur. +Failed to set replacer to "@1". If there was one in your inventory, then maybe.=Impossible de définir le remplaçant sur "@1". S'il y en avait un dans votre inventaire, alors peut-être. Node replacement tool set to:@n@1.=Remplaçant défini sur :@n@1. +alloying=alliage +CNC machining=Usinage CNC +compressing=compression +extracting=extraire +freezing=gelé +grinding=affûtage +separating=séparer +painting=peindre +fermenting=fermentation +Ferment in barrel.=Fermentation en barrique. diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index 37e1be6..ba9ec20 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -25,10 +25,7 @@ Node replacement tool=Strumento di sostituzione del nodo Node replacement tool (technic)=Strumento di sostituzione del nodo (tecnico) Time-limit reached.=Tempo limite raggiunto. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Attiva o disattiva la verbosità.@nQuando è attiva, i messaggi vengono inviati alla chat. Quando è spento, il sostituto è silenzioso. - -on=1 -off=0 +Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Attiva/disattiva verbosità.@nchat: quando è attivo, i messaggi vengono inviati alla chat.@naudio: quando è disattivato, il sostituto è silenzioso. Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Strumento di ispezione@nUtilizzare per ispezionare il nodo o l'entità di destinazione.@nPosizionare per ispezionare il nodo adiacente. @@ -53,8 +50,11 @@ nothing=niente May drop on dig:=Può cadere durante lo scavo: This can be used as a fuel.=Questo può essere usato come carburante. Error: Unkown recipe.=Errore: ricetta sconosciuta. -Valid parameter is either "@1" or "@2"=Il parametro valido è "@1" o "@2" +fermenting/pickling=fermentazione/decapaggio +Store near group:wood, light < 12.=Negozio vicino al gruppo group:wood,@nluce < 12. +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=La sostituzione dei nodi di tipo "@1" non è consentita su questo server. Sostituzione non riuscita. Protected at @1=Protetto a @1 +printing=stampa This is your fellow player "@1"=Questo è il tuo compagno di gioco "@1" This is an entity "@1"=Questa è un'entità "@1" , dropped @1 minutes ago=, caduto @1 minuti fa @@ -69,6 +69,10 @@ Located at @1=Situato a @1 with param2 of @1=con param2 di @1 and receiving @1 light=e ricevendo @1 luce Alternate @1/@2=Alternativo @1/@2 +cutting=taglio +shearing=tosatura +Cut with shears.=Tagliare con le forbici. +sawing=segare You have no further "@1". Replacement failed.=Non hai più "@1". Sostituzione non riuscita. Unknown node: "@1"=Nodo sconosciuto: "@1" Unknown node to place: "@1"=Nodo sconosciuto da posizionare: "@1" @@ -77,7 +81,16 @@ Could not place "@1".=Impossibile posizionare "@1". Error: "@1" is not a node.=Errore: "@1" non è un nodo. @1 nodes replaced.=@1 nodi sostituiti. Mode changed to @1: @2=Modalità modificata in @1: @2 -Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=La sostituzione dei nodi di tipo "@1" non è consentita su questo server. Sostituzione non riuscita. -Item not in creative inventory: "@1".=Articolo non nell'inventario della creatività: "@1". -Item not in your inventory: "@1".=Articolo non nel tuo inventario: "@1". +Placing nodes of type "@1" is not allowed on this server.=Il posizionamento di nodi di tipo "@1" non è consentito su questo server. +Failed to set replacer to "@1". If there was one in your inventory, then maybe.=Impossibile impostare il sostituto su "@1". Se ce n'era uno nel tuo inventario, allora forse. Node replacement tool set to:@n@1.=Strumento di sostituzione del nodo impostato su:@n@1. +alloying=legare +CNC machining=Lavorazione CNC +compressing=compressione +extracting=estraendo +freezing=congelamento +grinding=macinazione +separating=separare +painting=dipingere +fermenting=fermentazione +Ferment in barrel.=Fermentazione in botte. diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index a687cfd..41671dc 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -25,10 +25,7 @@ Node replacement tool=Ferramenta de substituição de nós Node replacement tool (technic)=Ferramenta de substituição de nós (técnica) Time-limit reached.=Limite de tempo atingido. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Alterna a verbosidade.@nQuando ativado, as mensagens são postadas no bate-papo. Quando desligado, o substituto fica silencioso. - -on=em -off=não +Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Alterna a verbosidade.@nchat: Quando ativado, as mensagens são postadas no chat.@naudio: Quando desativado, o substituto é silencioso. Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Ferramenta de Inspeção@nUse para inspecionar o nó ou entidade de destino.@nPlace para inspecionar o nó adjacente. @@ -53,8 +50,11 @@ nothing=nada May drop on dig:=Pode cair na escavação: This can be used as a fuel.=Isso pode ser usado como combustível. Error: Unkown recipe.=Erro: receita desconhecida. -Valid parameter is either "@1" or "@2"=O parâmetro válido é "@1" ou "@2" +fermenting/pickling=fermentação/decapagem +Store near group:wood, light < 12.=Armazenar perto do grupo group:wood,@nluz < 12. +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=A substituição de nós do tipo "@1" não é permitida neste servidor. Falha na substituição. Protected at @1=Protegido em @1 +printing=impressão This is your fellow player "@1"=Este é seu colega jogador "@1" This is an entity "@1"=Esta é uma entidade "@1" , dropped @1 minutes ago=, caiu @1 minutos atrás @@ -69,6 +69,10 @@ Located at @1=Localizado em @1 with param2 of @1=com param2 de @1 and receiving @1 light=e recebendo @1 luz Alternate @1/@2=Alternativo @1/@2 +cutting=corte +shearing=cisalhamento +Cut with shears.=Corte com tesoura. +sawing=serrar You have no further "@1". Replacement failed.=Você não tem mais "@1". Falha na substituição. Unknown node: "@1"=Nó desconhecido: "@1" Unknown node to place: "@1"=Nó desconhecido para colocar: "@1" @@ -77,7 +81,16 @@ Could not place "@1".=Não foi possível colocar "@1". Error: "@1" is not a node.=Erro: "@1" não é um nó. @1 nodes replaced.=@1 nós substituídos. Mode changed to @1: @2=Modo alterado para @1: @2 -Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=A substituição de nós do tipo "@1" não é permitida neste servidor. Falha na substituição. -Item not in creative inventory: "@1".=Item não no inventário do criativo: "@1". -Item not in your inventory: "@1".=Item que não está em seu inventário: "@1". +Placing nodes of type "@1" is not allowed on this server.=A colocação de nós do tipo "@1" não é permitida neste servidor. +Failed to set replacer to "@1". If there was one in your inventory, then maybe.=Falha ao definir o substituto para "@1". Se houvesse um em seu inventário, então talvez. Node replacement tool set to:@n@1.=Ferramenta de substituição de nó definida como:@n@1. +alloying=liga +CNC machining=Usinagem CNC +compressing=comprimir +extracting=extrair +freezing=congelando +grinding=esmerilhamento +separating=separando +painting=pintar +fermenting=fermentando +Ferment in barrel.=Fermentar em barril. diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index 8770be4..ba3d790 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -25,10 +25,7 @@ Node replacement tool=Инструмент замены узлов Node replacement tool (technic)=Инструмент замены узла (техника) Time-limit reached.=Достигнут лимит времени. -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.=Включает многословие. @nКогда включено, сообщения отправляются в чат. Когда выключено, заменитель молчит. - -on=да -off=нет +Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Включает многословие. @nchat: когда включено, сообщения отправляются в чат. @naudio: когда выключено, заменитель молчит. Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Inspection Tool@nИспользуйте для проверки целевого узла или объекта. @nPlace для проверки соседнего узла. @@ -53,8 +50,11 @@ nothing=ничего May drop on dig:=Может выпасть при раскопках: This can be used as a fuel.=Это можно использовать в качестве топлива. Error: Unkown recipe.=Ошибка: Неизвестный рецепт. -Valid parameter is either "@1" or "@2"=Допустимый параметр: "@1" или "@2" +fermenting/pickling=ферментация/маринование +Store near group:wood, light < 12.=Хранить рядом с группой дерево@n(group:wood), свет < 12. +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Замена узлов типа "@1" на этом сервере запрещена. Замена не удалась. Protected at @1=Защищено в @1 +printing=печать This is your fellow player "@1"=Это ваш товарищ по игре "@1" This is an entity "@1"=Это сущность "@1" , dropped @1 minutes ago=, выпало @1 минут назад @@ -69,6 +69,10 @@ Located at @1=Находится по адресу @1 with param2 of @1=с параметром2 из @1 and receiving @1 light=и получаю @1 свет Alternate @1/@2=Альтернатива @1/@2 +cutting=резка +shearing=стрижка +Cut with shears.=Вырезать ножницами. +sawing=пиление You have no further "@1". Replacement failed.=У вас больше нет "@1". Замена не удалась. Unknown node: "@1"=Неизвестный узел: "@1" Unknown node to place: "@1"=Неизвестный узел для размещения: "@1" @@ -77,7 +81,16 @@ Could not place "@1".=Не удалось разместить "@1". Error: "@1" is not a node.=Ошибка: "@1" не является узлом. @1 nodes replaced.=Заменено узлов: @1. Mode changed to @1: @2=Режим изменен на @1: @2 -Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Замена узлов типа "@1" на этом сервере запрещена. Замена не удалась. -Item not in creative inventory: "@1".=Предмета нет в творческом инвентаре: "@1". -Item not in your inventory: "@1".=Предмета нет в вашем инвентаре: "@1". +Placing nodes of type "@1" is not allowed on this server.=Размещение узлов типа "@1" на этом сервере запрещено. +Failed to set replacer to "@1". If there was one in your inventory, then maybe.=Не удалось установить заменитель на "@1". Если бы он был в вашем инвентаре, то, возможно. Node replacement tool set to:@n@1.=Инструмент замены узлов установлен на:@n@1. +alloying=легирование +CNC machining=ЧПУ обработка +compressing=сжатие +extracting=извлечение +freezing=замораживание +grinding=шлифовка +separating=разделяющий +painting=рисования +fermenting=брожение +Ferment in barrel.=Ферментация в бочке. diff --git a/locale/template.txt b/locale/template.txt index af0eefc..83139c0 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -25,10 +25,7 @@ Node replacement tool= Node replacement tool (technic)= Time-limit reached.= -Toggles verbosity.@nWhen on, messages are posted to chat. When off, replacer is silent.= - -on= -off= +Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.= Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.= @@ -53,8 +50,11 @@ nothing= May drop on dig:= This can be used as a fuel.= Error: Unkown recipe.= -Valid parameter is either "@1" or "@2"= +fermenting/pickling= +Store near group:wood, light < 12.= +Replacing nodes of type "@1" is not allowed on this server. Replacement failed.= Protected at @1= +printing= This is your fellow player "@1"= This is an entity "@1"= , dropped @1 minutes ago= @@ -69,6 +69,10 @@ Located at @1= with param2 of @1= and receiving @1 light= Alternate @1/@2= +cutting= +shearing= +Cut with shears.= +sawing= You have no further "@1". Replacement failed.= Unknown node: "@1"= Unknown node to place: "@1"= @@ -77,7 +81,16 @@ Could not place "@1".= Error: "@1" is not a node.= @1 nodes replaced.= Mode changed to @1: @2= -Replacing nodes of type "@1" is not allowed on this server. Replacement failed.= -Item not in creative inventory: "@1".= -Item not in your inventory: "@1".= +Placing nodes of type "@1" is not allowed on this server.= +Failed to set replacer to "@1". If there was one in your inventory, then maybe.= Node replacement tool set to:@n@1.= +alloying= +CNC machining= +compressing= +extracting= +freezing= +grinding= +separating= +painting= +fermenting= +Ferment in barrel.= diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 8175e15..81fb417 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -656,7 +656,7 @@ function replacer.on_place(itemstack, player, pt) if not valid() then r.play_sound(name, true) r.inform(name, S('Failed to set replacer to "@1". ' - .. 'If you had one in your inventory, it could be set.', node.name)) + .. 'If there was one in your inventory, then maybe.', node.name)) return end From 20337bcfb41c60229673896ca8d67c8b7ac63b5b Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 27 Jan 2022 00:05:50 +0100 Subject: [PATCH 253/366] documentation update --- README.md | 55 +++++++++++--- doc/customization.md | 169 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+), 11 deletions(-) create mode 100644 doc/customization.md diff --git a/README.md b/README.md index 8f50fa6..c152b3a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ Replacement tool for creative building (Mod for Minetest) +========================================================= -This tool is helpful for creative purposes (i.e. build a wall and "paint" windows into it). +This tool is helpful for creative purposes (e.g. build a wall and "paint" windows into it). It replaces nodes with a previously selected other type of node (i.e. places said windows into a brick wall). # Crafting + Availability of recipes can be configured with server settings. Basic replacer: ``` @@ -38,24 +40,47 @@ Sneak-right-click on a node of which type you want to replace other nodes with. When in creative mode, the node will just be replaced. Your inventory will not be changed. -When *not* in creative mode, digging will be simulated and you will get what was there. +When *not* in creative mode, digging will be simulated and you will get what was there.
In return, the replacement node will be taken from your inventory. -If technic mod is installed, modes are available and use depletes charge. +If technic mod is installed, modes are available and use depletes charge.
This is true for users without "give" privs and also on servers not running in creative mode. -# Modes +# Modes (Major) -Special-right-click on a node or special-left-click anywhere to change the mode. -Single-mode does not need any charge. The other modes do. -For a description of the modes with pictures, refer to [doc/usage.md](doc/usage.md). +Special+Place on a node or Special+Use anywhere to change the mode.
+The first informs you in chat about the mode change while the second opens a formspec.
+Single-mode does not need any charge. The other modes do.
+For a description of the modes with pictures, refer to: * [Single Mode (doc/usageSingle.md)](doc/usageSingle.md) * [Field Mode (doc/usageField.md)](doc/usageField.md) * [Crust Mode (doc/usageCrust.md)](doc/usageCrust.md) +# Modes (Minor) + +Using the formspec or Sneak+Special+Place to change the minor mode. +* Both (standard) +* Node: Replaces the node using rotation of dug node. +* Rotation: Basically a screwdriver with set rotation. Doesn't dig the clicked node, only applies the stored rotation. +In Field and Crust Modes this will apply to multiple nodes according to respective search pattern.
+When Place-button is pressed, Rotation Mode does not make much sense as mostly air is being rotated. This can lead to confusion for beginners. + +# Chat Commands + +* /replacer (audio|chat) (1|0) toggles chat messages for advanced users. Also allows muting sounds. This command also accepts variants of "on"/"off" words in several languages. +* /place_all [dry-run][ move_player][ no_support_node][ [] ... [ ]] + This is only available to players with **priv** priv and only in development mode. [Read the comments in (test.lua)](test.lua) + +# Privelages + +**creative** priv allows setting to more node-types and **give** priv allows to set to any. They both +unlock modes even for basic replacer and allow using without charge constrain.
+They both also allow user to use unlimited amounts of items without checking inventory.
+The configurable priv allows using history. + # Inspection tool -The third tool included in this mod is the inspector. +The third tool included in this mod is the inspection tool. Crafting: ``` @@ -63,15 +88,22 @@ Crafting: | stick | | | | | | | ``` -Just wield it and click on any node or entity you want to know more about. A limited craft-guide is included. +Punch (dig/use on) any node or entity you want to know more about.
+Right-click (place) on any node to get information of the adjacent node. The node that would be placed if you were weilding something placeable.
+This is useful to inspect a node that is otherwise unclickable. E.g. airlight or activated stealthnodes.
+Apart from node name and description, light value and a limited craft-guide is included.
+Compatibility to many mods with special use cases have been added. Read [Customization (doc/customization.md)]((doc/customization.md)) for more information. # Settings -* **replacer.max_nodes** max allowed nodes to replace (default: 3168) +* **replacer.max_nodes** max allowed nodes to replace per action (default: 3168) * **replacer.hide_recipe_basic** hide the basic recipe (default: 0)
-These two require technic to be installed, if not they are hidden no matter how you set them +These two require technic to be installed, if not, the recipes are hidden. * **replacer.hide_recipe_technic_upgrade** hide the upgrade recipe (default: 0) * **replacer.hide_recipe_technic_direct** hide the direct technic recipe (default: 1) +* **replacer.history_priv** priv needed for using history (default: creative) +[All settings with medium length description in (settingtypes.txt)](settingtypes.txt) +Lengthy information about settings and customization can be found in the [Customization Guide (doc/customization.md)](doc/customization.md) # Contributors @@ -100,3 +132,4 @@ These two require technic to be installed, if not they are hidden no matter how You should have received a copy of the GNU General Public License along with this program. If not, see . + diff --git a/doc/customization.md b/doc/customization.md new file mode 100644 index 0000000..8868370 --- /dev/null +++ b/doc/customization.md @@ -0,0 +1,169 @@ +Customization documentation for replacer minetest mod +===================================================== + +- [Settings](#settings) +- [API Commands](#api-commands) +- [Inspection Tool](#inspection-tool) + +## Settings + +_default values in parentheses ()_
+All the setting names correspond to equivalents in Lua namespace. Allowing them to be +changed "on the fly". The recipe related ones won't have any effect though.
+For history related settings, users will have to relog or have their history priv +revoked and granted again for the values to take effect correctly. + +### replacer.max_nodes (3168) +Replace / place up to this many nodes when using modes other than single.
+Depending on server hardware and amount of users, this value needs adapting. +On singleplayer you can mostly use a higher value. + +### replacer.max_time (1.0) +Some nodes take a long time to be placed. This value limits the time in seconds +in which the nodes are placed. This prevents more lag on an already lagging server +with a high replacer.max_nodes setting.
+This time does not include the time used to search for nodes, only the time used +to replace them is measured and limited by this value. + +### replacer.radius_factor (0.4) +Radius limit factor when more possible positions are found than either max_nodes or charge +allow. Positions are traversed again and only those within radius * this factor are +passed back for replacement. Generates nice circles in field mode.
+Radius == floor(max_positions ^ radius_factor + .5) where max_positions is a min(max()) +of available charge and max_nodes. Small changes to this value can have big effects.
+Set radius_factor to 0 or less for behaviour prior to version 3.3 + +### replacer.history_priv (creative) +You can make history available to users with this priv. By default it is set to **creative** +as survival users can make several replacers. You can make this an acheivment for busy players +to work towards, or set to **interact** to allow any player to use history of previously +used node settings. + +### replacer.history_disable_persistancy (false) +When set, does not save history over sessions. Reason might be old MT version.
+Currently history is stored in player's meta on logoff and at intervals. + +### replacer.history_save_interval (7) +How frequently, in minutes, history is saved to player-meta.
+Only users with the priv are affected. + +### replacer.history_include_mode (false) +When set, changes the replacer's major and minor modes when picking an item from history.
+The modes are stored either way. + +### replacer.history_max (7) +Limits history length. Duplicates are removed so there isn't much need for long histories. + +### replacer.hide_recipe_basic (false) +You may choose to hide basic recipe but then make sure to enable the technic direct one +or add your own registration. Reason might be that you want another recipe and don't +want to use an override. + +### replacer.hide_recipe_technic_upgrade (false) +Hides the upgrade recipe.
+Only available if technic is installed. + +### replacer.hide_recipe_technic_direct (true) +Hides the direct recipe of technic replacer that does not require a basic replacer as +ingredient.
+Only available if technic is installed. + +### replacer.dev_mode (false) +Enable developer mode which gives users with **priv** priv to run **/place_all** chat command.
+This is not recommended on live servers as some nodes your mods provide may crash the server +when placed this way. [Read the comments in (test.lua)](test.lua) + +## API commands + +### Deny Groups +You can add groups that you don't want your users to be able to use replacer with.
+For example by default items from **group:seed** are forbidden. +```lua +replacer.deny_groups['seed'] = true +``` + +### Deny Nodes +A selection of nodes are added by default, such as tnt:* and protectors.
+You may want to deny the replacement **and** placement of certain nodes. +```lua +replacer.deny_list['tnt:boom'] = true +``` + +### Limit Node Count +This setting will be clamped to **replacer.max_nodes** if it exceeds it.
+If you pass 0, the node will be added to **deny_list**. Negative numbers are ignored. +```lua +replacer.register_limit('beacon:red', 5) +``` +Above snippet limits technic replacer to only place maximum 5 red beacon boxes per usage. + +### Max Technic Replacer Charge +Bellow example reduces the amount of charge a technic replacer can carry. +```lua +replacer.max_charge = 10000 +``` + +### Charge per Node +Bellow example increases the amount of charge a technic replacer uses to place/replace a node. +```lua +replacer.charge_per_node = 30 +``` + +### Replace Intervention +You can override ```replacer.permit_replace(pos, old_node_def, new_node_def, player_ref, player_name, player_inv, creative_or_give)``` +function to implement server specific rules about where, when, who may place/replace what.
+E.g. check if player has sufficient funds or privs to be using replacer in a certain region.
+[Read more about this function in (replacer/constrain.lua)](replacer/constrain.lua) + +### Enable Special Nodes +Register exceptions that don't rotate/colour using param1 and param2 by calling +```lua +replacer.register_exception(node_name, drop_name, callback) +``` +* **node_name** is the name of the node user clicks on. +* **drop_name** is the name of the item to be taken from inventory. +* **callback** is an optional function that is called after **drop_name** has been placed. +This function can apply other changes or build structures around the placed node. Your +imagination is the limit. (Well computational resources too.)
+The callback signature is: ```f(pos, old_node_def, new_node_def, player_ref)``` +[More details in (replacer/enable.lua)](replacer/enable.lua) + +### Aliases +For players without **give** or **creative** priv, you can add aliases. +```lua +replacer.register_non_creative_alias('vines:jungle_middle', 'vines:jungle_end') +``` +This allows users to click on "vines:jungle_middle" but set the replacer to "vines:jungle_end". +Many examples of these can be found in the "compat" directory. + +### Enable Set Callbacks +Some nodes don't show up in crafting guide and the above methods don't suffice.
+To still enable these, you can register a callback function which is called +after several pre-checks have passed. The first callback to respond with something +other than **false** or **nil** allows the node to be used to set the replacer to.
+The callback signature is ```f(node, player_ref, pointed_thing)``` +```lua +replacer.register_set_enabler(callback) +``` +[More details in (replacer/enable.lua)](replacer/enable.lua) + +## Inspection Tool + +### adding craft methods +Some mods provide precesses that go beyond simple crafting, mixing or cooking. To provide +better support for those there is: +```lua +replacer.register_craft_method(uid, machine_itemstring, func_inspect, func_formspec) +``` +* **uid** is a unique identifier for this method/mod. A good format is "mod_name:method_name". +* **machine_itemstring** is the node name that provides the service. It is used to lookup +the image displayed and the recipe of how to make the machine. +* **func_inspect** is a function that is called by the inspection tool when gathering +information for an item. It's signature is ```f(node_name, param2, recipes)``` and it +can manipulate **recipes** table adding more recipes. +* **func_formspec** is an optional function that is called when displaying the craft info. +The signature is ```f(recipe)``` where **recipe** is the recipe table **func_inspect** added.
+It returns a formspec string to be added to the main formspec.
+[It is defined in (inspect.lua)](inspect.lua)
+[Best examples of usage in (compat/technic.lua)](compat/technic.lua) + From 9339454fabb725bc29474a5c6f8a41143fcf92a0 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 27 Jan 2022 00:06:06 +0100 Subject: [PATCH 254/366] LICENSE added --- LICENSE | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5357f69 --- /dev/null +++ b/LICENSE @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + From 5a48c808c027a519db938efb1c38e3d891673315 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 27 Jan 2022 00:11:22 +0100 Subject: [PATCH 255/366] version bump 3.12 --- CHANGELOG | 3 +++ TODO | 3 +++ init.lua | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 812e0db..b167f37 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +20220126 * SwissalpS improved some compat items and redid translations. + * Documentation updated. + * Added LICENSE file. 20220125 * SwissalpS improved sytem for showing dynamicly added crafting methods which allowed to improve the output of technic and saw methods. * Better drop detection method. diff --git a/TODO b/TODO index 25c354d..7290c3b 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,6 @@ +-- clean up inspect.lua to use same var names as are used by rest of replacer + after that, we can bump version to 4 + -- inspection tool: add button to open unified_inventory's formspec this may no longer be as important and isn't that practical as there are now so many buttons. It would be hard to keep clear which item will be shown. diff --git a/init.lua b/init.lua index 4a31c0d..1b63072 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 3.11 (20220125) +-- Version 3.12 (20220126) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220125 +replacer.version = 20220126 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From 197c4ee9ad39d84371a0f6c50360e97fbbd48fdf Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 27 Jan 2022 00:47:54 +0100 Subject: [PATCH 256/366] cleanup depends and update .luacheckrc --- .luacheckrc | 15 ++++++++++----- compat/moreblocks.lua | 1 + mod.conf | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index 8c058c8..7a20ca6 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -5,17 +5,22 @@ globals = { read_globals = { -- Stdlib - string = {fields = {"split"}}, - table = {fields = {"copy", "getn"}}, + string = { fields = { "split", "match", "find", "lower" } }, + table = { fields = { "copy", "getn", "insert", "shuffle", "sort" }}, -- Minetest "vector", "ItemStack", "dump", "VoxelArea", -- deps - "technic", + "circular_saw", + "colormachine", + "creative", "default", + "dye", "minetest", - "creative", - "circular_saw" + "moreblocks", + "technic", + "unifieddyes" } + diff --git a/compat/moreblocks.lua b/compat/moreblocks.lua index cc97a74..9c59b9a 100644 --- a/compat/moreblocks.lua +++ b/compat/moreblocks.lua @@ -1,5 +1,6 @@ local r = replacer if not r.has_circular_saw then return end +-- ?? TODO do we need to also check for stairsplus and add it to optional_depends ?? local core_registered_nodes = minetest.registered_nodes local shapes_list_sorted = nil diff --git a/mod.conf b/mod.conf index 34e7e70..353583d 100644 --- a/mod.conf +++ b/mod.conf @@ -1,5 +1,5 @@ name = replacer description = Replacement tool for creative building and tool to inspect nodes. depends = default -optional_depends = bakedclay, biofuel, colormachine, dye, mobs_monster, moreblocks, prefab, ropes, technic, unifieddyes, vines +optional_depends = colormachine, dye, moreblocks, technic, unifieddyes From e7ecfd9480d8bf5756620689f0da6ef2a7ca1085 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 27 Jan 2022 01:01:45 +0100 Subject: [PATCH 257/366] add luacheck github workflow --- .github/workflows/luacheck.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/luacheck.yml diff --git a/.github/workflows/luacheck.yml b/.github/workflows/luacheck.yml new file mode 100644 index 0000000..6d20257 --- /dev/null +++ b/.github/workflows/luacheck.yml @@ -0,0 +1,14 @@ +name: luacheck +on: [push, pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: apt + run: sudo apt-get install -y luarocks + - name: luacheck install + run: luarocks install --local luacheck + - name: luacheck run + run: $HOME/.luarocks/bin/luacheck ./ + From 5bd6fea515956c0eea3b25f88057a10d65e0f505 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 27 Jan 2022 02:27:42 +0100 Subject: [PATCH 258/366] luacheck 'fixes' --- .luacheckrc | 7 +++++-- blabla.lua | 6 +++--- chat_commands.lua | 1 - compat/canned_food.lua | 1 + compat/default.lua | 4 ++-- compat/mobs.lua | 1 + compat/moreblocks.lua | 6 +++--- compat/technic.lua | 6 +++--- compat/unifieddyes.lua | 8 ++++---- compat/vines.lua | 1 + compat/wine.lua | 1 + inspect.lua | 6 +++--- replacer/constrain.lua | 1 + replacer/datastructures.lua | 2 +- replacer/formspecs.lua | 2 +- replacer/history.lua | 2 +- replacer/patterns.lua | 14 ++++++++------ replacer/replacer.lua | 30 ++++++++++++++++-------------- test.lua | 22 +++++++++++----------- utils.lua | 1 - 20 files changed, 66 insertions(+), 56 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index 7a20ca6..0b4581b 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -1,6 +1,7 @@ globals = { "replacer", + "minetest", } read_globals = { @@ -18,9 +19,11 @@ read_globals = { "creative", "default", "dye", - "minetest", + "flowers", "moreblocks", + "stairsplus", "technic", - "unifieddyes" + "unified_inventory", + "unifieddyes", } diff --git a/blabla.lua b/blabla.lua index adcb4fc..0b405e6 100644 --- a/blabla.lua +++ b/blabla.lua @@ -1,5 +1,5 @@ if not minetest.translate then - function minetest.translate(textdomain, str, ...) + function minetest.translate(_, str, ...) local arg = { n = select('#', ...), ... } return str:gsub('@(.)', function(matched) local c = string.byte(matched) @@ -11,8 +11,8 @@ if not minetest.translate then end) end - function core.get_translator(textdomain) - return function(str, ...) return core.translate(textdomain or '', str, ...) end + function minetest.get_translator(textdomain) + return function(str, ...) return minetest.translate(textdomain or '', str, ...) end end end -- backward compatibility replacer.S = minetest.get_translator('replacer') diff --git a/chat_commands.lua b/chat_commands.lua index 1def2df..8460a5c 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -1,6 +1,5 @@ local rb = replacer.blabla -local S = replacer.S -- let's hope there isn't a yes that means no in another language :/ -- TODO: better option would be to simply toggle (see postool) diff --git a/compat/canned_food.lua b/compat/canned_food.lua index 7cd09c4..3ea19ec 100644 --- a/compat/canned_food.lua +++ b/compat/canned_food.lua @@ -15,6 +15,7 @@ local function add_recipe(item_name, _, recipes) } end -- add_recipe +--luacheck: no unused args local function add_formspec(recipe) return 'label[0.5,3.5;' .. S('Store near group:wood, light < 12.') .. ']' end diff --git a/compat/default.lua b/compat/default.lua index 8518c98..70cffcc 100644 --- a/compat/default.lua +++ b/compat/default.lua @@ -41,10 +41,10 @@ end -- handle the standard dye color groups if replacer.has_basic_dyes then - for i, color in ipairs(dye.basecolors) do + for _, color in ipairs(dye.basecolors) do local def = minetest.registered_items['dye:' .. color] if def and def.groups then - for k, v in pairs(def.groups) do + for k, _ in pairs(def.groups) do if 'dye' ~= k then replacer.group_placeholder['group:dye,' .. k] = 'dye:' .. color end diff --git a/compat/mobs.lua b/compat/mobs.lua index 208d7b5..3943182 100644 --- a/compat/mobs.lua +++ b/compat/mobs.lua @@ -28,6 +28,7 @@ local function add_recipe(item_name, _, recipes) } end -- add_recipe +--luacheck: no unused args local function add_formspec(recipe) return 'label[0.5,3.5;' .. S('Cut with shears.') .. ']' end diff --git a/compat/moreblocks.lua b/compat/moreblocks.lua index 9c59b9a..94328f8 100644 --- a/compat/moreblocks.lua +++ b/compat/moreblocks.lua @@ -22,7 +22,7 @@ local function is_saw_output(node_name) end -- now iterate looking for match local mod_name, material, found - for i, t in ipairs(shapes_list_sorted) do + for _, t in ipairs(shapes_list_sorted) do mod_name, material = string.match(node_name, '^([^:]+):' .. t[1] .. '(.*)' .. t[2] .. '$') if mod_name and material then @@ -36,8 +36,8 @@ local function is_saw_output(node_name) else -- need to try the long way found = false - for itemstring, t in pairs(circular_saw.known_nodes) do - if t[1] == mod_name and t[2] == material then + for itemstring, t2 in pairs(circular_saw.known_nodes) do + if t2[1] == mod_name and t2[2] == material then mod_name = itemstring:match('^([^:]+)') or '' found = true break diff --git a/compat/technic.lua b/compat/technic.lua index 748971a..63e57d7 100644 --- a/compat/technic.lua +++ b/compat/technic.lua @@ -36,7 +36,7 @@ local S = replacer.S local function add_recipe_alloy(item_name, _, recipes) --pd(technic.recipes['alloy']) - for input_name, def in pairs(technic.recipes['alloy']['recipes']) do + for _, def in pairs(technic.recipes['alloy']['recipes']) do if def.output and 'string' == type(def.output) and def.output:find('^' .. item_name .. ' ?[0-9]*$') and def.input and 'table' == type(def.input) @@ -175,7 +175,7 @@ replacer.register_craft_method( local function add_recipe_grind(item_name, _, recipes) --pd(technic.recipes['grinding']) local inputs, input_type - for input_name, def in pairs(technic.recipes['grinding']['recipes']) do + for _, def in pairs(technic.recipes['grinding']['recipes']) do if 'string' == type(def.output) and def.output:find('^' .. item_name .. ' ?[0-9]*$') then @@ -207,7 +207,7 @@ replacer.register_craft_method('technic:grind', 'technic:lv_grinder', add_recipe local function add_recipe_separate(item_name, _, recipes) --pd(technic.recipes['separating']) local outputs, main_output, inputs - for input_name, def in pairs(technic.recipes['separating']['recipes']) do + for _, def in pairs(technic.recipes['separating']['recipes']) do if def.output and 'table' == type(def.output) and def.input and 'table' == type(def.input) then diff --git a/compat/unifieddyes.lua b/compat/unifieddyes.lua index 10760fe..3c5dbd7 100644 --- a/compat/unifieddyes.lua +++ b/compat/unifieddyes.lua @@ -3,7 +3,7 @@ local ud = replacer.unifieddyes if not replacer.has_unifieddyes_mod then -- replacer uses this - function ud.colour_name(param2, node_def) return '' end + function ud.colour_name() return '' end return end @@ -18,10 +18,10 @@ local function add_recipe(node_name, param2, recipes) local node_def = minetest.registered_items[node_name] if ud.is_airbrushed(node_def) then -- find the correct recipe and append it to bottom of list - local first, last + local first local needle = 'u0002' .. tostring(param2) - for i, t in ipairs(recipes) do - first, last = t.output:find(needle) + for _, t in ipairs(recipes) do + first = t.output:find(needle) if nil ~= first then t.method = S('painting') t.type = 'unifieddyes:airbrush' diff --git a/compat/vines.lua b/compat/vines.lua index 864abd3..ed39ce9 100644 --- a/compat/vines.lua +++ b/compat/vines.lua @@ -36,6 +36,7 @@ local function add_recipe(item_name, _, recipes) } end -- add_recipe +--luacheck: no unused args local function add_formspec(recipe) return 'label[0.5,3.5;' .. S('Cut with shears.') .. ']' end diff --git a/compat/wine.lua b/compat/wine.lua index bc96a46..31413dc 100644 --- a/compat/wine.lua +++ b/compat/wine.lua @@ -36,6 +36,7 @@ local function add_recipe(item_name, _, recipes) } end -- add_recipe +--luacheck: no unused args local function add_formspec(recipe) return 'label[0.5,3.5;' .. S('Ferment in barrel.') .. ']' end diff --git a/inspect.lua b/inspect.lua index 9aed0aa..b10622e 100644 --- a/inspect.lua +++ b/inspect.lua @@ -79,7 +79,7 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) local name = user:get_player_name() if 'object' == pointed_thing.type then local inventory_text = nil - local text = '' + local text local ref = pointed_thing.ref if not ref then text = rbi.broken_object @@ -94,6 +94,7 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) sdata = minetest.deserialize(sdata) or {} if sdata.itemstring then text = text .. ' [' .. sdata.itemstring .. ']' + local show_recipe = false if show_recipe then -- the fields part is used here to provide -- additional information about the entity @@ -127,7 +128,7 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) if 'table' == type(sdata.inv) then local item_count = 0 local type_count = 0 - for k, v in pairs(sdata.inv) do + for _, v in pairs(sdata.inv) do type_count = type_count + 1 item_count = item_count + v end @@ -370,7 +371,6 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) .. (((i - 1) % 3) + 1) .. ',' .. tostring(floor(((i - 1) / 3) + 2)) .. ';1.0,1.0;' .. r.image_button_link(n) .. ']' - i = i + 1 end -- output item on the right formspec = formspec diff --git a/replacer/constrain.lua b/replacer/constrain.lua index c3d94bc..7800eee 100644 --- a/replacer/constrain.lua +++ b/replacer/constrain.lua @@ -58,6 +58,7 @@ end -- This is called before replacing the node/air and expects -- a boolean return and in the case of fail, an optional message -- that will be sent to player +--luacheck: no unused args function replacer.permit_replace(pos, old_node_def, new_node_def, player_ref, player_name, player_inv, creative_or_give) diff --git a/replacer/datastructures.lua b/replacer/datastructures.lua index ded6b38..2d2d69c 100644 --- a/replacer/datastructures.lua +++ b/replacer/datastructures.lua @@ -32,7 +32,7 @@ stack_mt = { return self.n end, clone = function(self, copy_element) - local stack + local stack, n if copy_element then stack = { n = self.n, true } for i = 1, self.n do diff --git a/replacer/formspecs.lua b/replacer/formspecs.lua index 50c3ca9..30d61bc 100644 --- a/replacer/formspecs.lua +++ b/replacer/formspecs.lua @@ -72,7 +72,7 @@ function replacer.get_form_modes_4(player, mode) formspec = formspec .. 'label[0.33,3.22;' .. mfe(rb.choose_history) .. ']dropdown[0.38,3.55;7.5,0.6;history;' local db = r.history.get_player_table(player) - for i, data in ipairs(db) do + for _, data in ipairs(db) do if r.history_include_mode then formspec = formspec .. data.mode.major .. '.' .. data.mode.minor .. ' ' end diff --git a/replacer/history.lua b/replacer/history.lua index b8cc09a..9335fa3 100644 --- a/replacer/history.lua +++ b/replacer/history.lua @@ -52,7 +52,7 @@ function replacer.history.init_player(player) local db_strings = player:get_meta():get_string('replacer_his'):split('||', false, r.history_max) or {} local db = {} - local data, entry, mode_raw, colour_name, node_def + local data, entry, mode, mode_raw, colour_name, node_def for i, entry_raw in ipairs(db_strings) do data = entry_raw:split(' ', false, 4) mode_raw = data[4] or '1.1' diff --git a/replacer/patterns.lua b/replacer/patterns.lua index 24c1c81..d60d82c 100644 --- a/replacer/patterns.lua +++ b/replacer/patterns.lua @@ -80,6 +80,7 @@ replacer.patterns.offsets_touch = { -- 3x3x3 hollow cube replacer.patterns.offsets_hollowcube = {} +do local p for x = -1, 1 do for y = -1, 1 do @@ -91,6 +92,7 @@ for x = -1, 1 do end end end +end -- To get the crust, first nodes near it need to be collected function replacer.patterns.crust_above_position(pos, data) @@ -132,8 +134,8 @@ function replacer.patterns.reduce_crust_ps(data) local p, p2 for i = 1, data.num do p = data.ps[i] - for i = 1, 6 do - p2 = rp.offsets_touch[i] + for i2 = 1, 6 do + p2 = rp.offsets_touch[i2] if data.aboves[poshash(vector_add(p, p2))] then n = n + 1 newps[n] = p @@ -153,8 +155,8 @@ function replacer.patterns.reduce_crust_above_ps(data) for i = 1, data.num do p = data.ps[i] if rp.replaceable(p, 'air', data.pname) then - for i = 1, 6 do - p2 = rp.offsets_touch[i] + for i2 = 1, 6 do + p2 = rp.offsets_touch[i2] if rp.replaceable(vector_add(p, p2), data.name, data.pname) then n = n + 1 newps[n] = p @@ -257,7 +259,7 @@ function replacer.patterns.search_positions(params) visiteds = {} founds = {} n_founds = 0 - local function go(p) + local function go2(p) local vi = poshash(p) if visiteds[vi] then return false @@ -274,7 +276,7 @@ function replacer.patterns.search_positions(params) visiteds[vi] = true return true end - search_dfs(go, startpos, vector_add, moves) + search_dfs(go2, startpos, vector_add, moves) return founds, n_founds, visiteds end -- search_positions diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 81fb417..6cb79e5 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -13,7 +13,6 @@ local max, min, floor = math.max, math.min, math.floor local core_check_player_privs = minetest.check_player_privs local core_get_node = minetest.get_node local core_get_node_or_nil = minetest.get_node_or_nil -local core_get_node_drops = minetest.get_node_drops local core_get_item_group = minetest.get_item_group local core_registered_items = minetest.registered_items local core_registered_nodes = minetest.registered_nodes @@ -65,6 +64,7 @@ function replacer.set_data(stack, node, mode) node = 'table' == type(node) and node or {} -- allow passing nil mode -> when ignoring mode in history if 'table' ~= type(mode) then + local _ _, mode = r.get_data(stack) end local tool_itemstring = stack:get_name() @@ -121,8 +121,8 @@ if r.has_technic_mod then return meta.charge end - function replacer.set_charge(itemstack, charge, max) - technic.set_RE_wear(itemstack, charge, max) + function replacer.set_charge(itemstack, charge, maximum) + technic.set_RE_wear(itemstack, charge, maximum) local meta = itemstack:get_meta() local data = deserialize(meta:get_string('')) if (not data) or (not data.charge) then @@ -197,7 +197,8 @@ function replacer.replace_single_node(pos, node_old, node_new, player, -- place the node similar to how a player does it -- (other than the pointed_thing) - local new_item, succ = node_new_def.on_place(ItemStack(node_new.name), player, + local new_item + new_item, succ = node_new_def.on_place(ItemStack(node_new.name), player, { type = 'node', under = vector_new(pos), above = vector_new(pos) }) -- replacing with trellis set, succ is returned but new_item is nil -- possible that other nodes react the same way. @@ -234,8 +235,8 @@ function replacer.replace_single_node(pos, node_old, node_new, player, if 'function' == type(r.exception_callbacks[node_new.name]) then succ, error = r.exception_callbacks[node_new.name]( pos, node_old, node_new, player) - if (not succ) and error and ('' ~= sMsg) then - r.inform(name, rb.callback_error:format(sMsg)) + if (not succ) and error and ('' ~= error) then + r.inform(name, rb.callback_error:format(error)) end end @@ -291,13 +292,13 @@ function replacer.on_use(itemstack, player, pt, right_clicked) end -- utility function to adjust new node to mode.minor -- returns true if adjustments make them equal - local function adjust_new_to_minor(minor, node_old, node_new) + local function adjust_new_to_minor() -- minor mode overrides to node_new - if 2 == minor then + if 2 == mode.minor then -- node only node_new.param1 = node_old.param1 node_new.param2 = node_old.param2 - elseif 3 == minor then + elseif 3 == mode.minor then -- rotation only node_new.name = node_old.name end @@ -309,7 +310,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) return true end end -- adjust_new_to_minor - if adjust_new_to_minor(mode.minor, node_old, node_new) then + if adjust_new_to_minor() then r.inform(name, rb.nothing_to_replace) return end @@ -469,7 +470,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) -- Take the position nearest to the start position pos = found_positions:take() node_old = core_get_node(pos) - adjust_new_to_minor(minor, node_old, node_new) + adjust_new_to_minor() succ, error = r.replace_single_node(pos, node_old, node_new, player, name, inv, has_creative_or_give) if not succ then @@ -511,16 +512,17 @@ function replacer.on_place(itemstack, player, pt) local name = player:get_player_name() local creative_enabled = has_creative(name) local has_give = core_check_player_privs(name, 'give') - local has_creative_or_give = creative_enabled or has_give + --local has_creative_or_give = creative_enabled or has_give local is_technic = itemstack:get_name() == r.tool_name_technic local modes_are_available = is_technic or creative_enabled + local _, node, mode -- is special-key held? (aka fast-key) -> change mode if keys.aux1 then -- don't want anybody to think that special+rc = place if not modes_are_available then return end -- fetch current mode - local node, mode = r.get_data(itemstack) + node, mode = r.get_data(itemstack) if keys.sneak then -- increment and roll-over minor mode mode.minor = mode.minor % 3 + 1 @@ -575,7 +577,7 @@ function replacer.on_place(itemstack, player, pt) return end - local _, mode = r.get_data(itemstack) + _, mode = r.get_data(itemstack) if not modes_are_available then mode = { major = 1, minor = 1 } end diff --git a/test.lua b/test.lua index e890a63..7685d2f 100644 --- a/test.lua +++ b/test.lua @@ -3,8 +3,7 @@ replacer.dev_mode = minetest.settings:get_bool('replacer.dev_mode') or false if not replacer.dev_mode then return end -function pd(m) print(dump(m)) end -function i(m) replacer.inform('singleplayer', dump(m)) pd(m) end +local function pd(m) print(dump(m)) end replacer.test = {} local r = replacer @@ -63,20 +62,20 @@ function replacer.test.chatcommand_place_all(player_name, param) return false, 'There is an active task in progress, try again later' end param = param or '' - local dry_run, skip_corium + local dry_run local params = param:split(' ') local patterns = {} rt.no_support = false rt.move_player = false - for _, param in ipairs(params) do - if 'dry-run' == param then + for _, param2 in ipairs(params) do + if 'dry-run' == param2 then dry_run = true - elseif 'move_player' == param then + elseif 'move_player' == param2 then rt.move_player = true - elseif 'no_support_node' == param then + elseif 'no_support_node' == param2 then rt.no_support = true else - table.insert(patterns, param) + table.insert(patterns, param2) end end if 0 == #patterns then table.insert(patterns, '.*') end @@ -84,8 +83,8 @@ function replacer.test.chatcommand_place_all(player_name, param) rt.pos = rt.player:get_pos()--vector.add(player:get_pos(), vector.new(1, 0, 1))-- rt.selected = {} rt.count = 0 - local function has_match(name, patterns) - for _, pattern in ipairs(patterns) do + local function has_match(name, patterns_to_check) + for _, pattern in ipairs(patterns_to_check) do if name:find(pattern) then return true end end return false @@ -133,7 +132,7 @@ function replacer.test.step() rt.player:set_look_vertical(math.rad(45)) end -- move_player - for i = 1, rt.nodes_per_step do + for _ = 1, rt.nodes_per_step do name = rt.selected[rt.i] node = minetest.registered_nodes[name] pos_ = vector.add(rt.pos, vector.new(rt.x, 0, rt.z)) @@ -219,6 +218,7 @@ minetest.register_chatcommand('place_all', { local events = {} -- list of { minp, maxp, time } -- update last mapgen event time +--luacheck: no unused args minetest.register_on_generated(function(minp, maxp, seed) table.insert(events, { minp = minp, diff --git a/utils.lua b/utils.lua index ae4fae8..54ea26d 100644 --- a/utils.lua +++ b/utils.lua @@ -61,7 +61,6 @@ function replacer.possible_node_drops(node_name, return_names_only) end end end - checks = nil return droplist end -- possible_node_drops From ac47166d1c4f71cd25496dabd9cba5c19cb13313 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 27 Jan 2022 04:52:29 +0100 Subject: [PATCH 259/366] Update .luacheckrc --- .luacheckrc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index 0b4581b..6991c3d 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -1,13 +1,13 @@ globals = { "replacer", - "minetest", + minetest = { fields = { "translate", "get_translator" } }, } read_globals = { -- Stdlib string = { fields = { "split", "match", "find", "lower" } }, - table = { fields = { "copy", "getn", "insert", "shuffle", "sort" }}, + table = { fields = { "copy", "getn", "insert", "shuffle", "sort" } }, -- Minetest "vector", "ItemStack", From db172ec5d9e72b50340332fab07c282a53293a82 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 27 Jan 2022 04:55:01 +0100 Subject: [PATCH 260/366] Update .luacheckrc --- .luacheckrc | 1 + 1 file changed, 1 insertion(+) diff --git a/.luacheckrc b/.luacheckrc index 6991c3d..c7f3553 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -10,6 +10,7 @@ read_globals = { table = { fields = { "copy", "getn", "insert", "shuffle", "sort" } }, -- Minetest + "minetest", "vector", "ItemStack", "dump", "VoxelArea", From ed6eb095f9face6a7d46f7216627d4eb8541518a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 28 Jan 2022 15:33:47 +0100 Subject: [PATCH 261/366] debug lines --- inspect.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/inspect.lua b/inspect.lua index b10622e..e29ad69 100644 --- a/inspect.lua +++ b/inspect.lua @@ -15,7 +15,7 @@ local floor = math.floor local max, min = math.max, math.min local chat = minetest.chat_send_player local mfe = minetest.formspec_escape - +local function pd(m) print(dump(m)) end -- use r.register_craft_method() to populate replacer.recipe_adders = {} @@ -175,6 +175,7 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) -- EXPERIMENTAL: attempt to open unified_inventory's crafting guide if ui then local keys = user:get_player_control() +--pd(keys) -- while testing let's use zoom until we either drop the idea -- or get it to work if keys.zoom then --aux1 then ---and keys.sneak then @@ -186,6 +187,8 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) return end end +pd(node) +pd(minetest.registered_nodes[node.name].mod_origin) local protected_info = '' if minetest.is_protected(pos, name) then protected_info = rbi.is_protected @@ -217,6 +220,7 @@ function replacer.image_button_link(stack_string) -- TODO: show information about other groups not handled above local stack = ItemStack(stack_string) local new_node_name = stack:get_name() +pd(stack_string .. ';' .. new_node_name .. ';' .. group) return stack_string .. ';' .. new_node_name .. ';' .. group end -- image_button_link @@ -255,7 +259,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) if not res then res = {} end ---print(dump(res)) +--pd(res) -- TODO: filter out invalid recipes with no items -- such as "group:flower,color_dark_grey" -- also 'normal' recipe.type uranium*_dust recipes @@ -384,7 +388,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) -- reverse order; default recipes (and thus the most intresting ones) -- are usually the oldest local recipe = res[#res + 1 - recipe_nr] ---print(dump(recipe)) +--pd(recipe.type) if 'normal' == recipe.type and recipe.items then local width = recipe.width if not width or 0 == width then From 2876066ac3c3c5b8624f0c358cf4c1a72a474cf4 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 28 Jan 2022 20:22:46 +0100 Subject: [PATCH 262/366] adding print_dump() --- inspect.lua | 2 +- test.lua | 3 +-- utils.lua | 8 ++++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/inspect.lua b/inspect.lua index e29ad69..7bf5ed9 100644 --- a/inspect.lua +++ b/inspect.lua @@ -15,7 +15,7 @@ local floor = math.floor local max, min = math.max, math.min local chat = minetest.chat_send_player local mfe = minetest.formspec_escape -local function pd(m) print(dump(m)) end +local pd = r.print_dump -- use r.register_craft_method() to populate replacer.recipe_adders = {} diff --git a/test.lua b/test.lua index 7685d2f..60a087f 100644 --- a/test.lua +++ b/test.lua @@ -3,11 +3,10 @@ replacer.dev_mode = minetest.settings:get_bool('replacer.dev_mode') or false if not replacer.dev_mode then return end -local function pd(m) print(dump(m)) end - replacer.test = {} local r = replacer local rt = replacer.test +local pd = r.print_dump rt.spacing = 2 rt.player = nil rt.facing = vector.new(0, 0, 0) diff --git a/utils.lua b/utils.lua index 54ea26d..3cc4f9f 100644 --- a/utils.lua +++ b/utils.lua @@ -65,6 +65,14 @@ function replacer.possible_node_drops(node_name, return_names_only) end -- possible_node_drops +function replacer.print_dump(...) + if not replacer.dev_mode then return end + for _, m in ipairs(...) do + print(dump(m)) + end +end -- print_dump + + function replacer.inform(name, message) if (not message) or ('' == message) then return end From 5583ac8e171673238776751e5292183b7eb73567 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 28 Jan 2022 20:25:25 +0100 Subject: [PATCH 263/366] reorder methods (no code change) --- utils.lua | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/utils.lua b/utils.lua index 3cc4f9f..d730700 100644 --- a/utils.lua +++ b/utils.lua @@ -15,6 +15,31 @@ if r.has_technic_mod then end +function replacer.inform(name, message) + if (not message) or ('' == message) then return end + + log('info', rb.log_messages:format(name, message)) + local player = get_player_by_name(name) + if not player then return end + + local meta = player:get_meta() if not meta then return end + + if 0 < meta:get_int('replacer_mute') then return end + + chat_send_player(name, message) +end -- inform + + +function replacer.nice_pos_string(pos) + local no_info = '' + if 'table' ~= type(pos) then return no_info end + if not (pos.x and pos.y and pos.z) then return no_info end + + pos = { x = floor(pos.x + .5), y = floor(pos.y + .5), z = floor(pos.z + .5) } + return pos_to_string(pos) +end -- nice_pos_string + + function replacer.play_sound(player_name, fail) local player = get_player_by_name(player_name) if not player then return end @@ -73,31 +98,6 @@ function replacer.print_dump(...) end -- print_dump -function replacer.inform(name, message) - if (not message) or ('' == message) then return end - - log('info', rb.log_messages:format(name, message)) - local player = get_player_by_name(name) - if not player then return end - - local meta = player:get_meta() if not meta then return end - - if 0 < meta:get_int('replacer_mute') then return end - - chat_send_player(name, message) -end -- inform - - -function replacer.nice_pos_string(pos) - local no_info = '' - if 'table' ~= type(pos) then return no_info end - if not (pos.x and pos.y and pos.z) then return no_info end - - pos = { x = floor(pos.x + .5), y = floor(pos.y + .5), z = floor(pos.z + .5) } - return pos_to_string(pos) -end -- nice_pos_string - - -- from: http://lua-users.org/wiki/StringRecipes function replacer.titleCase(str) local function titleCaseHelper(first, rest) From be5137fe53a80ca7b790e984b642884385a04d3b Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 28 Jan 2022 22:00:31 +0100 Subject: [PATCH 264/366] proper var names in inspect code --- blabla.lua | 6 +-- inspect.lua | 106 ++++++++++++++++++++++++++-------------------------- 2 files changed, 57 insertions(+), 55 deletions(-) diff --git a/blabla.lua b/blabla.lua index 0b405e6..f74419b 100644 --- a/blabla.lua +++ b/blabla.lua @@ -82,9 +82,9 @@ rbi.owned_locked = S('owned and locked') rbi.this_is_object = S('This is an object') rbi.is_protected = S('WARNING: You can\'t dig this node. It is protected.') rbi.you_can_dig = S('INFO: You can dig this node, others can\'t.') -rbi.no_desc = S('~ no description provided ~') -rbi.no_node_desc = S('~ no node description provided ~') -rbi.no_item_desc = S('~ no item description provided ~') +rbi.no_description = S('~ no description provided ~') +rbi.no_node_description = S('~ no node description provided ~') +rbi.no_item_description = S('~ no item description provided ~') rbi.name = S('Name:') rbi.exit = S('Exit') rbi.this_is = S('This is:') diff --git a/inspect.lua b/inspect.lua index 7bf5ed9..d6c5023 100644 --- a/inspect.lua +++ b/inspect.lua @@ -61,32 +61,32 @@ minetest.register_tool('replacer:inspect', { wield_scale = { x = 1, y = 1, z = 1 }, liquids_pointable = true, -- it is ok to request information about liquids - on_use = function(itemstack, user, pointed_thing) - return replacer.inspect(itemstack, user, pointed_thing) + on_use = function(itemstack, player, pointed_thing) + return replacer.inspect(itemstack, player, pointed_thing) end, - on_place = function(itemstack, placer, pointed_thing) - return replacer.inspect(itemstack, placer, pointed_thing, true) + on_place = function(itemstack, player, pointed_thing) + return replacer.inspect(itemstack, player, pointed_thing, true) end, }) -function replacer.inspect(_, user, pointed_thing, right_clicked) - if nil == user or nil == pointed_thing then +function replacer.inspect(_, player, pointed_thing, right_clicked) + if nil == player or nil == pointed_thing then return nil end - local name = user:get_player_name() + local player_name = player:get_player_name() if 'object' == pointed_thing.type then local inventory_text = nil local text - local ref = pointed_thing.ref - if not ref then + local object_ref = pointed_thing.ref + if not object_ref then text = rbi.broken_object - elseif ref:is_player() then - text = S('This is your fellow player "@1"', ref:get_player_name()) + elseif object_ref:is_player() then + text = S('This is your fellow player "@1"', object_ref:get_player_name()) else - local luaob = ref:get_luaentity() + local luaob = object_ref:get_luaentity() if luaob and luaob.get_staticdata then text = S('This is an entity "@1"', luaob.name) local sdata = luaob:get_staticdata() @@ -99,7 +99,7 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) -- the fields part is used here to provide -- additional information about the entity r.inspect_show_crafting( - name, + player_name, sdata.itemstring, { luaob = luaob }) end @@ -152,45 +152,44 @@ function replacer.inspect(_, user, pointed_thing, right_clicked) end end - if ref then - text = text .. ' ' .. S('at @1', nice_pos_string(ref:getpos())) + if object_ref then + text = text .. ' ' .. S('at @1', nice_pos_string(object_ref:getpos())) end if inventory_text then text = text .. inventory_text end - chat(name, text) + chat(player_name, text) return nil elseif 'node' ~= pointed_thing.type then - chat(name, S('Sorry, this is an unkown something of type "@1". ' + chat(player_name, S('Sorry, this is an unkown something of type "@1". ' .. 'No information available.', pointed_thing.type)) return nil end local pos = minetest.get_pointed_thing_position(pointed_thing, right_clicked) local node = minetest.get_node_or_nil(pos) - if not node then - chat(name, rb.wait_for_load) + chat(player_name, rb.wait_for_load) return nil end -- EXPERIMENTAL: attempt to open unified_inventory's crafting guide if ui then - local keys = user:get_player_control() + local keys = player:get_player_control() --pd(keys) -- while testing let's use zoom until we either drop the idea -- or get it to work if keys.zoom then --aux1 then ---and keys.sneak then - ui.current_item[name] = node.name - ui.current_craft_direction[name] = 'recipe'-- keys.x and 'usage' or 'recipe' - ui.current_searchbox[name] = node.name - ui.apply_filter(user, node.name, 'recipe')--'usage' --nochange') - minetest.show_formspec(name, '', ui.get_formspec(user, 'craftguide')) + ui.current_item[player_name] = node.name + ui.current_craft_direction[player_name] = 'recipe'-- keys.x and 'usage' or 'recipe' + ui.current_searchbox[player_name] = node.name + ui.apply_filter(player, node.name, 'recipe')--'usage' --nochange') + minetest.show_formspec(player_name, '', ui.get_formspec(player, 'craftguide')) return end end pd(node) pd(minetest.registered_nodes[node.name].mod_origin) local protected_info = '' - if minetest.is_protected(pos, name) then + if minetest.is_protected(pos, player_name) then protected_info = rbi.is_protected elseif minetest.is_protected(pos, '_THIS_NAME_DOES_NOT_EXIST_') then protected_info = rbi.you_can_dig @@ -200,9 +199,12 @@ pd(minetest.registered_nodes[node.name].mod_origin) local light = minetest.get_node_light(pos, nil) -- the fields part is used here to provide additional -- information about the node - r.inspect_show_crafting(name, node.name, { - pos = pos, param2 = node.param2, light = light, - protected_info = protected_info }) + r.inspect_show_crafting(player_name, node.name, { + pos = pos, + param2 = node.param2, + light = light, + protected_info = protected_info + }) return nil -- no item shall be removed from inventory end -- replacer.inspect @@ -255,18 +257,18 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) end -- fetch recipes from core - local res = minetest.get_all_craft_recipes(node_name) - if not res then - res = {} + local recipes = minetest.get_all_craft_recipes(node_name) + if not recipes then + recipes = {} end ---pd(res) +--pd(recipes) -- TODO: filter out invalid recipes with no items -- such as "group:flower,color_dark_grey" -- also 'normal' recipe.type uranium*_dust recipes -- add special recipes for nodes created by machines for _, adder in pairs(r.recipe_adders) do - adder.add_recipe(node_name, fields.param2, res) + adder.add_recipe(node_name, fields.param2, recipes) end -- offer all alternate crafting recipes through prev/next buttons @@ -276,34 +278,34 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) recipe_nr = recipe_nr + 1 end -- wrap around - if #res < recipe_nr then + if #recipes < recipe_nr then recipe_nr = 1 elseif 1 > recipe_nr then - recipe_nr = #res + recipe_nr = #recipes end -- fetch description -- when clicking unknown nodes - local desc = ' ' .. rbi.no_desc .. ' ' + local description = ' ' .. rbi.no_description .. ' ' if minetest.registered_nodes[node_name] then if minetest.registered_nodes[node_name].description and '' ~= minetest.registered_nodes[node_name].description then - desc = minetest.registered_nodes[node_name].description + description = minetest.registered_nodes[node_name].description elseif minetest.registered_nodes[node_name].name then - desc = minetest.registered_nodes[node_name].name + description = minetest.registered_nodes[node_name].name else - desc = ' ' .. rbi.no_node_desc .. ' ' + description = ' ' .. rbi.no_node_description .. ' ' end elseif minetest.registered_items[node_name] then if minetest.registered_items[node_name].description and '' ~= minetest.registered_items[node_name].description then - desc = minetest.registered_items[node_name].description + description = minetest.registered_items[node_name].description elseif minetest.registered_items[node_name].name then - desc = minetest.registered_items[node_name].name + description = minetest.registered_items[node_name].name else - desc = ' ' .. rbi.no_item_desc .. ' ' + description = ' ' .. rbi.no_item_description .. ' ' end end @@ -317,7 +319,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) .. 'tooltip[quit;'.. mfe(rbi.exit) .. ']' -- prev. and next buttons - if 1 < #res then + if 1 < #recipes then formspec = formspec .. 'button[4.1,5;1,0.75;prev_recipe;<-]' .. 'tooltip[prev_recipe;'.. mfe(rbi.prev) .. ']' @@ -327,8 +329,8 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) formspec = formspec -- description at bottom - .. 'label[0,5.7;' .. mfe(rbi.this_is) .. ' ' .. mfe(desc) .. ']' - .. 'tooltip[-1,5.7;7,2;' .. mfe(rbi.this_is) .. ' ' .. mfe(desc) .. ']' + .. 'label[0,5.7;' .. mfe(rbi.this_is) .. ' ' .. mfe(description) .. ']' + .. 'tooltip[-1,5.7;7,2;' .. mfe(rbi.this_is) .. ' ' .. mfe(description) .. ']' -- invisible field for passing on information .. 'field[20,20;0.1,0.1;node_name;node_name;' .. node_name .. ']' -- another invisible field @@ -358,7 +360,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) end -- if no recipes, collect drops else show current recipe - if 1 > #res then + if 1 > #recipes then formspec = formspec .. 'label[3,1;' .. mfe(rbi.no_recipes) .. ']' -- always returns a table local drops = r.possible_node_drops(node_name) @@ -370,24 +372,24 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) else formspec = formspec .. mfe(rbi.may_drop_on_dig) .. ']' end - for i, n in ipairs(drops) do + for i, drop_name in ipairs(drops) do formspec = formspec .. 'item_image_button[' .. (((i - 1) % 3) + 1) .. ',' .. tostring(floor(((i - 1) / 3) + 2)) - .. ';1.0,1.0;' .. r.image_button_link(n) .. ']' + .. ';1.0,1.0;' .. r.image_button_link(drop_name) .. ']' end -- output item on the right formspec = formspec .. 'item_image_button[5,2;1.0,1.0;' .. node_name .. ';normal;]' else - if 1 < #res then + if 1 < #recipes then formspec = formspec .. 'label[1,5;' - .. mfe(S('Alternate @1/@2', tostring(recipe_nr), tostring(#res))) .. ']' + .. mfe(S('Alternate @1/@2', tostring(recipe_nr), tostring(#recipes))) .. ']' end -- reverse order; default recipes (and thus the most intresting ones) -- are usually the oldest - local recipe = res[#res + 1 - recipe_nr] + local recipe = recipes[#recipes + 1 - recipe_nr] --pd(recipe.type) if 'normal' == recipe.type and recipe.items then local width = recipe.width From 7a44dbdfac7d56e519640bfcbd8e399d036a80ad Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 28 Jan 2022 23:43:18 +0100 Subject: [PATCH 265/366] fix print_dump --- utils.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils.lua b/utils.lua index d730700..030b2bd 100644 --- a/utils.lua +++ b/utils.lua @@ -92,7 +92,8 @@ end -- possible_node_drops function replacer.print_dump(...) if not replacer.dev_mode then return end - for _, m in ipairs(...) do + + for _, m in ipairs({ ... }) do print(dump(m)) end end -- print_dump From f5797f5169345f374dc24737ea795dd27082b2df Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 28 Jan 2022 23:44:54 +0100 Subject: [PATCH 266/366] mute some often used debug lines --- inspect.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/inspect.lua b/inspect.lua index d6c5023..ec0f2b4 100644 --- a/inspect.lua +++ b/inspect.lua @@ -174,7 +174,6 @@ function replacer.inspect(_, player, pointed_thing, right_clicked) -- EXPERIMENTAL: attempt to open unified_inventory's crafting guide if ui then local keys = player:get_player_control() ---pd(keys) -- while testing let's use zoom until we either drop the idea -- or get it to work if keys.zoom then --aux1 then ---and keys.sneak then @@ -186,8 +185,8 @@ function replacer.inspect(_, player, pointed_thing, right_clicked) return end end -pd(node) -pd(minetest.registered_nodes[node.name].mod_origin) + +--pd(node, minetest.registered_nodes[node.name].mod_origin) local protected_info = '' if minetest.is_protected(pos, player_name) then protected_info = rbi.is_protected @@ -222,7 +221,7 @@ function replacer.image_button_link(stack_string) -- TODO: show information about other groups not handled above local stack = ItemStack(stack_string) local new_node_name = stack:get_name() -pd(stack_string .. ';' .. new_node_name .. ';' .. group) +--pd(stack_string .. ';' .. new_node_name .. ';' .. group) return stack_string .. ';' .. new_node_name .. ';' .. group end -- image_button_link @@ -390,7 +389,6 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) -- reverse order; default recipes (and thus the most intresting ones) -- are usually the oldest local recipe = recipes[#recipes + 1 - recipe_nr] ---pd(recipe.type) if 'normal' == recipe.type and recipe.items then local width = recipe.width if not width or 0 == width then @@ -447,6 +445,8 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) formspec = formspec .. (handler.formspec and handler.formspec(recipe) or '') else +--pd('unhandled recipe encountered', recipe) +--r.play_sound(player_name, true) formspec = formspec .. 'label[3,1;' .. mfe(rbi.unkown_recipe) .. ']' end -- output item on the right From d845356edf824f8a6d9a6a8b43de7053e8dc4881 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 28 Jan 2022 23:59:17 +0100 Subject: [PATCH 267/366] version bump 4.0 --- CHANGELOG | 3 +++ TODO | 3 --- init.lua | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b167f37..87f9079 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +20220127 * SwissalpS cleaned up var names in inspect.lua + * Added .luacheckrc and print_dump() + * Bumped version to 4.0 20220126 * SwissalpS improved some compat items and redid translations. * Documentation updated. * Added LICENSE file. diff --git a/TODO b/TODO index 7290c3b..25c354d 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,3 @@ --- clean up inspect.lua to use same var names as are used by rest of replacer - after that, we can bump version to 4 - -- inspection tool: add button to open unified_inventory's formspec this may no longer be as important and isn't that practical as there are now so many buttons. It would be hard to keep clear which item will be shown. diff --git a/init.lua b/init.lua index 1b63072..de9062c 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 3.12 (20220126) +-- Version 4.0 (20220127) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220126 +replacer.version = 20220127 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From dcd9a16b44086d62c997ee99efad616def56d624 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 1 Feb 2022 22:33:19 +0100 Subject: [PATCH 268/366] locale improvements --- locale/replacer.de.tr | 4 ++-- locale/replacer.es.tr | 4 ++-- locale/replacer.fi.tr | 4 ++-- locale/replacer.fr.tr | 4 ++-- locale/replacer.it.tr | 4 ++-- locale/replacer.pt.tr | 4 ++-- locale/replacer.ru.tr | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index 7c35391..7f560cf 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -42,8 +42,8 @@ INFO: You can dig this node, others can't.=INFO: Du kannst diese Node graben, an Name:=Name: Exit=Schliessen This is:=Dies ist: -prev=zurück -next=weiter +prev=vorheriges Rezept +next=nächstes Rezept No recipes.=Keine Rezepte. Drops on dig:=Lässt fallen beim Graben: nothing=nichts diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index f207514..982f963 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -42,8 +42,8 @@ INFO: You can dig this node, others can't.=INFO: Puedes excavar este nodo, pero Name:=Nombre: Exit=Salir This is:=Esto es: -prev=ant. -next=sig. +prev=receta anterior +next=siguiente receta No recipes.=Sin recetas. Drops on dig:=Cae en excavación: nothing=nada diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index dd29e06..dde7a13 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -42,8 +42,8 @@ INFO: You can dig this node, others can't.=INFO: Voit kaivaa tämän solmun, mut Name:=Nimi: Exit=Poistu This is:=Tämä on: -prev=edellinen -next=seuraava +prev=edellinen resepti +next=seuraava resepti No recipes.=Ei reseptejä. Drops on dig:=Pudotukset kaivamaan: nothing=ei mitään diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index 3357e74..2a943c1 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -42,8 +42,8 @@ INFO: You can dig this node, others can't.=INFO: Tu peux creuser ce nœud, mais Name:=Nom: Exit=Sortir This is:=C'est: -prev=préc -next=suiv. +prev=recette précédente +next=recette suivante No recipes.=Aucune recette. Drops on dig:=Gouttes sur creuser: nothing=rien diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index ba9ec20..3915f9f 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -42,8 +42,8 @@ INFO: You can dig this node, others can't.=INFO: puoi scavare questo nodo, ma al Name:=Nome: Exit=Uscita This is:=Questo è: -prev=pre. -next=suc. +prev=ricetta precedente +next=prossima ricetta No recipes.=Nessuna ricetta. Drops on dig:=Gocce allo scavo: nothing=niente diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index 41671dc..70e2c9f 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -42,8 +42,8 @@ INFO: You can dig this node, others can't.=INFO: Você pode cavar este nó, mas Name:=Nome: Exit=Saída This is:=Isto é: -prev=ant. -next=pró. +prev=receita anterior +next=próxima receita No recipes.=Sem receitas. Drops on dig:=Gotas na escavação: nothing=nada diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index ba3d790..e8e522d 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -42,8 +42,8 @@ INFO: You can dig this node, others can't.=ИНФОРМАЦИЯ: Вы может Name:=Имя: Exit=Выход This is:=Это: -prev=предыдущая -next=следующий +prev=предыдущий рецепт +next=следующий рецепт No recipes.=Нет рецептов. Drops on dig:=Выпадает при раскопках: nothing=ничего From e459df34fddbb021cf398dcfceb35c438e06a33f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 2 Feb 2022 17:08:46 +0100 Subject: [PATCH 269/366] fix version 5 formspec from version 5 padding actually does something which turns out to be horrible for our case. --- replacer/formspecs.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/replacer/formspecs.lua b/replacer/formspecs.lua index 30d61bc..a79b0c1 100644 --- a/replacer/formspecs.lua +++ b/replacer/formspecs.lua @@ -30,8 +30,7 @@ function replacer.get_form_modes_4(player, mode) end local tmp_name = '_' local formspec = 'formspec_version[4]' - .. 'size[' .. form_dimensions - .. ']padding[0.375,0.375]' + .. 'size[' .. form_dimensions .. ']' .. 'label[0.33,0.44;' .. mfe(rb.choose_mode) .. ']button_exit[' .. button_single_dimensions .. button_height .. ';' if 1 == major then @@ -82,6 +81,7 @@ function replacer.get_form_modes_4(player, mode) return formspec end -- get_form_modes_4 + function replacer.get_form_modes_default(mode) local major = mode.major local tmp_name = '_' @@ -167,7 +167,7 @@ function replacer.show_mode_formspec(player, mode) if 4 > version then formspec = r.get_form_modes_default(mode) else - -- version 4+ allows us to use proper dropdowns and other gimmics + -- version 4 allows us to use proper dropdowns and other gimmics formspec = r.get_form_modes_4(player, mode) end -- show the formspec to player From e9b2c98fa1a5b83094c1597b9a71f554231eb9eb Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 2 Feb 2022 17:09:34 +0100 Subject: [PATCH 270/366] add buckets to inspection tool --- blabla.lua | 2 ++ compat/bucket.lua | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 compat/bucket.lua diff --git a/blabla.lua b/blabla.lua index f74419b..67a0061 100644 --- a/blabla.lua +++ b/blabla.lua @@ -99,4 +99,6 @@ rbi.unkown_recipe = S('Error: Unkown recipe.') rbi.log_reg_craft_method_wrong_arguments = '[replacer] register_craft_method invalid arguments given.' rbi.log_reg_craft_method_overriding_method = '[replacer] register_craft_method overriding existing method ' rbi.log_reg_craft_method_added = '[replacer] register_craft_method method added: %s %s' +rbi.scoop = 'scoop up' +rbi.pour = 'pour out' diff --git a/compat/bucket.lua b/compat/bucket.lua new file mode 100644 index 0000000..5b15af1 --- /dev/null +++ b/compat/bucket.lua @@ -0,0 +1,47 @@ +if not minetest.get_modpath('bucket') then return end + +local rbi = replacer.blabla.inspect + +local pours = { + ['default:water_source'] = 'bucket:bucket_water', + ['default:river_water_source'] = 'bucket:bucket_river_water', + ['default:lava_source'] = 'bucket:bucket_lava', + ['technic:corium_source'] = 'technic:bucket_corium', +} +local scoops = {} +for k, v in pairs(pours) do scoops[v] = k end + +local function add_recipe(item_name, _, recipes) + local item, method, empty_bucket + if scoops[item_name] then + item = scoops[item_name] + method = rbi.scoop + elseif pours[item_name] then + item = pours[item_name] + method = rbi.pour + empty_bucket = true + else + return + end + + recipes[#recipes + 1] = { + method = method, + type = 'bucket:bucket', + items = { item }, + output = item_name, + empty_bucket = empty_bucket, + } +end -- add_recipe + +local function add_formspec(recipe) + if not recipe.empty_bucket then + return '' + end + + return 'item_image_button[5,3;1.0,1.0;' + .. replacer.image_button_link('bucket:bucket_empty') .. ']' +end -- add_formspec + +replacer.register_craft_method( + 'bucket:bucket', 'bucket:bucket_empty', add_recipe, add_formspec) + From e33969a1588563eb3b6ab88d78f25e292e4de31f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 2 Feb 2022 17:10:48 +0100 Subject: [PATCH 271/366] add scoop and pour methods for cans --- TODO | 5 +++- compat/technic.lua | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 25c354d..a1c8a7d 100644 --- a/TODO +++ b/TODO @@ -13,7 +13,6 @@ is the new drop detection hindering setting replacer to wine:blue_agave filter out 'normal' recipe.type uranium*_dust recipes given by core.get_all_craft_recipes() add mixing method - add bucket/cannister as method add home_workshop_misc:beer_tap as method -> home_workshop_misc:beer_mug add digging method for ores add info for seeds and saplings about planting @@ -86,3 +85,7 @@ bridger:corrugated_steelyellow -- christmas presents say they don't drop anything +-- will not implement -- + add helper so when setting replacer to an itemframe that contains something, + set to the contents --> but which param values? This isn't a good idea. + diff --git a/compat/technic.lua b/compat/technic.lua index 63e57d7..f10e04e 100644 --- a/compat/technic.lua +++ b/compat/technic.lua @@ -1,6 +1,8 @@ -- skip if technic isn't loaded at all if not replacer.has_technic_mod then return end +local rbi = replacer.blabla.inspect + -- adds exceptions for technic cable plates local lTiers = { 'lv', 'mv', 'hv' } local lPlates = { '_digi_cable_plate_', '_cable_plate_' } @@ -255,3 +257,75 @@ replacer.register_craft_method( 'technic:separate', 'technic:mv_centrifuge', add_recipe_separate, add_formspec_separate) + +local function add_recipe_can_lava(item_name, _, recipes) + local item, method + if 'technic:lava_can' == item_name then + item = 'default:lava_source' + method = rbi.scoop + elseif 'default:lava_source' == item_name then + item = 'technic:lava_can' + method = rbi.pour + else + return + end + + recipes[#recipes + 1] = { + method = method, + type = 'technic:lava_can', + items = { item }, + output = item_name, + } +end -- add_recipe_can_lava + +replacer.register_craft_method( + 'technic:lava_can', 'technic:lava_can', add_recipe_can_lava) + + +local function add_recipe_can_river(item_name, _, recipes) + local item, method + if 'technic:river_water_can' == item_name then + item = 'default:river_water_source' + method = rbi.scoop + elseif 'default:river_water_source' == item_name then + item = 'technic:river_water_can' + method = rbi.pour + else + return + end + + recipes[#recipes + 1] = { + method = method, + type = 'technic:river_water_can', + items = { item }, + output = item_name, + } +end -- add_recipe_can_river + +replacer.register_craft_method( + 'technic:river_water_can', 'technic:river_water_can', add_recipe_can_river) + + +local function add_recipe_can_water(item_name, _, recipes) + local item, method + if 'technic:water_can' == item_name then + item = 'default:water_source' + method = rbi.scoop + elseif 'default:water_source' == item_name then + item = 'technic:water_can' + method = rbi.pour + else + return + end + + recipes[#recipes + 1] = { + method = method, + type = 'technic:water_can', + items = { item }, + output = item_name, + } +end -- add_recipe_can_water + +replacer.register_craft_method( + 'technic:water_can', 'technic:water_can', add_recipe_can_water) + From 1e507fef71174ad630a0d2d28fb838002691b3e3 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 2 Feb 2022 18:07:37 +0100 Subject: [PATCH 272/366] beertap compat --- TODO | 1 - blabla.lua | 1 + compat/home_workshop_misc.lua | 22 ++++++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 compat/home_workshop_misc.lua diff --git a/TODO b/TODO index a1c8a7d..5c3eadb 100644 --- a/TODO +++ b/TODO @@ -13,7 +13,6 @@ is the new drop detection hindering setting replacer to wine:blue_agave filter out 'normal' recipe.type uranium*_dust recipes given by core.get_all_craft_recipes() add mixing method - add home_workshop_misc:beer_tap as method -> home_workshop_misc:beer_mug add digging method for ores add info for seeds and saplings about planting add info for plants telling when they are ripe -> allowing user to click on the ripe diff --git a/blabla.lua b/blabla.lua index 67a0061..5fca442 100644 --- a/blabla.lua +++ b/blabla.lua @@ -101,4 +101,5 @@ rbi.log_reg_craft_method_overriding_method = '[replacer] register_craft_method o rbi.log_reg_craft_method_added = '[replacer] register_craft_method method added: %s %s' rbi.scoop = 'scoop up' rbi.pour = 'pour out' +rbi.filling = S('filling') diff --git a/compat/home_workshop_misc.lua b/compat/home_workshop_misc.lua new file mode 100644 index 0000000..cebdbf5 --- /dev/null +++ b/compat/home_workshop_misc.lua @@ -0,0 +1,22 @@ +if not minetest.get_modpath('home_workshop_misc') then return end + +-- for replacer +local mug = 'home_workshop_misc:beer_mug' +replacer.register_exception(mug, mug) + +-- for inspection tool + +local function add_recipe(item_name, _, recipes) + if 'home_workshop_misc:beer_mug' ~= item_name then return end + + recipes[#recipes + 1] = { + method = replacer.blabla.inspect.filling, + type = 'home_workshop_misc:beer_tap', + items = { 'vessels:drinking_glass' }, + output = item_name, + } +end -- add_recipe + +replacer.register_craft_method( + 'home_workshop_misc:beer_tap', 'home_workshop_misc:beer_tap', add_recipe) + From bce8c92711a82156bd8d3dcf857c10a35a5d5704 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 2 Feb 2022 18:08:52 +0100 Subject: [PATCH 273/366] some blabla changes --- blabla.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/blabla.lua b/blabla.lua index 5fca442..9878db8 100644 --- a/blabla.lua +++ b/blabla.lua @@ -88,18 +88,18 @@ rbi.no_item_description = S('~ no item description provided ~') rbi.name = S('Name:') rbi.exit = S('Exit') rbi.this_is = S('This is:') -rbi.prev = S('prev') -rbi.next = S('next') +rbi.prev = S('previous recipe') +rbi.next = S('next recipe') rbi.no_recipes = S('No recipes.') rbi.drops_on_dig = S('Drops on dig:') -rbi.nothing = S('nothing') +rbi.nothing = S('nothing or itself.') rbi.may_drop_on_dig = S('May drop on dig:') rbi.can_be_fuel = S('This can be used as a fuel.') rbi.unkown_recipe = S('Error: Unkown recipe.') rbi.log_reg_craft_method_wrong_arguments = '[replacer] register_craft_method invalid arguments given.' rbi.log_reg_craft_method_overriding_method = '[replacer] register_craft_method overriding existing method ' rbi.log_reg_craft_method_added = '[replacer] register_craft_method method added: %s %s' -rbi.scoop = 'scoop up' -rbi.pour = 'pour out' +rbi.scoop = S('scoop up') +rbi.pour = S('pour out') rbi.filling = S('filling') From 561e270f2895e05bae74fc45abd8684d6852f693 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 2 Feb 2022 18:41:45 +0100 Subject: [PATCH 274/366] locale updates --- locale/replacer.de.tr | 11 +++++++---- locale/replacer.es.tr | 11 +++++++---- locale/replacer.fi.tr | 11 +++++++---- locale/replacer.fr.tr | 11 +++++++---- locale/replacer.it.tr | 11 +++++++---- locale/replacer.pt.tr | 11 +++++++---- locale/replacer.ru.tr | 11 +++++++---- locale/template.txt | 11 +++++++---- 8 files changed, 56 insertions(+), 32 deletions(-) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index 7f560cf..f8c62fd 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -42,14 +42,17 @@ INFO: You can dig this node, others can't.=INFO: Du kannst diese Node graben, an Name:=Name: Exit=Schliessen This is:=Dies ist: -prev=vorheriges Rezept -next=nächstes Rezept +previous recipe=vorheriges Rezept +next recipe=nächstes Rezept No recipes.=Keine Rezepte. Drops on dig:=Lässt fallen beim Graben: -nothing=nichts +nothing or itself.=nichts oder sich selbst. May drop on dig:=Kann beim Graben fallen lassen: This can be used as a fuel.=Dies kann als Brennstoff verwendet werden. Error: Unkown recipe.=Fehler: Unbekanntes Rezept. +scoop up=schöpfen +pour out=ausgiessen +filling=auffüllen fermenting/pickling=Gären Store near group:wood, light < 12.=In der Nähe der Holzgruppe@n(group:wood) lagern, Licht < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Node des Typs „@1“ dürfen auf diesem Server nicht ersetzt werden. Versuch fehlgeschlagen. @@ -71,7 +74,6 @@ and receiving @1 light=und empfängt @1 licht Alternate @1/@2=Alternative @1/@2 cutting=Schneiden shearing=Scheren -Cut with shears.=Mit Schere schneiden. sawing=Sägen You have no further "@1". Replacement failed.=Du hast keine weitere „@1“. Ersetzung fehlgeschlagen. Unknown node: "@1"=Unbekannter Node: „@1“ @@ -92,5 +94,6 @@ freezing=Einfrieren grinding=Mahlen separating=Trennen painting=Malen +Cut with shears.=Mit Schere schneiden. fermenting=Fermentieren Ferment in barrel.=Gärung im Fass. diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 982f963..4fd22b7 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -42,14 +42,17 @@ INFO: You can dig this node, others can't.=INFO: Puedes excavar este nodo, pero Name:=Nombre: Exit=Salir This is:=Esto es: -prev=receta anterior -next=siguiente receta +previous recipe=receta anterior +next recipe=siguiente receta No recipes.=Sin recetas. Drops on dig:=Cae en excavación: -nothing=nada +nothing or itself.=nada o él mismo. May drop on dig:=Puede caer en excavación: This can be used as a fuel.=Esto se puede usar como combustible. Error: Unkown recipe.=Error: Receta desconocida. +scoop up=recoger +pour out=derramar +filling=llena fermenting/pickling=fermentación/decapado Store near group:wood, light < 12.=Almacenar cerca del grupo de madera@n(group:wood), luz < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=No se permite reemplazar nodos de tipo "@1" en este servidor. Reemplazo fallido. @@ -71,7 +74,6 @@ and receiving @1 light=y recibiendo @1 luz Alternate @1/@2=Alternativo @1/@2 cutting=corte shearing=cizallamiento -Cut with shears.=Cortar con tijeras. sawing=aserradura You have no further "@1". Replacement failed.=No tienes más "@1". Reemplazo fallido. Unknown node: "@1"=Nodo desconocido: "@1" @@ -92,5 +94,6 @@ freezing=congelación grinding=molienda separating=separando painting=pintaando +Cut with shears.=Cortar con tijeras. fermenting=fermentando Ferment in barrel.=Fermentación en barrica. diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index dde7a13..112f6ad 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -42,14 +42,17 @@ INFO: You can dig this node, others can't.=INFO: Voit kaivaa tämän solmun, mut Name:=Nimi: Exit=Poistu This is:=Tämä on: -prev=edellinen resepti -next=seuraava resepti +previous recipe=edellinen resepti +next recipe=seuraava resepti No recipes.=Ei reseptejä. Drops on dig:=Pudotukset kaivamaan: -nothing=ei mitään +nothing or itself.=ei mitään tai itseään. May drop on dig:=Saattaa pudota kaivamaan: This can be used as a fuel.=Tätä voidaan käyttää polttoaineena. Error: Unkown recipe.=Virhe: Tuntematon resepti. +scoop up=kauhoa +pour out=kaataa +filling=täyttää fermenting/pickling=käyminen/peittaus Store near group:wood, light < 12.=Varasto lähellä group:wood,@nkevyt < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Tyypin "@1" solmujen korvaaminen ei ole sallittua tässä palvelimessa. Vaihto epäonnistui. @@ -71,7 +74,6 @@ and receiving @1 light=ja vastaanottaa @1 valoa Alternate @1/@2=Vaihtoehto @1/@2 cutting=leikkaus shearing=leikkaus -Cut with shears.=Leikkaa saksilla. sawing=sahaus You have no further "@1". Replacement failed.=Sinulla ei ole enempää "@1". Vaihto epäonnistui. Unknown node: "@1"=Tuntematon solmu: "@1" @@ -92,5 +94,6 @@ freezing=jäätyminen grinding=hionta separating=erottava painting=maalaus +Cut with shears.=Leikkaa saksilla. fermenting=käyminen Ferment in barrel.=Fermentoida tynnyrissä. diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index 2a943c1..8b3b73e 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -42,14 +42,17 @@ INFO: You can dig this node, others can't.=INFO: Tu peux creuser ce nœud, mais Name:=Nom: Exit=Sortir This is:=C'est: -prev=recette précédente -next=recette suivante +previous recipe=recette précédente +next recipe=recette suivante No recipes.=Aucune recette. Drops on dig:=Gouttes sur creuser: -nothing=rien +nothing or itself.=rien ou lui-même. May drop on dig:=Peut tomber en creusant: This can be used as a fuel.=Cela peut être utilisé comme carburant. Error: Unkown recipe.=Erreur : recette inconnue. +scoop up=ramasser +pour out=déverser +filling=remplir fermenting/pickling=fermentation/marinage Store near group:wood, light < 12.=Entreposer près du groupe @ngroup:wood, lumière < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Le remplacement de nœuds de type "@1" n'est pas autorisé sur ce serveur. Échec du remplacement. @@ -71,7 +74,6 @@ and receiving @1 light=et recevant @1 lumière Alternate @1/@2=Alternance @1/@2 cutting=Coupe shearing=Tonte -Cut with shears.=Couper avec des cisailles. sawing=Sciage You have no further "@1". Replacement failed.=Tu n'as plus de "@1". Échec du remplacement. Unknown node: "@1"=Nœud inconnu : "@1" @@ -92,5 +94,6 @@ freezing=gelé grinding=affûtage separating=séparer painting=peindre +Cut with shears.=Couper avec des cisailles. fermenting=fermentation Ferment in barrel.=Fermentation en barrique. diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index 3915f9f..70e05a5 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -42,14 +42,17 @@ INFO: You can dig this node, others can't.=INFO: puoi scavare questo nodo, ma al Name:=Nome: Exit=Uscita This is:=Questo è: -prev=ricetta precedente -next=prossima ricetta +previous recipe=ricetta precedente +next recipe=prossima ricetta No recipes.=Nessuna ricetta. Drops on dig:=Gocce allo scavo: -nothing=niente +nothing or itself.=niente o se stesso. May drop on dig:=Può cadere durante lo scavo: This can be used as a fuel.=Questo può essere usato come carburante. Error: Unkown recipe.=Errore: ricetta sconosciuta. +scoop up=raccogliere +pour out=versare +filling=riempire fermenting/pickling=fermentazione/decapaggio Store near group:wood, light < 12.=Negozio vicino al gruppo group:wood,@nluce < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=La sostituzione dei nodi di tipo "@1" non è consentita su questo server. Sostituzione non riuscita. @@ -71,7 +74,6 @@ and receiving @1 light=e ricevendo @1 luce Alternate @1/@2=Alternativo @1/@2 cutting=taglio shearing=tosatura -Cut with shears.=Tagliare con le forbici. sawing=segare You have no further "@1". Replacement failed.=Non hai più "@1". Sostituzione non riuscita. Unknown node: "@1"=Nodo sconosciuto: "@1" @@ -92,5 +94,6 @@ freezing=congelamento grinding=macinazione separating=separare painting=dipingere +Cut with shears.=Tagliare con le forbici. fermenting=fermentazione Ferment in barrel.=Fermentazione in botte. diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index 70e2c9f..d0862a9 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -42,14 +42,17 @@ INFO: You can dig this node, others can't.=INFO: Você pode cavar este nó, mas Name:=Nome: Exit=Saída This is:=Isto é: -prev=receita anterior -next=próxima receita +previous recipe=receita anterior +next recipe=próxima receita No recipes.=Sem receitas. Drops on dig:=Gotas na escavação: -nothing=nada +nothing or itself.=nada ou a si mesmo. May drop on dig:=Pode cair na escavação: This can be used as a fuel.=Isso pode ser usado como combustível. Error: Unkown recipe.=Erro: receita desconhecida. +scoop up=escavar +pour out=derramar +filling=encher fermenting/pickling=fermentação/decapagem Store near group:wood, light < 12.=Armazenar perto do grupo group:wood,@nluz < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=A substituição de nós do tipo "@1" não é permitida neste servidor. Falha na substituição. @@ -71,7 +74,6 @@ and receiving @1 light=e recebendo @1 luz Alternate @1/@2=Alternativo @1/@2 cutting=corte shearing=cisalhamento -Cut with shears.=Corte com tesoura. sawing=serrar You have no further "@1". Replacement failed.=Você não tem mais "@1". Falha na substituição. Unknown node: "@1"=Nó desconhecido: "@1" @@ -92,5 +94,6 @@ freezing=congelando grinding=esmerilhamento separating=separando painting=pintar +Cut with shears.=Corte com tesoura. fermenting=fermentando Ferment in barrel.=Fermentar em barril. diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index e8e522d..9cb781f 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -42,14 +42,17 @@ INFO: You can dig this node, others can't.=ИНФОРМАЦИЯ: Вы может Name:=Имя: Exit=Выход This is:=Это: -prev=предыдущий рецепт -next=следующий рецепт +previous recipe=предыдущий рецепт +next recipe=следующий рецепт No recipes.=Нет рецептов. Drops on dig:=Выпадает при раскопках: -nothing=ничего +nothing or itself.=ничего или самого себя. May drop on dig:=Может выпасть при раскопках: This can be used as a fuel.=Это можно использовать в качестве топлива. Error: Unkown recipe.=Ошибка: Неизвестный рецепт. +scoop up=зачерпнуть +pour out=вылить +filling=заполнить fermenting/pickling=ферментация/маринование Store near group:wood, light < 12.=Хранить рядом с группой дерево@n(group:wood), свет < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Замена узлов типа "@1" на этом сервере запрещена. Замена не удалась. @@ -71,7 +74,6 @@ and receiving @1 light=и получаю @1 свет Alternate @1/@2=Альтернатива @1/@2 cutting=резка shearing=стрижка -Cut with shears.=Вырезать ножницами. sawing=пиление You have no further "@1". Replacement failed.=У вас больше нет "@1". Замена не удалась. Unknown node: "@1"=Неизвестный узел: "@1" @@ -92,5 +94,6 @@ freezing=замораживание grinding=шлифовка separating=разделяющий painting=рисования +Cut with shears.=Вырезать ножницами. fermenting=брожение Ferment in barrel.=Ферментация в бочке. diff --git a/locale/template.txt b/locale/template.txt index 83139c0..c5b2329 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -42,14 +42,17 @@ INFO: You can dig this node, others can't.= Name:= Exit= This is:= -prev= -next= +previous recipe= +next recipe= No recipes.= Drops on dig:= -nothing= +nothing or itself.= May drop on dig:= This can be used as a fuel.= Error: Unkown recipe.= +scoop up= +pour out= +filling= fermenting/pickling= Store near group:wood, light < 12.= Replacing nodes of type "@1" is not allowed on this server. Replacement failed.= @@ -71,7 +74,6 @@ and receiving @1 light= Alternate @1/@2= cutting= shearing= -Cut with shears.= sawing= You have no further "@1". Replacement failed.= Unknown node: "@1"= @@ -92,5 +94,6 @@ freezing= grinding= separating= painting= +Cut with shears.= fermenting= Ferment in barrel.= From 0a62923494b97b25f7f14b2b55b3eb25fa06b9cf Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 2 Feb 2022 20:09:52 +0100 Subject: [PATCH 275/366] fix nodes that don't have drops but drop themselves --- TODO | 2 -- utils.lua | 29 ++++++++++++++++++++--------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/TODO b/TODO index 5c3eadb..66c25ab 100644 --- a/TODO +++ b/TODO @@ -10,7 +10,6 @@ -- inspection tool: figure out how to make the itemstring selectable for copy -> do that with new formspec version - is the new drop detection hindering setting replacer to wine:blue_agave filter out 'normal' recipe.type uranium*_dust recipes given by core.get_all_craft_recipes() add mixing method add digging method for ores @@ -29,7 +28,6 @@ ------ replacer fixes -------- -- can't be set --> no recipe -home_workshop_misc:beer_mug homedecor:glass_table_large_square homedecor:dvd_cd_cabinet homedecor:chains diff --git a/utils.lua b/utils.lua index 030b2bd..283e3e0 100644 --- a/utils.lua +++ b/utils.lua @@ -2,6 +2,7 @@ local r = replacer local rb = replacer.blabla local chat_send_player = minetest.chat_send_player local get_player_by_name = minetest.get_player_by_name +local get_node_drops = minetest.get_node_drops local log = minetest.log local floor = math.floor local pos_to_string = minetest.pos_to_string @@ -56,21 +57,31 @@ end -- play_sound function replacer.possible_node_drops(node_name, return_names_only) - if not minetest.registered_nodes[node_name] - or not minetest.registered_nodes[node_name].drop then return {} end + if not minetest.registered_nodes[node_name] then return {} end - local drop = minetest.registered_nodes[node_name].drop + local droplist = {} + local drop = minetest.registered_nodes[node_name].drop or '' if 'string' == type(drop) then - if '' == drop then return {} end - if return_names_only then - return { drop:match('^([^ ]+)') } + if '' == drop then + -- this returns value with randomness applied :/ + drop = get_node_drops(node_name) + if 0 == #drop then return {} end + + if not return_names_only then return drop end + + for _, item in ipairs(drop) do + table.insert(droplist, item:match('^([^ ]+)')) + end + return droplist end - return { drop } - end + + if not return_names_only then return { drop } end + + return { drop:match('^([^ ]+)') } + end -- if string if 'table' ~= type(drop) or not drop.items then return {} end - local droplist = {} local checks = {} for _, drops in ipairs(drop.items) do for _, item in ipairs(drops.items) do From 5afe25beeee01c1fc3447e423ceb2619c6798c6a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 2 Feb 2022 20:12:19 +0100 Subject: [PATCH 276/366] locale updates --- blabla.lua | 2 +- i18n.py | 2 +- locale/replacer.de.tr | 4 ++-- locale/replacer.es.tr | 4 ++-- locale/replacer.fi.tr | 4 ++-- locale/replacer.fr.tr | 4 ++-- locale/replacer.it.tr | 4 ++-- locale/replacer.pt.tr | 4 ++-- locale/replacer.ru.tr | 4 ++-- locale/template.txt | 4 ++-- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/blabla.lua b/blabla.lua index 9878db8..0a38a49 100644 --- a/blabla.lua +++ b/blabla.lua @@ -92,7 +92,7 @@ rbi.prev = S('previous recipe') rbi.next = S('next recipe') rbi.no_recipes = S('No recipes.') rbi.drops_on_dig = S('Drops on dig:') -rbi.nothing = S('nothing or itself.') +rbi.nothing = S('nothing.') rbi.may_drop_on_dig = S('May drop on dig:') rbi.can_be_fuel = S('This can be used as a fuel.') rbi.unkown_recipe = S('Error: Unkown recipe.') diff --git a/i18n.py b/i18n.py index 21c4657..67305b0 100755 --- a/i18n.py +++ b/i18n.py @@ -25,7 +25,7 @@ "break-long-lines": True, "sort": False, "print-source": False, - "truncate-unused": True, + "truncate-unused": False, } # Available CLI options options = {"recursive": ['--recursive', '-r'], diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index f8c62fd..423662e 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -46,7 +46,7 @@ previous recipe=vorheriges Rezept next recipe=nächstes Rezept No recipes.=Keine Rezepte. Drops on dig:=Lässt fallen beim Graben: -nothing or itself.=nichts oder sich selbst. +nothing.=nichts. May drop on dig:=Kann beim Graben fallen lassen: This can be used as a fuel.=Dies kann als Brennstoff verwendet werden. Error: Unkown recipe.=Fehler: Unbekanntes Rezept. @@ -74,6 +74,7 @@ and receiving @1 light=und empfängt @1 licht Alternate @1/@2=Alternative @1/@2 cutting=Schneiden shearing=Scheren +Cut with shears.=Mit Schere schneiden. sawing=Sägen You have no further "@1". Replacement failed.=Du hast keine weitere „@1“. Ersetzung fehlgeschlagen. Unknown node: "@1"=Unbekannter Node: „@1“ @@ -94,6 +95,5 @@ freezing=Einfrieren grinding=Mahlen separating=Trennen painting=Malen -Cut with shears.=Mit Schere schneiden. fermenting=Fermentieren Ferment in barrel.=Gärung im Fass. diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 4fd22b7..49b3043 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -46,7 +46,7 @@ previous recipe=receta anterior next recipe=siguiente receta No recipes.=Sin recetas. Drops on dig:=Cae en excavación: -nothing or itself.=nada o él mismo. +nothing.=nada. May drop on dig:=Puede caer en excavación: This can be used as a fuel.=Esto se puede usar como combustible. Error: Unkown recipe.=Error: Receta desconocida. @@ -74,6 +74,7 @@ and receiving @1 light=y recibiendo @1 luz Alternate @1/@2=Alternativo @1/@2 cutting=corte shearing=cizallamiento +Cut with shears.=Cortar con tijeras. sawing=aserradura You have no further "@1". Replacement failed.=No tienes más "@1". Reemplazo fallido. Unknown node: "@1"=Nodo desconocido: "@1" @@ -94,6 +95,5 @@ freezing=congelación grinding=molienda separating=separando painting=pintaando -Cut with shears.=Cortar con tijeras. fermenting=fermentando Ferment in barrel.=Fermentación en barrica. diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index 112f6ad..5a729dd 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -46,7 +46,7 @@ previous recipe=edellinen resepti next recipe=seuraava resepti No recipes.=Ei reseptejä. Drops on dig:=Pudotukset kaivamaan: -nothing or itself.=ei mitään tai itseään. +nothing.=ei mitään. May drop on dig:=Saattaa pudota kaivamaan: This can be used as a fuel.=Tätä voidaan käyttää polttoaineena. Error: Unkown recipe.=Virhe: Tuntematon resepti. @@ -74,6 +74,7 @@ and receiving @1 light=ja vastaanottaa @1 valoa Alternate @1/@2=Vaihtoehto @1/@2 cutting=leikkaus shearing=leikkaus +Cut with shears.=Leikkaa saksilla. sawing=sahaus You have no further "@1". Replacement failed.=Sinulla ei ole enempää "@1". Vaihto epäonnistui. Unknown node: "@1"=Tuntematon solmu: "@1" @@ -94,6 +95,5 @@ freezing=jäätyminen grinding=hionta separating=erottava painting=maalaus -Cut with shears.=Leikkaa saksilla. fermenting=käyminen Ferment in barrel.=Fermentoida tynnyrissä. diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index 8b3b73e..f739eab 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -46,7 +46,7 @@ previous recipe=recette précédente next recipe=recette suivante No recipes.=Aucune recette. Drops on dig:=Gouttes sur creuser: -nothing or itself.=rien ou lui-même. +nothing.=rien. May drop on dig:=Peut tomber en creusant: This can be used as a fuel.=Cela peut être utilisé comme carburant. Error: Unkown recipe.=Erreur : recette inconnue. @@ -74,6 +74,7 @@ and receiving @1 light=et recevant @1 lumière Alternate @1/@2=Alternance @1/@2 cutting=Coupe shearing=Tonte +Cut with shears.=Couper avec des cisailles. sawing=Sciage You have no further "@1". Replacement failed.=Tu n'as plus de "@1". Échec du remplacement. Unknown node: "@1"=Nœud inconnu : "@1" @@ -94,6 +95,5 @@ freezing=gelé grinding=affûtage separating=séparer painting=peindre -Cut with shears.=Couper avec des cisailles. fermenting=fermentation Ferment in barrel.=Fermentation en barrique. diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index 70e05a5..a25538a 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -46,7 +46,7 @@ previous recipe=ricetta precedente next recipe=prossima ricetta No recipes.=Nessuna ricetta. Drops on dig:=Gocce allo scavo: -nothing or itself.=niente o se stesso. +nothing.=niente. May drop on dig:=Può cadere durante lo scavo: This can be used as a fuel.=Questo può essere usato come carburante. Error: Unkown recipe.=Errore: ricetta sconosciuta. @@ -74,6 +74,7 @@ and receiving @1 light=e ricevendo @1 luce Alternate @1/@2=Alternativo @1/@2 cutting=taglio shearing=tosatura +Cut with shears.=Tagliare con le forbici. sawing=segare You have no further "@1". Replacement failed.=Non hai più "@1". Sostituzione non riuscita. Unknown node: "@1"=Nodo sconosciuto: "@1" @@ -94,6 +95,5 @@ freezing=congelamento grinding=macinazione separating=separare painting=dipingere -Cut with shears.=Tagliare con le forbici. fermenting=fermentazione Ferment in barrel.=Fermentazione in botte. diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index d0862a9..4e81581 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -46,7 +46,7 @@ previous recipe=receita anterior next recipe=próxima receita No recipes.=Sem receitas. Drops on dig:=Gotas na escavação: -nothing or itself.=nada ou a si mesmo. +nothing.=nada. May drop on dig:=Pode cair na escavação: This can be used as a fuel.=Isso pode ser usado como combustível. Error: Unkown recipe.=Erro: receita desconhecida. @@ -74,6 +74,7 @@ and receiving @1 light=e recebendo @1 luz Alternate @1/@2=Alternativo @1/@2 cutting=corte shearing=cisalhamento +Cut with shears.=Corte com tesoura. sawing=serrar You have no further "@1". Replacement failed.=Você não tem mais "@1". Falha na substituição. Unknown node: "@1"=Nó desconhecido: "@1" @@ -94,6 +95,5 @@ freezing=congelando grinding=esmerilhamento separating=separando painting=pintar -Cut with shears.=Corte com tesoura. fermenting=fermentando Ferment in barrel.=Fermentar em barril. diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index 9cb781f..4112462 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -46,7 +46,7 @@ previous recipe=предыдущий рецепт next recipe=следующий рецепт No recipes.=Нет рецептов. Drops on dig:=Выпадает при раскопках: -nothing or itself.=ничего или самого себя. +nothing.=ничего. May drop on dig:=Может выпасть при раскопках: This can be used as a fuel.=Это можно использовать в качестве топлива. Error: Unkown recipe.=Ошибка: Неизвестный рецепт. @@ -74,6 +74,7 @@ and receiving @1 light=и получаю @1 свет Alternate @1/@2=Альтернатива @1/@2 cutting=резка shearing=стрижка +Cut with shears.=Вырезать ножницами. sawing=пиление You have no further "@1". Replacement failed.=У вас больше нет "@1". Замена не удалась. Unknown node: "@1"=Неизвестный узел: "@1" @@ -94,6 +95,5 @@ freezing=замораживание grinding=шлифовка separating=разделяющий painting=рисования -Cut with shears.=Вырезать ножницами. fermenting=брожение Ferment in barrel.=Ферментация в бочке. diff --git a/locale/template.txt b/locale/template.txt index c5b2329..14e4a0e 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -46,7 +46,7 @@ previous recipe= next recipe= No recipes.= Drops on dig:= -nothing or itself.= +nothing.= May drop on dig:= This can be used as a fuel.= Error: Unkown recipe.= @@ -74,6 +74,7 @@ and receiving @1 light= Alternate @1/@2= cutting= shearing= +Cut with shears.= sawing= You have no further "@1". Replacement failed.= Unknown node: "@1"= @@ -94,6 +95,5 @@ freezing= grinding= separating= painting= -Cut with shears.= fermenting= Ferment in barrel.= From ce7415993c1a99199e78a52244de14299c59a07e Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 2 Feb 2022 20:13:32 +0100 Subject: [PATCH 277/366] luacheck ignore unused debug function --- inspect.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/inspect.lua b/inspect.lua index ec0f2b4..2d2a1dd 100644 --- a/inspect.lua +++ b/inspect.lua @@ -15,7 +15,9 @@ local floor = math.floor local max, min = math.max, math.min local chat = minetest.chat_send_player local mfe = minetest.formspec_escape +-- luacheck: push ignore unused local pd = r.print_dump +-- luacheck: pop -- use r.register_craft_method() to populate replacer.recipe_adders = {} From fa54eea7b14cb12251221055a6eb03a51964fc7c Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 2 Feb 2022 20:48:20 +0100 Subject: [PATCH 278/366] proper luacheck syntax --- inspect.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inspect.lua b/inspect.lua index 2d2a1dd..963ef2e 100644 --- a/inspect.lua +++ b/inspect.lua @@ -15,7 +15,7 @@ local floor = math.floor local max, min = math.max, math.min local chat = minetest.chat_send_player local mfe = minetest.formspec_escape --- luacheck: push ignore unused +-- luacheck: push ignore unused pd local pd = r.print_dump -- luacheck: pop -- use r.register_craft_method() to populate From a74e3138aabcf752df83dd9f2ae1a301e1b80352 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 2 Feb 2022 22:32:54 +0100 Subject: [PATCH 279/366] add setting to disable minor modes --- blabla.lua | 1 + doc/customization.md | 4 ++++ replacer/constrain.lua | 4 ++++ replacer/formspecs.lua | 7 ++++++- replacer/history.lua | 1 + replacer/replacer.lua | 8 ++++++++ settingtypes.txt | 2 ++ 7 files changed, 26 insertions(+), 1 deletion(-) diff --git a/blabla.lua b/blabla.lua index 0a38a49..a9a30c9 100644 --- a/blabla.lua +++ b/blabla.lua @@ -71,6 +71,7 @@ rb.log_reg_alias = '[replacer] registered alias for "%s" to "%s"' rb.log_reg_set_callback_fail = '[replacer] register_set_enabler called without passing function.' rb.formspec_error = '[replacer] formspec error, user "%s" attempting to change history. Fields: %s' rb.formspec_hacker = '[replacer] formspec forge? By user "%s" Fields: %s' +rb.minor_modes_disabled = S('Minor modes are disabled on this server.') ----------------- replacer:inspect ----------------- rbi.description = S('Inspection Tool\nUse to inspect target node or entity.\n' diff --git a/doc/customization.md b/doc/customization.md index 8868370..3245f76 100644 --- a/doc/customization.md +++ b/doc/customization.md @@ -33,6 +33,10 @@ Radius == floor(max_positions ^ radius_factor + .5) where max_positions is a min of available charge and max_nodes. Small changes to this value can have big effects.
Set radius_factor to 0 or less for behaviour prior to version 3.3 +### replacer.disable_minor_modes (bool) +If you don't want to use the minor modes at all, set to true. These are the modes where +only node or rotation is applied. + ### replacer.history_priv (creative) You can make history available to users with this priv. By default it is set to **creative** as survival users can make several replacers. You can make this an acheivment for busy players diff --git a/replacer/constrain.lua b/replacer/constrain.lua index 7800eee..fc35d2b 100644 --- a/replacer/constrain.lua +++ b/replacer/constrain.lua @@ -27,6 +27,10 @@ replacer.max_time = tonumber(minetest.settings:get('replacer.max_time') or 1.0) -- [see replacer_patterns.lua>replacer.patterns.search_positions()] replacer.radius_factor = tonumber(minetest.settings:get('replacer.radius_factor') or 0.4) +-- disable minor modes on server +replacer.disable_minor_modes = + minetest.settings:get_bool('replacer.disable_minor_modes') or false + -- priv to allow using history replacer.history_priv = minetest.settings:get('replacer.history_priv') or 'creative' -- disable saving history over sessions/reboots. IOW: don't use player meta e.g. if using old MT diff --git a/replacer/formspecs.lua b/replacer/formspecs.lua index a79b0c1..c54aaa0 100644 --- a/replacer/formspecs.lua +++ b/replacer/formspecs.lua @@ -60,12 +60,16 @@ function replacer.get_form_modes_4(player, mode) formspec = formspec .. 'mode3;' .. mfe(rb.mode_crust) end formspec = formspec .. ']tooltip[' .. tmp_name .. ';' - .. mfe(rb.mode_crust_tooltip) .. ']dropdown[' .. minor_dimensions .. ';minor;' + .. mfe(rb.mode_crust_tooltip) .. ']' + if not r.disable_minor_modes then + formspec = formspec .. 'dropdown[' .. minor_dimensions .. ';minor;' .. mfe(rb.mode_minor1) .. ',' .. mfe(rb.mode_minor2) .. ',' .. mfe(rb.mode_minor3) .. ';' .. tostring(minor) .. ';true]tooltip[' .. minor_dimensions .. ';' .. mfe(rb.mode_minor1 .. ': ' .. rb.mode_minor1_info .. '\n' .. rb.mode_minor2 .. ': ' .. rb.mode_minor2_info .. '\n' .. rb.mode_minor3 .. ': ' .. rb.mode_minor3_info) .. ']' + end + if not has_history_priv then return formspec end formspec = formspec .. 'label[0.33,3.22;' .. mfe(rb.choose_history) @@ -130,6 +134,7 @@ function replacer.on_player_receive_fields(player, form_name, fields) elseif fields.minor then -- clamp to { 1, 2, 3 } mode.minor = math.min(3, math.max(1, tonumber(fields.minor) or 1)) + if r.disable_minor_modes then mode.minor = 1 end elseif fields.history then -- ignore if user doesn't have privs if not check_player_privs(name, r.history_priv) then diff --git a/replacer/history.lua b/replacer/history.lua index 9335fa3..bd9320b 100644 --- a/replacer/history.lua +++ b/replacer/history.lua @@ -68,6 +68,7 @@ function replacer.history.init_player(player) minor = tonumber(mode[2]) or 1, }, } + if r.disable_minor_modes then entry.mode.minor = 1 end node_def = minetest.registered_items[entry.node.name] colour_name = rud_colour_name(entry.node.param2, node_def) if 0 < #colour_name then diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 6cb79e5..e4f430d 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -56,6 +56,7 @@ function replacer.get_data(stack) local mode, mode_bare = {}, meta:get_string('mode'):split('.') or {} mode.major = tonumber(mode_bare[1] or 1) or 1 mode.minor = tonumber(mode_bare[2] or 1) + if r.disable_minor_modes then mode.minor = 1 end return node, mode end -- get_data @@ -67,6 +68,7 @@ function replacer.set_data(stack, node, mode) local _ _, mode = r.get_data(stack) end + if r.disable_minor_modes then mode.minor = 1 end local tool_itemstring = stack:get_name() local tool_def = core_registered_items[tool_itemstring] -- some accidents or deliberate actions can be harmful @@ -524,6 +526,12 @@ function replacer.on_place(itemstack, player, pt) -- fetch current mode node, mode = r.get_data(itemstack) if keys.sneak then + if r.disable_minor_modes then + r.play_sound(name, true) + r.inform(name, rb.minor_modes_disabled) + return itemstack + end + -- increment and roll-over minor mode mode.minor = mode.minor % 3 + 1 -- spam chat diff --git a/settingtypes.txt b/settingtypes.txt index 6b24a67..a8cc543 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -9,6 +9,8 @@ replacer.max_time (Time limit when putting nodes) float 1.0 # Radius limit factor when more possible positions are found than either max_nodes or charge # Set to 0 or less for behaviour of before version 3.3 replacer.radius_factor (A factor to adjust size limit) float 0.4 +# If you don't want to use the minor modes at all, set to true +replacer.disable_minor_modes (Disable using minor modes) bool false # You can make history available to users with this priv. By default it is set to creative # as non-creative users can make several replacers. replacer.history_priv (Priv needed to allow using history) string creative From e270fa3f24b8643a4db3a71f41dbf364f5d5e957 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 2 Feb 2022 22:33:51 +0100 Subject: [PATCH 280/366] locale update --- locale/replacer.de.tr | 2 ++ locale/replacer.es.tr | 2 ++ locale/replacer.fi.tr | 2 ++ locale/replacer.fr.tr | 2 ++ locale/replacer.it.tr | 2 ++ locale/replacer.pt.tr | 2 ++ locale/replacer.ru.tr | 2 ++ locale/template.txt | 2 ++ 8 files changed, 16 insertions(+) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index 423662e..a2a7914 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -27,6 +27,8 @@ Time-limit reached.=Zeitbegrenzung erreicht. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Schaltet die Ausführlichkeit um.@nchat: Wenn eingeschaltet, werden Nachrichten im Chat ausgegeben.@audio: Wenn ausgeschaltet, ist der Ersetzer stumm. +Minor modes are disabled on this server.=Nebenmodi sind auf diesem Server deaktiviert. + Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Inspektionswerkzeug@nSchlagen zum Inspizieren der Zielnode oder der Entität.@nPlatzieren zum Inspizieren der angrenzenden Node. This is a broken object. We have no further information about it. It is located=Dies ist ein kaputtes Objekt. Wir haben keine weiteren Informationen darüber. Es befindet sich diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 49b3043..f16a642 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -27,6 +27,8 @@ Time-limit reached.=Límite de tiempo alcanzado. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Alterna la verbosidad. @nchat: cuando está activado, los mensajes se publican en el chat. @naudio: cuando está desactivado, el intercambiador está en silencio. +Minor modes are disabled on this server.=Los modos menores están deshabilitados en este servidor. + Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Herramienta de inspección@nUsar para inspeccionar el nodo o la entidad de destino.@nColocar para inspeccionar el nodo adyacente. This is a broken object. We have no further information about it. It is located=Este es un objeto roto. No tenemos más información al respecto. se encuentra diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index 5a729dd..f6ae49b 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -27,6 +27,8 @@ Time-limit reached.=Aikaraja saavutettu. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Vaihtaa verbosity.@nchat: Kun päällä, viestit lähetetään chat.@naudio: Kun pois päältä, korvaaja on äänetön. +Minor modes are disabled on this server.=Pienet tilat on poistettu käytöstä tällä palvelimella. + Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Tarkastustyökalu@nTarkista kohdesolmu tai entiteetti.@nTarkista viereinen solmu. This is a broken object. We have no further information about it. It is located=Tämä on rikkinäinen esine. Meillä ei ole asiasta enempää tietoa. Se sijaitsee diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index f739eab..281797f 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -27,6 +27,8 @@ Time-limit reached.=Délai atteint. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Active/désactive la verbosité.@nchat : lorsque cette option est activée, les messages sont publiés sur le chat.@naudio : lorsqu'elle est désactivée, le remplaçant est silencieux. +Minor modes are disabled on this server.=Les modes mineurs sont désactivés sur ce serveur. + Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Outil d'inspection@nUtiliser pour inspecter le nœud ou l'entité cible.@nPlacer pour inspecter le nœud adjacent. This is a broken object. We have no further information about it. It is located=Ceci est un objet cassé. Nous n'avons pas d'autres informations à ce sujet. Il est situé diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index a25538a..0af471e 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -27,6 +27,8 @@ Time-limit reached.=Tempo limite raggiunto. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Attiva/disattiva verbosità.@nchat: quando è attivo, i messaggi vengono inviati alla chat.@naudio: quando è disattivato, il sostituto è silenzioso. +Minor modes are disabled on this server.=Le modalità minori sono disabilitate su questo server. + Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Strumento di ispezione@nUtilizzare per ispezionare il nodo o l'entità di destinazione.@nPosizionare per ispezionare il nodo adiacente. This is a broken object. We have no further information about it. It is located=Questo è un oggetto rotto. Non abbiamo ulteriori informazioni a riguardo. Si trova diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index 4e81581..bdf8fde 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -27,6 +27,8 @@ Time-limit reached.=Limite de tempo atingido. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Alterna a verbosidade.@nchat: Quando ativado, as mensagens são postadas no chat.@naudio: Quando desativado, o substituto é silencioso. +Minor modes are disabled on this server.=Os modos secundários estão desabilitados neste servidor. + Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Ferramenta de Inspeção@nUse para inspecionar o nó ou entidade de destino.@nPlace para inspecionar o nó adjacente. This is a broken object. We have no further information about it. It is located=Este é um objeto quebrado. Não temos mais informações a respeito. está localizado diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index 4112462..90cc09b 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -27,6 +27,8 @@ Time-limit reached.=Достигнут лимит времени. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Включает многословие. @nchat: когда включено, сообщения отправляются в чат. @naudio: когда выключено, заменитель молчит. +Minor modes are disabled on this server.=Второстепенные режимы отключены на этом сервере. + Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Inspection Tool@nИспользуйте для проверки целевого узла или объекта. @nPlace для проверки соседнего узла. This is a broken object. We have no further information about it. It is located=Это сломанный объект. У нас нет никакой дополнительной информации об этом. Он расположен. diff --git a/locale/template.txt b/locale/template.txt index 14e4a0e..e9c2dd1 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -27,6 +27,8 @@ Time-limit reached.= Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.= +Minor modes are disabled on this server.= + Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.= This is a broken object. We have no further information about it. It is located= From cdda316a6b200c3acbc1a8475441fe3812ec810f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 3 Feb 2022 00:54:17 +0100 Subject: [PATCH 281/366] support for silicon aka forced aliases --- inspect.lua | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/inspect.lua b/inspect.lua index 963ef2e..df9563d 100644 --- a/inspect.lua +++ b/inspect.lua @@ -260,7 +260,19 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) -- fetch recipes from core local recipes = minetest.get_all_craft_recipes(node_name) if not recipes then - recipes = {} + -- some items have aliases that are set with force, and thus + -- don't show up in core.get_all_craft_recipes() + -- e.g. https://github.com/mt-mods/basic_materials/blob/d9e06980d33ec02c2321269f47ab9ec32b36551f/aliases.lua#L32 + -- https://github.com/mt-mods/basic_materials/blob/d9e06980d33ec02c2321269f47ab9ec32b36551f/crafts.lua#L256 + -- we try to reverse lookup here + for k, v in pairs(minetest.registered_aliases) do + if v == node_name then + node_name = k + recipes = minetest.get_all_craft_recipes(node_name) + if recipes then break end + end + end + recipes = recipes or {} end --pd(recipes) -- TODO: filter out invalid recipes with no items From fd707cb8bc68c7195b2c9faedb58cf10cddd77a0 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 3 Feb 2022 01:09:23 +0100 Subject: [PATCH 282/366] version bump 4.1 --- CHANGELOG | 5 +++++ TODO | 1 - init.lua | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 87f9079..75be0e3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +20220203 * SwissalpS fixed some issues: forced aliases, items that have no drops defined + Added compat for buckets, canisters and beertap/mugs + Fixed formspec for MT 5.5.0 (that now actually uses padding) + Added server setting to disable minor modes. + Updated documentation and locales. 20220127 * SwissalpS cleaned up var names in inspect.lua * Added .luacheckrc and print_dump() * Bumped version to 4.0 diff --git a/TODO b/TODO index 66c25ab..298309f 100644 --- a/TODO +++ b/TODO @@ -61,7 +61,6 @@ homedecor:table_lamp_12 homedecor:speaker_open -> homedecor:speaker (cable plate overrides) -- not fixing as user can have both in inventory ---------- known incompat inspect ----------- --- no recipe for silicon lump ---- missing icons ---- cottages:wool;cottages:wool (used by homedecor:curtain_open) -- meh, there is working recipe diff --git a/init.lua b/init.lua index de9062c..78adfbc 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 4.0 (20220127) +-- Version 4.1 (20220203) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220127 +replacer.version = 20220203 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From 25739a60b2ecda2dc0e0f8e68fd7d797f983acd2 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 3 Feb 2022 07:11:01 +0100 Subject: [PATCH 283/366] those uranium dust mixing recipes are deliberate so we leave them in untouched --- TODO | 1 - inspect.lua | 1 - 2 files changed, 2 deletions(-) diff --git a/TODO b/TODO index 298309f..5da48cf 100644 --- a/TODO +++ b/TODO @@ -10,7 +10,6 @@ -- inspection tool: figure out how to make the itemstring selectable for copy -> do that with new formspec version - filter out 'normal' recipe.type uranium*_dust recipes given by core.get_all_craft_recipes() add mixing method add digging method for ores add info for seeds and saplings about planting diff --git a/inspect.lua b/inspect.lua index df9563d..21de811 100644 --- a/inspect.lua +++ b/inspect.lua @@ -277,7 +277,6 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) --pd(recipes) -- TODO: filter out invalid recipes with no items -- such as "group:flower,color_dark_grey" - -- also 'normal' recipe.type uranium*_dust recipes -- add special recipes for nodes created by machines for _, adder in pairs(r.recipe_adders) do From cb4d433f2cc41f9a60929dc60d82f01909b8b7f8 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 3 Feb 2022 07:46:39 +0100 Subject: [PATCH 284/366] thoughts updated --- TODO | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index 5da48cf..86de76b 100644 --- a/TODO +++ b/TODO @@ -11,13 +11,16 @@ -- inspection tool: figure out how to make the itemstring selectable for copy -> do that with new formspec version add mixing method - add digging method for ores - add info for seeds and saplings about planting + add spawning, breading etc. info for mobs -> this sounds feasable for mobs_redo mobs. + add biofuel hints also general 'fuel' craft types -> if biofuel doesn't expose a list + this is also doomed (as I don't want to maintain lists) + add digging method for ores --> maybe not. Doing this dynamically seems overkill to + check every registered item to see if it drops the requested item + add info for seeds and saplings about planting -> this too seems like a task that will + include mainting a list of all plant types of any mod that adds them. Not my intention. add info for plants telling when they are ripe -> allowing user to click on the ripe stage and see possible seed drop -> showing info about planting. don't forget wine:blue_agave when doing that - add spawning, breading etc. info for mobs - add biofuel hints also general 'fuel' craft types -- known incompat replacer ------------------------ -- doors in general (low priority) From 438eabe13b5b43a4e15faf43f0e9e44fb32b4b97 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 3 Feb 2022 18:10:30 +0100 Subject: [PATCH 285/366] fix group:food_pumpkin --- compat/farming.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/compat/farming.lua b/compat/farming.lua index c46773a..8354f05 100644 --- a/compat/farming.lua +++ b/compat/farming.lua @@ -9,6 +9,7 @@ rgp['group:food_meat'] = 'farming:tofu_cooked' rgp['group:food_peppercorn'] = 'farming:peppercorn' rgp['group:food_pot'] = 'farming:pot' rgp['group:food_potato'] = 'farming:potato' +rgp['group:food_pumpkin'] = 'farming:pumpkin_8' rgp['group:food_salt'] = 'farming:salt' rgp['group:food_saucepan'] = 'farming:saucepan' rgp['group:food_soy'] = 'farming:soy_beans' From 7389f4f2e3102163dfc7d5d533aa14c165a17ec1 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 3 Feb 2022 18:13:24 +0100 Subject: [PATCH 286/366] adjust protection info --- inspect.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inspect.lua b/inspect.lua index 21de811..2daafa0 100644 --- a/inspect.lua +++ b/inspect.lua @@ -367,8 +367,9 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) -- show information about protection if fields.protected_info and '' ~= fields.protected_info then - formspec = formspec .. 'label[0.0,4.5;' + formspec = formspec .. 'label[0.0,4.7;' .. mfe(fields.protected_info) .. ']' + .. 'tooltip[-1,4.7;5,1;' .. mfe(fields.protected_info) .. ']' end -- if no recipes, collect drops else show current recipe From 634ce7755490374eac9f2051fd8cd38bb4240dfd Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 3 Feb 2022 18:15:32 +0100 Subject: [PATCH 287/366] fixed alias resolving not changing node_name helps keep other efforts in place --- inspect.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/inspect.lua b/inspect.lua index 2daafa0..ef9df48 100644 --- a/inspect.lua +++ b/inspect.lua @@ -258,8 +258,8 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) end -- fetch recipes from core - local recipes = minetest.get_all_craft_recipes(node_name) - if not recipes then + local recipes = minetest.get_all_craft_recipes(node_name) or {} + if 0 == #recipes then -- some items have aliases that are set with force, and thus -- don't show up in core.get_all_craft_recipes() -- e.g. https://github.com/mt-mods/basic_materials/blob/d9e06980d33ec02c2321269f47ab9ec32b36551f/aliases.lua#L32 @@ -267,8 +267,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) -- we try to reverse lookup here for k, v in pairs(minetest.registered_aliases) do if v == node_name then - node_name = k - recipes = minetest.get_all_craft_recipes(node_name) + recipes = minetest.get_all_craft_recipes(k) if recipes then break end end end From ffabbf2b0d0b29b357da04c51856364920b7b511 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 4 Feb 2022 04:37:59 +0100 Subject: [PATCH 288/366] use leaner time-out calculations this way no subtractions needed on every loop, just simple size comparison --- replacer/replacer.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index e4f430d..355a3c1 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -8,6 +8,7 @@ local rb = replacer.blabla local rp = replacer.patterns local rud = replacer.unifieddyes local S = replacer.S +local max_time_us = 1000000 * r.max_time -- math local max, min, floor = math.max, math.min, math.floor local core_check_player_privs = minetest.check_player_privs @@ -451,9 +452,6 @@ function replacer.on_use(itemstack, player, pt, right_clicked) end -- set nodes - local t_start = us_time() - -- TODO - local max_time_us = 1000000 * r.max_time -- Turn found_positions into a binary heap r.datastructures.create_binary_heap({ input = found_positions, @@ -486,8 +484,9 @@ function replacer.on_use(itemstack, player, pt, right_clicked) r.inform(name, rb.too_many_nodes_detected) break end + local us_time_limit = us_time() + max_time_us -- time-out check - if us_time() - t_start > max_time_us then + if us_time() > us_time_limit then r.inform(name, rb.timed_out) break end From 401c6ae5f236d971022db57249ea62e453ffb708 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 4 Feb 2022 05:00:38 +0100 Subject: [PATCH 289/366] don't use datastructure for replacing multiple nodes Only use datastructure system when searching for nodes. When re/placing them, use table.sort to ensure that even time-outs don't leave behind weird patterns that then require more clean up and making players regret to have used replacer. Use easy to read vector.distance for sorting. Use faster repeat ... until loop. Only count nodes that actually changed. --- replacer/replacer.lua | 61 ++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 355a3c1..6f3cc4a 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -24,6 +24,7 @@ local has_creative = creative.is_enabled_for local serialize = minetest.serialize local us_time = minetest.get_us_time -- vector +local vector_distance = vector.distance local vector_multiply = vector.multiply local vector_new = vector.new local vector_subtract = vector.subtract @@ -451,46 +452,42 @@ function replacer.on_use(itemstack, player, pt, right_clicked) end end + -- sort by distance, nearest last as we work backwards + table.sort(found_positions, function(pos1, pos2) + return vector_distance(pos1, pos) > vector_distance(pos2, pos) + end) + -- set nodes - -- Turn found_positions into a binary heap - r.datastructures.create_binary_heap({ - input = found_positions, - n = possible_count, - compare = function(pos1, pos2) - -- Return true iff pos1 is nearer to the start position than pos2 - local n1 = (pos1.x - pos.x) ^ 2 + (pos1.y - pos.y) ^ 2 + - (pos1.z - pos.z) ^ 2 - local n2 = (pos2.x - pos.x) ^ 2 + (pos2.y - pos.y) ^ 2 + - (pos2.z - pos.z) ^ 2 - return n1 < n2 - end, - }) + local pos3 local actual_node_count = 0 - while not found_positions:is_empty() do - -- Take the position nearest to the start position - pos = found_positions:take() - node_old = core_get_node(pos) - adjust_new_to_minor() - succ, error = r.replace_single_node(pos, node_old, node_new, - player, name, inv, has_creative_or_give) - if not succ then - r.inform(name, error) - break - end - actual_node_count = actual_node_count + 1 - if actual_node_count > max_nodes then - -- This can happen if too many nodes were detected and the nodes - -- limit has been set to a small value - r.inform(name, rb.too_many_nodes_detected) - break - end local us_time_limit = us_time() + max_time_us + local index = found_count + repeat -- use fast repeat loop + pos3 = found_positions[index] + node_old = core_get_node(pos3) + -- only change nodes that need changing + if not adjust_new_to_minor() then + succ, error = r.replace_single_node(pos3, node_old, node_new, + player, name, inv, has_creative_or_give) + if not succ then + r.inform(name, error) + break + end + actual_node_count = actual_node_count + 1 + if actual_node_count > max_nodes then + -- This can happen if too many nodes were detected and the nodes + -- limit has been set to a small value + r.inform(name, rb.too_many_nodes_detected) + break + end + end -- if can't skip -- time-out check if us_time() > us_time_limit then r.inform(name, rb.timed_out) break end - end + index = index - 1 + until (0 == index) or (actual_node_count == possible_count) -- loop found nodes r.discharge(itemstack, charge, actual_node_count, has_creative_or_give) if has_creative_or_give then From 85fa432b216e39e14fef2f116583a2188d796167 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 4 Feb 2022 05:05:02 +0100 Subject: [PATCH 290/366] version bump 4.2 --- CHANGELOG | 7 +++++++ TODO | 24 ++++++++++++------------ init.lua | 4 ++-- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 75be0e3..2d61fe2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +20220204 * SwissalpS added tooltip to protection info as that often clipped. + * fixed the alias resolving to not change node_name. + * fixed group:food_pumpkin. + * dropped datastructure usage for final sorting as it left weird patterns + when time-outs were reached. Instead using clasic table.sort with vector.distance + comparisons. Also using faster repeat ... until loop. + * In field and crust mode only count nodes that were actually changed. 20220203 * SwissalpS fixed some issues: forced aliases, items that have no drops defined Added compat for buckets, canisters and beertap/mugs Fixed formspec for MT 5.5.0 (that now actually uses padding) diff --git a/TODO b/TODO index 86de76b..acefd8a 100644 --- a/TODO +++ b/TODO @@ -9,18 +9,12 @@ maybe we can use this on group buttons -- inspection tool: - figure out how to make the itemstring selectable for copy -> do that with new formspec version - add mixing method - add spawning, breading etc. info for mobs -> this sounds feasable for mobs_redo mobs. - add biofuel hints also general 'fuel' craft types -> if biofuel doesn't expose a list - this is also doomed (as I don't want to maintain lists) - add digging method for ores --> maybe not. Doing this dynamically seems overkill to - check every registered item to see if it drops the requested item - add info for seeds and saplings about planting -> this too seems like a task that will - include mainting a list of all plant types of any mod that adds them. Not my intention. - add info for plants telling when they are ripe -> allowing user to click on the ripe - stage and see possible seed drop -> showing info about planting. - don't forget wine:blue_agave when doing that + figure out how to make the itemstring selectable for copy -> do that with new formspec version + add mixing method + add spawning, breading etc. info for mobs -> this sounds feasable for mobs_redo mobs. + add info for plants telling when they are ripe -> allowing user to click on the ripe + stage and see possible seed drop -> showing info about planting. + don't forget wine:blue_agave when doing that -- known incompat replacer ------------------------ -- doors in general (low priority) @@ -86,4 +80,10 @@ bridger:corrugated_steelyellow -- will not implement -- add helper so when setting replacer to an itemframe that contains something, set to the contents --> but which param values? This isn't a good idea. + add biofuel hints also general 'fuel' craft types -> if biofuel doesn't expose a list + this is also doomed (as I don't want to maintain lists) + add digging method for ores --> maybe not. Doing this dynamically seems overkill to + check every registered item to see if it drops the requested item + add info for seeds and saplings about planting -> this too seems like a task that will + include mainting a list of all plant types of any mod that adds them. Not my intention. diff --git a/init.lua b/init.lua index 78adfbc..90d5bbb 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 4.1 (20220203) +-- Version 4.2 (20220204) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220203 +replacer.version = 20220204 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From 2f499bd5a6816ece257a8e9d46f0e0e6bb8cd577 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 4 Feb 2022 13:33:53 +0100 Subject: [PATCH 291/366] enable changing modes with place without pointing at a node previously on had to be pointing at a node when placing. When using it was already possible. --- README.md | 2 +- replacer/replacer.lua | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c152b3a..cdb7aab 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ This is true for users without "give" privs and also on servers not running in c # Modes (Major) -Special+Place on a node or Special+Use anywhere to change the mode.
+Special+Place or Special+Use anywhere to change the mode.
The first informs you in chat about the mode change while the second opens a formspec.
Single-mode does not need any charge. The other modes do.
For a description of the modes with pictures, refer to: diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 6f3cc4a..7487a96 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -687,6 +687,7 @@ function replacer.tool_def_basic() --node_placement_prediction = nil, -- place node(s) on_place = r.on_place, + on_secondary_use = r.on_place, -- Replace node(s) on_use = r.on_use } From f29a88e04544c152c4f0f5bd465a3c9544712dd7 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 4 Feb 2022 14:22:58 +0100 Subject: [PATCH 292/366] formspec tweaks for disabled minor modes --- replacer/formspecs.lua | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/replacer/formspecs.lua b/replacer/formspecs.lua index c54aaa0..9a83b09 100644 --- a/replacer/formspecs.lua +++ b/replacer/formspecs.lua @@ -15,18 +15,30 @@ function replacer.get_form_modes_4(player, mode) local major, minor = mode.major, mode.minor local name = player:get_player_name() local has_history_priv = check_player_privs(name, r.history_priv) - local form_dimensions = '5.375,4.25' + local form_dimensions = r.disable_minor_modes and '5.375,3.5' or '5.375,4.25' local button_height = '1' local button_single_dimensions = '.33,.77;2,' local button_field_dimensions = '2.9,.77;2,' local button_crust_dimensions = '1.44,2.1;2,' local minor_dimensions = '.38,3.42;4.5,.55' + local history_label_position, history_dropdown_position if has_history_priv then - form_dimensions = '8.375,4.39' button_single_dimensions = '0.33,0.77;2.3,' button_field_dimensions = '3.04,0.77;2.3,' button_crust_dimensions = '5.75,0.77;2.3,' - minor_dimensions = '1.88,2.12;4.5,0.60' + if r.disable_minor_modes then + form_dimensions = '8.375,3.39' + history_label_position = '0.33,2.22;' + history_dropdown_position = '0.38,2.55' + else + form_dimensions = '8.375,4.39' + button_single_dimensions = '0.33,0.77;2.3,' + button_field_dimensions = '3.04,0.77;2.3,' + button_crust_dimensions = '5.75,0.77;2.3,' + minor_dimensions = '1.88,2.12;4.5,0.60' + history_label_position = '0.33,3.22;' + history_dropdown_position = '0.38,3.55' + end end local tmp_name = '_' local formspec = 'formspec_version[4]' @@ -72,8 +84,8 @@ function replacer.get_form_modes_4(player, mode) if not has_history_priv then return formspec end - formspec = formspec .. 'label[0.33,3.22;' .. mfe(rb.choose_history) - .. ']dropdown[0.38,3.55;7.5,0.6;history;' + formspec = formspec .. 'label[' .. history_label_position .. mfe(rb.choose_history) + .. ']dropdown[' .. history_dropdown_position .. ';7.5,0.6;history;' local db = r.history.get_player_table(player) for _, data in ipairs(db) do if r.history_include_mode then From 4bf1a4d84ce380ddfe1c8bb20f0f511221a0bf45 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sat, 5 Feb 2022 02:20:50 +0100 Subject: [PATCH 293/366] locale substitution fix --- locale/replacer.de.tr | 3 ++- locale/replacer.es.tr | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index a2a7914..253abca 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -65,7 +65,7 @@ This is an entity "@1"=Das ist eine Entität „@1“ , dropped @1 minutes ago=, vor @1 Minuten gefallen by "@1"=von „@1“ with order to @1=mit Befehl zu „@1“ -Has @1 different types of items,=Hat %s verschiedene Arten von Gegenständen, +Has @1 different types of items,=Hat @1 verschiedene Arten von Gegenständen, total of @1 items in inventory.=insgesamt @1 Artikel im Inventar. This is an object "@1"=Dies ist ein „@1“ Objekt at @1=bei @1 @@ -99,3 +99,4 @@ separating=Trennen painting=Malen fermenting=Fermentieren Ferment in barrel.=Gärung im Fass. + diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index f16a642..71b3a9a 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -69,7 +69,7 @@ Has @1 different types of items,=Tiene @1 tipos diferentes de artículos, total of @1 items in inventory.=total de @1 artículos en inventario. This is an object "@1"=Este es un objeto "@1" at @1=en @1 -Sorry, this is an unkown something of type "@1". No information available.=Lo sentimos, esto es algo desconocido de tipo "%s". No hay información disponible. +Sorry, this is an unkown something of type "@1". No information available.=Lo sentimos, esto es algo desconocido de tipo "@1". No hay información disponible. Located at @1=Ubicado en @1 with param2 of @1=con param2 de @1 and receiving @1 light=y recibiendo @1 luz @@ -99,3 +99,4 @@ separating=separando painting=pintaando fermenting=fermentando Ferment in barrel.=Fermentación en barrica. + From 92cf0fabe8acf740b625169dfd44a386383fc94d Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 6 Feb 2022 05:37:04 +0100 Subject: [PATCH 294/366] more info on mobs --- TODO | 3 +- blabla.lua | 10 ++ inspect.lua | 344 ++++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 276 insertions(+), 81 deletions(-) diff --git a/TODO b/TODO index acefd8a..ccce8dd 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,6 @@ -- inspection tool: figure out how to make the itemstring selectable for copy -> do that with new formspec version add mixing method - add spawning, breading etc. info for mobs -> this sounds feasable for mobs_redo mobs. add info for plants telling when they are ripe -> allowing user to click on the ripe stage and see possible seed drop -> showing info about planting. don't forget wine:blue_agave when doing that @@ -79,7 +78,7 @@ bridger:corrugated_steelyellow -- will not implement -- add helper so when setting replacer to an itemframe that contains something, - set to the contents --> but which param values? This isn't a good idea. + set to the contents --> but which param values? This isn't a good idea. add biofuel hints also general 'fuel' craft types -> if biofuel doesn't expose a list this is also doomed (as I don't want to maintain lists) add digging method for ores --> maybe not. Doing this dynamically seems overkill to diff --git a/blabla.lua b/blabla.lua index a9a30c9..b126a5b 100644 --- a/blabla.lua +++ b/blabla.lua @@ -103,4 +103,14 @@ rbi.log_reg_craft_method_added = '[replacer] register_craft_method method added: rbi.scoop = S('scoop up') rbi.pour = S('pour out') rbi.filling = S('filling') +rbi.mobs_disclaimer = S('(Functions may exist that change attributes and conditions of mobs)') +rbi.mobs_of_type = S('Is of type') +rbi.mobs_loyal = S('Is loyal to owner.') +rbi.mobs_attacks = S('Likes to attack:') +rbi.mobs_follows = S('Follows players holding:') +rbi.mobs_drops = S('May drop:') +rbi.mobs_shoots = S('Can shoot misiles.') +rbi.mobs_breed = S('Can breed.') +rbi.mobs_spawns_on = S('Spawns on:') +rbi.mobs_spawns_neighbours = S('with neighours:') diff --git a/inspect.lua b/inspect.lua index ef9df48..ac7fdc9 100644 --- a/inspect.lua +++ b/inspect.lua @@ -80,85 +80,7 @@ function replacer.inspect(_, player, pointed_thing, right_clicked) local player_name = player:get_player_name() if 'object' == pointed_thing.type then - local inventory_text = nil - local text - local object_ref = pointed_thing.ref - if not object_ref then - text = rbi.broken_object - elseif object_ref:is_player() then - text = S('This is your fellow player "@1"', object_ref:get_player_name()) - else - local luaob = object_ref:get_luaentity() - if luaob and luaob.get_staticdata then - text = S('This is an entity "@1"', luaob.name) - local sdata = luaob:get_staticdata() - if 0 < #sdata then - sdata = minetest.deserialize(sdata) or {} - if sdata.itemstring then - text = text .. ' [' .. sdata.itemstring .. ']' - local show_recipe = false - if show_recipe then - -- the fields part is used here to provide - -- additional information about the entity - r.inspect_show_crafting( - player_name, - sdata.itemstring, - { luaob = luaob }) - end - end - if sdata.age then - text = text .. S(', dropped @1 minutes ago', - tostring(floor((sdata.age / 60) + .5))) - end - if sdata.owner then - if true == sdata.protected then - if true == sdata.locked then - text = text .. ' ' .. rbi.owned_protected_locked - else - text = text .. ' ' .. rbi.owned_protected - end - else - if true == sdata.locked then - text = text .. ' ' .. rbi.owned_locked - end - end - text = text .. ' ' .. S('by "@1"', sdata.owner) - end - if 'string' == type(sdata.order) then - text = text .. ' ' .. S('with order to @1', sdata.order) - end - if 'table' == type(sdata.inv) then - local item_count = 0 - local type_count = 0 - for _, v in pairs(sdata.inv) do - type_count = type_count + 1 - item_count = item_count + v - end - if 0 < type_count then - inventory_text = '\n' - if 1 < type_count then - inventory_text = inventory_text - .. S('Has @1 different types of items,', - tostring(type_count)) .. ' ' - end - inventory_text = inventory_text - .. S('total of @1 items in inventory.', - tostring(item_count)) - end - end - end - elseif luaob then - text = S('This is an object "@1"', luaob.name) - else - text = rbi.this_is_object - end - - end - if object_ref then - text = text .. ' ' .. S('at @1', nice_pos_string(object_ref:getpos())) - end - if inventory_text then text = text .. inventory_text end - chat(player_name, text) + chat(player_name, r.inspect_entity(pointed_thing.ref)) return nil elseif 'node' ~= pointed_thing.type then chat(player_name, S('Sorry, this is an unkown something of type "@1". ' @@ -211,6 +133,270 @@ function replacer.inspect(_, player, pointed_thing, right_clicked) end -- replacer.inspect +-- bug work around to prevent using inspection tool as a weapon +local function is_endangered(luaob) + if not luaob._cmi_is_mob then return false end + if not minetest.registered_entities[luaob.name] then return false end + + return '' == luaob.owner +end -- is_endangered + + +-- helper for inspect_entity()/inspect_mob() +local function is_registered(item_name_or_group) + if 'string' ~= type(item_name_or_group) then return false end + if item_name_or_group:find('^:?group:') then return true end + return minetest.registered_items[item_name_or_group] and true or false +end + +function replacer.inspect_mob(luaob) + + local index, list + local entity_def = minetest.registered_entities[luaob.name] + local text = '\n' + if 'string' == type(entity_def.type) then + text = text .. rbi.mobs_of_type .. ' "' .. entity_def.type .. '". ' + end + if entity_def.owner_loyal then + text = text .. rbi.mobs_loyal .. ' ' + end +--[[ these are too inacurate. + if entity_def.attack_players then + text = text .. 'Can attack players. ' + end + if entity_def.attack_animals then + text = text .. 'Can attack animals. ' + end + if entity_def.attack_monsters then + text = text .. 'Can attack monsters. ' + end + if entity_def.attack_npcs then + text = text .. 'Can attack NPCs. ' + end +--]] + if 'table' == type(entity_def.specific_attack) then + list, index = {}, #entity_def.specific_attack + if 0 < index then repeat + if is_registered(entity_def.specific_attack[index]) then + list[#list + 1] = entity_def.specific_attack[index] + end + index = index - 1 + until 0 == index + if 0 < #list then + text = text .. rbi.mobs_attacks .. ' ' + .. table.concat(list, ', ') .. '\n' + end end + end + if 'table' == type(entity_def.follow) then + list, index = {}, #entity_def.follow + if 0 < index then repeat + if is_registered(entity_def.follow[index]) then + list[#list + 1] = entity_def.follow[index] + end + index = index - 1 + until 0 >= index + if 0 < #list then + text = text .. rbi.mobs_follows .. ' ' + .. table.concat(list, ', ') .. '\n' + end end + end + if 'table' == type(entity_def.drops) then + list, index = {}, #entity_def.drops + if 0 < index then repeat + if 'table' == type(entity_def.drops[index]) + and is_registered(entity_def.drops[index].name) + then + list[#list + 1] = entity_def.drops[index].name + end + index = index - 1 + until 0 >= index + if 0 < #list then + text = text .. rbi.mobs_drops .. ' ' + .. table.concat(list, ', ') .. '\n' + end end + end + if 'number' == type(entity_def.damage) and 0 < entity_def.damage then + text = text .. S('Can deal @1 damage. ', entity_def.damage) + end + if 'number' == type(entity_def.armor) and 0 < entity_def.armor then + text = text .. S('Has @1 armour. ', entity_def.armor) + end + if entity_def.arrow then + text = text .. rbi.mobs_shoots .. ' ' + end + -- some mobs could still be breedable without these two fields + if 'function' == type(entity_def.on_breed) or entity_def.child_texture then + text = text .. rbi.mobs_breed .. ' ' + end +--[[ some of these might be of interest too +reach +immune_to +light_damage +light_damage_min +light_damage_max +water_damage +lava_damage +fire_damage +air_damage +suffocation +stay_near +hp_min +hp_max +jump +jump_height +fear_height +fly +fly_in +floats +glow +passive +attack_type +docile_by_day +group_attack +group_helper +runaway +runaway_from +view_range +--]] + -- investigate spawning conditions (nodes and neighours) + local found, entry, j + local search_string = luaob.name .. ' spawning' + index = #minetest.registered_abms + if 0 < index then repeat + entry = minetest.registered_abms[index] + if entry.label and search_string == entry.label then + found = true + list, j = {}, #entry.nodenames + if 0 < j then repeat + if is_registered(entry.nodenames[j]) then + list[#list + 1] = entry.nodenames[j] + end + j = j - 1 + until 0 == j + if 0 < #list then + text = text .. '\n' .. rbi.mobs_spawns_on .. ' ' .. table.concat(list, ', ') + end end + list, j = {}, #entry.neighbors + if 0 < j then repeat + if is_registered(entry.neighbors[j]) then + list[#list + 1] = entry.neighbors[j] + end + j = j - 1 + until 0 == j + if 0 < #list then + text = text .. ' ' .. rbi.mobs_spawns_neighbours .. ' ' + .. table.concat(list, ', ') + end end + end + index = index - 1 + until (0 == index) or found end + if not found then + search_string = luaob.name .. '_spawning' + index = #minetest.registered_lbms + if 0 < index then repeat + entry = minetest.registered_lbms[index] + if entry.name and search_string == entry.name then + found = true + list, j = {}, #entry.nodenames + if 0 < j then repeat + if is_registered(entry.nodenames[j]) then + list[#list + 1] = entry.nodenames[j] + end + j = j - 1 + until 0 == j + if 0 < #list then + text = text .. '\n' .. rbi.mobs_spawns_on .. ' ' .. table.concat(list, ', ') + end end + end + index = index - 1 + until (0 == index) or found end + end + return text +end -- inspect_mob + + +function replacer.inspect_entity(object_ref) + if not object_ref then return rbi.broken_object end + + local pos_string = S('at @1', nice_pos_string(object_ref:getpos())) + if object_ref:is_player() then + return S('This is your fellow player "@1"', object_ref:get_player_name()) + .. ' ' .. pos_string + end + + local luaob = object_ref:get_luaentity() + if not luaob then return rbi.this_is_object .. ' ' .. pos_string end + + if (not luaob.get_staticdata) and (not minetest.registered_entities[luaob.name]) then + return S('This is an object "@1"', luaob.name) .. ' ' .. pos_string + end + + local text = (luaob._cmi_is_mob and rbi.mobs_disclaimer .. '\n' or '') + .. S('This is an entity "@1"', luaob.name) + if luaob.get_staticdata and not is_endangered(luaob) then + text = text .. r.inspect_staticdata(luaob:get_staticdata()) + end + if not minetest.registered_entities[luaob.name] then return text end + + if luaob._cmi_is_mob then return text .. r.inspect_mob(luaob) end + + return text +end -- inspect_entity + + +function replacer.inspect_staticdata(staticdata) + if (not staticdata) or (0 == #staticdata) then return '' end + + local text = '' + local sdata = minetest.deserialize(staticdata) or {} + if sdata.itemstring then + text = text .. ' [' .. sdata.itemstring .. ']' + end + if sdata.age then + text = text .. S(', dropped @1 minutes ago', + tostring(floor((sdata.age / 60) + .5))) + end + if sdata.owner then + if true == sdata.protected then + if true == sdata.locked then + text = text .. ' ' .. rbi.owned_protected_locked + else + text = text .. ' ' .. rbi.owned_protected + end + else + if true == sdata.locked then + text = text .. ' ' .. rbi.owned_locked + end + end + text = text .. ' ' .. S('by "@1"', sdata.owner) + end + if 'table' == type(sdata.follow) and 0 < #sdata.follow then + text = text .. ' is tamable' + end + if 'string' == type(sdata.order) then + text = text .. ' ' .. S('with order to @1', sdata.order) + end + if 'table' == type(sdata.inv) then + local item_count = 0 + local type_count = 0 + for _, v in pairs(sdata.inv) do + type_count = type_count + 1 + item_count = item_count + v + end + if 0 < type_count then + text = text .. '\n' + if 1 < type_count then + text = text .. S('Has @1 different types of items,', + tostring(type_count)) .. ' ' + end + text = text .. S('total of @1 items in inventory.', + tostring(item_count)) + end + end + return text +end -- inspect_staticdata + + function replacer.image_button_link(stack_string) local group = '' if r.image_replacements[stack_string] then From 224cf511ba74a5902626829a9043b72ef900ca02 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 6 Feb 2022 06:18:22 +0100 Subject: [PATCH 295/366] locale updates --- inspect.lua | 4 ++-- locale/replacer.de.tr | 19 +++++++++++++++---- locale/replacer.es.tr | 19 +++++++++++++++---- locale/replacer.fi.tr | 18 +++++++++++++++--- locale/replacer.fr.tr | 18 +++++++++++++++--- locale/replacer.it.tr | 18 +++++++++++++++--- locale/replacer.pt.tr | 18 +++++++++++++++--- locale/replacer.ru.tr | 18 +++++++++++++++--- locale/template.txt | 18 +++++++++++++++--- 9 files changed, 122 insertions(+), 28 deletions(-) diff --git a/inspect.lua b/inspect.lua index ac7fdc9..3bb0f14 100644 --- a/inspect.lua +++ b/inspect.lua @@ -216,10 +216,10 @@ function replacer.inspect_mob(luaob) end end end if 'number' == type(entity_def.damage) and 0 < entity_def.damage then - text = text .. S('Can deal @1 damage. ', entity_def.damage) + text = text .. S('Can deal @1 damage.', entity_def.damage) .. ' ' end if 'number' == type(entity_def.armor) and 0 < entity_def.armor then - text = text .. S('Has @1 armour. ', entity_def.armor) + text = text .. S('Has @1 armour.', entity_def.armor) .. ' ' end if entity_def.arrow then text = text .. rbi.mobs_shoots .. ' ' diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index 253abca..a66f7eb 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -55,21 +55,33 @@ Error: Unkown recipe.=Fehler: Unbekanntes Rezept. scoop up=schöpfen pour out=ausgiessen filling=auffüllen +(Functions may exist that change attributes and conditions of mobs)=(Möglicherweise gibt es Funktionen, die Attribute und Zustände von Mobs ändern) +Is of type=Ist vom Typ +Is loyal to owner.=Ist dem Besitzer treu. +Likes to attack:=Greift gerne an: +Follows players holding:=Folgt Spielern mit: +May drop:=Kann fallen lassen: +Can shoot misiles.=Kann schiessen. +Can breed.=Kann gezüchtet werden. +Spawns on:=Erscheinen auf: +with neighours:=mit Nachbarn: fermenting/pickling=Gären Store near group:wood, light < 12.=In der Nähe der Holzgruppe@n(group:wood) lagern, Licht < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Node des Typs „@1“ dürfen auf diesem Server nicht ersetzt werden. Versuch fehlgeschlagen. Protected at @1=Geschützt bei @1 printing=Drucken +Sorry, this is an unkown something of type "@1". No information available.=Tut mir leid, das ist etwas unbekanntes vom Typ „@1“. Keine Informationen verfügbar. +Can deal @1 damage.=Kann @1 Schaden verursachen. +Has @1 armour.=Hat @1 Rüstung. +at @1=bei @1 This is your fellow player "@1"=Dies ist dein Mitspieler „@1“ +This is an object "@1"=Dies ist ein „@1“ Objekt This is an entity "@1"=Das ist eine Entität „@1“ , dropped @1 minutes ago=, vor @1 Minuten gefallen by "@1"=von „@1“ with order to @1=mit Befehl zu „@1“ Has @1 different types of items,=Hat @1 verschiedene Arten von Gegenständen, total of @1 items in inventory.=insgesamt @1 Artikel im Inventar. -This is an object "@1"=Dies ist ein „@1“ Objekt -at @1=bei @1 -Sorry, this is an unkown something of type "@1". No information available.=Tut mir leid, das ist etwas unbekanntes vom Typ „@1“. Keine Informationen verfügbar. Located at @1=Befindet sich bei @1 with param2 of @1=mit param2 von @1 and receiving @1 light=und empfängt @1 licht @@ -99,4 +111,3 @@ separating=Trennen painting=Malen fermenting=Fermentieren Ferment in barrel.=Gärung im Fass. - diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 71b3a9a..2091cbe 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -55,21 +55,33 @@ Error: Unkown recipe.=Error: Receta desconocida. scoop up=recoger pour out=derramar filling=llena +(Functions may exist that change attributes and conditions of mobs)=(Pueden existir funciones que cambien los atributos y condiciones de los mobs) +Is of type=es de tipo +Is loyal to owner.=Es leal al dueño. +Likes to attack:=Le gusta atacar: +Follows players holding:=Sigue a los jugadores que tienen: +May drop:=Puede caer: +Can shoot misiles.=Puede disparar misiles. +Can breed.=Puede reproducirse. +Spawns on:=Aparece en: +with neighours:=con vecinos: fermenting/pickling=fermentación/decapado Store near group:wood, light < 12.=Almacenar cerca del grupo de madera@n(group:wood), luz < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=No se permite reemplazar nodos de tipo "@1" en este servidor. Reemplazo fallido. Protected at @1=Protegido en @1 printing=impresión +Sorry, this is an unkown something of type "@1". No information available.=Lo sentimos, esto es algo desconocido de tipo "@1". No hay información disponible. +Can deal @1 damage.=Puede causar daño @1. +Has @1 armour.=Tiene armadura @1. +at @1=en @1 This is your fellow player "@1"=Este es tu compañero de juego "@1" +This is an object "@1"=Este es un objeto "@1" This is an entity "@1"=Esta es una entidad "@1" , dropped @1 minutes ago=, caído hace @1 minutos by "@1"=por "@1" with order to @1=con pedido a "@1" Has @1 different types of items,=Tiene @1 tipos diferentes de artículos, total of @1 items in inventory.=total de @1 artículos en inventario. -This is an object "@1"=Este es un objeto "@1" -at @1=en @1 -Sorry, this is an unkown something of type "@1". No information available.=Lo sentimos, esto es algo desconocido de tipo "@1". No hay información disponible. Located at @1=Ubicado en @1 with param2 of @1=con param2 de @1 and receiving @1 light=y recibiendo @1 luz @@ -99,4 +111,3 @@ separating=separando painting=pintaando fermenting=fermentando Ferment in barrel.=Fermentación en barrica. - diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index f6ae49b..bd1caaf 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -55,21 +55,33 @@ Error: Unkown recipe.=Virhe: Tuntematon resepti. scoop up=kauhoa pour out=kaataa filling=täyttää +(Functions may exist that change attributes and conditions of mobs)=(Voi olla toimintoja, jotka muuttavat väkijoukon ominaisuuksia ja ehtoja) +Is of type=On tyyppiä +Is loyal to owner.=On lojaali omistajalleen. +Likes to attack:=Tykkää hyökätä: +Follows players holding:=Seuraa pelaajia, joilla on: +May drop:=Saattaa pudota: +Can shoot misiles.=Osaa ampua ohjuksia. +Can breed.=Voi lisääntyä. +Spawns on:=Syntyy: +with neighours:=naapureiden kanssa: fermenting/pickling=käyminen/peittaus Store near group:wood, light < 12.=Varasto lähellä group:wood,@nkevyt < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Tyypin "@1" solmujen korvaaminen ei ole sallittua tässä palvelimessa. Vaihto epäonnistui. Protected at @1=Suojattu @1 printing=painatus +Sorry, this is an unkown something of type "@1". No information available.=Anteeksi, tämä on tuntematon asia, jonka tyyppi on "@1". Tietoja ei ole saatavilla. +Can deal @1 damage.=Voi tehdä @1 vahinkoa. +Has @1 armour.=Siinä on @1-panssari. +at @1=osoitteessa @1 This is your fellow player "@1"=Tämä on pelikaverisi "@1" +This is an object "@1"=Tämä on objekti "@1" This is an entity "@1"=Tämä on entiteetti "@1" , dropped @1 minutes ago=, pudonnut @1 minuuttia sitten by "@1"=kirjoittaja "@1" with order to @1=tilauksella "@1" Has @1 different types of items,=Sisältää @1 erityyppistä tuotetta, total of @1 items in inventory.=yhteensä @1 tuotetta varastossa. -This is an object "@1"=Tämä on objekti "@1" -at @1=osoitteessa @1 -Sorry, this is an unkown something of type "@1". No information available.=Anteeksi, tämä on tuntematon asia, jonka tyyppi on "@1". Tietoja ei ole saatavilla. Located at @1=Sijaitsee @1 with param2 of @1=param2 @1 and receiving @1 light=ja vastaanottaa @1 valoa diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index 281797f..e5e44da 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -55,21 +55,33 @@ Error: Unkown recipe.=Erreur : recette inconnue. scoop up=ramasser pour out=déverser filling=remplir +(Functions may exist that change attributes and conditions of mobs)=(Des fonctions peuvent exister qui modifient les attributs et les conditions des monstres) +Is of type=Est de type +Is loyal to owner.=Est fidèle au propriétaire. +Likes to attack:=Aime attaquer : +Follows players holding:=Suit les joueurs détenant : +May drop:=Peut baisser : +Can shoot misiles.=Peut tirer des missiles. +Can breed.=Peut se reproduire. +Spawns on:=Apparaît sur : +with neighours:=avec des voisins : fermenting/pickling=fermentation/marinage Store near group:wood, light < 12.=Entreposer près du groupe @ngroup:wood, lumière < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Le remplacement de nœuds de type "@1" n'est pas autorisé sur ce serveur. Échec du remplacement. Protected at @1=Protégé à @1 printing=impression +Sorry, this is an unkown something of type "@1". No information available.=Désolé, c'est quelque chose d'inconnu de type "@1". Aucune information disponible. +Can deal @1 damage.=Peut infliger @1 dégâts. +Has @1 armour.=A @1 armure. +at @1=à @1 This is your fellow player "@1"=C'est votre coéquipier "@1" +This is an object "@1"=Ceci est un objet "@1" This is an entity "@1"=Ceci est une entité "@1" , dropped @1 minutes ago=, déposé il y a @1 minutes by "@1"=par "@1" with order to @1=avec l'ordre de "@1" Has @1 different types of items,=A @1 différents types d'éléments, total of @1 items in inventory.=total de @1 articles dans l'inventaire. -This is an object "@1"=Ceci est un objet "@1" -at @1=à @1 -Sorry, this is an unkown something of type "@1". No information available.=Désolé, c'est quelque chose d'inconnu de type "@1". Aucune information disponible. Located at @1=Situé à @1 with param2 of @1=avec param2 de @1 and receiving @1 light=et recevant @1 lumière diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index 0af471e..60cfb3f 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -55,21 +55,33 @@ Error: Unkown recipe.=Errore: ricetta sconosciuta. scoop up=raccogliere pour out=versare filling=riempire +(Functions may exist that change attributes and conditions of mobs)=(Potrebbero esistere funzioni che modificano gli attributi e le condizioni dei mob) +Is of type=È di tipo +Is loyal to owner.=È fedele al proprietario. +Likes to attack:=Ama attaccare: +Follows players holding:=Segue i giocatori che tengono: +May drop:=Può cadere: +Can shoot misiles.=Può sparare missili. +Can breed.=Può riprodursi. +Spawns on:=Genera su: +with neighours:=con i vicini: fermenting/pickling=fermentazione/decapaggio Store near group:wood, light < 12.=Negozio vicino al gruppo group:wood,@nluce < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=La sostituzione dei nodi di tipo "@1" non è consentita su questo server. Sostituzione non riuscita. Protected at @1=Protetto a @1 printing=stampa +Sorry, this is an unkown something of type "@1". No information available.=Siamo spiacenti, questo è un qualcosa sconosciuto di tipo "@1". Nessuna informazione disponibile. +Can deal @1 damage.=Può infliggere @1 danno. +Has @1 armour.=Ha @1 armatura. +at @1=alle @1 This is your fellow player "@1"=Questo è il tuo compagno di gioco "@1" +This is an object "@1"=Questo è un oggetto "@1" This is an entity "@1"=Questa è un'entità "@1" , dropped @1 minutes ago=, caduto @1 minuti fa by "@1"=per "@1" with order to @1=con ordine a "@1" Has @1 different types of items,=Ha @1 diversi tipi di elementi, total of @1 items in inventory.=totale di @1 articoli nell'inventario. -This is an object "@1"=Questo è un oggetto "@1" -at @1=alle @1 -Sorry, this is an unkown something of type "@1". No information available.=Siamo spiacenti, questo è un qualcosa sconosciuto di tipo "@1". Nessuna informazione disponibile. Located at @1=Situato a @1 with param2 of @1=con param2 di @1 and receiving @1 light=e ricevendo @1 luce diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index bdf8fde..ae4d265 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -55,21 +55,33 @@ Error: Unkown recipe.=Erro: receita desconhecida. scoop up=escavar pour out=derramar filling=encher +(Functions may exist that change attributes and conditions of mobs)=(Podem existir funções que alteram atributos e condições dos mobs) +Is of type=É do tipo +Is loyal to owner.=É leal ao dono. +Likes to attack:=Gosta de atacar: +Follows players holding:=Segue jogadores segurando: +May drop:=Pode cair: +Can shoot misiles.=Pode disparar mísseis. +Can breed.=Pode procriar. +Spawns on:=Gera em: +with neighours:=com vizinhos: fermenting/pickling=fermentação/decapagem Store near group:wood, light < 12.=Armazenar perto do grupo group:wood,@nluz < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=A substituição de nós do tipo "@1" não é permitida neste servidor. Falha na substituição. Protected at @1=Protegido em @1 printing=impressão +Sorry, this is an unkown something of type "@1". No information available.=Desculpe, isso é algo desconhecido do tipo "@1". Nenhuma informação disponível. +Can deal @1 damage.=Pode causar @1 de dano. +Has @1 armour.=Tem armadura @1. +at @1=em @1 This is your fellow player "@1"=Este é seu colega jogador "@1" +This is an object "@1"=Este é um objeto "@1" This is an entity "@1"=Esta é uma entidade "@1" , dropped @1 minutes ago=, caiu @1 minutos atrás by "@1"=por "@1" with order to @1=com ordem para "@1" Has @1 different types of items,=Tem @1 tipos diferentes de itens, total of @1 items in inventory.=total de @1 itens no inventário. -This is an object "@1"=Este é um objeto "@1" -at @1=em @1 -Sorry, this is an unkown something of type "@1". No information available.=Desculpe, isso é algo desconhecido do tipo "@1". Nenhuma informação disponível. Located at @1=Localizado em @1 with param2 of @1=com param2 de @1 and receiving @1 light=e recebendo @1 luz diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index 90cc09b..cb8627b 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -55,21 +55,33 @@ Error: Unkown recipe.=Ошибка: Неизвестный рецепт. scoop up=зачерпнуть pour out=вылить filling=заполнить +(Functions may exist that change attributes and conditions of mobs)=(Могут существовать функции, изменяющие атрибуты и состояния мобов) +Is of type=Типа +Is loyal to owner.=Верен хозяину. +Likes to attack:=Любит атаковать: +Follows players holding:=Следует за игроками, держащими: +May drop:=Может выпасть: +Can shoot misiles.=Может стрелять ракетами. +Can breed.=Может размножаться. +Spawns on:=Появляется на: +with neighours:=с соседями: fermenting/pickling=ферментация/маринование Store near group:wood, light < 12.=Хранить рядом с группой дерево@n(group:wood), свет < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Замена узлов типа "@1" на этом сервере запрещена. Замена не удалась. Protected at @1=Защищено в @1 printing=печать +Sorry, this is an unkown something of type "@1". No information available.=Извините, это неизвестное что-то типа "@1". Информация отсутствует. +Can deal @1 damage.=Может нанести @1 урона. +Has @1 armour.=Имеет @1 броню. +at @1=в @1 This is your fellow player "@1"=Это ваш товарищ по игре "@1" +This is an object "@1"=Это объект "@1" This is an entity "@1"=Это сущность "@1" , dropped @1 minutes ago=, выпало @1 минут назад by "@1"=по "@1" with order to @1=с заказом на "@1" Has @1 different types of items,=Имеет @1 различных типов предметов, total of @1 items in inventory.=всего @1 предметов в инвентаре. -This is an object "@1"=Это объект "@1" -at @1=в @1 -Sorry, this is an unkown something of type "@1". No information available.=Извините, это неизвестное что-то типа "@1". Информация отсутствует. Located at @1=Находится по адресу @1 with param2 of @1=с параметром2 из @1 and receiving @1 light=и получаю @1 свет diff --git a/locale/template.txt b/locale/template.txt index e9c2dd1..635cf6b 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -55,21 +55,33 @@ Error: Unkown recipe.= scoop up= pour out= filling= +(Functions may exist that change attributes and conditions of mobs)= +Is of type= +Is loyal to owner.= +Likes to attack:= +Follows players holding:= +May drop:= +Can shoot misiles.= +Can breed.= +Spawns on:= +with neighours:= fermenting/pickling= Store near group:wood, light < 12.= Replacing nodes of type "@1" is not allowed on this server. Replacement failed.= Protected at @1= printing= +Sorry, this is an unkown something of type "@1". No information available.= +Can deal @1 damage.= +Has @1 armour.= +at @1= This is your fellow player "@1"= +This is an object "@1"= This is an entity "@1"= , dropped @1 minutes ago= by "@1"= with order to @1= Has @1 different types of items,= total of @1 items in inventory.= -This is an object "@1"= -at @1= -Sorry, this is an unkown something of type "@1". No information available.= Located at @1= with param2 of @1= and receiving @1 light= From c16e883e8b8e85ddd3cdf2f97d78f48e8479a1bf Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 6 Feb 2022 06:31:20 +0100 Subject: [PATCH 296/366] version bump 4.3 --- CHANGELOG | 3 +++ init.lua | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 2d61fe2..10479b6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +20220205 * SwissalpS tweaked formspec of replacer to adjust when minor modes are disabled. + * Enabled changing modes with place without pointing at a node. + * Added more info on mobs. 20220204 * SwissalpS added tooltip to protection info as that often clipped. * fixed the alias resolving to not change node_name. * fixed group:food_pumpkin. diff --git a/init.lua b/init.lua index 90d5bbb..03aeffa 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 4.2 (20220204) +-- Version 4.3 (20220205) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220204 +replacer.version = 20220205 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From 2e9e7ffd460449fef16ab7866beea7e6abf0e1cb Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 10 Feb 2022 20:16:39 +0100 Subject: [PATCH 297/366] more local references --- inspect.lua | 122 +++++++++++++++++++++++++++++----------------------- utils.lua | 22 ++++++---- 2 files changed, 83 insertions(+), 61 deletions(-) diff --git a/inspect.lua b/inspect.lua index 3bb0f14..d2bc3a8 100644 --- a/inspect.lua +++ b/inspect.lua @@ -13,8 +13,27 @@ local nice_pos_string = replacer.nice_pos_string local S = replacer.S local floor = math.floor local max, min = math.max, math.min +local concat = table.concat +local insert = table.insert local chat = minetest.chat_send_player local mfe = minetest.formspec_escape +local core_log = minetest.log +local deserialize = minetest.deserialize +local parse_json = minetest.parse_json +local get_node_or_nil = minetest.get_node_or_nil +local get_node_light = minetest.get_node_light +local get_pointed_thing_position = minetest.get_pointed_thing_position +local get_all_craft_recipes = minetest.get_all_craft_recipes +local is_protected = minetest.is_protected +local show_formspec = minetest.show_formspec +local registered_abms = minetest.registered_abms +local registered_lbms = minetest.registered_lbms +local registered_aliases = minetest.registered_aliases +local registered_tools = minetest.registered_tools +local registered_nodes = minetest.registered_nodes +local registered_items = minetest.registered_items +local registered_entities = minetest.registered_entities +local registered_craftitems = minetest.registered_craftitems -- luacheck: push ignore unused pd local pd = r.print_dump -- luacheck: pop @@ -35,15 +54,15 @@ function replacer.register_craft_method(uid, machine_itemstring, func_inspect, func_formspec) if ('string' ~= type(uid) or '' == uid) or ('string' ~= type(machine_itemstring) - or not minetest.registered_items[machine_itemstring]) + or not registered_items[machine_itemstring]) or 'function' ~= type(func_inspect) then - minetest.log('warning', rbi.log_reg_craft_method_wrong_arguments) + core_log('warning', rbi.log_reg_craft_method_wrong_arguments) return end if r.recipe_adders[uid] then - minetest.log('warning', rbi.log_reg_craft_method_overriding_method .. uid) + core_log('warning', rbi.log_reg_craft_method_overriding_method .. uid) end r.recipe_adders[uid] = { @@ -51,7 +70,7 @@ function replacer.register_craft_method(uid, machine_itemstring, func_inspect, add_recipe = func_inspect, formspec = ('function' == type(func_formspec) and func_formspec) or nil } - minetest.log('info', rbi.log_reg_craft_method_added:format(uid, machine_itemstring)) + core_log('info', rbi.log_reg_craft_method_added:format(uid, machine_itemstring)) end -- register_craft_method @@ -64,11 +83,11 @@ minetest.register_tool('replacer:inspect', { liquids_pointable = true, -- it is ok to request information about liquids on_use = function(itemstack, player, pointed_thing) - return replacer.inspect(itemstack, player, pointed_thing) + return r.inspect(itemstack, player, pointed_thing) end, on_place = function(itemstack, player, pointed_thing) - return replacer.inspect(itemstack, player, pointed_thing, true) + return r.inspect(itemstack, player, pointed_thing, true) end, }) @@ -80,7 +99,7 @@ function replacer.inspect(_, player, pointed_thing, right_clicked) local player_name = player:get_player_name() if 'object' == pointed_thing.type then - chat(player_name, r.inspect_entity(pointed_thing.ref)) + chat(player_name, r.inspect_entity(pointed_thing.ref, player)) return nil elseif 'node' ~= pointed_thing.type then chat(player_name, S('Sorry, this is an unkown something of type "@1". ' @@ -88,8 +107,8 @@ function replacer.inspect(_, player, pointed_thing, right_clicked) return nil end - local pos = minetest.get_pointed_thing_position(pointed_thing, right_clicked) - local node = minetest.get_node_or_nil(pos) + local pos = get_pointed_thing_position(pointed_thing, right_clicked) + local node = get_node_or_nil(pos) if not node then chat(player_name, rb.wait_for_load) return nil @@ -105,21 +124,21 @@ function replacer.inspect(_, player, pointed_thing, right_clicked) ui.current_craft_direction[player_name] = 'recipe'-- keys.x and 'usage' or 'recipe' ui.current_searchbox[player_name] = node.name ui.apply_filter(player, node.name, 'recipe')--'usage' --nochange') - minetest.show_formspec(player_name, '', ui.get_formspec(player, 'craftguide')) + show_formspec(player_name, '', ui.get_formspec(player, 'craftguide')) return end end ---pd(node, minetest.registered_nodes[node.name].mod_origin) +--pd(node, registered_nodes[node.name].mod_origin) local protected_info = '' - if minetest.is_protected(pos, player_name) then + if is_protected(pos, player_name) then protected_info = rbi.is_protected - elseif minetest.is_protected(pos, '_THIS_NAME_DOES_NOT_EXIST_') then + elseif is_protected(pos, '_THIS_NAME_DOES_NOT_EXIST_') then protected_info = rbi.you_can_dig end -- get light of the node at the current time - local light = minetest.get_node_light(pos, nil) + local light = get_node_light(pos, nil) -- the fields part is used here to provide additional -- information about the node r.inspect_show_crafting(player_name, node.name, { @@ -136,7 +155,7 @@ end -- replacer.inspect -- bug work around to prevent using inspection tool as a weapon local function is_endangered(luaob) if not luaob._cmi_is_mob then return false end - if not minetest.registered_entities[luaob.name] then return false end + if not registered_entities[luaob.name] then return false end return '' == luaob.owner end -- is_endangered @@ -146,13 +165,13 @@ end -- is_endangered local function is_registered(item_name_or_group) if 'string' ~= type(item_name_or_group) then return false end if item_name_or_group:find('^:?group:') then return true end - return minetest.registered_items[item_name_or_group] and true or false + return registered_items[item_name_or_group] and true or false end function replacer.inspect_mob(luaob) local index, list - local entity_def = minetest.registered_entities[luaob.name] + local entity_def = registered_entities[luaob.name] local text = '\n' if 'string' == type(entity_def.type) then text = text .. rbi.mobs_of_type .. ' "' .. entity_def.type .. '". ' @@ -183,8 +202,7 @@ function replacer.inspect_mob(luaob) index = index - 1 until 0 == index if 0 < #list then - text = text .. rbi.mobs_attacks .. ' ' - .. table.concat(list, ', ') .. '\n' + text = text .. rbi.mobs_attacks .. ' ' .. concat(list, ', ') .. '\n' end end end if 'table' == type(entity_def.follow) then @@ -196,8 +214,7 @@ function replacer.inspect_mob(luaob) index = index - 1 until 0 >= index if 0 < #list then - text = text .. rbi.mobs_follows .. ' ' - .. table.concat(list, ', ') .. '\n' + text = text .. rbi.mobs_follows .. ' ' .. concat(list, ', ') .. '\n' end end end if 'table' == type(entity_def.drops) then @@ -211,8 +228,7 @@ function replacer.inspect_mob(luaob) index = index - 1 until 0 >= index if 0 < #list then - text = text .. rbi.mobs_drops .. ' ' - .. table.concat(list, ', ') .. '\n' + text = text .. rbi.mobs_drops .. ' ' .. concat(list, ', ') .. '\n' end end end if 'number' == type(entity_def.damage) and 0 < entity_def.damage then @@ -261,9 +277,9 @@ view_range -- investigate spawning conditions (nodes and neighours) local found, entry, j local search_string = luaob.name .. ' spawning' - index = #minetest.registered_abms + index = #registered_abms if 0 < index then repeat - entry = minetest.registered_abms[index] + entry = registered_abms[index] if entry.label and search_string == entry.label then found = true list, j = {}, #entry.nodenames @@ -274,7 +290,7 @@ view_range j = j - 1 until 0 == j if 0 < #list then - text = text .. '\n' .. rbi.mobs_spawns_on .. ' ' .. table.concat(list, ', ') + text = text .. '\n' .. rbi.mobs_spawns_on .. ' ' .. concat(list, ', ') end end list, j = {}, #entry.neighbors if 0 < j then repeat @@ -285,16 +301,16 @@ view_range until 0 == j if 0 < #list then text = text .. ' ' .. rbi.mobs_spawns_neighbours .. ' ' - .. table.concat(list, ', ') + .. concat(list, ', ') end end end index = index - 1 until (0 == index) or found end if not found then search_string = luaob.name .. '_spawning' - index = #minetest.registered_lbms + index = #registered_lbms if 0 < index then repeat - entry = minetest.registered_lbms[index] + entry = registered_lbms[index] if entry.name and search_string == entry.name then found = true list, j = {}, #entry.nodenames @@ -305,7 +321,7 @@ view_range j = j - 1 until 0 == j if 0 < #list then - text = text .. '\n' .. rbi.mobs_spawns_on .. ' ' .. table.concat(list, ', ') + text = text .. '\n' .. rbi.mobs_spawns_on .. ' ' .. concat(list, ', ') end end end index = index - 1 @@ -327,7 +343,7 @@ function replacer.inspect_entity(object_ref) local luaob = object_ref:get_luaentity() if not luaob then return rbi.this_is_object .. ' ' .. pos_string end - if (not luaob.get_staticdata) and (not minetest.registered_entities[luaob.name]) then + if (not luaob.get_staticdata) and (not registered_entities[luaob.name]) then return S('This is an object "@1"', luaob.name) .. ' ' .. pos_string end @@ -336,7 +352,7 @@ function replacer.inspect_entity(object_ref) if luaob.get_staticdata and not is_endangered(luaob) then text = text .. r.inspect_staticdata(luaob:get_staticdata()) end - if not minetest.registered_entities[luaob.name] then return text end + if not registered_entities[luaob.name] then return text end if luaob._cmi_is_mob then return text .. r.inspect_mob(luaob) end @@ -348,7 +364,7 @@ function replacer.inspect_staticdata(staticdata) if (not staticdata) or (0 == #staticdata) then return '' end local text = '' - local sdata = minetest.deserialize(staticdata) or {} + local sdata = deserialize(staticdata) or {} if sdata.itemstring then text = text .. ' [' .. sdata.itemstring .. ']' end @@ -432,10 +448,10 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) if fields then for k, v in pairs(fields) do if v and '' == v - and minetest.registered_items[k] - or minetest.registered_nodes[k] - or minetest.registered_craftitems[k] - or minetest.registered_tools[k] + and registered_items[k] + or registered_nodes[k] + or registered_craftitems[k] + or registered_tools[k] then node_name = k recipe_nr = 1 @@ -444,16 +460,16 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) end -- fetch recipes from core - local recipes = minetest.get_all_craft_recipes(node_name) or {} + local recipes = get_all_craft_recipes(node_name) or {} if 0 == #recipes then -- some items have aliases that are set with force, and thus -- don't show up in core.get_all_craft_recipes() -- e.g. https://github.com/mt-mods/basic_materials/blob/d9e06980d33ec02c2321269f47ab9ec32b36551f/aliases.lua#L32 -- https://github.com/mt-mods/basic_materials/blob/d9e06980d33ec02c2321269f47ab9ec32b36551f/crafts.lua#L256 -- we try to reverse lookup here - for k, v in pairs(minetest.registered_aliases) do + for k, v in pairs(registered_aliases) do if v == node_name then - recipes = minetest.get_all_craft_recipes(k) + recipes = get_all_craft_recipes(k) if recipes then break end end end @@ -484,23 +500,23 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) -- fetch description -- when clicking unknown nodes local description = ' ' .. rbi.no_description .. ' ' - if minetest.registered_nodes[node_name] then - if minetest.registered_nodes[node_name].description - and '' ~= minetest.registered_nodes[node_name].description + if registered_nodes[node_name] then + if registered_nodes[node_name].description + and '' ~= registered_nodes[node_name].description then - description = minetest.registered_nodes[node_name].description - elseif minetest.registered_nodes[node_name].name then - description = minetest.registered_nodes[node_name].name + description = registered_nodes[node_name].description + elseif registered_nodes[node_name].name then + description = registered_nodes[node_name].name else description = ' ' .. rbi.no_node_description .. ' ' end - elseif minetest.registered_items[node_name] then - if minetest.registered_items[node_name].description - and '' ~= minetest.registered_items[node_name].description + elseif registered_items[node_name] then + if registered_items[node_name].description + and '' ~= registered_items[node_name].description then - description = minetest.registered_items[node_name].description - elseif minetest.registered_items[node_name].name then - description = minetest.registered_items[node_name].name + description = registered_items[node_name].description + elseif registered_items[node_name].name then + description = registered_items[node_name].name else description = ' ' .. rbi.no_item_description .. ' ' end @@ -652,7 +668,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) formspec = formspec .. 'item_image_button[5,2;1.0,1.0;' .. recipe.output .. ';normal;]' end - minetest.show_formspec(player_name, 'replacer:crafting', formspec) + show_formspec(player_name, 'replacer:crafting', formspec) end -- inspect_show_crafting diff --git a/utils.lua b/utils.lua index 283e3e0..f5e6d3b 100644 --- a/utils.lua +++ b/utils.lua @@ -3,9 +3,15 @@ local rb = replacer.blabla local chat_send_player = minetest.chat_send_player local get_player_by_name = minetest.get_player_by_name local get_node_drops = minetest.get_node_drops -local log = minetest.log +local core_log = minetest.log local floor = math.floor +local absolute = math.abs +local concat = table.concat +local insert = table.insert +local gmatch = string.gmatch +local registered_nodes = minetest.registered_nodes local pos_to_string = minetest.pos_to_string +local sound_play = minetest.sound_play local sound_fail = 'default_break_glass' local sound_success = 'default_item_smoke' local sound_gain = 0.5 @@ -19,7 +25,7 @@ end function replacer.inform(name, message) if (not message) or ('' == message) then return end - log('info', rb.log_messages:format(name, message)) + core_log('info', rb.log_messages:format(name, message)) local player = get_player_by_name(name) if not player then return end @@ -49,7 +55,7 @@ function replacer.play_sound(player_name, fail) if 0 < meta:get_int('replacer_muteS') then return end - minetest.sound_play(fail and sound_fail or sound_success, { + sound_play(fail and sound_fail or sound_success, { to_player = player_name, max_hear_distance = 2, gain = sound_gain }, true) @@ -57,10 +63,10 @@ end -- play_sound function replacer.possible_node_drops(node_name, return_names_only) - if not minetest.registered_nodes[node_name] then return {} end + if not registered_nodes[node_name] then return {} end local droplist = {} - local drop = minetest.registered_nodes[node_name].drop or '' + local drop = registered_nodes[node_name].drop or '' if 'string' == type(drop) then if '' == drop then -- this returns value with randomness applied :/ @@ -70,7 +76,7 @@ function replacer.possible_node_drops(node_name, return_names_only) if not return_names_only then return drop end for _, item in ipairs(drop) do - table.insert(droplist, item:match('^([^ ]+)')) + insert(droplist, item:match('^([^ ]+)')) end return droplist end @@ -93,7 +99,7 @@ function replacer.possible_node_drops(node_name, return_names_only) end if not checks[item] then checks[item] = 1 - table.insert(droplist, item) + insert(droplist, item) end end end @@ -102,7 +108,7 @@ end -- possible_node_drops function replacer.print_dump(...) - if not replacer.dev_mode then return end + if not r.dev_mode then return end for _, m in ipairs({ ... }) do print(dump(m)) From 6958e1b204801b8415b2f902929356f3e0f6f344 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 10 Feb 2022 20:19:07 +0100 Subject: [PATCH 298/366] more player inspection --- blabla.lua | 13 +++++++++ inspect.lua | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++--- utils.lua | 48 +++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 3 deletions(-) diff --git a/blabla.lua b/blabla.lua index b126a5b..e572a48 100644 --- a/blabla.lua +++ b/blabla.lua @@ -72,6 +72,8 @@ rb.log_reg_set_callback_fail = '[replacer] register_set_enabler called without p rb.formspec_error = '[replacer] formspec error, user "%s" attempting to change history. Fields: %s' rb.formspec_hacker = '[replacer] formspec forge? By user "%s" Fields: %s' rb.minor_modes_disabled = S('Minor modes are disabled on this server.') +rb.no_pos = S('') +rb.days = S('days') ----------------- replacer:inspect ----------------- rbi.description = S('Inspection Tool\nUse to inspect target node or entity.\n' @@ -113,4 +115,15 @@ rbi.mobs_shoots = S('Can shoot misiles.') rbi.mobs_breed = S('Can breed.') rbi.mobs_spawns_on = S('Spawns on:') rbi.mobs_spawns_neighbours = S('with neighours:') +rbi.player_placed = S('Placed:') +rbi.player_digs = S('Digs:') +rbi.player_inflicted = S('Inflicted:') +rbi.player_punches = S('Punched:') +rbi.player_xp = S('XP:') +rbi.player_deaths = S('Deaths:') +rbi.player_duration = S('Played:') +rbi.player_has_active_mission = S('Is currently on a mission.') +rbi.player_no_common_channels = S("You don't have any common channels.") +rbi.player_common_channels = S('You are both on these channels:') +rbi.player_is_wearing = S('Is wearing:') diff --git a/inspect.lua b/inspect.lua index d2bc3a8..38f4e67 100644 --- a/inspect.lua +++ b/inspect.lua @@ -331,13 +331,84 @@ view_range end -- inspect_mob -function replacer.inspect_entity(object_ref) +function replacer.inspect_player(object_ref, player) + local lines = { S('This is your fellow player "@1"', object_ref:get_player_name()) } + local meta = object_ref:get_meta() + local xp_hud_on = 'off' ~= meta:get_string('hud_state') + local placed = xp_hud_on and meta:get_int('placed_nodes') + local digs = xp_hud_on and meta:get_int('digged_nodes') + local punches = xp_hud_on and meta:get_int('punch_count') + local inflicted = xp_hud_on and meta:get_int('inflicted_damage') + local xp = xp_hud_on and meta:get_int('xp') + local play_seconds = meta:get_int('played_time') + local deaths = meta:get_int('died') + -- TODO: not accurate if either player has never joined any channel, then #main is not yet in list + local channels = nil --parse_json(meta:get_string('beerchat:channels')) + local has_active_mission = deserialize(meta:get_string('currentmission')) and true or false + local wearing = deserialize(meta:get_string('3d_armor_inventory')) + -- other possible interesting points: + -- ["stamina:poisoned"] = "no", + -- ["stamina:exhaustion"] = "0" + + -- short_data_points + local shorts = {} + if placed and 0 < placed then + insert(shorts, rbi.player_placed .. ' ' .. r.nice_number(placed)) + end + if digs and 0 < digs then + insert(shorts, rbi.player_digs .. ' ' .. r.nice_number(digs)) + end + if punches and 0 < punches then + insert(shorts, rbi.player_punches .. ' ' .. r.nice_number(punches)) + end + if inflicted and 0 < inflicted then + insert(shorts, rbi.player_inflicted .. ' ' .. r.nice_number(inflicted)) + end + if xp and 0 < xp then + insert(shorts, rbi.player_xp .. ' ' .. r.nice_number(xp)) + end + if 0 < deaths then + insert(shorts, rbi.player_deaths .. ' ' .. r.nice_number(deaths)) + end + if 0 < #shorts then + insert(lines, concat(shorts, '\t')) + end + if 0 < play_seconds then + insert(lines, rbi.player_duration .. ' ' .. r.nice_duration(play_seconds)) + end + if has_active_mission then + insert(lines, rbi.player_has_active_mission) + end + if channels then + local common = r.common_list_items(channels, + parse_json(player:get_meta():get_string('beerchat:channels'))) + if 0 == #common then + insert(lines, rbi.player_no_common_channels) + else + insert(lines, rbi.player_common_channels .. ' ' .. concat(common, ', ')) + end + end + if wearing and 0 < #wearing then + parts = {} + local index = #wearing + repeat + if '' ~= wearing[index] then insert(parts, wearing[index]) end + index = index - 1 + until 0 == index + if 0 < #parts then + insert(lines, rbi.player_is_wearing .. ' ' .. concat(parts, ', ')) + end + end + return concat(lines, '\n') +end -- inspect_player + + +function replacer.inspect_entity(object_ref, player) if not object_ref then return rbi.broken_object end local pos_string = S('at @1', nice_pos_string(object_ref:getpos())) if object_ref:is_player() then - return S('This is your fellow player "@1"', object_ref:get_player_name()) - .. ' ' .. pos_string + return r.inspect_player(object_ref, player) --.. ' ' .. pos_string end local luaob = object_ref:get_luaentity() diff --git a/utils.lua b/utils.lua index f5e6d3b..67cc7ec 100644 --- a/utils.lua +++ b/utils.lua @@ -22,6 +22,27 @@ if r.has_technic_mod then end +function replacer.common_list_items(list1, list2) + if 'table' ~= type(list1) or 'table' ~= type(list2) then return {} end + if 0 == #list1 or 0 == #list2 then return {} end + + local common, index1, total2, j = {}, #list1, #list2 + repeat + j = total2 + repeat + if list1[index] == list2[j] then + insert(common, list2[j]) + break + end + j = j - 1 + until 0 == j + index = index - 1 + until 0 == index + + return common +end -- common_list_items + + function replacer.inform(name, message) if (not message) or ('' == message) then return end @@ -37,6 +58,33 @@ function replacer.inform(name, message) end -- inform +function replacer.nice_duration(seconds) + if 'number' ~= type(seconds) then return '' end + + seconds = absolute(seconds) + local days = floor(seconds / 86400) + seconds = seconds % 86400 + local text = (0 == days and '') or (tostring(days) .. ' ' .. rb.days .. ' ') + return text .. os.date('! %H:%M:%S', seconds) +end -- nice_duration + + +function replacer.nice_number(number, seperator) + if 'number' ~= type(number) then return '' end + + local sign = 0 > number and '-' or '' + -- TODO: use default depending on locale, won't work as not all 'de' use same + -- and not all 'en' use same, hindi has it's own format: 12'34'567 + seperator = seperator or "'" + local reversed = tostring(absolute(number)):reverse() + local list = {} + for s in gmatch(reversed, '...') do insert(list, s) end + local rest = #reversed % 3 + if 0 ~= rest then insert(list, reversed:sub(-rest, -1)) end + return sign .. concat(list, seperator):reverse() +end -- nice_number + + function replacer.nice_pos_string(pos) local no_info = '' if 'table' ~= type(pos) then return no_info end From 1099618ed09fa95d2c2024f3e1a41787994478f4 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 10 Feb 2022 20:19:50 +0100 Subject: [PATCH 299/366] one more translatable string --- utils.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/utils.lua b/utils.lua index 67cc7ec..6b52a17 100644 --- a/utils.lua +++ b/utils.lua @@ -86,9 +86,8 @@ end -- nice_number function replacer.nice_pos_string(pos) - local no_info = '' - if 'table' ~= type(pos) then return no_info end - if not (pos.x and pos.y and pos.z) then return no_info end + if 'table' ~= type(pos) then return rb.no_pos end + if not (pos.x and pos.y and pos.z) then return rb.no_pos end pos = { x = floor(pos.x + .5), y = floor(pos.y + .5), z = floor(pos.z + .5) } return pos_to_string(pos) From 2139e2a6c6b6ec91bc584e7bb57f8d27378e35a9 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 10 Feb 2022 20:28:17 +0100 Subject: [PATCH 300/366] better variable names: j -> index2; index -> index1 --- utils.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/utils.lua b/utils.lua index 6b52a17..7dbde33 100644 --- a/utils.lua +++ b/utils.lua @@ -26,18 +26,18 @@ function replacer.common_list_items(list1, list2) if 'table' ~= type(list1) or 'table' ~= type(list2) then return {} end if 0 == #list1 or 0 == #list2 then return {} end - local common, index1, total2, j = {}, #list1, #list2 + local common, index1, total2, index2 = {}, #list1, #list2 repeat - j = total2 + index2 = total2 repeat - if list1[index] == list2[j] then - insert(common, list2[j]) + if list1[index1] == list2[index2] then + insert(common, list2[index2]) break end - j = j - 1 - until 0 == j - index = index - 1 - until 0 == index + index2 = index2 - 1 + until 0 == index2 + index1 = index1 - 1 + until 0 == index1 return common end -- common_list_items From 614cf024ce1484566f91637634d274ba1ac18e84 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 10 Feb 2022 20:28:54 +0100 Subject: [PATCH 301/366] whitespace --- inspect.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/inspect.lua b/inspect.lua index 38f4e67..9d2358c 100644 --- a/inspect.lua +++ b/inspect.lua @@ -399,6 +399,7 @@ function replacer.inspect_player(object_ref, player) insert(lines, rbi.player_is_wearing .. ' ' .. concat(parts, ', ')) end end + return concat(lines, '\n') end -- inspect_player From 89c8e6d64b4c1ef396da41eb5088cf12e237ea10 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 10 Feb 2022 21:12:30 +0100 Subject: [PATCH 302/366] locale updates --- locale/replacer.de.tr | 15 ++++++++++++++- locale/replacer.es.tr | 15 ++++++++++++++- locale/replacer.fi.tr | 15 ++++++++++++++- locale/replacer.fr.tr | 27 ++++++++++++++++++++------- locale/replacer.it.tr | 15 ++++++++++++++- locale/replacer.pt.tr | 15 ++++++++++++++- locale/replacer.ru.tr | 15 ++++++++++++++- locale/template.txt | 15 ++++++++++++++- 8 files changed, 118 insertions(+), 14 deletions(-) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index a66f7eb..9bf1036 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -28,6 +28,8 @@ Time-limit reached.=Zeitbegrenzung erreicht. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Schaltet die Ausführlichkeit um.@nchat: Wenn eingeschaltet, werden Nachrichten im Chat ausgegeben.@audio: Wenn ausgeschaltet, ist der Ersetzer stumm. Minor modes are disabled on this server.=Nebenmodi sind auf diesem Server deaktiviert. += +days=Tage Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Inspektionswerkzeug@nSchlagen zum Inspizieren der Zielnode oder der Entität.@nPlatzieren zum Inspizieren der angrenzenden Node. @@ -65,6 +67,17 @@ Can shoot misiles.=Kann schiessen. Can breed.=Kann gezüchtet werden. Spawns on:=Erscheinen auf: with neighours:=mit Nachbarn: +Placed:=Platziert: +Digs:=Ausgrabungen: +Inflicted:=Verltezte: +Punched:=Geschlagen: +XP:=XP: +Deaths:=Todesfälle: +Played:=Gespielt: +Is currently on a mission.=Befindet sich derzeit auf einer Mission. +You don't have any common channels.=Ihr habt keine gemeinsamen Kanäle. +You are both on these channels:=Ihr seid beide auf diesen Kanälen: +Is wearing:=Trägt: fermenting/pickling=Gären Store near group:wood, light < 12.=In der Nähe der Holzgruppe@n(group:wood) lagern, Licht < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Node des Typs „@1“ dürfen auf diesem Server nicht ersetzt werden. Versuch fehlgeschlagen. @@ -73,8 +86,8 @@ printing=Drucken Sorry, this is an unkown something of type "@1". No information available.=Tut mir leid, das ist etwas unbekanntes vom Typ „@1“. Keine Informationen verfügbar. Can deal @1 damage.=Kann @1 Schaden verursachen. Has @1 armour.=Hat @1 Rüstung. -at @1=bei @1 This is your fellow player "@1"=Dies ist dein Mitspieler „@1“ +at @1=bei @1 This is an object "@1"=Dies ist ein „@1“ Objekt This is an entity "@1"=Das ist eine Entität „@1“ , dropped @1 minutes ago=, vor @1 Minuten gefallen diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 2091cbe..3c37702 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -28,6 +28,8 @@ Time-limit reached.=Límite de tiempo alcanzado. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Alterna la verbosidad. @nchat: cuando está activado, los mensajes se publican en el chat. @naudio: cuando está desactivado, el intercambiador está en silencio. Minor modes are disabled on this server.=Los modos menores están deshabilitados en este servidor. += +days=días Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Herramienta de inspección@nUsar para inspeccionar el nodo o la entidad de destino.@nColocar para inspeccionar el nodo adyacente. @@ -65,6 +67,17 @@ Can shoot misiles.=Puede disparar misiles. Can breed.=Puede reproducirse. Spawns on:=Aparece en: with neighours:=con vecinos: +Placed:=Colocados: +Digs:=Excavaciones: +Inflicted:=Infligido: +Punched:=Golpes: +XP:=EXP: +Deaths:=Fallecidos: +Played:=Jugó: +Is currently on a mission.=Está actualmente en una misión. +You don't have any common channels.=No tienes ningún canal común. +You are both on these channels:=Ambos están en estos canales: +Is wearing:=Está vistiendo: fermenting/pickling=fermentación/decapado Store near group:wood, light < 12.=Almacenar cerca del grupo de madera@n(group:wood), luz < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=No se permite reemplazar nodos de tipo "@1" en este servidor. Reemplazo fallido. @@ -73,8 +86,8 @@ printing=impresión Sorry, this is an unkown something of type "@1". No information available.=Lo sentimos, esto es algo desconocido de tipo "@1". No hay información disponible. Can deal @1 damage.=Puede causar daño @1. Has @1 armour.=Tiene armadura @1. -at @1=en @1 This is your fellow player "@1"=Este es tu compañero de juego "@1" +at @1=en @1 This is an object "@1"=Este es un objeto "@1" This is an entity "@1"=Esta es una entidad "@1" , dropped @1 minutes ago=, caído hace @1 minutos diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index bd1caaf..c33924e 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -28,6 +28,8 @@ Time-limit reached.=Aikaraja saavutettu. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Vaihtaa verbosity.@nchat: Kun päällä, viestit lähetetään chat.@naudio: Kun pois päältä, korvaaja on äänetön. Minor modes are disabled on this server.=Pienet tilat on poistettu käytöstä tällä palvelimella. += +days=päivää Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Tarkastustyökalu@nTarkista kohdesolmu tai entiteetti.@nTarkista viereinen solmu. @@ -65,6 +67,17 @@ Can shoot misiles.=Osaa ampua ohjuksia. Can breed.=Voi lisääntyä. Spawns on:=Syntyy: with neighours:=naapureiden kanssa: +Placed:=Sijoitettu: +Digs:=Kaivaukset: +Inflicted:=Aiheutettu: +Punched:=Lävistetty: +XP:=XP: +Deaths:=Kuolemat: +Played:=Pelasi: +Is currently on a mission.=On tällä hetkellä tehtävässä. +You don't have any common channels.=Sinulla ei ole yhteisiä kanavia. +You are both on these channels:=Olette molemmat näillä kanavilla: +Is wearing:=On yllään: fermenting/pickling=käyminen/peittaus Store near group:wood, light < 12.=Varasto lähellä group:wood,@nkevyt < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Tyypin "@1" solmujen korvaaminen ei ole sallittua tässä palvelimessa. Vaihto epäonnistui. @@ -73,8 +86,8 @@ printing=painatus Sorry, this is an unkown something of type "@1". No information available.=Anteeksi, tämä on tuntematon asia, jonka tyyppi on "@1". Tietoja ei ole saatavilla. Can deal @1 damage.=Voi tehdä @1 vahinkoa. Has @1 armour.=Siinä on @1-panssari. -at @1=osoitteessa @1 This is your fellow player "@1"=Tämä on pelikaverisi "@1" +at @1=osoitteessa @1 This is an object "@1"=Tämä on objekti "@1" This is an entity "@1"=Tämä on entiteetti "@1" , dropped @1 minutes ago=, pudonnut @1 minuuttia sitten diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index e5e44da..b928972 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -28,6 +28,8 @@ Time-limit reached.=Délai atteint. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Active/désactive la verbosité.@nchat : lorsque cette option est activée, les messages sont publiés sur le chat.@naudio : lorsqu'elle est désactivée, le remplaçant est silencieux. Minor modes are disabled on this server.=Les modes mineurs sont désactivés sur ce serveur. += +days=jours Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Outil d'inspection@nUtiliser pour inspecter le nœud ou l'entité cible.@nPlacer pour inspecter le nœud adjacent. @@ -36,20 +38,20 @@ owned, protected and locked=possédé, protégé et verrouillé owned and protected=possédé et protégé owned and locked=possédé et verrouillé This is an object=Ceci est un objet -WARNING: You can't dig this node. It is protected.=AVERTISSEMENT: Tu ne peux pas creuser ce nœud. Il est protégé. -INFO: You can dig this node, others can't.=INFO: Tu peux creuser ce nœud, mais les autres ne le peuvent pas. +WARNING: You can't dig this node. It is protected.=AVERTISSEMENT : Tu ne peux pas creuser ce nœud. Il est protégé. +INFO: You can dig this node, others can't.=INFO : Tu peux creuser ce nœud, mais les autres ne le peuvent pas. ~ no description provided ~=~ aucune description fournie ~ ~ no node description provided ~=~ aucune description de nœud fournie ~ ~ no item description provided ~=~ aucune description d'article fournie ~ -Name:=Nom: +Name:=Nom : Exit=Sortir -This is:=C'est: +This is:=C'est : previous recipe=recette précédente next recipe=recette suivante No recipes.=Aucune recette. -Drops on dig:=Gouttes sur creuser: +Drops on dig:=Gouttes sur creuser : nothing.=rien. -May drop on dig:=Peut tomber en creusant: +May drop on dig:=Peut tomber en creusant : This can be used as a fuel.=Cela peut être utilisé comme carburant. Error: Unkown recipe.=Erreur : recette inconnue. scoop up=ramasser @@ -65,6 +67,17 @@ Can shoot misiles.=Peut tirer des missiles. Can breed.=Peut se reproduire. Spawns on:=Apparaît sur : with neighours:=avec des voisins : +Placed:=Mises en place : +Digs:=Creusers : +Inflicted:=Infligé : +Punched:=Frappes : +XP:=XP : +Deaths:=Décès : +Played:=Joué : +Is currently on a mission.=Est actuellement en mission. +You don't have any common channels.=Vous n'avez aucun canal commun. +You are both on these channels:=Vous êtes tous les deux sur ces canaux : +Is wearing:=Porte : fermenting/pickling=fermentation/marinage Store near group:wood, light < 12.=Entreposer près du groupe @ngroup:wood, lumière < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Le remplacement de nœuds de type "@1" n'est pas autorisé sur ce serveur. Échec du remplacement. @@ -73,8 +86,8 @@ printing=impression Sorry, this is an unkown something of type "@1". No information available.=Désolé, c'est quelque chose d'inconnu de type "@1". Aucune information disponible. Can deal @1 damage.=Peut infliger @1 dégâts. Has @1 armour.=A @1 armure. -at @1=à @1 This is your fellow player "@1"=C'est votre coéquipier "@1" +at @1=à @1 This is an object "@1"=Ceci est un objet "@1" This is an entity "@1"=Ceci est une entité "@1" , dropped @1 minutes ago=, déposé il y a @1 minutes diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index 60cfb3f..78f7a81 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -28,6 +28,8 @@ Time-limit reached.=Tempo limite raggiunto. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Attiva/disattiva verbosità.@nchat: quando è attivo, i messaggi vengono inviati alla chat.@naudio: quando è disattivato, il sostituto è silenzioso. Minor modes are disabled on this server.=Le modalità minori sono disabilitate su questo server. += +days=giorni Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Strumento di ispezione@nUtilizzare per ispezionare il nodo o l'entità di destinazione.@nPosizionare per ispezionare il nodo adiacente. @@ -65,6 +67,17 @@ Can shoot misiles.=Può sparare missili. Can breed.=Può riprodursi. Spawns on:=Genera su: with neighours:=con i vicini: +Placed:=Posizionato: +Digs:=Scavi: +Inflicted:=Inflitto: +Punched:=Punzonato: +XP:=XP: +Deaths:=Deceduti: +Played:=Giocato: +Is currently on a mission.=Attualmente è in missione. +You don't have any common channels.=Non hai canali comuni. +You are both on these channels:=Siete entrambi su questi canali: +Is wearing:=Indossa: fermenting/pickling=fermentazione/decapaggio Store near group:wood, light < 12.=Negozio vicino al gruppo group:wood,@nluce < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=La sostituzione dei nodi di tipo "@1" non è consentita su questo server. Sostituzione non riuscita. @@ -73,8 +86,8 @@ printing=stampa Sorry, this is an unkown something of type "@1". No information available.=Siamo spiacenti, questo è un qualcosa sconosciuto di tipo "@1". Nessuna informazione disponibile. Can deal @1 damage.=Può infliggere @1 danno. Has @1 armour.=Ha @1 armatura. -at @1=alle @1 This is your fellow player "@1"=Questo è il tuo compagno di gioco "@1" +at @1=alle @1 This is an object "@1"=Questo è un oggetto "@1" This is an entity "@1"=Questa è un'entità "@1" , dropped @1 minutes ago=, caduto @1 minuti fa diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index ae4d265..53f290c 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -28,6 +28,8 @@ Time-limit reached.=Limite de tempo atingido. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Alterna a verbosidade.@nchat: Quando ativado, as mensagens são postadas no chat.@naudio: Quando desativado, o substituto é silencioso. Minor modes are disabled on this server.=Os modos secundários estão desabilitados neste servidor. += +days=dias Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Ferramenta de Inspeção@nUse para inspecionar o nó ou entidade de destino.@nPlace para inspecionar o nó adjacente. @@ -65,6 +67,17 @@ Can shoot misiles.=Pode disparar mísseis. Can breed.=Pode procriar. Spawns on:=Gera em: with neighours:=com vizinhos: +Placed:=Colocada: +Digs:=Escavações: +Inflicted:=Infligido: +Punched:=Golpes: +XP:=EXP: +Deaths:=Mortes: +Played:=Jogado: +Is currently on a mission.=Atualmente está em uma missão. +You don't have any common channels.=Você não tem canais comuns. +You are both on these channels:=Vocês dois estão nestes canais: +Is wearing:=Está vestindo: fermenting/pickling=fermentação/decapagem Store near group:wood, light < 12.=Armazenar perto do grupo group:wood,@nluz < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=A substituição de nós do tipo "@1" não é permitida neste servidor. Falha na substituição. @@ -73,8 +86,8 @@ printing=impressão Sorry, this is an unkown something of type "@1". No information available.=Desculpe, isso é algo desconhecido do tipo "@1". Nenhuma informação disponível. Can deal @1 damage.=Pode causar @1 de dano. Has @1 armour.=Tem armadura @1. -at @1=em @1 This is your fellow player "@1"=Este é seu colega jogador "@1" +at @1=em @1 This is an object "@1"=Este é um objeto "@1" This is an entity "@1"=Esta é uma entidade "@1" , dropped @1 minutes ago=, caiu @1 minutos atrás diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index cb8627b..37caf47 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -28,6 +28,8 @@ Time-limit reached.=Достигнут лимит времени. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Включает многословие. @nchat: когда включено, сообщения отправляются в чат. @naudio: когда выключено, заменитель молчит. Minor modes are disabled on this server.=Второстепенные режимы отключены на этом сервере. +=<нет информации о местоположении> +days=дни Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.=Inspection Tool@nИспользуйте для проверки целевого узла или объекта. @nPlace для проверки соседнего узла. @@ -65,6 +67,17 @@ Can shoot misiles.=Может стрелять ракетами. Can breed.=Может размножаться. Spawns on:=Появляется на: with neighours:=с соседями: +Placed:=Размещено: +Digs:=Раскопки: +Inflicted:=Нанесено: +Punched:=Перфорировано: +XP:=Опыт: +Deaths:=Летальные исходы: +Played:=Играл: +Is currently on a mission.=В настоящее время находится в командировке. +You don't have any common channels.=У вас нет общих каналов. +You are both on these channels:=Вы оба на этих каналах: +Is wearing:=Носит: fermenting/pickling=ферментация/маринование Store near group:wood, light < 12.=Хранить рядом с группой дерево@n(group:wood), свет < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Замена узлов типа "@1" на этом сервере запрещена. Замена не удалась. @@ -73,8 +86,8 @@ printing=печать Sorry, this is an unkown something of type "@1". No information available.=Извините, это неизвестное что-то типа "@1". Информация отсутствует. Can deal @1 damage.=Может нанести @1 урона. Has @1 armour.=Имеет @1 броню. -at @1=в @1 This is your fellow player "@1"=Это ваш товарищ по игре "@1" +at @1=в @1 This is an object "@1"=Это объект "@1" This is an entity "@1"=Это сущность "@1" , dropped @1 minutes ago=, выпало @1 минут назад diff --git a/locale/template.txt b/locale/template.txt index 635cf6b..727e2e6 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -28,6 +28,8 @@ Time-limit reached.= Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.= Minor modes are disabled on this server.= += +days= Inspection Tool@nUse to inspect target node or entity.@nPlace to inspect the adjacent node.= @@ -65,6 +67,17 @@ Can shoot misiles.= Can breed.= Spawns on:= with neighours:= +Placed:= +Digs:= +Inflicted:= +Punched:= +XP:= +Deaths:= +Played:= +Is currently on a mission.= +You don't have any common channels.= +You are both on these channels:= +Is wearing:= fermenting/pickling= Store near group:wood, light < 12.= Replacing nodes of type "@1" is not allowed on this server. Replacement failed.= @@ -73,8 +86,8 @@ printing= Sorry, this is an unkown something of type "@1". No information available.= Can deal @1 damage.= Has @1 armour.= -at @1= This is your fellow player "@1"= +at @1= This is an object "@1"= This is an entity "@1"= , dropped @1 minutes ago= From 90ca3c55757f94e60dd7591812e63d3a7d754f93 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 10 Feb 2022 21:16:29 +0100 Subject: [PATCH 303/366] beautify code --- inspect.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/inspect.lua b/inspect.lua index 9d2358c..bc992b0 100644 --- a/inspect.lua +++ b/inspect.lua @@ -389,10 +389,11 @@ function replacer.inspect_player(object_ref, player) end end if wearing and 0 < #wearing then - parts = {} - local index = #wearing + local index, parts = #wearing, {} repeat - if '' ~= wearing[index] then insert(parts, wearing[index]) end + if '' ~= wearing[index] then + insert(parts, wearing[index]) + end index = index - 1 until 0 == index if 0 < #parts then From 8f7a4bef1e7e9ab2c24da2817cefcd08ce524d7a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 10 Feb 2022 21:20:07 +0100 Subject: [PATCH 304/366] version bump 4.4 --- CHANGELOG | 1 + init.lua | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 10479b6..58f11c5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +20220210 * SwissalpS added some more info to inspection tool when inspecting players. 20220205 * SwissalpS tweaked formspec of replacer to adjust when minor modes are disabled. * Enabled changing modes with place without pointing at a node. * Added more info on mobs. diff --git a/init.lua b/init.lua index 03aeffa..823b26f 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 4.3 (20220205) +-- Version 4.4 (20220210) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220205 +replacer.version = 20220210 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From e5ae6b667cab6d20efcd3429395969f67fc22442 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sat, 12 Feb 2022 14:03:03 +0100 Subject: [PATCH 305/366] add note to TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index ccce8dd..2c19599 100644 --- a/TODO +++ b/TODO @@ -9,6 +9,8 @@ maybe we can use this on group buttons -- inspection tool: + support for itemframes, itemholder, drawers info about content + crafting info on craftable entities like bikes, trains figure out how to make the itemstring selectable for copy -> do that with new formspec version add mixing method add info for plants telling when they are ripe -> allowing user to click on the ripe From 25d9b3d1ff4c5878782952c029d2d37084da3578 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 14 Feb 2022 14:35:23 +0100 Subject: [PATCH 306/366] pass full context to recipe adders for more functionality --- compat/unifieddyes.lua | 5 +++-- inspect.lua | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/compat/unifieddyes.lua b/compat/unifieddyes.lua index 3c5dbd7..748e55b 100644 --- a/compat/unifieddyes.lua +++ b/compat/unifieddyes.lua @@ -12,9 +12,10 @@ local colour_to_name = unifieddyes.color_to_name -- for inspection tool formspec local S = replacer.S -local function add_recipe(node_name, param2, recipes) - if not param2 then return end +local function add_recipe(node_name, context, recipes) + if not (context and context.param2) then return end + local param2 = context.param2 local node_def = minetest.registered_items[node_name] if ud.is_airbrushed(node_def) then -- find the correct recipe and append it to bottom of list diff --git a/inspect.lua b/inspect.lua index bc992b0..caf5443 100644 --- a/inspect.lua +++ b/inspect.lua @@ -554,7 +554,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) -- add special recipes for nodes created by machines for _, adder in pairs(r.recipe_adders) do - adder.add_recipe(node_name, fields.param2, recipes) + adder.add_recipe(node_name, fields, recipes) end -- offer all alternate crafting recipes through prev/next buttons From 8fb48e1327a8a2b50143a4da5d00478979663847 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 14 Feb 2022 14:36:33 +0100 Subject: [PATCH 307/366] accept recipes without output --- inspect.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/inspect.lua b/inspect.lua index caf5443..8b07c97 100644 --- a/inspect.lua +++ b/inspect.lua @@ -738,8 +738,10 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) formspec = formspec .. 'label[3,1;' .. mfe(rbi.unkown_recipe) .. ']' end -- output item on the right - formspec = formspec - .. 'item_image_button[5,2;1.0,1.0;' .. recipe.output .. ';normal;]' + if recipe.output then + formspec = formspec + .. 'item_image_button[5,2;1.0,1.0;' .. recipe.output .. ';normal;]' + end end show_formspec(player_name, 'replacer:crafting', formspec) end -- inspect_show_crafting From 46472739a3423784d865d338f47290ffa890dedb Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 14 Feb 2022 14:39:13 +0100 Subject: [PATCH 308/366] compat for item holders --- compat/itemframes.lua | 44 +++++++++++++++++++++++ compat/scifi_nodes.lua | 79 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 compat/itemframes.lua diff --git a/compat/itemframes.lua b/compat/itemframes.lua new file mode 100644 index 0000000..c897ef5 --- /dev/null +++ b/compat/itemframes.lua @@ -0,0 +1,44 @@ +if not minetest.get_modpath('itemframes') then return end + +-- for inspection tool -- +local S = replacer.S + +local function add_recipe_itemframe(item_name, context, recipes) + if 'itemframes:frame' ~= item_name then return end + + if not (context and context.pos) then return end + + local held_name = minetest.get_meta(context.pos):get_string('item') + if '' == held_name then return end + + recipes[#recipes + 1] = { + method = S('holding'), + type = 'itemframes:frame', + items = { held_name }, + output = nil, + } +end -- add_recipe_itemframe + +replacer.register_craft_method( + 'itemframes:frame', 'itemframes:frame', add_recipe_itemframe) + + +local function add_recipe_pedestal(item_name, context, recipes) + if 'itemframes:pedestal' ~= item_name then return end + + if not (context and context.pos) then return end + + local held_name = minetest.get_meta(context.pos):get_string('item') + if '' == held_name then return end + + recipes[#recipes + 1] = { + method = S('holding'), + type = 'itemframes:pedestal', + items = { held_name }, + output = nil, + } +end -- add_recipe_pedestal + +replacer.register_craft_method( + 'itemframes:pedestal', 'itemframes:pedestal', add_recipe_pedestal) + diff --git a/compat/scifi_nodes.lua b/compat/scifi_nodes.lua index edb7252..c778f80 100644 --- a/compat/scifi_nodes.lua +++ b/compat/scifi_nodes.lua @@ -1,4 +1,83 @@ if not minetest.get_modpath('scifi_nodes') then return end +local S = replacer.S + +-- for replacer -- + replacer.register_exception('scifi_nodes:laptop_open', 'scifi_nodes:laptop_closed') +-- for inspection tool -- + +-- These are not 100% accurate as other items could be dropped on the holders. +-- We can't be more accurate as long as scifi_nodes does't store the item's name. + +local function add_recipe_itemholder(item_name, context, recipes) + if 'scifi_nodes:itemholder' ~= item_name then return end + + if not (context and context.pos) then return end + + local objects = minetest.get_objects_inside_radius(context.pos, .5) + if (not objects) or (0 == #objects) then return end + + local held_name, luaentity + for _, obj in ipairs(objects) do + if obj and obj.get_luaentity then + luaentity = obj:get_luaentity() + if luaentity and luaentity.itemstring + and ('' ~= luaentity.itemstring) + and minetest.registered_items[luaentity.itemstring] + then + held_name = luaentity.itemstring + break + end + end + end + if not held_name then return end + + recipes[#recipes + 1] = { + method = S('holding'), + type = 'scifi_nodes:itemholder', + items = { held_name }, + output = nil, + } +end -- add_recipe_itemholder + +replacer.register_craft_method( + 'scifi_nodes:itemholder', 'scifi_nodes:itemholder', add_recipe_itemholder) + + +local function add_recipe_powered_stand(item_name, context, recipes) + if 'scifi_nodes:powered_stand' ~= item_name then return end + + if not (context and context.pos) then return end + + local objects = minetest.get_objects_inside_radius( + vector.add(context.pos, vector.new(0, 1, 0)), .5) + if (not objects) or (0 == #objects) then return end + + local held_name, luaentity + for _, obj in ipairs(objects) do + if obj and obj.get_luaentity then + luaentity = obj:get_luaentity() + if luaentity and luaentity.itemstring + and ('' ~= luaentity.itemstring) + and minetest.registered_items[luaentity.itemstring] + then + held_name = luaentity.itemstring + break + end + end + end + if not held_name then return end + + recipes[#recipes + 1] = { + method = S('holding'), + type = 'scifi_nodes:powered_stand', + items = { held_name }, + output = nil, + } +end -- add_recipe_powered_stand + +replacer.register_craft_method( + 'scifi_nodes:powered_stand', 'scifi_nodes:powered_stand', add_recipe_powered_stand) + From 85bcd5ec1601b318f89aad0cae1dc84d9370a4f7 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 14 Feb 2022 14:48:39 +0100 Subject: [PATCH 309/366] locale updates --- locale/replacer.de.tr | 1 + locale/replacer.es.tr | 1 + locale/replacer.fi.tr | 1 + locale/replacer.fr.tr | 1 + locale/replacer.it.tr | 1 + locale/replacer.pt.tr | 1 + locale/replacer.ru.tr | 1 + locale/template.txt | 1 + 8 files changed, 8 insertions(+) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index 9bf1036..a5aba11 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -99,6 +99,7 @@ Located at @1=Befindet sich bei @1 with param2 of @1=mit param2 von @1 and receiving @1 light=und empfängt @1 licht Alternate @1/@2=Alternative @1/@2 +holding=Halten cutting=Schneiden shearing=Scheren Cut with shears.=Mit Schere schneiden. diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 3c37702..826e0a2 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -99,6 +99,7 @@ Located at @1=Ubicado en @1 with param2 of @1=con param2 de @1 and receiving @1 light=y recibiendo @1 luz Alternate @1/@2=Alternativo @1/@2 +holding=sosteniendo cutting=corte shearing=cizallamiento Cut with shears.=Cortar con tijeras. diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index c33924e..6b427e1 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -99,6 +99,7 @@ Located at @1=Sijaitsee @1 with param2 of @1=param2 @1 and receiving @1 light=ja vastaanottaa @1 valoa Alternate @1/@2=Vaihtoehto @1/@2 +holding=pitää cutting=leikkaus shearing=leikkaus Cut with shears.=Leikkaa saksilla. diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index b928972..9b60c7f 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -99,6 +99,7 @@ Located at @1=Situé à @1 with param2 of @1=avec param2 de @1 and receiving @1 light=et recevant @1 lumière Alternate @1/@2=Alternance @1/@2 +holding=Tient cutting=Coupe shearing=Tonte Cut with shears.=Couper avec des cisailles. diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index 78f7a81..28728d3 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -99,6 +99,7 @@ Located at @1=Situato a @1 with param2 of @1=con param2 di @1 and receiving @1 light=e ricevendo @1 luce Alternate @1/@2=Alternativo @1/@2 +holding=tenendo cutting=taglio shearing=tosatura Cut with shears.=Tagliare con le forbici. diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index 53f290c..aca318e 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -99,6 +99,7 @@ Located at @1=Localizado em @1 with param2 of @1=com param2 de @1 and receiving @1 light=e recebendo @1 luz Alternate @1/@2=Alternativo @1/@2 +holding=segurando cutting=corte shearing=cisalhamento Cut with shears.=Corte com tesoura. diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index 37caf47..b11f287 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -99,6 +99,7 @@ Located at @1=Находится по адресу @1 with param2 of @1=с параметром2 из @1 and receiving @1 light=и получаю @1 свет Alternate @1/@2=Альтернатива @1/@2 +holding=держит cutting=резка shearing=стрижка Cut with shears.=Вырезать ножницами. diff --git a/locale/template.txt b/locale/template.txt index 727e2e6..e9fb515 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -99,6 +99,7 @@ Located at @1= with param2 of @1= and receiving @1 light= Alternate @1/@2= +holding= cutting= shearing= Cut with shears.= From e77a4c8510db6fbea46df9972389cb824ba4367e Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 14 Feb 2022 14:54:51 +0100 Subject: [PATCH 310/366] version bump 4.5 --- CHANGELOG | 2 ++ TODO | 3 ++- init.lua | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 58f11c5..c265973 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +20220214 * SwissalpS added compat for itemframe, pedestal, itemholder and powered_stand + (itemframes and scifi_nodes) showing info on what they are holding. 20220210 * SwissalpS added some more info to inspection tool when inspecting players. 20220205 * SwissalpS tweaked formspec of replacer to adjust when minor modes are disabled. * Enabled changing modes with place without pointing at a node. diff --git a/TODO b/TODO index 2c19599..3dc5008 100644 --- a/TODO +++ b/TODO @@ -9,7 +9,8 @@ maybe we can use this on group buttons -- inspection tool: - support for itemframes, itemholder, drawers info about content + stop passing context in hidden fields, use runtime cache to keep + context -> enables to keep all recipes in cycle and possibly reduce look-ups. crafting info on craftable entities like bikes, trains figure out how to make the itemstring selectable for copy -> do that with new formspec version add mixing method diff --git a/init.lua b/init.lua index 823b26f..da95397 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 4.4 (20220210) +-- Version 4.5 (20220214) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220210 +replacer.version = 20220214 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From 3c4ae2aed154afd816762600c69bf0bc74de5022 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 14 Feb 2022 16:05:48 +0100 Subject: [PATCH 311/366] add support for improved scifi_nodes holders https://github.com/pandorabox-io/pandorabox_custom/blob/master/scifi_override.lua https://github.com/D00Med/scifi_nodes/pull/22 --- compat/scifi_nodes.lua | 80 ++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 31 deletions(-) diff --git a/compat/scifi_nodes.lua b/compat/scifi_nodes.lua index c778f80..b408600 100644 --- a/compat/scifi_nodes.lua +++ b/compat/scifi_nodes.lua @@ -10,34 +10,44 @@ replacer.register_exception('scifi_nodes:laptop_open', 'scifi_nodes:laptop_close -- These are not 100% accurate as other items could be dropped on the holders. -- We can't be more accurate as long as scifi_nodes does't store the item's name. +-- Like https://github.com/pandorabox-io/pandorabox_custom/blob/master/scifi_override.lua +-- does. When this override isn't installed, up to 9 objects are returned. local function add_recipe_itemholder(item_name, context, recipes) if 'scifi_nodes:itemholder' ~= item_name then return end if not (context and context.pos) then return end - local objects = minetest.get_objects_inside_radius(context.pos, .5) - if (not objects) or (0 == #objects) then return end - - local held_name, luaentity - for _, obj in ipairs(objects) do - if obj and obj.get_luaentity then - luaentity = obj:get_luaentity() - if luaentity and luaentity.itemstring - and ('' ~= luaentity.itemstring) - and minetest.registered_items[luaentity.itemstring] - then - held_name = luaentity.itemstring - break + local held_name = minetest.get_meta(context.pos):get_string('item') + local items + if '' ~= held_name then + items = { held_name } + else + -- servers without override need to search for dropped items. + items = {} + local luaentity + local objects = minetest.get_objects_inside_radius(context.pos, .5) + if (not objects) or (0 == #objects) then return end + + for _, obj in ipairs(objects) do + if obj and obj.get_luaentity then + luaentity = obj:get_luaentity() + if luaentity and luaentity.itemstring + and ('' ~= luaentity.itemstring) + and minetest.registered_items[ItemStack(luaentity.itemstring):get_name()] + then + table.insert(items, luaentity.itemstring) + end end + if 9 == #items then break end end + if 0 == #items then return end end - if not held_name then return end recipes[#recipes + 1] = { method = S('holding'), type = 'scifi_nodes:itemholder', - items = { held_name }, + items = items, output = nil, } end -- add_recipe_itemholder @@ -51,29 +61,37 @@ local function add_recipe_powered_stand(item_name, context, recipes) if not (context and context.pos) then return end - local objects = minetest.get_objects_inside_radius( - vector.add(context.pos, vector.new(0, 1, 0)), .5) - if (not objects) or (0 == #objects) then return end - - local held_name, luaentity - for _, obj in ipairs(objects) do - if obj and obj.get_luaentity then - luaentity = obj:get_luaentity() - if luaentity and luaentity.itemstring - and ('' ~= luaentity.itemstring) - and minetest.registered_items[luaentity.itemstring] - then - held_name = luaentity.itemstring - break + local held_name = minetest.get_meta(context.pos):get_string('item') + local items + if '' ~= held_name then + items = { held_name } + else + -- servers without override need to search for dropped items. + items = {} + local luaentity + local objects = minetest.get_objects_inside_radius( + vector.add(context.pos, vector.new(0, 1, 0)), .5) + if (not objects) or (0 == #objects) then return end + + for _, obj in ipairs(objects) do + if obj and obj.get_luaentity then + luaentity = obj:get_luaentity() + if luaentity and luaentity.itemstring + and ('' ~= luaentity.itemstring) + and minetest.registered_items[ItemStack(luaentity.itemstring):get_name()] + then + table.insert(items, luaentity.itemstring) + end end + if 9 == #items then break end end + if 0 == #items then return end end - if not held_name then return end recipes[#recipes + 1] = { method = S('holding'), type = 'scifi_nodes:powered_stand', - items = { held_name }, + items = items, output = nil, } end -- add_recipe_powered_stand From 6c4863aa3a442c6924db4b3332dee9ff8287cdcb Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 14 Feb 2022 16:11:05 +0100 Subject: [PATCH 312/366] version bump 4.6 --- CHANGELOG | 3 +++ init.lua | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c265973..e97e074 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +20220215 * SwissalpS added compat for itemholder and powered_stand when override is used + to make them work nicely: + https://github.com/pandorabox-io/pandorabox_custom/blob/master/scifi_override.lua 20220214 * SwissalpS added compat for itemframe, pedestal, itemholder and powered_stand (itemframes and scifi_nodes) showing info on what they are holding. 20220210 * SwissalpS added some more info to inspection tool when inspecting players. diff --git a/init.lua b/init.lua index da95397..cf14264 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 4.5 (20220214) +-- Version 4.6 (20220215) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220214 +replacer.version = 20220215 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From 34f181a675f382bd2b760b4b97788736b545871e Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Mon, 14 Feb 2022 17:02:43 +0100 Subject: [PATCH 313/366] fix #39 fixes: https://github.com/SwissalpS/replacer/issues/39 --- inspect.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/inspect.lua b/inspect.lua index 8b07c97..8558918 100644 --- a/inspect.lua +++ b/inspect.lua @@ -52,10 +52,9 @@ replacer.recipe_adders = {} -- returns a string, even if empty. function replacer.register_craft_method(uid, machine_itemstring, func_inspect, func_formspec) - if ('string' ~= type(uid) or '' == uid) - or ('string' ~= type(machine_itemstring) - or not registered_items[machine_itemstring]) - or 'function' ~= type(func_inspect) + if (('string' ~= type(uid)) or ('' == uid)) + or ('string' ~= type(machine_itemstring)) + or ('function' ~= type(func_inspect)) then core_log('warning', rbi.log_reg_craft_method_wrong_arguments) return From 05d0b58f0efb98b33abd0f500e512f53d3d345d8 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 15 May 2022 23:58:18 +0200 Subject: [PATCH 314/366] fix unsafe negation --- test.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.lua b/test.lua index 60a087f..93497c4 100644 --- a/test.lua +++ b/test.lua @@ -193,7 +193,7 @@ end -- step function replacer.test.dealloc_player(player) if not rt.player or not rt.player.get_player_name then return end - if not rt.player:get_player_name() == player:get_player_name() then return end + if rt.player:get_player_name() ~= player:get_player_name() then return end rt.active = false rt.player = nil end -- dealloc_player From c2fc1666bffe87269ce1836bb52585118e7e8735 Mon Sep 17 00:00:00 2001 From: SX <50966843+S-S-X@users.noreply.github.com> Date: Thu, 16 Jun 2022 04:33:18 +0300 Subject: [PATCH 315/366] Reduce Technic registration warnings --- replacer/replacer.lua | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 7487a96..df88564 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -700,11 +700,19 @@ if r.has_technic_mod then function replacer.tool_def_technic() local def = r.tool_def_basic() def.description = rb.description_technic - def.wear_represents = 'technic_RE_charge' - def.on_refill = technic.refill_RE_charge + if technic.plus then + def.technic_max_charge = r.max_charge + else + def.wear_represents = 'technic_RE_charge' + def.on_refill = technic.refill_RE_charge + end return def end - technic.register_power_tool(r.tool_name_technic, r.max_charge) - minetest.register_tool(r.tool_name_technic, r.tool_def_technic()) + if technic.plus then + technic.register_power_tool(r.tool_name_technic, r.tool_def_technic()) + else + technic.register_power_tool(r.tool_name_technic, r.max_charge) + minetest.register_tool(r.tool_name_technic, r.tool_def_technic()) + end end From 2599568d2e8a48d47ab54c118641e0fa75492a82 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 24 Jun 2022 12:50:41 +0200 Subject: [PATCH 316/366] Update CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index e97e074..0138441 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +20220624 * SX added technic.plus compat fix 20220215 * SwissalpS added compat for itemholder and powered_stand when override is used to make them work nicely: https://github.com/pandorabox-io/pandorabox_custom/blob/master/scifi_override.lua From 939a4a7e69a24972b02c2f4fc1d1c9b0f10fa7e7 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 24 Jun 2022 12:52:51 +0200 Subject: [PATCH 317/366] version bump 4.7 --- init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index cf14264..b11b22e 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 4.6 (20220215) +-- Version 4.7 (20220624) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220215 +replacer.version = 20220624 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From 3ebe76a5de75e632fe4a30d34a97375a452fb6ac Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 26 Jun 2022 21:39:07 +0200 Subject: [PATCH 318/366] improve setting replacer The drop list from engine is in reverse order, so e.g. when trying to set to leaves without leaves in main inventory, replacer would be set to sapling. This commit checks all drops first and if finds same drop as node, it is used. Otherwise the first in list is used. --- replacer/replacer.lua | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index df88564..eeb4cd7 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -622,6 +622,7 @@ function replacer.on_place(itemstack, player, pt) -- let's check if digging this would drop something use-able local drops = r.possible_node_drops(node.name, true) local drop_name + local valid_drops = {} -- if 0 == core_get_item_group(node.name, 'not_in_creative_inventory') then for i = 1, #drops do drop_name = drops[i] @@ -631,15 +632,28 @@ function replacer.on_place(itemstack, player, pt) or (0 == core_get_item_group(drop_name, 'not_in_creative_inventory'))) then + -- it drops itself, so let's shortcut and set to it + if drop_name == node.name then + return true + end + -- otherwise let's add to valid options so user can choose (once we add that feature) + table.insert(valid_drops, drop_name) -- example dirt_with_rainforest_litter can not be -- crafted on all servers but drops dirt, so -- replacer would be set to dirt - node.name = drop_name - return true + --node.name = drop_name + --return true end end -- loop drops -- end -- node is in creative inventory + -- TODO: show formspec for user to choose, if there are multiple options + if 0 < #valid_drops then + -- for now we just take the first option + node.name = valid_drops[1] + return true + end + if not creative_enabled then return false end -- creative users have access to more items From c5ba2a7665fa217041e6760e2b488bea0d8a501f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 26 Jun 2022 21:44:26 +0200 Subject: [PATCH 319/366] version bump 4.9 --- CHANGELOG | 1 + TODO | 4 ++++ init.lua | 4 ++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0138441..b0dc0c8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +20220626 * SwissalpS fixed case where other drops were prefered from actual node that user tried to set to. 20220624 * SX added technic.plus compat fix 20220215 * SwissalpS added compat for itemholder and powered_stand when override is used to make them work nicely: diff --git a/TODO b/TODO index 3dc5008..252817a 100644 --- a/TODO +++ b/TODO @@ -25,6 +25,10 @@ -- letters: similar to elphabet ------ replacer fixes -------- + +try to add a formspec for player to be able to choose from multiple valid drops + when node does not drop itself. + -- can't be set --> no recipe homedecor:glass_table_large_square homedecor:dvd_cd_cabinet diff --git a/init.lua b/init.lua index b11b22e..c816bde 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 4.7 (20220624) +-- Version 4.9 (20220626) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220624 +replacer.version = 20220626 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From b0e653e24a5ddc6bd05e62772b2c216b00de0814 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 30 Aug 2022 22:50:51 +0200 Subject: [PATCH 320/366] bugfix de translation typo Thanks Niklp09 for reporting. fixes: #47 --- locale/replacer.de.tr | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index a5aba11..b927fe1 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -25,7 +25,7 @@ Node replacement tool=Ersetzer Node replacement tool (technic)=Ersetzer (Technik) Time-limit reached.=Zeitbegrenzung erreicht. -Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Schaltet die Ausführlichkeit um.@nchat: Wenn eingeschaltet, werden Nachrichten im Chat ausgegeben.@audio: Wenn ausgeschaltet, ist der Ersetzer stumm. +Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Schaltet die Ausführlichkeit um.@nchat: Wenn eingeschaltet, werden Nachrichten im Chat ausgegeben.@naudio: Wenn ausgeschaltet, ist der Ersetzer stumm. Minor modes are disabled on this server.=Nebenmodi sind auf diesem Server deaktiviert. = @@ -125,3 +125,4 @@ separating=Trennen painting=Malen fermenting=Fermentieren Ferment in barrel.=Gärung im Fass. + From 1ac2ab2c76a8f939b76d50e598ef1a6f5ad8a477 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 30 Aug 2022 22:51:29 +0200 Subject: [PATCH 321/366] version bump 4.91 --- CHANGELOG | 1 + init.lua | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b0dc0c8..4e8f7ac 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +20220830 * SwissalpS fixed de translation typo. Thanks Niklp09 for reporting. 20220626 * SwissalpS fixed case where other drops were prefered from actual node that user tried to set to. 20220624 * SX added technic.plus compat fix 20220215 * SwissalpS added compat for itemholder and powered_stand when override is used diff --git a/init.lua b/init.lua index c816bde..b836f8a 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 4.9 (20220626) +-- Version 4.91 (20220830) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220626 +replacer.version = 20220830 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From 1fd714be5b06463575c07936a2ff60f967beb5b4 Mon Sep 17 00:00:00 2001 From: flux <25628292+fluxionary@users.noreply.github.com> Date: Mon, 7 Nov 2022 11:48:33 -0800 Subject: [PATCH 322/366] fix typo --- blabla.lua | 2 +- inspect.lua | 4 ++-- locale/replacer.de.tr | 4 ++-- locale/replacer.es.tr | 4 ++-- locale/replacer.fi.tr | 4 ++-- locale/replacer.fr.tr | 4 ++-- locale/replacer.it.tr | 4 ++-- locale/replacer.pt.tr | 4 ++-- locale/replacer.ru.tr | 4 ++-- locale/template.txt | 4 ++-- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/blabla.lua b/blabla.lua index e572a48..f9a8c5c 100644 --- a/blabla.lua +++ b/blabla.lua @@ -98,7 +98,7 @@ rbi.drops_on_dig = S('Drops on dig:') rbi.nothing = S('nothing.') rbi.may_drop_on_dig = S('May drop on dig:') rbi.can_be_fuel = S('This can be used as a fuel.') -rbi.unkown_recipe = S('Error: Unkown recipe.') +rbi.unknown_recipe = S('Error: Unknown recipe.') rbi.log_reg_craft_method_wrong_arguments = '[replacer] register_craft_method invalid arguments given.' rbi.log_reg_craft_method_overriding_method = '[replacer] register_craft_method overriding existing method ' rbi.log_reg_craft_method_added = '[replacer] register_craft_method method added: %s %s' diff --git a/inspect.lua b/inspect.lua index 8558918..d7db9d3 100644 --- a/inspect.lua +++ b/inspect.lua @@ -101,7 +101,7 @@ function replacer.inspect(_, player, pointed_thing, right_clicked) chat(player_name, r.inspect_entity(pointed_thing.ref, player)) return nil elseif 'node' ~= pointed_thing.type then - chat(player_name, S('Sorry, this is an unkown something of type "@1". ' + chat(player_name, S('Sorry, this is an unknown something of type "@1". ' .. 'No information available.', pointed_thing.type)) return nil end @@ -734,7 +734,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) else --pd('unhandled recipe encountered', recipe) --r.play_sound(player_name, true) - formspec = formspec .. 'label[3,1;' .. mfe(rbi.unkown_recipe) .. ']' + formspec = formspec .. 'label[3,1;' .. mfe(rbi.unknown_recipe) .. ']' end -- output item on the right if recipe.output then diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index b927fe1..8a188ac 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -53,7 +53,7 @@ Drops on dig:=Lässt fallen beim Graben: nothing.=nichts. May drop on dig:=Kann beim Graben fallen lassen: This can be used as a fuel.=Dies kann als Brennstoff verwendet werden. -Error: Unkown recipe.=Fehler: Unbekanntes Rezept. +Error: Unknown recipe.=Fehler: Unbekanntes Rezept. scoop up=schöpfen pour out=ausgiessen filling=auffüllen @@ -83,7 +83,7 @@ Store near group:wood, light < 12.=In der Nähe der Holzgruppe@n(group:wood) lag Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Node des Typs „@1“ dürfen auf diesem Server nicht ersetzt werden. Versuch fehlgeschlagen. Protected at @1=Geschützt bei @1 printing=Drucken -Sorry, this is an unkown something of type "@1". No information available.=Tut mir leid, das ist etwas unbekanntes vom Typ „@1“. Keine Informationen verfügbar. +Sorry, this is an unknown something of type "@1". No information available.=Tut mir leid, das ist etwas unbekanntes vom Typ „@1“. Keine Informationen verfügbar. Can deal @1 damage.=Kann @1 Schaden verursachen. Has @1 armour.=Hat @1 Rüstung. This is your fellow player "@1"=Dies ist dein Mitspieler „@1“ diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 826e0a2..df40df9 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -53,7 +53,7 @@ Drops on dig:=Cae en excavación: nothing.=nada. May drop on dig:=Puede caer en excavación: This can be used as a fuel.=Esto se puede usar como combustible. -Error: Unkown recipe.=Error: Receta desconocida. +Error: Unknown recipe.=Error: Receta desconocida. scoop up=recoger pour out=derramar filling=llena @@ -83,7 +83,7 @@ Store near group:wood, light < 12.=Almacenar cerca del grupo de madera@n(group:w Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=No se permite reemplazar nodos de tipo "@1" en este servidor. Reemplazo fallido. Protected at @1=Protegido en @1 printing=impresión -Sorry, this is an unkown something of type "@1". No information available.=Lo sentimos, esto es algo desconocido de tipo "@1". No hay información disponible. +Sorry, this is an unknown something of type "@1". No information available.=Lo sentimos, esto es algo desconocido de tipo "@1". No hay información disponible. Can deal @1 damage.=Puede causar daño @1. Has @1 armour.=Tiene armadura @1. This is your fellow player "@1"=Este es tu compañero de juego "@1" diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index 6b427e1..a91c3e1 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -53,7 +53,7 @@ Drops on dig:=Pudotukset kaivamaan: nothing.=ei mitään. May drop on dig:=Saattaa pudota kaivamaan: This can be used as a fuel.=Tätä voidaan käyttää polttoaineena. -Error: Unkown recipe.=Virhe: Tuntematon resepti. +Error: Unknown recipe.=Virhe: Tuntematon resepti. scoop up=kauhoa pour out=kaataa filling=täyttää @@ -83,7 +83,7 @@ Store near group:wood, light < 12.=Varasto lähellä group:wood,@nkevyt < 12. Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Tyypin "@1" solmujen korvaaminen ei ole sallittua tässä palvelimessa. Vaihto epäonnistui. Protected at @1=Suojattu @1 printing=painatus -Sorry, this is an unkown something of type "@1". No information available.=Anteeksi, tämä on tuntematon asia, jonka tyyppi on "@1". Tietoja ei ole saatavilla. +Sorry, this is an unknown something of type "@1". No information available.=Anteeksi, tämä on tuntematon asia, jonka tyyppi on "@1". Tietoja ei ole saatavilla. Can deal @1 damage.=Voi tehdä @1 vahinkoa. Has @1 armour.=Siinä on @1-panssari. This is your fellow player "@1"=Tämä on pelikaverisi "@1" diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index 9b60c7f..ed8189b 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -53,7 +53,7 @@ Drops on dig:=Gouttes sur creuser : nothing.=rien. May drop on dig:=Peut tomber en creusant : This can be used as a fuel.=Cela peut être utilisé comme carburant. -Error: Unkown recipe.=Erreur : recette inconnue. +Error: Unknown recipe.=Erreur : recette inconnue. scoop up=ramasser pour out=déverser filling=remplir @@ -83,7 +83,7 @@ Store near group:wood, light < 12.=Entreposer près du groupe @ngroup:wood, lum Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Le remplacement de nœuds de type "@1" n'est pas autorisé sur ce serveur. Échec du remplacement. Protected at @1=Protégé à @1 printing=impression -Sorry, this is an unkown something of type "@1". No information available.=Désolé, c'est quelque chose d'inconnu de type "@1". Aucune information disponible. +Sorry, this is an unknown something of type "@1". No information available.=Désolé, c'est quelque chose d'inconnu de type "@1". Aucune information disponible. Can deal @1 damage.=Peut infliger @1 dégâts. Has @1 armour.=A @1 armure. This is your fellow player "@1"=C'est votre coéquipier "@1" diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index 28728d3..f7083dd 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -53,7 +53,7 @@ Drops on dig:=Gocce allo scavo: nothing.=niente. May drop on dig:=Può cadere durante lo scavo: This can be used as a fuel.=Questo può essere usato come carburante. -Error: Unkown recipe.=Errore: ricetta sconosciuta. +Error: Unknown recipe.=Errore: ricetta sconosciuta. scoop up=raccogliere pour out=versare filling=riempire @@ -83,7 +83,7 @@ Store near group:wood, light < 12.=Negozio vicino al gruppo group:wood,@nluce < Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=La sostituzione dei nodi di tipo "@1" non è consentita su questo server. Sostituzione non riuscita. Protected at @1=Protetto a @1 printing=stampa -Sorry, this is an unkown something of type "@1". No information available.=Siamo spiacenti, questo è un qualcosa sconosciuto di tipo "@1". Nessuna informazione disponibile. +Sorry, this is an unknown something of type "@1". No information available.=Siamo spiacenti, questo è un qualcosa sconosciuto di tipo "@1". Nessuna informazione disponibile. Can deal @1 damage.=Può infliggere @1 danno. Has @1 armour.=Ha @1 armatura. This is your fellow player "@1"=Questo è il tuo compagno di gioco "@1" diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index aca318e..d628650 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -53,7 +53,7 @@ Drops on dig:=Gotas na escavação: nothing.=nada. May drop on dig:=Pode cair na escavação: This can be used as a fuel.=Isso pode ser usado como combustível. -Error: Unkown recipe.=Erro: receita desconhecida. +Error: Unknown recipe.=Erro: receita desconhecida. scoop up=escavar pour out=derramar filling=encher @@ -83,7 +83,7 @@ Store near group:wood, light < 12.=Armazenar perto do grupo group:wood,@nluz < 1 Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=A substituição de nós do tipo "@1" não é permitida neste servidor. Falha na substituição. Protected at @1=Protegido em @1 printing=impressão -Sorry, this is an unkown something of type "@1". No information available.=Desculpe, isso é algo desconhecido do tipo "@1". Nenhuma informação disponível. +Sorry, this is an unknown something of type "@1". No information available.=Desculpe, isso é algo desconhecido do tipo "@1". Nenhuma informação disponível. Can deal @1 damage.=Pode causar @1 de dano. Has @1 armour.=Tem armadura @1. This is your fellow player "@1"=Este é seu colega jogador "@1" diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index b11f287..ca897b7 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -53,7 +53,7 @@ Drops on dig:=Выпадает при раскопках: nothing.=ничего. May drop on dig:=Может выпасть при раскопках: This can be used as a fuel.=Это можно использовать в качестве топлива. -Error: Unkown recipe.=Ошибка: Неизвестный рецепт. +Error: Unknown recipe.=Ошибка: Неизвестный рецепт. scoop up=зачерпнуть pour out=вылить filling=заполнить @@ -83,7 +83,7 @@ Store near group:wood, light < 12.=Хранить рядом с группой Replacing nodes of type "@1" is not allowed on this server. Replacement failed.=Замена узлов типа "@1" на этом сервере запрещена. Замена не удалась. Protected at @1=Защищено в @1 printing=печать -Sorry, this is an unkown something of type "@1". No information available.=Извините, это неизвестное что-то типа "@1". Информация отсутствует. +Sorry, this is an unknown something of type "@1". No information available.=Извините, это неизвестное что-то типа "@1". Информация отсутствует. Can deal @1 damage.=Может нанести @1 урона. Has @1 armour.=Имеет @1 броню. This is your fellow player "@1"=Это ваш товарищ по игре "@1" diff --git a/locale/template.txt b/locale/template.txt index e9fb515..3f48f4d 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -53,7 +53,7 @@ Drops on dig:= nothing.= May drop on dig:= This can be used as a fuel.= -Error: Unkown recipe.= +Error: Unknown recipe.= scoop up= pour out= filling= @@ -83,7 +83,7 @@ Store near group:wood, light < 12.= Replacing nodes of type "@1" is not allowed on this server. Replacement failed.= Protected at @1= printing= -Sorry, this is an unkown something of type "@1". No information available.= +Sorry, this is an unknown something of type "@1". No information available.= Can deal @1 damage.= Has @1 armour.= This is your fellow player "@1"= From 6b83c8881cfc42c520a22c0c66f710e7cfc4435a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 8 Jun 2023 03:22:30 +0200 Subject: [PATCH 323/366] typo in comment --- compat/technic.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compat/technic.lua b/compat/technic.lua index f10e04e..e636c82 100644 --- a/compat/technic.lua +++ b/compat/technic.lua @@ -26,7 +26,7 @@ replacer.register_set_enabler(function(node) end) ------------------------------------------ ------------ for inpection tool ----------- +----------- for inspection tool ----------- ------------------------------------------ -- have not tested 'other' technic mod, so just support technic.plus --if not technic.plus then return end From 8a0e3e9b15cad41fa2d2ef0c689290676351d914 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Thu, 8 Jun 2023 05:16:39 +0200 Subject: [PATCH 324/366] another trivial comment fix --- compat/technic.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compat/technic.lua b/compat/technic.lua index e636c82..c5bb9d2 100644 --- a/compat/technic.lua +++ b/compat/technic.lua @@ -73,7 +73,7 @@ local function add_recipe_cnc(item_name, _, recipes) output = item_name, program = program --:gsub('_', ' ') } -end -- add_recipe_freeze +end -- add_recipe_cnc local function add_formspec_cnc(recipe) if not recipe.program then return '' end From 3b7db127f793d2e90e4b81688c0636da2af8716a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 25 Feb 2024 13:37:05 +0100 Subject: [PATCH 325/366] fix multinode trouble in field mode when clicking on the 'wrong' part of a multinode-node, direction calculation is nerfed. This patch avoids a server crash and emits a sound and message. User can simply click on another part of the multinode- node and the procedure should work. I didn't bother adjusting the pointed_thing to make this work, as I don't consider the trouble worthwhile for this kind of node that breaks the voxel world. The bug was detected by player frogTheSecond and reported by Huhhila on pandorabox. Thanks guys. --- CHANGELOG | 1 + init.lua | 2 +- replacer/replacer.lua | 12 ++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 4e8f7ac..5f2cd48 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +20240225 * SwissalpS patched a crash situation with multinode-nodes. Thanks frogTheSecond and Huhhila for detecting and reporting. 20220830 * SwissalpS fixed de translation typo. Thanks Niklp09 for reporting. 20220626 * SwissalpS fixed case where other drops were prefered from actual node that user tried to set to. 20220624 * SX added technic.plus compat fix diff --git a/init.lua b/init.lua index b836f8a..a317a32 100644 --- a/init.lua +++ b/init.lua @@ -24,7 +24,7 @@ -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20220830 +replacer.version = 20240225 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') diff --git a/replacer/replacer.lua b/replacer/replacer.lua index eeb4cd7..983534a 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -364,6 +364,18 @@ function replacer.on_use(itemstack, player, pt, right_clicked) end end end + -- with multinode-nodes it is possible to click the + -- node in a way that none of the coordinates of + -- ``normal`` is 0, leading to empty ``dirs`` and crash + -- when passing nil to vector functions. + -- Player can click on another part of the node to + -- have success. + if 0 == #dirs then + r.play_sound(name, true) + r.inform(name, rb.no_pos) + return + end + -- The normal is used as offset to test if the searched position -- is next to the field; the offset goes in the other direction when -- a right click happens From a364db40ca62d83617bf9ba56706a72d2aa58fa0 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 25 Feb 2024 13:49:48 +0100 Subject: [PATCH 326/366] unrelated luacheck 'fixes' --- compat/ehlphabet.lua | 2 +- compat/letters.lua | 4 ++-- compat/wine.lua | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compat/ehlphabet.lua b/compat/ehlphabet.lua index 775c3eb..8250ac5 100644 --- a/compat/ehlphabet.lua +++ b/compat/ehlphabet.lua @@ -10,7 +10,7 @@ local skip = {} for _, n in ipairs(exceptions) do skip[n] = true end local function ehlphabet_number_sticker(item_name) - if not item_name or not 'string' == type(item_name) then return end + if not item_name or 'string' ~= type(item_name) then return end return item_name:match('^ehlphabet:([0-9]+)'), item_name:find('_sticker$') and true diff --git a/compat/letters.lua b/compat/letters.lua index 5e8fced..16ac770 100644 --- a/compat/letters.lua +++ b/compat/letters.lua @@ -3,7 +3,7 @@ if not minetest.get_modpath('letters') then return end -- for inspection tool local S = replacer.S local function add_recipe_u(item_name, _, recipes) - if not item_name or not 'string' == type(item_name) then return end + if not item_name or 'string' ~= type(item_name) then return end local input, letter = item_name:match('^(.+)_letter_(.)u$') if not input then return end @@ -21,7 +21,7 @@ replacer.register_craft_method('letters:upper', 'letters:letter_cutter_upper', a local function add_recipe_l(item_name, _, recipes) - if not item_name or not 'string' == type(item_name) then return end + if not item_name or 'string' ~= type(item_name) then return end local input, letter = item_name:match('^(.+)_letter_(.)l$') if not input then return end diff --git a/compat/wine.lua b/compat/wine.lua index 31413dc..46307d0 100644 --- a/compat/wine.lua +++ b/compat/wine.lua @@ -20,7 +20,7 @@ in_out['wine:glass_coffee_liquor'] = 'farming:coffee_beans' in_out['wine:glass_champagne'] = 'wine:glass_champagne_raw' local function add_recipe(item_name, _, recipes) - if not 'string' == type(item_name) + if 'string' ~= type(item_name) or not item_name:find('^wine:glass_') then return end -- this one is an exception From 6eddf9e394564b3acc83884cb451c9804d6db5c0 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 21 Jul 2024 03:15:37 +0200 Subject: [PATCH 327/366] phase 1 of going game agnostic - add materials for crafting tools and sounds. - optionally depend on default and xcompat in later phase we can drop dependancy on default and make xcompat a hard dependancy (still in consideration) --- .luacheckrc | 1 + crafts.lua | 19 ++++++++------ init.lua | 4 +++ mod.conf | 3 +-- replacer/replacer.lua | 2 +- utils.lua | 13 +++------ xcompat.lua | 61 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 82 insertions(+), 21 deletions(-) create mode 100644 xcompat.lua diff --git a/.luacheckrc b/.luacheckrc index c7f3553..d7e7f27 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -26,5 +26,6 @@ read_globals = { "technic", "unified_inventory", "unifieddyes", + "xcompat", } diff --git a/crafts.lua b/crafts.lua index 2e3dc26..0da59b2 100644 --- a/crafts.lua +++ b/crafts.lua @@ -1,11 +1,13 @@ +local r = replacer +local rm = r.materials if not replacer.hide_recipe_basic then minetest.register_craft({ output = replacer.tool_name_basic, recipe = { - { 'default:chest', '', 'default:gold_ingot' }, - { '', 'default:mese_crystal_fragment', '' }, - { 'default:steel_ingot', '', 'default:chest' }, + { rm.chest, '', rm.gold_ingot }, + { '', rm.mese_crystal_fragment, '' }, + { rm.steel_ingot, '', '' }, } }) end @@ -28,9 +30,9 @@ if replacer.has_technic_mod then minetest.register_craft({ output = replacer.tool_name_technic, recipe = { - { 'default:chest', 'technic:green_energy_crystal', 'default:gold_ingot' }, - { '', 'default:mese_crystal_fragment', '' }, - { 'default:steel_ingot', '', 'default:chest' }, + { rm.chest, 'technic:green_energy_crystal', rm.gold_ingot }, + { '', rm.mese_crystal_fragment, '' }, + { rm.steel_ingot, '', rm.chest }, } }) end @@ -40,7 +42,8 @@ end minetest.register_craft({ output = 'replacer:inspect', recipe = { - { 'default:torch' }, - { 'default:stick' }, + { rm.torch }, + { rm.stick }, } }) + diff --git a/init.lua b/init.lua index a317a32..e03e0c7 100644 --- a/init.lua +++ b/init.lua @@ -42,6 +42,8 @@ replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') and minetest.global_exists('unifieddyes') replacer.has_unified_inventory_mod = minetest.get_modpath('unified_inventory') and true or false +replacer.has_xcompat_mod = minetest.get_modpath('xcompat') + and minetest.global_exists('xcompat') -- image mapping tables for replacer:inspect replacer.group_placeholder = {} @@ -53,6 +55,8 @@ dofile(path .. 'test.lua') -- strings for translation (i+r) dofile(path .. 'blabla.lua') -- utilities (i+r) +-- material and sound compatibility for various games +dofile(path .. 'xcompat.lua') dofile(path .. 'utils.lua') -- more settings and functions dofile(path .. 'replacer/constrain.lua') diff --git a/mod.conf b/mod.conf index 353583d..bea4d23 100644 --- a/mod.conf +++ b/mod.conf @@ -1,5 +1,4 @@ name = replacer description = Replacement tool for creative building and tool to inspect nodes. -depends = default -optional_depends = colormachine, dye, moreblocks, technic, unifieddyes +optional_depends = colormachine, default, dye, moreblocks, technic, unifieddyes, xcompat diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 983534a..ad18202 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -1,6 +1,6 @@ replacer.tool_name_basic = 'replacer:replacer' replacer.tool_name_technic = 'replacer:replacer_technic' -replacer.tool_default_node = 'default:dirt' +replacer.tool_default_node = replacer.materials.dirt -- pulling to local scope especially those used in loops local r = replacer diff --git a/utils.lua b/utils.lua index 7dbde33..94f4507 100644 --- a/utils.lua +++ b/utils.lua @@ -12,14 +12,6 @@ local gmatch = string.gmatch local registered_nodes = minetest.registered_nodes local pos_to_string = minetest.pos_to_string local sound_play = minetest.sound_play -local sound_fail = 'default_break_glass' -local sound_success = 'default_item_smoke' -local sound_gain = 0.5 -if r.has_technic_mod then - sound_fail = 'technic_prospector_miss' - --sound_success = 'technic_prospector_hit' - sound_gain = 0.1 -end function replacer.common_list_items(list1, list2) @@ -102,10 +94,11 @@ function replacer.play_sound(player_name, fail) if 0 < meta:get_int('replacer_muteS') then return end - sound_play(fail and sound_fail or sound_success, { + local sound = fail and r.sounds.fail or r.sounds.success + sound_play(sound.name, { to_player = player_name, max_hear_distance = 2, - gain = sound_gain }, true) + gain = sound.gain or 0.5 }, true) end -- play_sound diff --git a/xcompat.lua b/xcompat.lua new file mode 100644 index 0000000..42800e2 --- /dev/null +++ b/xcompat.lua @@ -0,0 +1,61 @@ +local r = replacer +r.materials = {} +local rm = r.materials + +if r.has_xcompat_mod then + -- let xcompat decide what is available + do + local material_keys = { + 'chest', + 'dirt', + 'gold_ingot', + 'mese_crystal_fragment', + 'steel_ingot', + 'stick', + 'torch', + } + local i = #material_keys + repeat + rm[material_keys[i]] = xcompat.materials[material_keys[i]] or '' + i = i - 1 + until 0 == i + end + + r.sounds = { + fail = { + name = xcompat.sounds.node_sound_glass_defaults().dug.name + }, + -- TODO: PR xcompat to have 'default_item_smoke' and similar + success = { + name = xcompat.sounds.node_sound_sand_defaults().dug.name + } + } +else + -- assume default game + r.materials = { + chest = 'default:chest', + dirt = 'default:dirt', + gold_ingot = 'default:gold_ingot', + mese_crystal_fragment = 'default:mese_crystal_fragment', + steel_ingot = 'default:steel_ingot', + stick = 'default:stick', + torch = 'default:torch', + } + + r.sounds = { + fail = { + name = 'default_break_glass' + }, + success = { + name = 'default_item_smoke' + } + } +end + +if r.has_technic_mod then + r.sounds.fail.name = 'technic_prospector_miss' + r.sounds.fail.gain = 0.1 + --r.sounds.success.name = 'technic_prospector_hit' + --r.sounds.success.gain = 0.1 +end + From d50912760a2d7685b4a237eeb33cd0645e728846 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 21 Jul 2024 04:15:13 +0200 Subject: [PATCH 328/366] use local variable (since we already have it) --- crafts.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crafts.lua b/crafts.lua index 0da59b2..335d641 100644 --- a/crafts.lua +++ b/crafts.lua @@ -1,9 +1,9 @@ local r = replacer local rm = r.materials -if not replacer.hide_recipe_basic then +if not r.hide_recipe_basic then minetest.register_craft({ - output = replacer.tool_name_basic, + output = r.tool_name_basic, recipe = { { rm.chest, '', rm.gold_ingot }, { '', rm.mese_crystal_fragment, '' }, @@ -14,21 +14,21 @@ end -- only if technic mod is installed -if replacer.has_technic_mod then - if not replacer.hide_recipe_technic_upgrade then +if r.has_technic_mod then + if not r.hide_recipe_technic_upgrade then minetest.register_craft({ - output = replacer.tool_name_technic, + output = r.tool_name_technic, recipe = { - { replacer.tool_name_basic, 'technic:green_energy_crystal', '' }, + { r.tool_name_basic, 'technic:green_energy_crystal', '' }, { '', '', '' }, { '', '', '' }, } }) end - if not replacer.hide_recipe_technic_direct then + if not r.hide_recipe_technic_direct then -- direct upgrade craft minetest.register_craft({ - output = replacer.tool_name_technic, + output = r.tool_name_technic, recipe = { { rm.chest, 'technic:green_energy_crystal', rm.gold_ingot }, { '', rm.mese_crystal_fragment, '' }, From 0e30dc3ad02dcb24dd3c3bca794a8415c1fc46c8 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 24 Jul 2024 13:52:56 +0200 Subject: [PATCH 329/366] handle games that don't return sounds --- xcompat.lua | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/xcompat.lua b/xcompat.lua index 42800e2..90bc347 100644 --- a/xcompat.lua +++ b/xcompat.lua @@ -23,13 +23,25 @@ if r.has_xcompat_mod then r.sounds = { fail = { - name = xcompat.sounds.node_sound_glass_defaults().dug.name + name = '' }, - -- TODO: PR xcompat to have 'default_item_smoke' and similar success = { - name = xcompat.sounds.node_sound_sand_defaults().dug.name + name = '' } } + local sound = xcompat.sounds.node_sound_glass_defaults() + if sound and sound.dug and sound.dug.name then + r.sounds.fail.name = sound.dug.name + else + r.sounds.fail.gain = 0.0 + end + -- TODO: PR xcompat to have 'default_item_smoke' and similar + sound = xcompat.sounds.node_sound_sand_defaults() + if sound and sound.dug and sound.dug.name then + r.sounds.success.name = sound.dug.name + else + r.sounds.success.gain = 0.0 + end else -- assume default game r.materials = { From 83cc4d1696dc76142979eeb654896ce08c11774f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 24 Jul 2024 13:53:35 +0200 Subject: [PATCH 330/366] don't load [default] compat if not using it --- compat/default.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compat/default.lua b/compat/default.lua index 70cffcc..560ae49 100644 --- a/compat/default.lua +++ b/compat/default.lua @@ -1,4 +1,4 @@ --- replacer has default mod as hard dependancy, so no checking +if not minetest.get_modpath('default') then return end -- helpers for inspection tool -- some common groups replacer.group_placeholder['group:water_bucket'] = 'bucket:bucket_river_water' From ff6364f8ba26c68d1de5dd723aff524a92f7772c Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 24 Jul 2024 13:54:07 +0200 Subject: [PATCH 331/366] handle games not using creative global --- replacer/replacer.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index ad18202..6b1a049 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -20,7 +20,8 @@ local core_registered_nodes = minetest.registered_nodes local core_swap_node = minetest.swap_node local deserialize = minetest.deserialize local get_craft_recipe = minetest.get_craft_recipe -local has_creative = creative.is_enabled_for +local has_creative = minetest.global_exists('creative') + and creative.is_enabled_for or function() return false end local serialize = minetest.serialize local us_time = minetest.get_us_time -- vector From 68675eacf57995c158732ab34c1a8e0b4696119c Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 24 Jul 2024 14:47:11 +0200 Subject: [PATCH 332/366] add replacer.no() there is a replacer.yes() function (not used by replacer) so makes sense to offer api for no() -> false (used by games not providing creative global). --- replacer/constrain.lua | 4 ++++ replacer/replacer.lua | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/replacer/constrain.lua b/replacer/constrain.lua index fc35d2b..94dcc8f 100644 --- a/replacer/constrain.lua +++ b/replacer/constrain.lua @@ -56,6 +56,10 @@ if nil == replacer.hide_recipe_technic_direct then replacer.hide_recipe_technic_direct = true end + +function replacer.no() return false end + + -- function that other mods, especially custom server mods, -- can override. e.g. restrict usage of replacer in certain -- areas, privs, throttling etc. diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 6b1a049..34cfb10 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -21,7 +21,7 @@ local core_swap_node = minetest.swap_node local deserialize = minetest.deserialize local get_craft_recipe = minetest.get_craft_recipe local has_creative = minetest.global_exists('creative') - and creative.is_enabled_for or function() return false end + and creative.is_enabled_for or r.no local serialize = minetest.serialize local us_time = minetest.get_us_time -- vector From 609643352f6baa0c39beb91bc47fa86d0a28be56 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 24 Jul 2024 14:49:32 +0200 Subject: [PATCH 333/366] add replacer.log() not strictly part of xcompat support, just couldn't help myself. log messages aren't translated, so no need to rework locale files for this. --- blabla.lua | 30 +++++++++++++++--------------- inspect.lua | 7 +++---- replacer/constrain.lua | 6 +++--- replacer/enable.lua | 12 ++++++------ replacer/formspecs.lua | 5 ++--- utils.lua | 12 +++++++++++- 6 files changed, 40 insertions(+), 32 deletions(-) diff --git a/blabla.lua b/blabla.lua index f9a8c5c..f3e58ec 100644 --- a/blabla.lua +++ b/blabla.lua @@ -23,7 +23,7 @@ replacer.blabla.inspect = {} local rb = replacer.blabla local rbi = replacer.blabla.inspect -rb.log_messages = '[replacer] %s: %s' +rb.log_messages = '%s: %s' rb.choose_history = S('History') rb.choose_mode = S('Choose mode') rb.mode_minor1 = S('Both') @@ -50,9 +50,9 @@ rb.too_many_nodes_detected = S('Aborted, too many nodes detected.') rb.none_selected = S('Error: No node selected.') rb.description_basic = S('Node replacement tool') rb.description_technic = S('Node replacement tool (technic)') -rb.log_limit_override = '[replacer] Setting already set node-limit for "%s" was %d.' -rb.log_limit_insert = '[replacer] Setting node-limit for "%s" to %d.' -rb.log_deny_list_insert = '[replacer] Added "%s" to deny list.' +rb.log_limit_override = 'Setting already set node-limit for "%s" was %d.' +rb.log_limit_insert = 'Setting node-limit for "%s" to %d.' +rb.log_deny_list_insert = 'Added "%s" to deny list.' rb.timed_out = S('Time-limit reached.') rb.tool_short_description = '(%s %s%s) %s' rb.tool_long_description = '%s\n%s\n%s' @@ -61,16 +61,16 @@ rb.ccm_description = S('Toggles verbosity.\nchat: When on, ' .. 'messages are posted to chat.\naudio: When off, replacer is silent.') rb.ccm_player_not_found = 'Player not found' rb.ccm_player_meta_error = 'Player meta not existant' -rb.log_reg_exception_override = '[replacer] register_exception: ' +rb.log_reg_exception_override = 'register_exception: ' .. 'exception for "%s" already exists.' -rb.log_reg_exception = '[replacer] registered exception for "%s" to "%s"' -rb.log_reg_exception_callback = '[replacer] registered after on_place callback for "%s"' -rb.log_reg_alias_override = '[replacer] register_non_creative_alias: ' +rb.log_reg_exception = 'registered exception for "%s" to "%s"' +rb.log_reg_exception_callback = 'registered after on_place callback for "%s"' +rb.log_reg_alias_override = 'register_non_creative_alias: ' .. ' alias for "%s" already exists.' -rb.log_reg_alias = '[replacer] registered alias for "%s" to "%s"' -rb.log_reg_set_callback_fail = '[replacer] register_set_enabler called without passing function.' -rb.formspec_error = '[replacer] formspec error, user "%s" attempting to change history. Fields: %s' -rb.formspec_hacker = '[replacer] formspec forge? By user "%s" Fields: %s' +rb.log_reg_alias = 'registered alias for "%s" to "%s"' +rb.log_reg_set_callback_fail = 'register_set_enabler called without passing function.' +rb.formspec_error = 'formspec error, user "%s" attempting to change history. Fields: %s' +rb.formspec_hacker = 'formspec forge? By user "%s" Fields: %s' rb.minor_modes_disabled = S('Minor modes are disabled on this server.') rb.no_pos = S('') rb.days = S('days') @@ -99,9 +99,9 @@ rbi.nothing = S('nothing.') rbi.may_drop_on_dig = S('May drop on dig:') rbi.can_be_fuel = S('This can be used as a fuel.') rbi.unknown_recipe = S('Error: Unknown recipe.') -rbi.log_reg_craft_method_wrong_arguments = '[replacer] register_craft_method invalid arguments given.' -rbi.log_reg_craft_method_overriding_method = '[replacer] register_craft_method overriding existing method ' -rbi.log_reg_craft_method_added = '[replacer] register_craft_method method added: %s %s' +rbi.log_reg_craft_method_wrong_arguments = 'register_craft_method invalid arguments given.' +rbi.log_reg_craft_method_overriding_method = 'register_craft_method overriding existing method ' +rbi.log_reg_craft_method_added = 'register_craft_method method added: %s %s' rbi.scoop = S('scoop up') rbi.pour = S('pour out') rbi.filling = S('filling') diff --git a/inspect.lua b/inspect.lua index d7db9d3..462609a 100644 --- a/inspect.lua +++ b/inspect.lua @@ -17,7 +17,6 @@ local concat = table.concat local insert = table.insert local chat = minetest.chat_send_player local mfe = minetest.formspec_escape -local core_log = minetest.log local deserialize = minetest.deserialize local parse_json = minetest.parse_json local get_node_or_nil = minetest.get_node_or_nil @@ -56,12 +55,12 @@ function replacer.register_craft_method(uid, machine_itemstring, func_inspect, or ('string' ~= type(machine_itemstring)) or ('function' ~= type(func_inspect)) then - core_log('warning', rbi.log_reg_craft_method_wrong_arguments) + r.log(rbi.log_reg_craft_method_wrong_arguments) return end if r.recipe_adders[uid] then - core_log('warning', rbi.log_reg_craft_method_overriding_method .. uid) + r.log(rbi.log_reg_craft_method_overriding_method .. uid) end r.recipe_adders[uid] = { @@ -69,7 +68,7 @@ function replacer.register_craft_method(uid, machine_itemstring, func_inspect, add_recipe = func_inspect, formspec = ('function' == type(func_formspec) and func_formspec) or nil } - core_log('info', rbi.log_reg_craft_method_added:format(uid, machine_itemstring)) + r.log('info', rbi.log_reg_craft_method_added:format(uid, machine_itemstring)) end -- register_craft_method diff --git a/replacer/constrain.lua b/replacer/constrain.lua index 94dcc8f..975c197 100644 --- a/replacer/constrain.lua +++ b/replacer/constrain.lua @@ -95,15 +95,15 @@ function replacer.register_limit(node_name, node_max) -- add to deny_list if limit is zero if 0 == node_max then r.deny_list[node_name] = true - minetest.log('info', rb.log_deny_list_insert:format(node_name)) + r.log('info', rb.log_deny_list_insert:format(node_name)) return end -- log info if already limited if nil ~= r.limit_list[node_name] then - minetest.log('info', rb.log_limit_override:format(node_name, r.limit_list[node_name])) + r.log('info', rb.log_limit_override:format(node_name, r.limit_list[node_name])) end r.limit_list[node_name] = node_max - minetest.log('info', rb.log_limit_insert:format(node_name, node_max)) + r.log('info', rb.log_limit_insert:format(node_name, node_max)) end -- register_limit diff --git a/replacer/enable.lua b/replacer/enable.lua index ef69bcd..37c1479 100644 --- a/replacer/enable.lua +++ b/replacer/enable.lua @@ -28,15 +28,15 @@ replacer.alias_map = {} -- r.register_exception('mobs:cobweb', 'mobs:cobweb') function replacer.register_exception(node_name, drop_name, callback) if r.exception_map[node_name] then - minetest.log('warning', rb.log_reg_exception_override:format(node_name)) + r.log('warning', rb.log_reg_exception_override:format(node_name)) end r.exception_map[node_name] = drop_name - minetest.log('info', rb.log_reg_exception:format(node_name, drop_name)) + r.log('info', rb.log_reg_exception:format(node_name, drop_name)) if 'function' ~= type(callback) then return end r.exception_callbacks[node_name] = callback - minetest.log('info', rb.log_reg_exception_callback:format(node_name)) + r.log('info', rb.log_reg_exception_callback:format(node_name)) end -- register_exception @@ -48,10 +48,10 @@ end -- register_exception -- replacer.register_non_creative_alias('vines:jungle_middle', 'vines:jungle_end') function replacer.register_non_creative_alias(name_sibling, name_placed) if r.alias_map[name_sibling] then - minetest.log('warning', rb.log_reg_alias_override:format(name_sibling)) + r.log('warning', rb.log_reg_alias_override:format(name_sibling)) end r.alias_map[name_sibling] = name_placed - minetest.log('info', rb.log_reg_alias:format(name_sibling, name_placed)) + r.log('info', rb.log_reg_alias:format(name_sibling, name_placed)) end -- register_non_creative_alias @@ -73,7 +73,7 @@ end -- register_non_creative_alias -- the callback signature is f(node, player, pointed_thing) function replacer.register_set_enabler(callback) if 'function' ~= type(callback) then - minetest.log('error', rb.log_reg_set_callback_fail) + r.log('error', rb.log_reg_set_callback_fail) return end diff --git a/replacer/formspecs.lua b/replacer/formspecs.lua index 9a83b09..4286736 100644 --- a/replacer/formspecs.lua +++ b/replacer/formspecs.lua @@ -3,7 +3,6 @@ local r = replacer local rb = replacer.blabla -local log = minetest.log local get_player_information = minetest.get_player_information local mfe = minetest.formspec_escape local check_player_privs = minetest.check_player_privs @@ -150,7 +149,7 @@ function replacer.on_player_receive_fields(player, form_name, fields) elseif fields.history then -- ignore if user doesn't have privs if not check_player_privs(name, r.history_priv) then - log('info', rb.formspec_error:format(name, dump(fields))) + r.log('info', rb.formspec_error:format(name, dump(fields))) return end local entry = r.history.get_by_index(player, tonumber(fields.history) or 1) @@ -163,7 +162,7 @@ function replacer.on_player_receive_fields(player, form_name, fields) return else -- some hacked client forging formspec? - log('info', rb.formspec_hacker:format(name, dump(fields))) + r.log('info', rb.formspec_hacker:format(name, dump(fields))) return end diff --git a/utils.lua b/utils.lua index 94f4507..3d0ab33 100644 --- a/utils.lua +++ b/utils.lua @@ -38,7 +38,7 @@ end -- common_list_items function replacer.inform(name, message) if (not message) or ('' == message) then return end - core_log('info', rb.log_messages:format(name, message)) + r.log('info', rb.log_messages:format(name, message)) local player = get_player_by_name(name) if not player then return end @@ -50,6 +50,16 @@ function replacer.inform(name, message) end -- inform +function replacer.log(level, message) + if not message then + message = level + level = 'warning' + end + + core_log(level, '[replacer] ' .. message) +end -- log + + function replacer.nice_duration(seconds) if 'number' ~= type(seconds) then return '' end From 1fcb17406d1ec2a06aae368026eb454b9be0ef82 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 28 Jul 2024 03:37:47 +0200 Subject: [PATCH 334/366] make sure these are booleans --- init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index e03e0c7..72d38cd 100644 --- a/init.lua +++ b/init.lua @@ -29,11 +29,11 @@ replacer.version = 20240225 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') and minetest.global_exists('dye') - and dye.basecolors + and dye.basecolors and true or false replacer.has_circular_saw = minetest.get_modpath('moreblocks') and minetest.global_exists('moreblocks') and minetest.global_exists('circular_saw') - and circular_saw.names + and circular_saw.names and true or false replacer.has_colormachine_mod = minetest.get_modpath('colormachine') and minetest.global_exists('colormachine') replacer.has_technic_mod = minetest.get_modpath('technic') From b2bc1d2071cea4e17e496d6f5de654ed55610180 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 28 Jul 2024 03:49:41 +0200 Subject: [PATCH 335/366] xcompat sounds 'whitespace' reformat --- xcompat.lua | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/xcompat.lua b/xcompat.lua index 90bc347..4c8b10d 100644 --- a/xcompat.lua +++ b/xcompat.lua @@ -1,5 +1,9 @@ local r = replacer r.materials = {} +r.sounds = { + fail = { name = '' }, + success = { name = '' }, +} local rm = r.materials if r.has_xcompat_mod then @@ -21,14 +25,6 @@ if r.has_xcompat_mod then until 0 == i end - r.sounds = { - fail = { - name = '' - }, - success = { - name = '' - } - } local sound = xcompat.sounds.node_sound_glass_defaults() if sound and sound.dug and sound.dug.name then r.sounds.fail.name = sound.dug.name @@ -54,14 +50,8 @@ else torch = 'default:torch', } - r.sounds = { - fail = { - name = 'default_break_glass' - }, - success = { - name = 'default_item_smoke' - } - } + r.sounds.fail.name = 'default_break_glass' + r.sounds.success.name = 'default_item_smoke' end if r.has_technic_mod then From 0ca5fddd49468f3f9b4d27cb8d938e14bb606a90 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 28 Jul 2024 03:50:15 +0200 Subject: [PATCH 336/366] xcompat materials 'whitespace' reformat --- xcompat.lua | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/xcompat.lua b/xcompat.lua index 4c8b10d..ca659e8 100644 --- a/xcompat.lua +++ b/xcompat.lua @@ -40,15 +40,13 @@ if r.has_xcompat_mod then end else -- assume default game - r.materials = { - chest = 'default:chest', - dirt = 'default:dirt', - gold_ingot = 'default:gold_ingot', - mese_crystal_fragment = 'default:mese_crystal_fragment', - steel_ingot = 'default:steel_ingot', - stick = 'default:stick', - torch = 'default:torch', - } + rm.chest = 'default:chest' + rm.dirt = 'default:dirt' + rm.gold_ingot = 'default:gold_ingot' + rm.mese_crystal_fragment = 'default:mese_crystal_fragment' + rm.steel_ingot = 'default:steel_ingot' + rm.stick = 'default:stick' + rm.torch = 'default:torch' r.sounds.fail.name = 'default_break_glass' r.sounds.success.name = 'default_item_smoke' From dd65ce6c593de0ea46491feb47556c84581b3808 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 28 Jul 2024 03:50:52 +0200 Subject: [PATCH 337/366] add 'xcompat' machines --- xcompat.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/xcompat.lua b/xcompat.lua index ca659e8..92f54a0 100644 --- a/xcompat.lua +++ b/xcompat.lua @@ -1,5 +1,6 @@ local r = replacer r.materials = {} +r.machines = {} r.sounds = { fail = { name = '' }, success = { name = '' }, @@ -59,3 +60,21 @@ if r.has_technic_mod then --r.sounds.success.gain = 0.1 end + +-- machines are not yet covered by xcompat +local gameid = xcompat.gameid +if 'farlands_reloaded' == gameid then + r.machines.furnace = 'fl_workshop:furnace' + r.machines.furnace_active = 'fl_workshop:furnace_active' +elseif 'hades_revisited' == gameid then + r.machines.furnace = 'hades_furnaces:furnace' + r.machines.furnace_active = 'hades_furnaces:furnace_active' +elseif 'mineclonia' == gameid then + r.machines.furnace = 'mcl_furnaces:furnace' + r.machines.furnace_active = 'mcl_furnaces:furnace_active' +else + -- fallback to default game + r.machines.furnace = 'default:furnace' + r.machines.furnace_active = 'default:furnace_active' +end + From 3d14ba1381173245d3629ce3c9c74e6135d15176 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 28 Jul 2024 03:51:32 +0200 Subject: [PATCH 338/366] exclude some liquids from test --- test.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test.lua b/test.lua index 93497c4..bc33ee3 100644 --- a/test.lua +++ b/test.lua @@ -23,7 +23,12 @@ rt.skip = { '^air$', '^ignore$', 'corium', '^tnt:', '^technic:hv_nuclear_reactor_core_active$', '^default:lava_source$', '^default:lava_flowing$', + '^hades_core:lava_source$', '^hades_core:lava_flowing$', + '^mcl_core:lava_source$', '^mcl_core:lava_flowing$', '^default:.*water_source$', '^default:.*water_flowing$', + '^hades_core:water_source$', '^hades_core:water_flowing$', + '^ks_terrain:water_source$', '^ks_terrain:water_flowing$', + '^mcl_core:water_source$', '^mcl_core:water_flowing$', --'^default:large_cactus_seedling$', -- depends on support_node '^digistuff:heatsink_onic$', -- depends on support_node --'^farming:seed_', -- depends on support_node From cc123cc429c2a0b65a84a66bc486585945fcd68d Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 28 Jul 2024 04:02:15 +0200 Subject: [PATCH 339/366] handle farlands and mineclonia mobs limited extent --- inspect.lua | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/inspect.lua b/inspect.lua index 462609a..4553c95 100644 --- a/inspect.lua +++ b/inspect.lua @@ -329,6 +329,13 @@ view_range end -- inspect_mob +function replacer.inspect_mob_farlands_reloaded(luaob) + local text = '\n' + text = text .. S('Health: @1/@2', luaob.hp or '?', luaob.max_hp or '?') + return text +end -- inspect_mob_farlands_reloaded + + function replacer.inspect_player(object_ref, player) local lines = { S('This is your fellow player "@1"', object_ref:get_player_name()) } local meta = object_ref:get_meta() @@ -425,7 +432,13 @@ function replacer.inspect_entity(object_ref, player) end if not registered_entities[luaob.name] then return text end - if luaob._cmi_is_mob then return text .. r.inspect_mob(luaob) end + if luaob._cmi_is_mob or luaob.name:find('^mobs_mc:') then + -- mobs_redo, mineclonia and VoxelLibre mobs + return text .. r.inspect_mob(luaob) + elseif luaob.name:find('^fl_wildlife:') then + -- farlands_reloaded mob + return text .. r.inspect_mob_farlands_reloaded(luaob) + end return text end -- inspect_entity @@ -443,6 +456,11 @@ function replacer.inspect_staticdata(staticdata) text = text .. S(', dropped @1 minutes ago', tostring(floor((sdata.age / 60) + .5))) end + if 'number' == type(sdata.health) then + -- mineclonia / VoxelLibre + text = text .. '\n' .. S('Health: @1/@2', + tostring(.1 * floor(10 * (sdata.health + 0.05))), '?') + end if sdata.owner then if true == sdata.protected then if true == sdata.locked then From fd62e8b4e58e68568e1d4aa618d86e66cab1c13c Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 28 Jul 2024 04:03:06 +0200 Subject: [PATCH 340/366] locale 'Health: x/y' --- locale/replacer.de.tr | 2 +- locale/replacer.es.tr | 1 + locale/replacer.fi.tr | 1 + locale/replacer.fr.tr | 1 + locale/replacer.it.tr | 1 + locale/replacer.pt.tr | 1 + locale/replacer.ru.tr | 1 + locale/template.txt | 1 + 8 files changed, 8 insertions(+), 1 deletion(-) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index 8a188ac..daea92b 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -125,4 +125,4 @@ separating=Trennen painting=Malen fermenting=Fermentieren Ferment in barrel.=Gärung im Fass. - +Health: @1/@2=Gesundheit: @1 von @2 diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index df40df9..277f839 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -125,3 +125,4 @@ separating=separando painting=pintaando fermenting=fermentando Ferment in barrel.=Fermentación en barrica. +Health: @1/@2=Salud: @1 de @2 diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index a91c3e1..3394255 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -125,3 +125,4 @@ separating=erottava painting=maalaus fermenting=käyminen Ferment in barrel.=Fermentoida tynnyrissä. +Health: @1/@2=Terveys: @1/@2 diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index ed8189b..2b1a73c 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -125,3 +125,4 @@ separating=séparer painting=peindre fermenting=fermentation Ferment in barrel.=Fermentation en barrique. +Health: @1/@2=Santé: @1/@2 diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index f7083dd..159c4f4 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -125,3 +125,4 @@ separating=separare painting=dipingere fermenting=fermentazione Ferment in barrel.=Fermentazione in botte. +Health: @1/@2=Salute: @1/@2 diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index d628650..0455d69 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -125,3 +125,4 @@ separating=separando painting=pintar fermenting=fermentando Ferment in barrel.=Fermentar em barril. +Health: @1/@2=Saúde: @1/@2 diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index ca897b7..f10e860 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -125,3 +125,4 @@ separating=разделяющий painting=рисования fermenting=брожение Ferment in barrel.=Ферментация в бочке. +Health: @1/@2=Здоровье: @1/@2 diff --git a/locale/template.txt b/locale/template.txt index 3f48f4d..be51d9b 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -125,3 +125,4 @@ separating= painting= fermenting= Ferment in barrel.= +Health: @1/@2= From ccc94839aae0645a02be9ff781ef1531289b5898 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 28 Jul 2024 04:04:38 +0200 Subject: [PATCH 341/366] inspect dynamic group fallback --- inspect.lua | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/inspect.lua b/inspect.lua index 4553c95..80b3fc6 100644 --- a/inspect.lua +++ b/inspect.lua @@ -503,15 +503,25 @@ end -- inspect_staticdata function replacer.image_button_link(stack_string) - local group = '' + local group, g = '' if r.image_replacements[stack_string] then stack_string = r.image_replacements[stack_string] end if r.group_placeholder[stack_string] then stack_string = r.group_placeholder[stack_string] group = 'G' + elseif stack_string:find('^:?group:') then + -- dynamically figure out a group replacement + g = stack_string:sub(1 + stack_string:find(':', 2)) + for item_name, _ in pairs(registered_items) do + if 0 ~= minetest.get_item_group(item_name, g) then + r.group_placeholder[stack_string] = item_name + stack_string = item_name + group = 'G' + break + end + end end --- TODO: show information about other groups not handled above local stack = ItemStack(stack_string) local new_node_name = stack:get_name() --pd(stack_string .. ';' .. new_node_name .. ';' .. group) From 5e0c5c7d7a65b80edbd1a920fae9b87b615e33d4 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 28 Jul 2024 04:05:52 +0200 Subject: [PATCH 342/366] inspect: game agnostic machines --- inspect.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inspect.lua b/inspect.lua index 80b3fc6..55d297c 100644 --- a/inspect.lua +++ b/inspect.lua @@ -723,7 +723,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) and '' == recipe.output then formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' - .. r.image_button_link('default:furnace_active') .. ']' + .. r.image_button_link(r.machines.furnace_active) .. ']' .. 'item_image_button[2.9,2.7;1.0,1.0;' .. r.image_button_link(recipe.items[1]) .. ']' .. 'label[1.0,0;' .. tostring(recipe.items[1]) .. ']' @@ -733,7 +733,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) and 1 == #recipe.items then formspec = formspec .. 'item_image_button[1,1;3.4,3.4;' - .. r.image_button_link('default:furnace') .. ']' + .. r.image_button_link(r.machines.furnace) .. ']' .. 'item_image_button[2.2,2.2;1.0,1.0;' .. r.image_button_link(recipe.items[1]) .. ']' elseif recipe.items From d811cbf6e7e23de93188839358879e8f2807c0ec Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 28 Jul 2024 04:08:02 +0200 Subject: [PATCH 343/366] inspect formspec size tweak mainly for mineclonia family that uses many multiline descriptions. Only shows one more line nicely, some items ave three or even more though. --- inspect.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inspect.lua b/inspect.lua index 55d297c..2365181 100644 --- a/inspect.lua +++ b/inspect.lua @@ -622,7 +622,7 @@ function replacer.inspect_show_crafting(player_name, node_name, fields) end -- base info - local formspec = 'size[6,6]' + local formspec = 'size[6,6.5]' -- label on top --.. 'textarea[-9,-18,6,1;;' .. mfe(rbi.name) .. ' ' .. node_name .. ';]' .. 'label[0,0;' .. mfe(rbi.name) .. ' ' .. node_name .. ']' From 184637f688371e76ee944981954eb32a96ed6a2d Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 28 Jul 2024 04:08:48 +0200 Subject: [PATCH 344/366] support any game in CDB --- mod.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/mod.conf b/mod.conf index bea4d23..77a8ee4 100644 --- a/mod.conf +++ b/mod.conf @@ -1,4 +1,5 @@ name = replacer description = Replacement tool for creative building and tool to inspect nodes. optional_depends = colormachine, default, dye, moreblocks, technic, unifieddyes, xcompat +supported_games = * From 26958343b3019c37d60f83dfcdadb4a0624e4758 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sat, 3 Aug 2024 12:02:17 +0200 Subject: [PATCH 345/366] fix spelling, wording, spacing and some comments - persistancy -> persistency - acheivment -> achievement --- chat_commands.lua | 7 +++++-- doc/customization.md | 6 +++--- init.lua | 4 ++-- replacer/constrain.lua | 6 +++--- replacer/history.lua | 6 +++--- settingtypes.txt | 14 +++++++++++++- xcompat.lua | 3 +++ 7 files changed, 32 insertions(+), 14 deletions(-) diff --git a/chat_commands.lua b/chat_commands.lua index 8460a5c..d5c8079 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -15,11 +15,14 @@ replacer.chatcommand_mute = { description = rb.ccm_description, func = function(name, param) local player = minetest.get_player_by_name(name) - if not player then -- TODO: seems unlikely to happen + -- can happen if command was issued by e.g. command block + -- while owner isn't online. Rather unlikely but possible. + if not player then return false, rb.ccm_player_not_found end local meta = player:get_meta() - if not meta then -- TODO: seems unlikely to happen + -- TODO: low chance of this happening, above check would already fail. + if not meta then return false, rb.ccm_player_meta_error end diff --git a/doc/customization.md b/doc/customization.md index 3245f76..9cf6d56 100644 --- a/doc/customization.md +++ b/doc/customization.md @@ -39,11 +39,11 @@ only node or rotation is applied. ### replacer.history_priv (creative) You can make history available to users with this priv. By default it is set to **creative** -as survival users can make several replacers. You can make this an acheivment for busy players +as survival users can make several replacers. You can make this an achievement for busy players to work towards, or set to **interact** to allow any player to use history of previously used node settings. -### replacer.history_disable_persistancy (false) +### replacer.history_disable_persistency (false) When set, does not save history over sessions. Reason might be old MT version.
Currently history is stored in player's meta on logoff and at intervals. @@ -153,7 +153,7 @@ replacer.register_set_enabler(callback) ## Inspection Tool -### adding craft methods +### Adding craft methods Some mods provide precesses that go beyond simple crafting, mixing or cooking. To provide better support for those there is: ```lua diff --git a/init.lua b/init.lua index 72d38cd..b4116d8 100644 --- a/init.lua +++ b/init.lua @@ -52,9 +52,9 @@ replacer.image_replacements = {} local path = minetest.get_modpath('replacer') .. '/' -- for developers dofile(path .. 'test.lua') --- strings for translation (i+r) +-- strings for translation (inspect & replacer) dofile(path .. 'blabla.lua') --- utilities (i+r) +-- utilities (inspect & replacer) -- material and sound compatibility for various games dofile(path .. 'xcompat.lua') dofile(path .. 'utils.lua') diff --git a/replacer/constrain.lua b/replacer/constrain.lua index 975c197..2bb2e84 100644 --- a/replacer/constrain.lua +++ b/replacer/constrain.lua @@ -34,9 +34,9 @@ replacer.disable_minor_modes = -- priv to allow using history replacer.history_priv = minetest.settings:get('replacer.history_priv') or 'creative' -- disable saving history over sessions/reboots. IOW: don't use player meta e.g. if using old MT -replacer.history_disable_persistancy = - minetest.settings:get_bool('replacer.history_disable_persistancy') or false --- ignored when persistancy is disabled. Interval in minutes to +replacer.history_disable_persistency = + minetest.settings:get_bool('replacer.history_disable_persistency') or false +-- ignored when persistency is disabled. Interval in minutes to replacer.history_save_interval = tonumber(minetest.settings:get('replacer.history_save_interval') or 7) -- include mode when changing from history diff --git a/replacer/history.lua b/replacer/history.lua index bd9320b..f037658 100644 --- a/replacer/history.lua +++ b/replacer/history.lua @@ -98,7 +98,7 @@ end -- on_priv_revoke function replacer.history.save(player) local name = player:get_player_name() - if r.history_disable_persistancy then + if r.history_disable_persistency then r.history.db[name] = nil r.history.dirty[name] = nil return @@ -121,8 +121,8 @@ minetest.register_on_joinplayer(r.history.init_player) minetest.register_on_leaveplayer(r.history.dealloc_player) minetest.register_on_priv_grant(r.history.on_priv_grant) minetest.register_on_priv_revoke(r.history.on_priv_revoke) -if not r.history_disable_persistancy then +if not r.history_disable_persistency then r.history_save_interval = 60 * r.history_save_interval minetest.after(r.history_save_interval, r.history.auto_save) -end -- if persistancy is enabled +end -- if persistency is enabled diff --git a/settingtypes.txt b/settingtypes.txt index a8cc543..9587827 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -3,32 +3,44 @@ # On singleplayer you can mostly use a higher value. # The default is 3168 replacer.max_nodes (Maximum nodes to replace with one click) int 3168 + # Some nodes take a long time to be placed. This value limits the time # in seconds in which the nodes are placed. replacer.max_time (Time limit when putting nodes) float 1.0 + # Radius limit factor when more possible positions are found than either max_nodes or charge # Set to 0 or less for behaviour of before version 3.3 replacer.radius_factor (A factor to adjust size limit) float 0.4 + # If you don't want to use the minor modes at all, set to true replacer.disable_minor_modes (Disable using minor modes) bool false + # You can make history available to users with this priv. By default it is set to creative # as non-creative users can make several replacers. replacer.history_priv (Priv needed to allow using history) string creative + # When set, does not save history over sessions. Reason might be old MT version. -replacer.history_disable_persistancy (Disable saving history) bool false +replacer.history_disable_persistency (Disable saving history) bool false + # How frequently history is saved to player-meta. Only users with the priv are affected. replacer.history_save_interval (Interval in minutes at which history is saved) int 7 + # When set, changes the replacer's major and minor modes when picking an item from history. # The modes are stored either way. replacer.history_include_mode (Should picking from history also set mode) bool false + # Limit history length. Duplicates are removed so there isn't much need for long histories. replacer.history_max (Maximum amount of history items) int 7 2 55555 + # You may choose to hide basic recipe but then make sure to enable the technic direct one replacer.hide_recipe_basic (Hide basic recipe) bool false + # Hide the upgrade recipe. Only available if technic is installed. replacer.hide_recipe_technic_upgrade (Hide upgrade recipe) bool false + # Hide the direct upgrade recipe. Only available if technic is installed. replacer.hide_recipe_technic_direct (Hide direct recipe) bool true + # Enable developer mode replacer.dev_mode (Enable developer mode) bool false diff --git a/xcompat.lua b/xcompat.lua index 92f54a0..671dcd1 100644 --- a/xcompat.lua +++ b/xcompat.lua @@ -1,6 +1,9 @@ local r = replacer +-- materials for crafting recipes r.materials = {} +-- machines for inspector to show standard processes r.machines = {} +-- sounds for replacer feedback r.sounds = { fail = { name = '' }, success = { name = '' }, From 7c2cacebe8e2cb4fc577b6a4652396e66f88de94 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sat, 3 Aug 2024 16:05:40 +0200 Subject: [PATCH 346/366] expose has_creative() --- doc/customization.md | 12 ++++++++++++ replacer/replacer.lua | 3 +-- utils.lua | 11 +++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/doc/customization.md b/doc/customization.md index 9cf6d56..9ef54aa 100644 --- a/doc/customization.md +++ b/doc/customization.md @@ -3,6 +3,7 @@ Customization documentation for replacer minetest mod - [Settings](#settings) - [API Commands](#api-commands) +- [Overrides](#overrides) - [Inspection Tool](#inspection-tool) ## Settings @@ -151,6 +152,17 @@ replacer.register_set_enabler(callback) ``` [More details in (replacer/enable.lua)](replacer/enable.lua) +## Overrides + +Most functions are public and can be overridden. + +### Creative priv check +Depending on game there may not be ```creative``` global and +its functions. Or you may want to give creative priv to some users +but only when they are using replacer. For this you can override +```replacer.has_creative(name)``` function returning a boolean value. +[Default located in (utils.lua)](utils.lua) + ## Inspection Tool ### Adding craft methods diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 34cfb10..caac4ed 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -20,8 +20,7 @@ local core_registered_nodes = minetest.registered_nodes local core_swap_node = minetest.swap_node local deserialize = minetest.deserialize local get_craft_recipe = minetest.get_craft_recipe -local has_creative = minetest.global_exists('creative') - and creative.is_enabled_for or r.no +local has_creative = r.has_creative local serialize = minetest.serialize local us_time = minetest.get_us_time -- vector diff --git a/utils.lua b/utils.lua index 3d0ab33..cd4c805 100644 --- a/utils.lua +++ b/utils.lua @@ -35,6 +35,17 @@ function replacer.common_list_items(list1, list2) end -- common_list_items +-- expose creative check function for servers/games to override +-- e.g. server override could check for a priv allowing +-- user to have 'creative' priv only with replacer +function replacer.has_creative(name) + if minetest.global_exists('creative') and creative.is_enabled_for then + return creative.is_enabled_for(name) + end + return false +end -- has_creative + + function replacer.inform(name, message) if (not message) or ('' == message) then return end From 087dced6371c3da63e5d3826b1fb2aef531d0f9f Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sat, 3 Aug 2024 16:09:15 +0200 Subject: [PATCH 347/366] allow technic replacer without [technic] --- crafts.lua | 9 +++++++++ doc/customization.md | 6 ++++++ replacer/enable.lua | 4 ++++ replacer/replacer.lua | 18 +++++++++++------- settingtypes.txt | 4 ++++ xcompat.lua | 2 ++ 6 files changed, 36 insertions(+), 7 deletions(-) diff --git a/crafts.lua b/crafts.lua index 335d641..61785bd 100644 --- a/crafts.lua +++ b/crafts.lua @@ -36,6 +36,15 @@ if r.has_technic_mod then } }) end +elseif r.enable_recipe_technic_without_technic then + minetest.register_craft({ + output = r.tool_name_technic, + recipe = { + { rm.chest, rm.axe_diamond, rm.gold_ingot }, + { rm.axe_diamond, rm.mese_crystal_fragment, rm.axe_diamond }, + { rm.steel_ingot, rm.axe_diamond, rm.chest }, + } + }) end diff --git a/doc/customization.md b/doc/customization.md index 9ef54aa..df58926 100644 --- a/doc/customization.md +++ b/doc/customization.md @@ -73,6 +73,12 @@ Hides the direct recipe of technic replacer that does not require a basic replac ingredient.
Only available if technic is installed. +### replacer.enable_recipe_technic_without_technic (false) +Enables a direct recipe of technic replacer without technic mod installed.
+The recipe is rather cheap and it is recommended to override it to play well with
+the type of server you are running.
+Only has effect if technic isn't installed. + ### replacer.dev_mode (false) Enable developer mode which gives users with **priv** priv to run **/place_all** chat command.
This is not recommended on live servers as some nodes your mods provide may crash the server diff --git a/replacer/enable.lua b/replacer/enable.lua index 37c1479..a9e4560 100644 --- a/replacer/enable.lua +++ b/replacer/enable.lua @@ -1,6 +1,10 @@ local r = replacer local rb = replacer.blabla +replacer.enable_recipe_technic_without_technic = + minetest.settings:get_bool('replacer.enable_recipe_technic_without_technic') + or false + -- see replacer.register_exception() replacer.exception_map = {} replacer.exception_callbacks = {} diff --git a/replacer/replacer.lua b/replacer/replacer.lua index caac4ed..2e56f3c 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -722,23 +722,27 @@ end minetest.register_tool(r.tool_name_basic, r.tool_def_basic()) -if r.has_technic_mod then - function replacer.tool_def_technic() - local def = r.tool_def_basic() - def.description = rb.description_technic +function replacer.tool_def_technic() + local def = r.tool_def_basic() + def.description = rb.description_technic + if r.has_technic_mod then if technic.plus then def.technic_max_charge = r.max_charge else def.wear_represents = 'technic_RE_charge' def.on_refill = technic.refill_RE_charge end - return def end - if technic.plus then + return def +end +if r.has_technic_mod or r.enable_recipe_technic_without_technic then + if r.has_technic_mod and technic.plus then technic.register_power_tool(r.tool_name_technic, r.tool_def_technic()) - else + elseif r.has_technic_mod then technic.register_power_tool(r.tool_name_technic, r.max_charge) minetest.register_tool(r.tool_name_technic, r.tool_def_technic()) + else + minetest.register_tool(r.tool_name_technic, r.tool_def_technic()) end end diff --git a/settingtypes.txt b/settingtypes.txt index 9587827..a1fa4d0 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -41,6 +41,10 @@ replacer.hide_recipe_technic_upgrade (Hide upgrade recipe) bool false # Hide the direct upgrade recipe. Only available if technic is installed. replacer.hide_recipe_technic_direct (Hide direct recipe) bool true +# Enable technic replacer recipe without technic mod installed. You may want to +# override the recipe to match your server type and be more expensive. +replacer.enable_recipe_technic_without_technic (Enable technic replacer without [technic]) bool false + # Enable developer mode replacer.dev_mode (Enable developer mode) bool false diff --git a/xcompat.lua b/xcompat.lua index 671dcd1..faa660f 100644 --- a/xcompat.lua +++ b/xcompat.lua @@ -14,6 +14,7 @@ if r.has_xcompat_mod then -- let xcompat decide what is available do local material_keys = { + 'axe_diamond', 'chest', 'dirt', 'gold_ingot', @@ -44,6 +45,7 @@ if r.has_xcompat_mod then end else -- assume default game + rm.axe_diamond = 'default:axe_diamond' rm.chest = 'default:chest' rm.dirt = 'default:dirt' rm.gold_ingot = 'default:gold_ingot' From 5d5dfc0f2127bb8d257bd4e518acc2aeafba26df Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sat, 3 Aug 2024 18:55:04 +0200 Subject: [PATCH 348/366] version bump 4.93 --- CHANGELOG | 1 + init.lua | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3e6e85c..b4cf767 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +20240803 * SwissalpS made replacer game agnostic (using [xcompat]). 20240225 * SwissalpS patched a crash situation with multinode-nodes. Thanks frogTheSecond and Huhhila for detecting and reporting. 20221107 * fluxionary fixed typo unkown -> unknown 20220830 * SwissalpS fixed de translation typo. Thanks Niklp09 for reporting. diff --git a/init.lua b/init.lua index b4116d8..f8cbb75 100644 --- a/init.lua +++ b/init.lua @@ -3,7 +3,7 @@ Copyright (C) 2013 Sokomine Copyright (C) 2019 coil0 Copyright (C) 2019 HybridDog - Copyright (C) 2019-2022 SwissalpS + Copyright (C) 2019-2024 SwissalpS This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 4.91 (20220830) +-- Version 4.93 (20240803) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20240225 +replacer.version = 20240803 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From b79bf146b9cc390d35e5c04d8ed6043f061a3614 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 4 Aug 2024 01:17:15 +0200 Subject: [PATCH 349/366] roll with own charge manager This should help a little with game and mod independance. Also theoretically speeds up process as technic's backward compatibility isn't run. Worst that happens is that some technic replacer runs out of charge after update and needs to be recharged. --- replacer/replacer.lua | 88 ++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 2e56f3c..e2957ff 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -111,43 +111,48 @@ function replacer.set_data(stack, node, mode) end -- set_data -if r.has_technic_mod then - if technic.plus then - replacer.get_charge = technic.get_RE_charge - replacer.set_charge = technic.set_RE_charge - else - -- technic still stores data serialized, so this is the nearest we get to current standard - function replacer.get_charge(itemstack) - local meta = deserialize(itemstack:get_meta():get_string('')) - if (not meta) or (not meta.charge) then - return 0 - end - return meta.charge - end +function replacer.discharge(stack, charge, num_nodes, has_creative_or_give) + if has_creative_or_give or (r.has_technic_mod and technic.creative_mode) then + return + end - function replacer.set_charge(itemstack, charge, maximum) - technic.set_RE_wear(itemstack, charge, maximum) - local meta = itemstack:get_meta() - local data = deserialize(meta:get_string('')) - if (not data) or (not data.charge) then - data = { charge = 0 } - end - data.charge = charge - meta:set_string('', serialize(data)) - end + charge = charge - r.charge_per_node * num_nodes + r.set_charge(stack, charge) + return stack +end -- discharge + + +function replacer.get_charge(stack) + if r.has_technic_mod and technic.creative_mode then + return r.max_charge, r.max_charge end - function replacer.discharge(itemstack, charge, num_nodes, has_creative_or_give) - if (not technic.creative_mode) and (not has_creative_or_give) then - charge = charge - r.charge_per_node * num_nodes - r.set_charge(itemstack, charge, r.max_charge) - return itemstack - end + return stack:get_meta():get_float('charge'), r.max_charge +end -- get_charge + + +-- do division once so subsequent calls can use faster multiplication +local wear_to_charge_factor = 1 / r.max_charge * 65536 +function replacer.set_charge(stack, charge) + -- clamp and set charge + charge = max(0, min(charge, r.max_charge)) + stack:get_meta():set_float('charge', charge) + + -- update wear indicator + if 0 == charge then + stack:set_wear(0) + return end -else - function replacer.discharge() end - function replacer.get_charge() return r.max_charge end -end + + local wear = 65536 - floor(charge * wear_to_charge_factor) + stack:set_wear(max(1, min(65536, wear))) +end -- set_charge + + +function replacer.refill_charge(stack) + r.set_charge(stack, r.max_charge) + return stack +end -- refill_charge -- replaces one node with another one and returns if it was successful @@ -722,19 +727,32 @@ end minetest.register_tool(r.tool_name_basic, r.tool_def_basic()) + function replacer.tool_def_technic() local def = r.tool_def_basic() def.description = rb.description_technic + def.wear_color = { + blend = 'linear', + color_stops = { + [0.3] = 'red', + [0.45] = 'yellow', + [0.75] = 'green', + } + } if r.has_technic_mod then + def.technic_get_charge = r.get_charge + def.technic_set_charge = r.set_charge if technic.plus then def.technic_max_charge = r.max_charge else def.wear_represents = 'technic_RE_charge' - def.on_refill = technic.refill_RE_charge + def.on_refill = r.refill_charge end end return def -end +end -- tool_def_technic + + if r.has_technic_mod or r.enable_recipe_technic_without_technic then if r.has_technic_mod and technic.plus then technic.register_power_tool(r.tool_name_technic, r.tool_def_technic()) From 70025d257bb32299ade3b4919d62344ae8fe0772 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 4 Aug 2024 03:12:52 +0200 Subject: [PATCH 350/366] clamp read charge JIC --- replacer/replacer.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index e2957ff..f245880 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -127,7 +127,8 @@ function replacer.get_charge(stack) return r.max_charge, r.max_charge end - return stack:get_meta():get_float('charge'), r.max_charge + local charge = stack:get_meta():get_float('charge') + return max(0, min(charge, r.max_charge)), r.max_charge end -- get_charge From 6ac97291d680962827ac141de8d1fe5cf07e5dd0 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 6 Aug 2024 11:37:46 +0200 Subject: [PATCH 351/366] harden against crash vector There is a very small chance these functions could be called on a player that is offline, crashing the server. --- replacer/history.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/replacer/history.lua b/replacer/history.lua index f037658..3fd5887 100644 --- a/replacer/history.lua +++ b/replacer/history.lua @@ -33,6 +33,8 @@ function r.history.auto_save() end -- auto_save function replacer.history.dealloc_player(player) + if not player then return end + r.history.save(player) r.history.db[player:get_player_name()] = nil end -- dealloc_player @@ -46,6 +48,8 @@ function replacer.history.get_player_table(player) end -- get_player_table function replacer.history.init_player(player) + if not player then return end + local name = player:get_player_name() if not minetest.check_player_privs(name, r.history_priv) then return end From 006a44658b499b52ad00618910855685ab573923 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 10 Oct 2025 20:07:16 +0200 Subject: [PATCH 352/366] save data in multiple meta fields a) use fieldnames starting with '_' to make more clear which are fields from this mod and avoid possible name colissions. b) splitting data into separate fields allows more flexible and simple changes in the future and by other mods. c) add '_title' field for user defined item-title when hovering. --- replacer/replacer.lua | 55 ++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index f245880..a78d0f2 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -46,18 +46,39 @@ replacer.mode_colours = { { '#f4b755', '#d29533', '#9F6200' } } +function replacer.convert_legacy_meta(stack, meta) + local data = meta:get_string('replacer'):split(' ') + local node = { + name = data[1] or r.tool_default_node, + param1 = tonumber(data[2] or 0), + param2 = tonumber(data[3] or 0) + } + local mode, mode_bare = {}, meta:get_string('mode'):split('.') + mode.major = tonumber(mode_bare[1] or 1) + mode.minor = tonumber(mode_bare[2] or 1) + -- remove old entries + meta:set_string('replacer', '') + meta:set_string('mode', '') + -- write in new format + r.set_data(stack, node, mode) +end -- convert_legacy + function replacer.get_data(stack) local meta = stack:get_meta() - local data = meta:get_string('replacer'):split(' ') or {} + if meta:contains('replacer') then + r.convert_legacy_meta(stack, meta) + end + local name = meta:get_string('_name') local node = { - name = data[1] or r.tool_default_node, - param1 = tonumber(data[2]) or 0, - param2 = tonumber(data[3]) or 0 + name = '' ~= name and name or r.tool_default_node, + param1 = max(0, min(255, meta:get_int('_param1'))), + param2 = max(0, min(255, meta:get_int('_param2'))), + } + local mode = { + major = max(1, min(3, meta:get_int('_mmajor'))), + minor = max(1, min(3, meta:get_int('_mminor'))), } - local mode, mode_bare = {}, meta:get_string('mode'):split('.') or {} - mode.major = tonumber(mode_bare[1] or 1) or 1 - mode.minor = tonumber(mode_bare[2] or 1) if r.disable_minor_modes then mode.minor = 1 end return node, mode end -- get_data @@ -70,26 +91,31 @@ function replacer.set_data(stack, node, mode) local _ _, mode = r.get_data(stack) end + mode.major = mode.major or 1 + mode.minor = mode.minor or 1 if r.disable_minor_modes then mode.minor = 1 end local tool_itemstring = stack:get_name() local tool_def = core_registered_items[tool_itemstring] -- some accidents or deliberate actions can be harmful -- if user has an unknown item. So we check here to -- prevent possible server crash - if (not tool_itemstring) or (not tool_def) then + if not (tool_itemstring and tool_def) then local t = { 'Blessed', 'Somewhat known', 'Unknown if known', 'Pwned', 'Hued', 'Strange', 'Found' } return t[os.date('*t').wday] .. ' Item' end - local param1 = tostring(node.param1 or 0) - local param2 = tostring(node.param2 or 0) + local node_name = node.name or r.tool_default_node - local data = node_name .. ' ' .. param1 .. ' ' .. param2 + local param1 = node.param1 or 0 + local param2 = node.param2 or 0 local meta = stack:get_meta() - meta:set_string('mode', mode.major .. '.' .. mode.minor) - meta:set_string('replacer', data) + meta:set_string('_name', node_name) + meta:set_int('_param1', param1) + meta:set_int('_param2', param2) + meta:set_int('_mmajor', mode.major) + meta:set_int('_mminor', mode.minor) meta:set_string('color', r.mode_colours[mode.major][mode.minor]) local node_def = core_registered_items[node_name] local node_description = node_name @@ -103,8 +129,9 @@ function replacer.set_data(stack, node, mode) local tool_name = tool_def.description local short_description = rb.tool_short_description:format( param1, param2, colour_name, node_name) + local title = meta:contains('_title') and meta:get_string('_title') local description = rb.tool_long_description:format( - tool_name, short_description, node_description) -- r.titleCase(colour_name)) + title or tool_name, short_description, node_description) -- r.titleCase(colour_name)) meta:set_string('description', description) return short_description From 544ada18390d3c8b3efb5ba022dea03339a86619 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 10 Oct 2025 20:10:18 +0200 Subject: [PATCH 353/366] simpler param validation logic enables 'version' subcommand --- chat_commands.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/chat_commands.lua b/chat_commands.lua index d5c8079..349c95e 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -30,12 +30,11 @@ replacer.chatcommand_mute = { local parts = lower:split(' ') local usage = rb.ccm_params .. '\n' .. rb.ccm_description - if 2 > #parts then return false, usage end + local command, value, key = parts[1], parts[2], nil - local command, value, key = parts[1], parts[2] - if 'chat' == command then + if 'chat' == command and value then key = 'replacer_mute' - elseif 'audio' == command then + elseif 'audio' == command and value then key = 'replacer_muteS' elseif 'version' == command then return true, tostring(replacer.version) From 959884846bb8aecbaa5bcdd163667c795bbf9e2a Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 10 Oct 2025 20:14:22 +0200 Subject: [PATCH 354/366] add mechanics to set tool title --- blabla.lua | 2 ++ chat_commands.lua | 18 ++++++++++++++++++ replacer/replacer.lua | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/blabla.lua b/blabla.lua index f3e58ec..2dba51d 100644 --- a/blabla.lua +++ b/blabla.lua @@ -59,8 +59,10 @@ rb.tool_long_description = '%s\n%s\n%s' rb.ccm_params = '(chat|audio) (0|1)' rb.ccm_description = S('Toggles verbosity.\nchat: When on, ' .. 'messages are posted to chat.\naudio: When off, replacer is silent.') +rb.ccm_failed_to_set_title = 'Failed to set title on replacer tool.' rb.ccm_player_not_found = 'Player not found' rb.ccm_player_meta_error = 'Player meta not existant' +rb.ccm_wrong_wielditem = S('Wrong type of item wielded.') rb.log_reg_exception_override = 'register_exception: ' .. 'exception for "%s" already exists.' rb.log_reg_exception = 'registered exception for "%s" to "%s"' diff --git a/chat_commands.lua b/chat_commands.lua index 349c95e..68b7b2c 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -38,6 +38,8 @@ replacer.chatcommand_mute = { key = 'replacer_muteS' elseif 'version' == command then return true, tostring(replacer.version) + elseif 'title' == command then + return replacer.chatcommand_set_title(player, param:sub(7)) else return false, usage end @@ -55,5 +57,21 @@ replacer.chatcommand_mute = { end } + +function replacer.chatcommand_set_title(player, title) + local stack = player:get_wielded_item() + if replacer.tool_name_basic ~= stack:get_name():sub(1, #replacer.tool_name_basic) then + return false, rb.ccm_wrong_wielditem + end + + if replacer.set_title(stack, title) then + player:set_wielded_item(stack) + return true, '' + else + return false, rb.ccm_failed_to_set_title + end +end + + minetest.register_chatcommand('replacer', replacer.chatcommand_mute) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index a78d0f2..40ad746 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -138,6 +138,16 @@ function replacer.set_data(stack, node, mode) end -- set_data +function replacer.set_title(stack, title) + if 'string' ~= type(title) then return false end + + -- trim to max 80 characters, not because core can't handle it. + stack:get_meta():set_string('_title', title:sub(1, 80)) + r.set_data(stack, r.get_data(stack)) + return true +end -- set_title + + function replacer.discharge(stack, charge, num_nodes, has_creative_or_give) if has_creative_or_give or (r.has_technic_mod and technic.creative_mode) then return From 4e5fd3b194aaae3b63d65c3c953690dadfedf763 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 10 Oct 2025 20:15:08 +0200 Subject: [PATCH 355/366] add foundation for 'help' subcommand --- chat_commands.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chat_commands.lua b/chat_commands.lua index 68b7b2c..c5f9158 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -40,6 +40,8 @@ replacer.chatcommand_mute = { return true, tostring(replacer.version) elseif 'title' == command then return replacer.chatcommand_set_title(player, param:sub(7)) + elseif 'help' == command then + return true, 'TODO: output tool instructions and chat command help.' else return false, usage end From 772bbdbfe252e3c71f07a5ca68884965cb77d4e0 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 10 Oct 2025 20:15:35 +0200 Subject: [PATCH 356/366] update readme.md --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cdb7aab..0f01d3a 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,15 @@ When Place-button is pressed, Rotation Mode does not make much sense as mostly a # Chat Commands -* /replacer (audio|chat) (1|0) toggles chat messages for advanced users. Also allows muting sounds. This command also accepts variants of "on"/"off" words in several languages. +* /replacer (audio|chat) (1|0) + Toggles chat messages for advanced users. Also allows muting sounds. + This command also accepts variants of "on"/"off" words in several languages. +* /replacer title + Sets the description of currently wielded replacer to . + This title persists when changing other settings of the tool. +* /replacer help TODO: output usage help of tool and chat commands. +* /replacer version + Outputs current version of replacer mod to chat. * /place_all [dry-run][ move_player][ no_support_node][ [] ... [ ]] This is only available to players with **priv** priv and only in development mode. [Read the comments in (test.lua)](test.lua) From 870d4f7bcf97e8bef70a2186a2f9fb1987e27c0c Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 10 Oct 2025 20:16:58 +0200 Subject: [PATCH 357/366] update translation scrapper scripts regex pattern --- i18n.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n.py b/i18n.py index 67305b0..3ca4702 100755 --- a/i18n.py +++ b/i18n.py @@ -330,7 +330,7 @@ def read_lua_file_strings(lua_file): for s in strings: s = re.sub(r'"\.\.\s+"', "", s) - s = re.sub("@[^@=0-9]", "@@", s) + s = re.sub("@[^@=0-9n]", "@@", s) s = s.replace('\\"', '"') s = s.replace("\\'", "'") s = s.replace("\n", "@n") From 49af4b55918ad6d170bd2e34da5ec80d6f3fdc8c Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 10 Oct 2025 20:37:40 +0200 Subject: [PATCH 358/366] update locales --- locale/replacer.de.tr | 1 + locale/replacer.es.tr | 1 + locale/replacer.fi.tr | 1 + locale/replacer.fr.tr | 1 + locale/replacer.it.tr | 1 + locale/replacer.pt.tr | 1 + locale/replacer.ru.tr | 1 + locale/template.txt | 1 + 8 files changed, 8 insertions(+) diff --git a/locale/replacer.de.tr b/locale/replacer.de.tr index daea92b..667c7f4 100644 --- a/locale/replacer.de.tr +++ b/locale/replacer.de.tr @@ -27,6 +27,7 @@ Time-limit reached.=Zeitbegrenzung erreicht. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Schaltet die Ausführlichkeit um.@nchat: Wenn eingeschaltet, werden Nachrichten im Chat ausgegeben.@naudio: Wenn ausgeschaltet, ist der Ersetzer stumm. +Wrong type of item wielded.=Der gehaltene Gegenstand kann nicht bennant werden. Minor modes are disabled on this server.=Nebenmodi sind auf diesem Server deaktiviert. = days=Tage diff --git a/locale/replacer.es.tr b/locale/replacer.es.tr index 277f839..539e132 100644 --- a/locale/replacer.es.tr +++ b/locale/replacer.es.tr @@ -27,6 +27,7 @@ Time-limit reached.=Límite de tiempo alcanzado. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Alterna la verbosidad. @nchat: cuando está activado, los mensajes se publican en el chat. @naudio: cuando está desactivado, el intercambiador está en silencio. +Wrong type of item wielded.=El artículo en mano no es compatible. Minor modes are disabled on this server.=Los modos menores están deshabilitados en este servidor. = days=días diff --git a/locale/replacer.fi.tr b/locale/replacer.fi.tr index 3394255..be9dc5c 100644 --- a/locale/replacer.fi.tr +++ b/locale/replacer.fi.tr @@ -27,6 +27,7 @@ Time-limit reached.=Aikaraja saavutettu. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Vaihtaa verbosity.@nchat: Kun päällä, viestit lähetetään chat.@naudio: Kun pois päältä, korvaaja on äänetön. +Wrong type of item wielded.=Väärän tyyppinen esine kädessä. Minor modes are disabled on this server.=Pienet tilat on poistettu käytöstä tällä palvelimella. = days=päivää diff --git a/locale/replacer.fr.tr b/locale/replacer.fr.tr index 2b1a73c..a750ae2 100644 --- a/locale/replacer.fr.tr +++ b/locale/replacer.fr.tr @@ -27,6 +27,7 @@ Time-limit reached.=Délai atteint. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Active/désactive la verbosité.@nchat : lorsque cette option est activée, les messages sont publiés sur le chat.@naudio : lorsqu'elle est désactivée, le remplaçant est silencieux. +Wrong type of item wielded.=Mauvais type d'objet utilisé en main. Minor modes are disabled on this server.=Les modes mineurs sont désactivés sur ce serveur. = days=jours diff --git a/locale/replacer.it.tr b/locale/replacer.it.tr index 159c4f4..ad8b743 100644 --- a/locale/replacer.it.tr +++ b/locale/replacer.it.tr @@ -27,6 +27,7 @@ Time-limit reached.=Tempo limite raggiunto. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Attiva/disattiva verbosità.@nchat: quando è attivo, i messaggi vengono inviati alla chat.@naudio: quando è disattivato, il sostituto è silenzioso. +Wrong type of item wielded.=Oggetto sbagliato impugnato. Minor modes are disabled on this server.=Le modalità minori sono disabilitate su questo server. = days=giorni diff --git a/locale/replacer.pt.tr b/locale/replacer.pt.tr index 0455d69..6ef2239 100644 --- a/locale/replacer.pt.tr +++ b/locale/replacer.pt.tr @@ -27,6 +27,7 @@ Time-limit reached.=Limite de tempo atingido. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Alterna a verbosidade.@nchat: Quando ativado, as mensagens são postadas no chat.@naudio: Quando desativado, o substituto é silencioso. +Wrong type of item wielded.=Tipo errado de item empunhado na mão. Minor modes are disabled on this server.=Os modos secundários estão desabilitados neste servidor. = days=dias diff --git a/locale/replacer.ru.tr b/locale/replacer.ru.tr index f10e860..89f1a58 100644 --- a/locale/replacer.ru.tr +++ b/locale/replacer.ru.tr @@ -27,6 +27,7 @@ Time-limit reached.=Достигнут лимит времени. Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.=Включает многословие. @nchat: когда включено, сообщения отправляются в чат. @naudio: когда выключено, заменитель молчит. +Wrong type of item wielded.=В руке находится не тот предмет. Minor modes are disabled on this server.=Второстепенные режимы отключены на этом сервере. =<нет информации о местоположении> days=дни diff --git a/locale/template.txt b/locale/template.txt index be51d9b..7b2b83c 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -27,6 +27,7 @@ Time-limit reached.= Toggles verbosity.@nchat: When on, messages are posted to chat.@naudio: When off, replacer is silent.= +Wrong type of item wielded.= Minor modes are disabled on this server.= = days= From 21b648cb187fd7ab96a920827002c548a30f384d Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 10 Oct 2025 20:38:31 +0200 Subject: [PATCH 359/366] update TODO thoughts --- TODO | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/TODO b/TODO index 252817a..19fd70b 100644 --- a/TODO +++ b/TODO @@ -26,6 +26,13 @@ ------ replacer fixes -------- +add /replacer help [] to show help on subcommands and without param + output general usage help + +think about possibly allowing drop-ins in title for e.g. mode or param values + e.g. 'Garden %M.%m %p' --> 'Garden 3.1 122' (mode major, minor, param2) + param1 would be 'P'; node name 'N' or similar. + try to add a formspec for player to be able to choose from multiple valid drops when node does not drop itself. From 6deb6158946938bb53db9f7e08847d8029f80d9e Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 10 Oct 2025 21:05:29 +0200 Subject: [PATCH 360/366] version bump 4.94 --- CHANGELOG | 3 +++ init.lua | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b4cf767..b8d5dd1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +20251010 * SwissalpS rolled own charge logic for more game/mod independance. + * Changed meta data storage format + * Added 'title' chat subcommand (also enabled 'version' subcommand). 20240803 * SwissalpS made replacer game agnostic (using [xcompat]). 20240225 * SwissalpS patched a crash situation with multinode-nodes. Thanks frogTheSecond and Huhhila for detecting and reporting. 20221107 * fluxionary fixed typo unkown -> unknown diff --git a/init.lua b/init.lua index f8cbb75..50ae596 100644 --- a/init.lua +++ b/init.lua @@ -3,7 +3,7 @@ Copyright (C) 2013 Sokomine Copyright (C) 2019 coil0 Copyright (C) 2019 HybridDog - Copyright (C) 2019-2024 SwissalpS + Copyright (C) 2019-2025 SwissalpS This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 4.93 (20240803) +-- Version 4.94 (20251010) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20240803 +replacer.version = 20251010 replacer.has_bakedclay = minetest.get_modpath('bakedclay') replacer.has_basic_dyes = minetest.get_modpath('dye') From dd32dfcf45c01003165f8d899932fafb828cc469 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 10 Oct 2025 21:52:00 +0200 Subject: [PATCH 361/366] fix using this mod without [xcompat] --- xcompat.lua | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/xcompat.lua b/xcompat.lua index faa660f..5631137 100644 --- a/xcompat.lua +++ b/xcompat.lua @@ -67,19 +67,20 @@ end -- machines are not yet covered by xcompat -local gameid = xcompat.gameid -if 'farlands_reloaded' == gameid then - r.machines.furnace = 'fl_workshop:furnace' - r.machines.furnace_active = 'fl_workshop:furnace_active' -elseif 'hades_revisited' == gameid then - r.machines.furnace = 'hades_furnaces:furnace' - r.machines.furnace_active = 'hades_furnaces:furnace_active' -elseif 'mineclonia' == gameid then - r.machines.furnace = 'mcl_furnaces:furnace' - r.machines.furnace_active = 'mcl_furnaces:furnace_active' -else - -- fallback to default game - r.machines.furnace = 'default:furnace' - r.machines.furnace_active = 'default:furnace_active' +-- fallback to default game +r.machines.furnace = 'default:furnace' +r.machines.furnace_active = 'default:furnace_active' +if r.has_xcompat_mod then + local gameid = xcompat.gameid + if 'farlands_reloaded' == gameid then + r.machines.furnace = 'fl_workshop:furnace' + r.machines.furnace_active = 'fl_workshop:furnace_active' + elseif 'hades_revisited' == gameid then + r.machines.furnace = 'hades_furnaces:furnace' + r.machines.furnace_active = 'hades_furnaces:furnace_active' + elseif 'mineclonia' == gameid then + r.machines.furnace = 'mcl_furnaces:furnace' + r.machines.furnace_active = 'mcl_furnaces:furnace_active' + end end From 5886e2b7f333f014f248575cbf8afb67ac31d3ec Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Fri, 10 Oct 2025 22:35:08 +0200 Subject: [PATCH 362/366] minetest -> luanti/core --- .luacheckrc | 6 ++--- README.md | 2 +- blabla.lua | 10 ++++----- chat_commands.lua | 4 ++-- compat/advtrains.lua | 8 +++---- compat/beacon.lua | 2 +- compat/biofuel.lua | 2 +- compat/bridger.lua | 2 +- compat/bucket.lua | 2 +- compat/canned_food.lua | 2 +- compat/default.lua | 4 ++-- compat/digtron.lua | 2 +- compat/drawers.lua | 2 +- compat/ehlphabet.lua | 2 +- compat/farming.lua | 2 +- compat/home_workshop_misc.lua | 2 +- compat/homedecor.lua | 2 +- compat/itemframes.lua | 6 ++--- compat/jumping.lua | 2 +- compat/letters.lua | 2 +- compat/mesecons.lua | 2 +- compat/mobs.lua | 5 ++--- compat/moreblocks.lua | 2 +- compat/realTest.lua | 10 ++++----- compat/ropes.lua | 2 +- compat/scifi_nodes.lua | 14 ++++++------ compat/telemosaic.lua | 2 +- compat/travelnet.lua | 2 +- compat/unifieddyes.lua | 4 ++-- compat/vines.lua | 2 +- compat/wine.lua | 2 +- crafts.lua | 10 ++++----- doc/customization.md | 4 ++-- init.lua | 36 +++++++++++++++--------------- inspect.lua | 42 +++++++++++++++++------------------ replacer/constrain.lua | 26 +++++++++++----------- replacer/enable.lua | 2 +- replacer/formspecs.lua | 10 ++++----- replacer/history.lua | 22 +++++++++--------- replacer/patterns.lua | 10 ++++----- replacer/replacer.lua | 30 ++++++++++++------------- test.lua | 40 ++++++++++++++++----------------- utils.lua | 16 ++++++------- 43 files changed, 180 insertions(+), 181 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index d7e7f27..87e6618 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -1,7 +1,7 @@ globals = { "replacer", - minetest = { fields = { "translate", "get_translator" } }, + core = { fields = { "translate", "get_translator" } }, } read_globals = { @@ -9,8 +9,8 @@ read_globals = { string = { fields = { "split", "match", "find", "lower" } }, table = { fields = { "copy", "getn", "insert", "shuffle", "sort" } }, - -- Minetest - "minetest", + -- Luanti + "core", "vector", "ItemStack", "dump", "VoxelArea", diff --git a/README.md b/README.md index 0f01d3a..2548f86 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Replacement tool for creative building (Mod for Minetest) +Replacement tool for creative building (Mod for Luanti) ========================================================= This tool is helpful for creative purposes (e.g. build a wall and "paint" windows into it). diff --git a/blabla.lua b/blabla.lua index 2dba51d..935b438 100644 --- a/blabla.lua +++ b/blabla.lua @@ -1,5 +1,5 @@ -if not minetest.translate then - function minetest.translate(_, str, ...) +if not core.translate then + function core.translate(_, str, ...) local arg = { n = select('#', ...), ... } return str:gsub('@(.)', function(matched) local c = string.byte(matched) @@ -11,11 +11,11 @@ if not minetest.translate then end) end - function minetest.get_translator(textdomain) - return function(str, ...) return minetest.translate(textdomain or '', str, ...) end + function core.get_translator(textdomain) + return function(str, ...) return core.translate(textdomain or '', str, ...) end end end -- backward compatibility -replacer.S = minetest.get_translator('replacer') +replacer.S = core.get_translator('replacer') local S = replacer.S replacer.blabla = {} diff --git a/chat_commands.lua b/chat_commands.lua index c5f9158..cd0ab72 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -14,7 +14,7 @@ replacer.chatcommand_mute = { params = rb.ccm_params,--(chat|audio) (0|1) description = rb.ccm_description, func = function(name, param) - local player = minetest.get_player_by_name(name) + local player = core.get_player_by_name(name) -- can happen if command was issued by e.g. command block -- while owner isn't online. Rather unlikely but possible. if not player then @@ -75,5 +75,5 @@ function replacer.chatcommand_set_title(player, title) end -minetest.register_chatcommand('replacer', replacer.chatcommand_mute) +core.register_chatcommand('replacer', replacer.chatcommand_mute) diff --git a/compat/advtrains.lua b/compat/advtrains.lua index 7598918..3dc4563 100644 --- a/compat/advtrains.lua +++ b/compat/advtrains.lua @@ -1,7 +1,7 @@ -if not minetest.get_modpath('advtrains') then return end +if not core.get_modpath('advtrains') then return end local function add_advtrains_aliases() - local core_get_node_drops = minetest.get_node_drops + local core_get_node_drops = core.get_node_drops local reg = replacer.register_non_creative_alias -- these cause crashes local deny_list = { @@ -9,7 +9,7 @@ local function add_advtrains_aliases() ['advtrains_line_automation:dtrack_stop_st'] = true, } local drops, drop_name - for name, _ in pairs(minetest.registered_nodes) do + for name, _ in pairs(core.registered_nodes) do if not deny_list[name] and name:find('^advtrains') then drops = core_get_node_drops(name) drop_name = drops and drops[1] or '' @@ -20,5 +20,5 @@ local function add_advtrains_aliases() end end -- add_advtrains_aliases -minetest.after(.2, add_advtrains_aliases) +core.after(.2, add_advtrains_aliases) diff --git a/compat/beacon.lua b/compat/beacon.lua index 1172a12..d02e40d 100644 --- a/compat/beacon.lua +++ b/compat/beacon.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('beacon') then return end +if not core.get_modpath('beacon') then return end local function is_beacon_beam_or_base(node_name) if 'string' ~= type(node_name) then return nil end diff --git a/compat/biofuel.lua b/compat/biofuel.lua index a6704a9..9fd2e14 100644 --- a/compat/biofuel.lua +++ b/compat/biofuel.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('biofuel') then return end +if not core.get_modpath('biofuel') then return end replacer.register_non_creative_alias('biofuel:refinery_active', 'biofuel:refinery') diff --git a/compat/bridger.lua b/compat/bridger.lua index 4a70c8e..795fa13 100644 --- a/compat/bridger.lua +++ b/compat/bridger.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('bridger') then return end +if not core.get_modpath('bridger') then return end local rir = replacer.image_replacements rir['bridger:corrugated_steelgreen'] = 'bridger:corrugated_steel_green' diff --git a/compat/bucket.lua b/compat/bucket.lua index 5b15af1..487fd9e 100644 --- a/compat/bucket.lua +++ b/compat/bucket.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('bucket') then return end +if not core.get_modpath('bucket') then return end local rbi = replacer.blabla.inspect diff --git a/compat/canned_food.lua b/compat/canned_food.lua index 3ea19ec..003928e 100644 --- a/compat/canned_food.lua +++ b/compat/canned_food.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('canned_food') then return end +if not core.get_modpath('canned_food') then return end local S = replacer.S diff --git a/compat/default.lua b/compat/default.lua index 560ae49..0c29f3b 100644 --- a/compat/default.lua +++ b/compat/default.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('default') then return end +if not core.get_modpath('default') then return end -- helpers for inspection tool -- some common groups replacer.group_placeholder['group:water_bucket'] = 'bucket:bucket_river_water' @@ -42,7 +42,7 @@ end -- handle the standard dye color groups if replacer.has_basic_dyes then for _, color in ipairs(dye.basecolors) do - local def = minetest.registered_items['dye:' .. color] + local def = core.registered_items['dye:' .. color] if def and def.groups then for k, _ in pairs(def.groups) do if 'dye' ~= k then diff --git a/compat/digtron.lua b/compat/digtron.lua index e5d38e0..d50dc39 100644 --- a/compat/digtron.lua +++ b/compat/digtron.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('digtron') then return end +if not core.get_modpath('digtron') then return end -- prevent accidental replacement of digtron crates -- also placing isn't a good idea either diff --git a/compat/drawers.lua b/compat/drawers.lua index a9a5529..fd5b893 100644 --- a/compat/drawers.lua +++ b/compat/drawers.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('drawers') then return end +if not core.get_modpath('drawers') then return end local rgp = replacer.group_placeholder rgp['group:drawer'] = 'drawers:wood2' diff --git a/compat/ehlphabet.lua b/compat/ehlphabet.lua index 8250ac5..ad37b8b 100644 --- a/compat/ehlphabet.lua +++ b/compat/ehlphabet.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('ehlphabet') then return end +if not core.get_modpath('ehlphabet') then return end -- for inspection tool local S = replacer.S diff --git a/compat/farming.lua b/compat/farming.lua index 8354f05..da5276e 100644 --- a/compat/farming.lua +++ b/compat/farming.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('farming') then return end +if not core.get_modpath('farming') then return end local rgp = replacer.group_placeholder rgp['group:food_cheese'] = 'farming:cheese_vegan' diff --git a/compat/home_workshop_misc.lua b/compat/home_workshop_misc.lua index cebdbf5..1849f66 100644 --- a/compat/home_workshop_misc.lua +++ b/compat/home_workshop_misc.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('home_workshop_misc') then return end +if not core.get_modpath('home_workshop_misc') then return end -- for replacer local mug = 'home_workshop_misc:beer_mug' diff --git a/compat/homedecor.lua b/compat/homedecor.lua index 5306578..ea67297 100644 --- a/compat/homedecor.lua +++ b/compat/homedecor.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('homedecor_kitchen') then return end +if not core.get_modpath('homedecor_kitchen') then return end local rir = replacer.image_replacements rir['homedecor:kitchen_cabinet'] = 'homedecor:kitchen_cabinet_colorable' diff --git a/compat/itemframes.lua b/compat/itemframes.lua index c897ef5..dd1b7e1 100644 --- a/compat/itemframes.lua +++ b/compat/itemframes.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('itemframes') then return end +if not core.get_modpath('itemframes') then return end -- for inspection tool -- local S = replacer.S @@ -8,7 +8,7 @@ local function add_recipe_itemframe(item_name, context, recipes) if not (context and context.pos) then return end - local held_name = minetest.get_meta(context.pos):get_string('item') + local held_name = core.get_meta(context.pos):get_string('item') if '' == held_name then return end recipes[#recipes + 1] = { @@ -28,7 +28,7 @@ local function add_recipe_pedestal(item_name, context, recipes) if not (context and context.pos) then return end - local held_name = minetest.get_meta(context.pos):get_string('item') + local held_name = core.get_meta(context.pos):get_string('item') if '' == held_name then return end recipes[#recipes + 1] = { diff --git a/compat/jumping.lua b/compat/jumping.lua index 9ace6d9..b279a2c 100644 --- a/compat/jumping.lua +++ b/compat/jumping.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('jumping') then return end +if not core.get_modpath('jumping') then return end local sBaseName = 'jumping:trampoline' local sDropName = sBaseName .. '1' diff --git a/compat/letters.lua b/compat/letters.lua index 16ac770..12fc06c 100644 --- a/compat/letters.lua +++ b/compat/letters.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('letters') then return end +if not core.get_modpath('letters') then return end -- for inspection tool local S = replacer.S diff --git a/compat/mesecons.lua b/compat/mesecons.lua index 2b2bac2..db5e5b1 100644 --- a/compat/mesecons.lua +++ b/compat/mesecons.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('mesecons') then return end +if not core.get_modpath('mesecons') then return end replacer.group_placeholder['group:mesecon_conductor_craftable'] = 'mesecons:wire_00000000_off' diff --git a/compat/mobs.lua b/compat/mobs.lua index 3943182..ec3d7e0 100644 --- a/compat/mobs.lua +++ b/compat/mobs.lua @@ -1,12 +1,11 @@ -if not minetest.get_modpath('mobs') then return end +if not core.get_modpath('mobs') then return end local rgp = replacer.group_placeholder if not rgp['group:food_cheese'] then rgp['group:food_cheese'] = 'mobs:cheese' end if not rgp['group:food_meat'] then rgp['group:food_meat'] = 'mobs:meat' end -if not minetest.get_modpath('mobs_animal') then return end -if not minetest.get_modpath('mobs_animal') then return end +if not core.get_modpath('mobs_animal') then return end local S = replacer.S diff --git a/compat/moreblocks.lua b/compat/moreblocks.lua index 94328f8..917ef8c 100644 --- a/compat/moreblocks.lua +++ b/compat/moreblocks.lua @@ -2,7 +2,7 @@ local r = replacer if not r.has_circular_saw then return end -- ?? TODO do we need to also check for stairsplus and add it to optional_depends ?? -local core_registered_nodes = minetest.registered_nodes +local core_registered_nodes = core.registered_nodes local shapes_list_sorted = nil local confirmed_saw_items = {} diff --git a/compat/realTest.lua b/compat/realTest.lua index efc46c0..2454cc1 100644 --- a/compat/realTest.lua +++ b/compat/realTest.lua @@ -1,10 +1,10 @@ -- overrides for replacer:inspect -- support for RealTest -if minetest.get_modpath('trees') - and minetest.get_modpath('core') - and minetest.get_modpath('instruments') - and minetest.get_modpath('anvil') - and minetest.get_modpath('scribing_table') +if core.get_modpath('trees') + and core.get_modpath('core') + and core.get_modpath('instruments') + and core.get_modpath('anvil') + and core.get_modpath('scribing_table') then replacer.image_replacements['group:planks'] = 'trees:pine_planks' replacer.image_replacements['group:plank'] = 'trees:pine_plank' diff --git a/compat/ropes.lua b/compat/ropes.lua index fa1c4ad..4b31cbe 100644 --- a/compat/ropes.lua +++ b/compat/ropes.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('ropes') then return end +if not core.get_modpath('ropes') then return end replacer.register_non_creative_alias('ropes:ropeladder', 'ropes:ropeladder_top') replacer.register_non_creative_alias('ropes:ropeladder_bottom', 'ropes:ropeladder_top') diff --git a/compat/scifi_nodes.lua b/compat/scifi_nodes.lua index b408600..7a8fd2e 100644 --- a/compat/scifi_nodes.lua +++ b/compat/scifi_nodes.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('scifi_nodes') then return end +if not core.get_modpath('scifi_nodes') then return end local S = replacer.S @@ -18,7 +18,7 @@ local function add_recipe_itemholder(item_name, context, recipes) if not (context and context.pos) then return end - local held_name = minetest.get_meta(context.pos):get_string('item') + local held_name = core.get_meta(context.pos):get_string('item') local items if '' ~= held_name then items = { held_name } @@ -26,7 +26,7 @@ local function add_recipe_itemholder(item_name, context, recipes) -- servers without override need to search for dropped items. items = {} local luaentity - local objects = minetest.get_objects_inside_radius(context.pos, .5) + local objects = core.get_objects_inside_radius(context.pos, .5) if (not objects) or (0 == #objects) then return end for _, obj in ipairs(objects) do @@ -34,7 +34,7 @@ local function add_recipe_itemholder(item_name, context, recipes) luaentity = obj:get_luaentity() if luaentity and luaentity.itemstring and ('' ~= luaentity.itemstring) - and minetest.registered_items[ItemStack(luaentity.itemstring):get_name()] + and core.registered_items[ItemStack(luaentity.itemstring):get_name()] then table.insert(items, luaentity.itemstring) end @@ -61,7 +61,7 @@ local function add_recipe_powered_stand(item_name, context, recipes) if not (context and context.pos) then return end - local held_name = minetest.get_meta(context.pos):get_string('item') + local held_name = core.get_meta(context.pos):get_string('item') local items if '' ~= held_name then items = { held_name } @@ -69,7 +69,7 @@ local function add_recipe_powered_stand(item_name, context, recipes) -- servers without override need to search for dropped items. items = {} local luaentity - local objects = minetest.get_objects_inside_radius( + local objects = core.get_objects_inside_radius( vector.add(context.pos, vector.new(0, 1, 0)), .5) if (not objects) or (0 == #objects) then return end @@ -78,7 +78,7 @@ local function add_recipe_powered_stand(item_name, context, recipes) luaentity = obj:get_luaentity() if luaentity and luaentity.itemstring and ('' ~= luaentity.itemstring) - and minetest.registered_items[ItemStack(luaentity.itemstring):get_name()] + and core.registered_items[ItemStack(luaentity.itemstring):get_name()] then table.insert(items, luaentity.itemstring) end diff --git a/compat/telemosaic.lua b/compat/telemosaic.lua index c153fa6..0f20a19 100644 --- a/compat/telemosaic.lua +++ b/compat/telemosaic.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('telemosaic') then return end +if not core.get_modpath('telemosaic') then return end local rgp = replacer.group_placeholder rgp['group:telemosaic_extender_one'] = 'telemosaic:extender_one' diff --git a/compat/travelnet.lua b/compat/travelnet.lua index 1cb3e68..65c671d 100644 --- a/compat/travelnet.lua +++ b/compat/travelnet.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('telemosaic') then return end +if not core.get_modpath('telemosaic') then return end local rgp = replacer.group_placeholder rgp['group:travelnet'] = 'travelnet:travelnet' diff --git a/compat/unifieddyes.lua b/compat/unifieddyes.lua index 748e55b..39e874a 100644 --- a/compat/unifieddyes.lua +++ b/compat/unifieddyes.lua @@ -16,7 +16,7 @@ local function add_recipe(node_name, context, recipes) if not (context and context.param2) then return end local param2 = context.param2 - local node_def = minetest.registered_items[node_name] + local node_def = core.registered_items[node_name] if ud.is_airbrushed(node_def) then -- find the correct recipe and append it to bottom of list local first @@ -78,6 +78,6 @@ end -- is_airbrushed -- mostly for scifi_nodes plastic. replacer.register_set_enabler(function(node) return node and node.name - and ud.is_airbrush_compatible(minetest.registered_nodes[node.name]) + and ud.is_airbrush_compatible(core.registered_nodes[node.name]) end) diff --git a/compat/vines.lua b/compat/vines.lua index ed39ce9..9a2d4d4 100644 --- a/compat/vines.lua +++ b/compat/vines.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('vines') then return end +if not core.get_modpath('vines') then return end local S = replacer.S diff --git a/compat/wine.lua b/compat/wine.lua index 46307d0..44a7a33 100644 --- a/compat/wine.lua +++ b/compat/wine.lua @@ -1,4 +1,4 @@ -if not minetest.get_modpath('wine') then return end +if not core.get_modpath('wine') then return end local S = replacer.S diff --git a/crafts.lua b/crafts.lua index 61785bd..478a468 100644 --- a/crafts.lua +++ b/crafts.lua @@ -2,7 +2,7 @@ local r = replacer local rm = r.materials if not r.hide_recipe_basic then - minetest.register_craft({ + core.register_craft({ output = r.tool_name_basic, recipe = { { rm.chest, '', rm.gold_ingot }, @@ -16,7 +16,7 @@ end -- only if technic mod is installed if r.has_technic_mod then if not r.hide_recipe_technic_upgrade then - minetest.register_craft({ + core.register_craft({ output = r.tool_name_technic, recipe = { { r.tool_name_basic, 'technic:green_energy_crystal', '' }, @@ -27,7 +27,7 @@ if r.has_technic_mod then end if not r.hide_recipe_technic_direct then -- direct upgrade craft - minetest.register_craft({ + core.register_craft({ output = r.tool_name_technic, recipe = { { rm.chest, 'technic:green_energy_crystal', rm.gold_ingot }, @@ -37,7 +37,7 @@ if r.has_technic_mod then }) end elseif r.enable_recipe_technic_without_technic then - minetest.register_craft({ + core.register_craft({ output = r.tool_name_technic, recipe = { { rm.chest, rm.axe_diamond, rm.gold_ingot }, @@ -48,7 +48,7 @@ elseif r.enable_recipe_technic_without_technic then end -minetest.register_craft({ +core.register_craft({ output = 'replacer:inspect', recipe = { { rm.torch }, diff --git a/doc/customization.md b/doc/customization.md index df58926..b4f41e4 100644 --- a/doc/customization.md +++ b/doc/customization.md @@ -1,5 +1,5 @@ -Customization documentation for replacer minetest mod -===================================================== +Customization documentation for replacer Luanti mod +==================================================== - [Settings](#settings) - [API Commands](#api-commands) diff --git a/init.lua b/init.lua index 50ae596..0f4cc27 100644 --- a/init.lua +++ b/init.lua @@ -1,5 +1,5 @@ --[[ - Replacement tool for creative building (Mod for MineTest) + Replacement tool for creative building (Mod for Luanti aka MineTest) Copyright (C) 2013 Sokomine Copyright (C) 2019 coil0 Copyright (C) 2019 HybridDog @@ -26,30 +26,30 @@ replacer = {} replacer.version = 20251010 -replacer.has_bakedclay = minetest.get_modpath('bakedclay') -replacer.has_basic_dyes = minetest.get_modpath('dye') - and minetest.global_exists('dye') +replacer.has_bakedclay = core.get_modpath('bakedclay') +replacer.has_basic_dyes = core.get_modpath('dye') + and core.global_exists('dye') and dye.basecolors and true or false -replacer.has_circular_saw = minetest.get_modpath('moreblocks') - and minetest.global_exists('moreblocks') - and minetest.global_exists('circular_saw') +replacer.has_circular_saw = core.get_modpath('moreblocks') + and core.global_exists('moreblocks') + and core.global_exists('circular_saw') and circular_saw.names and true or false -replacer.has_colormachine_mod = minetest.get_modpath('colormachine') - and minetest.global_exists('colormachine') -replacer.has_technic_mod = minetest.get_modpath('technic') - and minetest.global_exists('technic') -replacer.has_unifieddyes_mod = minetest.get_modpath('unifieddyes') - and minetest.global_exists('unifieddyes') -replacer.has_unified_inventory_mod = minetest.get_modpath('unified_inventory') +replacer.has_colormachine_mod = core.get_modpath('colormachine') + and core.global_exists('colormachine') +replacer.has_technic_mod = core.get_modpath('technic') + and core.global_exists('technic') +replacer.has_unifieddyes_mod = core.get_modpath('unifieddyes') + and core.global_exists('unifieddyes') +replacer.has_unified_inventory_mod = core.get_modpath('unified_inventory') and true or false -replacer.has_xcompat_mod = minetest.get_modpath('xcompat') - and minetest.global_exists('xcompat') +replacer.has_xcompat_mod = core.get_modpath('xcompat') + and core.global_exists('xcompat') -- image mapping tables for replacer:inspect replacer.group_placeholder = {} replacer.image_replacements = {} -local path = minetest.get_modpath('replacer') .. '/' +local path = core.get_modpath('replacer') .. '/' -- for developers dofile(path .. 'test.lua') -- strings for translation (inspect & replacer) @@ -67,7 +67,7 @@ dofile(path .. 'inspect.lua') -- loop through compat dir local path_compat = path .. 'compat/' -for _, file in ipairs(minetest.get_dir_list(path_compat, false)) do +for _, file in ipairs(core.get_dir_list(path_compat, false)) do if file:find('^[^._].+[.]lua$') then dofile(path_compat .. file) end diff --git a/inspect.lua b/inspect.lua index 2365181..83c1cd6 100644 --- a/inspect.lua +++ b/inspect.lua @@ -15,24 +15,24 @@ local floor = math.floor local max, min = math.max, math.min local concat = table.concat local insert = table.insert -local chat = minetest.chat_send_player -local mfe = minetest.formspec_escape -local deserialize = minetest.deserialize -local parse_json = minetest.parse_json -local get_node_or_nil = minetest.get_node_or_nil -local get_node_light = minetest.get_node_light -local get_pointed_thing_position = minetest.get_pointed_thing_position -local get_all_craft_recipes = minetest.get_all_craft_recipes -local is_protected = minetest.is_protected -local show_formspec = minetest.show_formspec -local registered_abms = minetest.registered_abms -local registered_lbms = minetest.registered_lbms -local registered_aliases = minetest.registered_aliases -local registered_tools = minetest.registered_tools -local registered_nodes = minetest.registered_nodes -local registered_items = minetest.registered_items -local registered_entities = minetest.registered_entities -local registered_craftitems = minetest.registered_craftitems +local chat = core.chat_send_player +local mfe = core.formspec_escape +local deserialize = core.deserialize +local parse_json = core.parse_json +local get_node_or_nil = core.get_node_or_nil +local get_node_light = core.get_node_light +local get_pointed_thing_position = core.get_pointed_thing_position +local get_all_craft_recipes = core.get_all_craft_recipes +local is_protected = core.is_protected +local show_formspec = core.show_formspec +local registered_abms = core.registered_abms +local registered_lbms = core.registered_lbms +local registered_aliases = core.registered_aliases +local registered_tools = core.registered_tools +local registered_nodes = core.registered_nodes +local registered_items = core.registered_items +local registered_entities = core.registered_entities +local registered_craftitems = core.registered_craftitems -- luacheck: push ignore unused pd local pd = r.print_dump -- luacheck: pop @@ -72,7 +72,7 @@ function replacer.register_craft_method(uid, machine_itemstring, func_inspect, end -- register_craft_method -minetest.register_tool('replacer:inspect', { +core.register_tool('replacer:inspect', { description = rbi.description, groups = {}, inventory_image = 'replacer_inspect.png', @@ -514,7 +514,7 @@ function replacer.image_button_link(stack_string) -- dynamically figure out a group replacement g = stack_string:sub(1 + stack_string:find(':', 2)) for item_name, _ in pairs(registered_items) do - if 0 ~= minetest.get_item_group(item_name, g) then + if 0 ~= core.get_item_group(item_name, g) then r.group_placeholder[stack_string] = item_name stack_string = item_name group = 'G' @@ -788,5 +788,5 @@ end -- establish a callback so that input from the player-specific -- formspec gets handled -minetest.register_on_player_receive_fields(replacer.form_input_handler) +core.register_on_player_receive_fields(replacer.form_input_handler) diff --git a/replacer/constrain.lua b/replacer/constrain.lua index 2bb2e84..706afa9 100644 --- a/replacer/constrain.lua +++ b/replacer/constrain.lua @@ -1,7 +1,7 @@ local r = replacer local rb = replacer.blabla local S = replacer.S -local is_protected = minetest.is_protected +local is_protected = core.is_protected local pos_to_string = replacer.nice_pos_string -- limit by node, use replacer.register_limit(sName, iMax) @@ -19,39 +19,39 @@ replacer.deny_list = {} replacer.max_charge = 30000 replacer.charge_per_node = 15 -- node count limit -replacer.max_nodes = tonumber(minetest.settings:get('replacer.max_nodes') or 3168) +replacer.max_nodes = tonumber(core.settings:get('replacer.max_nodes') or 3168) -- Time limit when placing the nodes, in seconds (not including search time) -replacer.max_time = tonumber(minetest.settings:get('replacer.max_time') or 1.0) +replacer.max_time = tonumber(core.settings:get('replacer.max_time') or 1.0) -- Radius limit factor when more possible positions are found than either max_nodes or charge -- Set to 0 or less for behaviour of before version 3.3 -- [see replacer_patterns.lua>replacer.patterns.search_positions()] -replacer.radius_factor = tonumber(minetest.settings:get('replacer.radius_factor') or 0.4) +replacer.radius_factor = tonumber(core.settings:get('replacer.radius_factor') or 0.4) -- disable minor modes on server replacer.disable_minor_modes = - minetest.settings:get_bool('replacer.disable_minor_modes') or false + core.settings:get_bool('replacer.disable_minor_modes') or false -- priv to allow using history -replacer.history_priv = minetest.settings:get('replacer.history_priv') or 'creative' +replacer.history_priv = core.settings:get('replacer.history_priv') or 'creative' -- disable saving history over sessions/reboots. IOW: don't use player meta e.g. if using old MT replacer.history_disable_persistency = - minetest.settings:get_bool('replacer.history_disable_persistency') or false + core.settings:get_bool('replacer.history_disable_persistency') or false -- ignored when persistency is disabled. Interval in minutes to replacer.history_save_interval = - tonumber(minetest.settings:get('replacer.history_save_interval') or 7) + tonumber(core.settings:get('replacer.history_save_interval') or 7) -- include mode when changing from history replacer.history_include_mode = - minetest.settings:get_bool('replacer.history_include_mode') or false + core.settings:get_bool('replacer.history_include_mode') or false -- amount of items in history -replacer.history_max = tonumber(minetest.settings:get('replacer.history_max') or 7) +replacer.history_max = tonumber(core.settings:get('replacer.history_max') or 7) -- select which recipes to hide (not all combinations make sense) replacer.hide_recipe_basic = - minetest.settings:get_bool('replacer.hide_recipe_basic') or false + core.settings:get_bool('replacer.hide_recipe_basic') or false replacer.hide_recipe_technic_upgrade = - minetest.settings:get_bool('replacer.hide_recipe_technic_upgrade') or false + core.settings:get_bool('replacer.hide_recipe_technic_upgrade') or false replacer.hide_recipe_technic_direct = - minetest.settings:get_bool('replacer.hide_recipe_technic_direct') + core.settings:get_bool('replacer.hide_recipe_technic_direct') if nil == replacer.hide_recipe_technic_direct then replacer.hide_recipe_technic_direct = true end diff --git a/replacer/enable.lua b/replacer/enable.lua index a9e4560..1819488 100644 --- a/replacer/enable.lua +++ b/replacer/enable.lua @@ -2,7 +2,7 @@ local r = replacer local rb = replacer.blabla replacer.enable_recipe_technic_without_technic = - minetest.settings:get_bool('replacer.enable_recipe_technic_without_technic') + core.settings:get_bool('replacer.enable_recipe_technic_without_technic') or false -- see replacer.register_exception() diff --git a/replacer/formspecs.lua b/replacer/formspecs.lua index 4286736..f405209 100644 --- a/replacer/formspecs.lua +++ b/replacer/formspecs.lua @@ -3,10 +3,10 @@ local r = replacer local rb = replacer.blabla -local get_player_information = minetest.get_player_information -local mfe = minetest.formspec_escape -local check_player_privs = minetest.check_player_privs -local show_formspec = minetest.show_formspec +local get_player_information = core.get_player_information +local mfe = core.formspec_escape +local check_player_privs = core.check_player_privs +local show_formspec = core.show_formspec replacer.form_name_modes = 'replacer_replacer_mode_change' @@ -172,7 +172,7 @@ function replacer.on_player_receive_fields(player, form_name, fields) player:set_wielded_item(wielded) end -- on_player_receive_fields -- listen to submitted fields -minetest.register_on_player_receive_fields(r.on_player_receive_fields) +core.register_on_player_receive_fields(r.on_player_receive_fields) function replacer.show_mode_formspec(player, mode) if not player then return end diff --git a/replacer/history.lua b/replacer/history.lua index 3fd5887..f63187d 100644 --- a/replacer/history.lua +++ b/replacer/history.lua @@ -24,8 +24,8 @@ function replacer.history.add_item(player, mode, node, short_description) end -- add_item function r.history.auto_save() - minetest.after(r.history_save_interval, r.history.auto_save) - for _, player in ipairs(minetest.get_connected_players()) do + core.after(r.history_save_interval, r.history.auto_save) + for _, player in ipairs(core.get_connected_players()) do if r.history.dirty[player:get_player_name()] then r.history.save(player) end @@ -51,7 +51,7 @@ function replacer.history.init_player(player) if not player then return end local name = player:get_player_name() - if not minetest.check_player_privs(name, r.history_priv) then return end + if not core.check_player_privs(name, r.history_priv) then return end local db_strings = player:get_meta():get_string('replacer_his'):split('||', false, r.history_max) or {} @@ -73,7 +73,7 @@ function replacer.history.init_player(player) }, } if r.disable_minor_modes then entry.mode.minor = 1 end - node_def = minetest.registered_items[entry.node.name] + node_def = core.registered_items[entry.node.name] colour_name = rud_colour_name(entry.node.param2, node_def) if 0 < #colour_name then colour_name = ' ' .. colour_name @@ -90,14 +90,14 @@ function replacer.history.on_priv_grant(name, granter, priv) -- skip duplicate calls if granter then return end if priv ~= r.history_priv then return end - r.history.init_player(minetest.get_player_by_name(name)) + r.history.init_player(core.get_player_by_name(name)) end -- on_priv_grant function replacer.history.on_priv_revoke(name, revoker, priv) -- skip duplicate calls if revoker then return end if priv ~= r.history_priv then return end - r.history.dealloc_player(minetest.get_player_by_name(name)) + r.history.dealloc_player(core.get_player_by_name(name)) end -- on_priv_revoke function replacer.history.save(player) @@ -121,12 +121,12 @@ function replacer.history.save(player) r.history.dirty[name] = nil end -- save -minetest.register_on_joinplayer(r.history.init_player) -minetest.register_on_leaveplayer(r.history.dealloc_player) -minetest.register_on_priv_grant(r.history.on_priv_grant) -minetest.register_on_priv_revoke(r.history.on_priv_revoke) +core.register_on_joinplayer(r.history.init_player) +core.register_on_leaveplayer(r.history.dealloc_player) +core.register_on_priv_grant(r.history.on_priv_grant) +core.register_on_priv_revoke(r.history.on_priv_revoke) if not r.history_disable_persistency then r.history_save_interval = 60 * r.history_save_interval - minetest.after(r.history_save_interval, r.history.auto_save) + core.after(r.history_save_interval, r.history.auto_save) end -- if persistency is enabled diff --git a/replacer/patterns.lua b/replacer/patterns.lua index d60d82c..d18866f 100644 --- a/replacer/patterns.lua +++ b/replacer/patterns.lua @@ -2,13 +2,13 @@ replacer.patterns = {} local r = replacer local rp = replacer.patterns local floor = math.floor -local is_protected = minetest.is_protected -local poshash = minetest.hash_node_position -local core_registered_nodes = minetest.registered_nodes +local is_protected = core.is_protected +local poshash = core.hash_node_position +local core_registered_nodes = core.registered_nodes local vector_add = vector.add local vector_distance = vector.distance --- cache results of minetest.get_node +-- cache results of core.get_node replacer.patterns.known_nodes = {} function replacer.patterns.get_node(pos) local i = poshash(pos) @@ -16,7 +16,7 @@ function replacer.patterns.get_node(pos) if nil ~= node then return node end - node = minetest.get_node(pos) + node = core.get_node(pos) rp.known_nodes[i] = node return node end -- get_node diff --git a/replacer/replacer.lua b/replacer/replacer.lua index 40ad746..eafcf8e 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -11,18 +11,18 @@ local S = replacer.S local max_time_us = 1000000 * r.max_time -- math local max, min, floor = math.max, math.min, math.floor -local core_check_player_privs = minetest.check_player_privs -local core_get_node = minetest.get_node -local core_get_node_or_nil = minetest.get_node_or_nil -local core_get_item_group = minetest.get_item_group -local core_registered_items = minetest.registered_items -local core_registered_nodes = minetest.registered_nodes -local core_swap_node = minetest.swap_node -local deserialize = minetest.deserialize -local get_craft_recipe = minetest.get_craft_recipe +local core_check_player_privs = core.check_player_privs +local core_get_node = core.get_node +local core_get_node_or_nil = core.get_node_or_nil +local core_get_item_group = core.get_item_group +local core_registered_items = core.registered_items +local core_registered_nodes = core.registered_nodes +local core_swap_node = core.swap_node +local deserialize = core.deserialize +local get_craft_recipe = core.get_craft_recipe local has_creative = r.has_creative -local serialize = minetest.serialize -local us_time = minetest.get_us_time +local serialize = core.serialize +local us_time = core.get_us_time -- vector local vector_distance = vector.distance local vector_multiply = vector.multiply @@ -324,7 +324,7 @@ function replacer.on_use(itemstack, player, pt, right_clicked) return end - local pos = minetest.get_pointed_thing_position(pt, right_clicked) + local pos = core.get_pointed_thing_position(pt, right_clicked) local node_old = core_get_node_or_nil(pos) if not node_old then @@ -763,7 +763,7 @@ function replacer.tool_def_basic() end -minetest.register_tool(r.tool_name_basic, r.tool_def_basic()) +core.register_tool(r.tool_name_basic, r.tool_def_basic()) function replacer.tool_def_technic() @@ -796,9 +796,9 @@ if r.has_technic_mod or r.enable_recipe_technic_without_technic then technic.register_power_tool(r.tool_name_technic, r.tool_def_technic()) elseif r.has_technic_mod then technic.register_power_tool(r.tool_name_technic, r.max_charge) - minetest.register_tool(r.tool_name_technic, r.tool_def_technic()) + core.register_tool(r.tool_name_technic, r.tool_def_technic()) else - minetest.register_tool(r.tool_name_technic, r.tool_def_technic()) + core.register_tool(r.tool_name_technic, r.tool_def_technic()) end end diff --git a/test.lua b/test.lua index bc33ee3..a4720c1 100644 --- a/test.lua +++ b/test.lua @@ -1,6 +1,6 @@ -- enable developer mode replacer.dev_mode = - minetest.settings:get_bool('replacer.dev_mode') or false + core.settings:get_bool('replacer.dev_mode') or false if not replacer.dev_mode then return end replacer.test = {} @@ -83,7 +83,7 @@ function replacer.test.chatcommand_place_all(player_name, param) end end if 0 == #patterns then table.insert(patterns, '.*') end - rt.player = minetest.get_player_by_name(player_name) + rt.player = core.get_player_by_name(player_name) rt.pos = rt.player:get_pos()--vector.add(player:get_pos(), vector.new(1, 0, 1))-- rt.selected = {} rt.count = 0 @@ -93,7 +93,7 @@ function replacer.test.chatcommand_place_all(player_name, param) end return false end -- has_match - for name, _ in pairs(minetest.registered_nodes) do + for name, _ in pairs(core.registered_nodes) do if not has_match(name, rt.skip) and has_match(name, patterns) then @@ -113,11 +113,11 @@ function replacer.test.chatcommand_place_all(player_name, param) .. ' to ' .. r.nice_pos_string(pos2) end - minetest.emerge_area(rt.pos, vector.add(pos2, vector.new(0, -1, 0))) + core.emerge_area(rt.pos, vector.add(pos2, vector.new(0, -1, 0))) rt.i = 1 rt.active = true rt.succ_count = 0 - minetest.after(.1, rt.step) + core.after(.1, rt.step) return true, 'Started process' end -- chatcommand_place_all @@ -138,27 +138,27 @@ function replacer.test.step() for _ = 1, rt.nodes_per_step do name = rt.selected[rt.i] - node = minetest.registered_nodes[name] + node = core.registered_nodes[name] pos_ = vector.add(rt.pos, vector.new(rt.x, 0, rt.z)) pos__ = vector.add(pos_, vector.new(0, -1, 0)) -- ensure area is generated and loaded if rt.check_mapgen(pos_) then rti('waiting for mapgen') - minetest.after(5, rt.step) + core.after(5, rt.step) return end - if minetest.find_node_near(pos_, 1, 'ignore', true) then + if core.find_node_near(pos_, 1, 'ignore', true) then rti('emerging area') move_player() - minetest.emerge_area(pos_, pos__) - minetest.after(2, rt.step) + core.emerge_area(pos_, pos__) + core.after(2, rt.step) return end - minetest.set_node(pos_, rt.air_node) + core.set_node(pos_, rt.air_node) if not rt.no_support then - minetest.set_node(pos__, rt.support_node) + core.set_node(pos__, rt.support_node) end move_player() print(r.nice_pos_string(pos_) .. ' ' .. name) @@ -181,7 +181,7 @@ function replacer.test.step() end -- keep player alive --rt.player:set_hp(55555, { type = 'set_hp', from = 'mod' }) - minetest.do_item_eat(55555, 'farming:bread 99', ItemStack('farming:bread 99'), + core.do_item_eat(55555, 'farming:bread 99', ItemStack('farming:bread 99'), rt.player, { type = 'nothing' }) if rt.count <= rt.i then rti(tostring(rt.succ_count) .. ' of ' .. tostring(rt.count) @@ -192,7 +192,7 @@ function replacer.test.step() rti('Step ' .. tostring(rt.i) .. ' of ' .. tostring(rt.count) .. ' done') - minetest.after(rt.seconds_between_steps, rt.step) + core.after(rt.seconds_between_steps, rt.step) end -- step @@ -204,8 +204,8 @@ function replacer.test.dealloc_player(player) end -- dealloc_player -minetest.register_on_leaveplayer(rt.dealloc_player) -minetest.register_chatcommand('place_all', { +core.register_on_leaveplayer(rt.dealloc_player) +core.register_chatcommand('place_all', { params = '[dry-run][ move_player][ no_support_node][ [] ... [ ] ]', description = 'Places one of all registered nodes on a grid in +x,+z plane starting ' .. 'at player position. You can use dry-run option to detect how much space you will need. ' @@ -223,11 +223,11 @@ local events = {} -- list of { minp, maxp, time } -- update last mapgen event time --luacheck: no unused args -minetest.register_on_generated(function(minp, maxp, seed) +core.register_on_generated(function(minp, maxp, seed) table.insert(events, { minp = minp, maxp = maxp, - time = minetest.get_us_time() + time = core.get_us_time() }) end) @@ -246,12 +246,12 @@ end -- check_mapgen -- cleanup local timer = 0 -minetest.register_globalstep(function(dtime) +core.register_globalstep(function(dtime) timer = timer + dtime if 5 > timer then return end timer = 0 - local time = minetest.get_us_time() + local time = core.get_us_time() local delay_seconds = 10 local copied_events = events diff --git a/utils.lua b/utils.lua index cd4c805..1520a59 100644 --- a/utils.lua +++ b/utils.lua @@ -1,17 +1,17 @@ local r = replacer local rb = replacer.blabla -local chat_send_player = minetest.chat_send_player -local get_player_by_name = minetest.get_player_by_name -local get_node_drops = minetest.get_node_drops -local core_log = minetest.log +local chat_send_player = core.chat_send_player +local get_player_by_name = core.get_player_by_name +local get_node_drops = core.get_node_drops +local core_log = core.log local floor = math.floor local absolute = math.abs local concat = table.concat local insert = table.insert local gmatch = string.gmatch -local registered_nodes = minetest.registered_nodes -local pos_to_string = minetest.pos_to_string -local sound_play = minetest.sound_play +local registered_nodes = core.registered_nodes +local pos_to_string = core.pos_to_string +local sound_play = core.sound_play function replacer.common_list_items(list1, list2) @@ -39,7 +39,7 @@ end -- common_list_items -- e.g. server override could check for a priv allowing -- user to have 'creative' priv only with replacer function replacer.has_creative(name) - if minetest.global_exists('creative') and creative.is_enabled_for then + if core.global_exists('creative') and creative.is_enabled_for then return creative.is_enabled_for(name) end return false From e464583fc5df6dee3f23dab0c20b7d983509f9ae Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sat, 11 Oct 2025 10:18:47 +0200 Subject: [PATCH 363/366] version bump 4.95 --- CHANGELOG | 2 ++ init.lua | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b8d5dd1..34d8318 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +20251011 * SwissalpS fixes bug when using this mod without xcompat. + * minetest to Luanti and core rename. 20251010 * SwissalpS rolled own charge logic for more game/mod independance. * Changed meta data storage format * Added 'title' chat subcommand (also enabled 'version' subcommand). diff --git a/init.lua b/init.lua index 0f4cc27..3ec464b 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 4.94 (20251010) +-- Version 4.95 (20251011) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20251010 +replacer.version = 20251011 replacer.has_bakedclay = core.get_modpath('bakedclay') replacer.has_basic_dyes = core.get_modpath('dye') From bab94a23023ce0ddb6d0a5bee043d8db268136c7 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 14 Oct 2025 20:39:47 +0200 Subject: [PATCH 364/366] fix toggle sub-commands --- chat_commands.lua | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/chat_commands.lua b/chat_commands.lua index cd0ab72..e54ddfc 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -26,16 +26,28 @@ replacer.chatcommand_mute = { return false, rb.ccm_player_meta_error end + local simple_toggles = { + chat = 'replacer_mute', + audio = 'replacer_muteS', + } local lower = string.lower(param) local parts = lower:split(' ') local usage = rb.ccm_params .. '\n' .. rb.ccm_description - local command, value, key = parts[1], parts[2], nil + local command, value = parts[1], parts[2] + local key = simple_toggles[command] - if 'chat' == command and value then - key = 'replacer_mute' - elseif 'audio' == command and value then - key = 'replacer_muteS' + if value and key then + if tOff[value] then + value = 1 + elseif tOn[value] then + value = 0 + else + return false, usage + end + + meta:set_int(key, value) + return true, '' elseif 'version' == command then return true, tostring(replacer.version) elseif 'title' == command then @@ -45,17 +57,6 @@ replacer.chatcommand_mute = { else return false, usage end - - if tOff[value] then - value = 1 - elseif tOn[value] then - value = 0 - else - return false, usage - end - - meta:set_int(key, value) - return true, '' end } From b0563629f943b9f789791a3c01a0e76ed5931d65 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Tue, 14 Oct 2025 20:49:41 +0200 Subject: [PATCH 365/366] purge unused vars --- replacer/replacer.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/replacer/replacer.lua b/replacer/replacer.lua index eafcf8e..c483def 100644 --- a/replacer/replacer.lua +++ b/replacer/replacer.lua @@ -18,10 +18,8 @@ local core_get_item_group = core.get_item_group local core_registered_items = core.registered_items local core_registered_nodes = core.registered_nodes local core_swap_node = core.swap_node -local deserialize = core.deserialize local get_craft_recipe = core.get_craft_recipe local has_creative = r.has_creative -local serialize = core.serialize local us_time = core.get_us_time -- vector local vector_distance = vector.distance From 77636feb3580f8eb3d2017e3426f32d6b6f4fbe3 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 15 Oct 2025 15:01:22 +0200 Subject: [PATCH 366/366] version bump 4.96 --- CHANGELOG | 1 + init.lua | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 34d8318..95aa30a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +20251015 * SwissalpS fixed bugs caused by recent fixes/additions 20251011 * SwissalpS fixes bug when using this mod without xcompat. * minetest to Luanti and core rename. 20251010 * SwissalpS rolled own charge logic for more game/mod independance. diff --git a/init.lua b/init.lua index 3ec464b..6ccc1bc 100644 --- a/init.lua +++ b/init.lua @@ -19,12 +19,12 @@ along with this program. If not, see . --]] --- Version 4.95 (20251011) +-- Version 4.96 (20251015) -- Changelog: see CHANGELOG file replacer = {} -replacer.version = 20251011 +replacer.version = 20251015 replacer.has_bakedclay = core.get_modpath('bakedclay') replacer.has_basic_dyes = core.get_modpath('dye')