Update cleaner mod to Git commit 182726e...

https://github.com/AntumMT/mod-cleaner/tree/182726e
master
Jordan Irwin 2021-07-30 00:01:28 -07:00
parent 65702b88c4
commit 09b94a0279
14 changed files with 529 additions and 99 deletions

View File

@ -11,7 +11,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
* admin/
* [alternode][] ([MIT][lic.alternode]) -- version: [1.3][ver.alternode] *2021-05-18*
* [cleaner][] ([MIT][lic.cleaner]) -- version: [9fa1b2b Git][ver.cleaner] *2021-07-20*
* [cleaner][] ([MIT][lic.cleaner]) -- version: [182726e Git][ver.cleaner] *2021-07-29*
* [no_fall_damage][] ([MIT][lic.no_fall_damage]) -- version [1.0.0][ver.no_fall_damage] *2020-12-19*
* [spectator_mode][] ([WTFPL][lic.spectator_mode]) -- version: [3648371 Git][ver.spectator_mode] *2020-07-15*
* [whitelist][] ([MIT][lic.whitelist]) -- version: [1.1][ver.whitelist] *2021-06-09*
@ -580,7 +580,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
[ver.castle_weapons]: https://github.com/minetest-mods/castle_weapons/tree/d3cf095
[ver.chatlog]: https://github.com/AntumMT/mod-chatlog/tree/v1.1
[ver.christmas]: https://github.com/TheZenKitteh/minetest-christmas/tree/d3bd872
[ver.cleaner]: https://github.com/AntumMT/mod-cleaner/tree/9fa1b2b
[ver.cleaner]: https://github.com/AntumMT/mod-cleaner/tree/182726e
[ver.cmer]: https://github.com/AntumMT/mod-cmer/tree/2843875
[ver.cmer_chicken]: http://github.com/AntumMT/mod-cmer/tree/085706f
[ver.cmer_ghost]: https://github.com/AntumMT/mod-cmer/tree/2f70906

View File

@ -6,7 +6,11 @@ A [Minetest][] mod that can be used to remove/replace unknown entities, nodes, &
### Licensing:
[MIT](LICENSE.txt)
- Code: [MIT](LICENSE.txt)
- Textures: CC0
- Sounds:
- cleaner_pencil_write: [CC0](https://freesound.org/people/NachtmahrTV/sounds/571800/)
- cleaner_pencil_erase: [CC0](https://freesound.org/people/damsur/sounds/443241/)
### Requirements:

View File

@ -4,4 +4,9 @@ TODO:
- update inventories when items are replaced:
- creative
- storage (chests, etc.)
- fix top nodes disappearing with /replace_node command
- add LBM when removing an item if it is a node
- update localization files
- add "radius" option for pencil or "xlen", "ylen", & "zlen" options
- add "xrotate" & "zrorate" modes for pencil
- fix pencil "write" mode when pointing to side of node (node gets placed below)
- add config file usage to HTML docs

View File

@ -3,15 +3,19 @@ v1.2
----
- added API
- added chat commands:
- remove_entity
- remove_node
- replace_item
- replace_node
- remove_entities
- remove_nodes
- replace_items
- replace_nodes
- find_unknown_nodes
- replace_ores (unsafe)
- added support for unregistering ores (unsafe)
- added setting for enabling "unsafe" methods & commands
- added support for unregistering ores
- all types are loaded from <world_path>/cleaner.json file
- added localization support
- added Spanish localization
- added pencil tool for erasing, adding, & swapping nodes
- added "cleaner" chat command for managing pencil tool settings
v1.1
----

View File

@ -7,6 +7,8 @@
local S = core.get_translator(cleaner.modname)
local aux = dofile(cleaner.modpath .. "/misc_functions.lua")
local function pos_list(ppos, radius)
local plist = {}
@ -21,54 +23,44 @@ local function pos_list(ppos, radius)
return plist
end
local param_desc = {
["radius"] = S("Search radius."),
["entity"] = S("Entity technical name."),
["node"] = S("Node technical name."),
["old_node"] = S("Technical name of node to be replaced."),
["new_node"] = S("Technical name of node to be used in place."),
["old_item"] = S("Technical name of item to be replaced."),
["new_item"] = S("Technical name of item to be used in place."),
["ore"] = S("Ore technical name."),
local param_def = {
radius = {name=S("radius"), desc=S("Search radius.")},
entity = {name=S("entity"), desc=S("Entity technical name.")},
node = {name=S("node"), desc=S("Node technical name.")},
old_node = {name=S("old_node"), desc=S("Technical name of node to be replaced.")},
new_node = {name=S("new_node"), desc=S("Technical name of node to be used in place.")},
old_item = {name=S("old_item"), desc=S("Technical name of item to be replaced.")},
new_item = {name=S("new_item"), desc=S("Technical name of item to be used in place.")},
ore = {name=S("ore"), desc=S("Ore technical name.")},
}
local function format_help(cmd, param_string, params)
local retval = S("Usage:") .. "\n /" .. cmd .. " " .. param_string
.. "\n"
local p_count = 0
for _, p in ipairs(params) do
if p_count == 0 then
retval = retval .. "\n" .. S("Params:")
end
retval = retval .. "\n " .. S(p) .. ": " .. param_desc[p]
p_count = p_count + 1
end
return retval
end
local cmd_repo = {
entity = {
cmd = "remove_entity",
params = "<" .. S("entity") .. "> [" .. S("radius") .. "]",
cmd = "remove_entities",
params = {"entity"},
oparams = {radius=100},
},
node = {
cmd_rem = "remove_node",
cmd_rep = "replace_node",
cmd_find = "find_unknown_nodes",
params_rem = "<" .. S("node") .. "> [" .. S("radius") .. "]",
params_rep = "<" .. S("old_node") .. "> <" .. S("new_node") .. "> [" .. S("radius") .. "]",
params_find = "[" .. S("radius") .. "]",
rem_node = {
cmd = "remove_nodes",
params = {"node"},
oparams = {radius=5},
},
rep_node = {
cmd = "replace_nodes",
params = {"old_node", "new_node"},
oparams = {radius=5},
},
find_node = {
cmd = "find_unknown_nodes",
oparams = {radius=100},
},
item = {
cmd = "replace_item",
params = "<" .. S("old_item") .. "> <" .. S("new_item") .. ">",
cmd = "replace_items",
params = {"old_item", "new_item"},
},
ore = {
cmd = "remove_ore",
params = "<" .. S("ore") .. ">",
cmd = "remove_ores",
params = {"ore"},
},
param = {
missing = S("Missing parameter."),
@ -77,19 +69,131 @@ local cmd_repo = {
},
}
for k, def in pairs(cmd_repo) do
if k ~= "param" then
local cmd_help = {
param_string = "",
usage_string = "/" .. def.cmd,
}
if def.params or def.oparams then
if def.params then
local params = {}
for _, p in ipairs(def.params) do
-- translate
table.insert(params, S(p))
end
cmd_help.param_string = "<" .. table.concat(params, "> <") .. ">"
end
end
if def.oparams then
for k, v in pairs(def.oparams) do
local op = k
if type(op) == "number" then
op = v
end
cmd_help.param_string = cmd_help.param_string .. " [" .. S(op) .. "]"
end
end
if cmd_help.param_string ~= "" then
cmd_help.usage_string = cmd_help.usage_string .. " " .. cmd_help.param_string
end
cmd_repo[k].help = cmd_help
end
end
local function get_cmd_def(cmd)
for k, v in pairs(cmd_repo) do
if v.cmd == cmd then return v end
end
end
local function format_usage(cmd)
local def = get_cmd_def(cmd)
if def then
return S("Usage:") .. "\n " .. def.help.usage_string
end
end
local function format_params(cmd)
local def = get_cmd_def(cmd)
local param_count
local all_params = {}
if def.params then
for k, v in ipairs(def.params) do
table.insert(all_params, p)
end
end
if def.oparams then
for k, v in pairs(def.oparams) do
end
end
local retval = ""
local p_count = 0
if def.params then
for _, p in ipairs(def.params) do
if p_count == 0 then
retval = retval .. S("Params:")
end
retval = retval .. "\n " .. S(p) .. ": " .. param_def[p].desc
p_count = p_count + 1
end
end
if def.oparams then
for k, v in pairs(def.oparams) do
if p_count == 0 then
retval = retval .. S("Params:")
end
local p = k
local dvalue = v
if type(p) == "number" then
p = v
dvalue = nil
end
retval = retval .. "\n " .. S(p) .. ": " .. param_def[p].desc
if dvalue then
retval = retval .. " (" .. S("default: @1", dvalue) .. ")"
end
p_count = p_count + 1
end
end
return retval
end
local function format_help(cmd)
return format_usage(cmd) .. "\n\n" .. format_params(cmd)
end
--- Removes nearby entities.
--
-- @chatcmd remove_entity
-- @chatcmd remove_entities
-- @param entity Entity technical name.
-- @tparam[opt] int radius
core.register_chatcommand(cmd_repo.entity.cmd, {
privs = {server=true},
description = S("Remove an entity from game."),
params = cmd_repo.entity.params,
description = S("Remove an entity from game.") .. "\n\n"
.. format_params(cmd_repo.entity.cmd),
params = cmd_repo.entity.help.param_string,
func = function(name, param)
local entity
local radius = 100
local radius = cmd_repo.entity.oparams.radius
if param:find(" ") then
entity = param:split(" ")
radius = tonumber(entity[2])
@ -106,8 +210,7 @@ core.register_chatcommand(cmd_repo.entity.cmd, {
end
if err then
return false, err .. "\n\n"
.. format_help(cmd_repo.entity.cmd, cmd_repo.entity.params, {"entity", "radius"})
return false, err .. "\n\n" .. format_help(cmd_repo.entity.cmd)
end
local player = core.get_player_by_name(name)
@ -135,16 +238,17 @@ core.register_chatcommand(cmd_repo.entity.cmd, {
--- Removes nearby nodes.
--
-- @chatcmd remove_node
-- @chatcmd remove_nodes
-- @param node Node technical name.
-- @tparam[opt] int radius
core.register_chatcommand(cmd_repo.node.cmd_rem, {
core.register_chatcommand(cmd_repo.rem_node.cmd, {
privs = {server=true},
description = S("Remove a node from game."),
params = cmd_repo.node.params_rem,
description = S("Remove a node from game.") .. "\n\n"
.. format_params(cmd_repo.rem_node.cmd),
params = cmd_repo.rem_node.help.param_string,
func = function(name, param)
local nname
local radius = 100
local radius = cmd_repo.rem_node.oparams.radius
if param:find(" ") then
nname = param:split(" ")
radius = tonumber(nname[2])
@ -161,8 +265,7 @@ core.register_chatcommand(cmd_repo.node.cmd_rem, {
end
if err then
return false, err .. "\n\n"
.. format_help(cmd_repo.node.cmd_rem, cmd_repo.node.params_rem, {"node", "radius"})
return false, err .. "\n\n" .. format_help(cmd_repo.rem_node.cmd)
end
local ppos = core.get_player_by_name(name):get_pos()
@ -182,18 +285,17 @@ core.register_chatcommand(cmd_repo.node.cmd_rem, {
--- Replaces an item.
--
-- @chatcmd replace_item
-- @chatcmd replace_items
-- @param old_item Technical name of item to replace.
-- @param new_item Technical name of item to be used in place.
core.register_chatcommand(cmd_repo.item.cmd, {
privs = {server=true},
description = S("Replace an item in game."),
params = cmd_repo.item.params,
description = S("Replace an item in game.") .. "\n\n"
.. format_params(cmd_repo.item.cmd),
params = cmd_repo.item.help.param_string,
func = function(name, param)
local help = format_help(cmd_repo.item.cmd, cmd_repo.item.params, {"old_item", "new_item"})
if not param:find(" ") then
return false, cmd_repo.param.missing .. "\n\n" .. help
return false, cmd_repo.param.missing .. "\n\n" .. format_help(cmd_repo.item.cmd)
end
local src = param:split(" ")
@ -211,24 +313,23 @@ core.register_chatcommand(cmd_repo.item.cmd, {
--- Replaces nearby nodes.
--
-- FIXME: sometimes nodes on top disappear
--
-- @chatcmd replace_node
-- @chatcmd replace_nodes
-- @param old_node Technical name of node to replace.
-- @param new_node Technical name of node to be used in place.
-- @tparam[opt] int radius
core.register_chatcommand(cmd_repo.node.cmd_rep, {
core.register_chatcommand(cmd_repo.rep_node.cmd, {
privs = {server=true},
description = S("Replace a node in game."),
params = cmd_repo.node.params_rep,
description = S("Replace a node in game.") .. "\n\n"
.. format_params(cmd_repo.rep_node.cmd),
params = cmd_repo.rep_node.help.param_string,
func = function(name, param)
local help = format_help(cmd_repo.node.cmd_rep, cmd_repo.node.params_rep, {"old_node", "new_node", "radius"})
local help = format_help(cmd_repo.rep_node.cmd)
if not param:find(" ") then
return false, cmd_repo.param.missing .. "\n\n" .. help
end
local radius = 100
local radius = cmd_repo.rep_node.oparams.radius
local params = param:split(" ")
local src = params[1]
@ -241,8 +342,7 @@ core.register_chatcommand(cmd_repo.node.cmd_rep, {
return false, cmd_repo.param.mal_radius .. "\n\n" .. help
end
local new_node = core.registered_nodes[tgt]
if not new_node then
if not core.registered_nodes[tgt] then
return false, S('Cannot use unknown node "@1" as replacement.', tgt)
end
@ -251,9 +351,11 @@ core.register_chatcommand(cmd_repo.node.cmd_rep, {
for _, npos in ipairs(pos_list(ppos, radius)) do
local node = core.get_node_or_nil(npos)
if node and node.name == src then
core.remove_node(npos)
core.place_node(npos, new_node)
total_replaced = total_replaced + 1
if core.swap_node(npos, {name=tgt}) then
total_replaced = total_replaced + 1
else
cleaner.log("error", "could not replace node at " .. core.pos_to_string(npos, 0))
end
end
end
@ -265,18 +367,19 @@ core.register_chatcommand(cmd_repo.node.cmd_rep, {
--
-- @chatcmd find_unknown_nodes
-- @tparam[opt] int radius Search radius.
core.register_chatcommand(cmd_repo.node.cmd_find, {
core.register_chatcommand(cmd_repo.find_node.cmd, {
privs = {server=true},
description = S("Find names of unknown nodes."),
params = cmd_repo.node.params_find,
description = S("Find names of unknown nodes.") .. "\n\n"
.. format_params(cmd_repo.find_node.cmd),
params = cmd_repo.find_node.help.param_string,
func = function(name, param)
local help = format_help(cmd_repo.node.cmd_find, cmd_repo.node.params_find, {"radius"})
local help = format_help(cmd_repo.find_node.cmd)
if param:find(" ") then
return false, cmd_repo.param.excess .. "\n\n" .. help
end
local radius = 100
local radius = cmd_repo.find_node.oparams.radius
if param and param:trim() ~= "" then
radius = tonumber(param)
end
@ -322,12 +425,13 @@ core.register_chatcommand(cmd_repo.node.cmd_find, {
if cleaner.unsafe then
--- Registers an ore to be removed.
--
-- @chatcmd remove_ore
-- @chatcmd remove_ores
-- @param ore Ore technical name.
core.register_chatcommand(cmd_repo.ore.cmd, {
privs = {server=true},
description = S("Remove an ore from game."),
params = cmd_repo.ore.params,
description = S("Remove an ore from game.") .. "\n\n"
.. format_params(cmd_repo.ore.cmd),
params = cmd_repo.ore.help.param_string,
func = function(name, param)
local err
if not param or param:trim() == "" then
@ -337,7 +441,7 @@ if cleaner.unsafe then
end
if err then
return false, err .. "\n\n" .. format_help(cmd_repo.ore.cmd, cmd_repo.ore.params, {"ore"})
return false, err .. "\n\n" .. format_help(cmd_repo.ore.cmd)
end
local success = false
@ -355,3 +459,57 @@ if cleaner.unsafe then
end
})
end
--- @section end
--- Manages settings for wielded cleaner tool.
--
-- @chatcmd cleaner
-- @param action Action to execute. Can be "status", "setmode", or "setnode".
-- @param value Mode or node to be set for tool.
core.register_chatcommand("cleaner", {
privs = {server=true},
description = S("Manage settings for wielded cleaner tool.") .. "\n\n"
.. S("Params:") .. "\n action: Action to execute. Can be one of \"status\", \"setmode\", or \"setnode\"."
.. "\n value: Mode or node to be set for tool.",
params = "<action> <value>",
func = function(name, param)
local action, value = param
local idx = param:find(" ")
if idx then
param = string.split(param, " ")
action = param[1]
value = param[2]
end
local player = core.get_player_by_name(name)
local stack = player:get_wielded_item()
local iname = aux.tool:format_name(stack)
local imeta = stack:get_meta()
if iname ~= "cleaner:pencil" then
return false, S("Unrecognized wielded item: @1", iname)
end
if action == "status" then
core.chat_send_player(name, iname .. ": "
.. S("mode=@1, node=@2", imeta:get_string("mode"), imeta:get_string("node")))
return true
end
if not action or not value then
return false, S("Missing parameter.")
end
if action == "setmode" then
stack = aux.tool:set_mode(stack, value, name)
elseif action == "setnode" then
stack = aux.tool:set_node(stack, value, name)
else
return false, S("Unrecognized action: @1", action)
end
return player:set_wielded_item(stack)
end,
})

View File

@ -1,7 +1,3 @@
--[[ Cleaner mod
License: MIT
]]
cleaner = {}
cleaner.modname = core.get_current_modname()
@ -40,6 +36,7 @@ local scripts = {
"settings",
"api",
"chat",
"tools",
"entities",
"nodes",
"items",

View File

@ -0,0 +1,44 @@
# textdomain:cleaner
# Translators: Jordan Irwin (AntumDeluge)
# chat commands
entity=entidad
node=nodo
radius=radio
old_item=objeto_antiguo
new_item=objeto_nuevo
old_node=nodo_antiguo
new_node=nodo_nuevo
ore=mineral
Usage:=Uso:
Params:=Parámetros:
default: @1=por defecto: @1
Search radius.=Radio de búsqueda.
Entity technical name.=Nombre técnico de entidad.
Node technical name.=Nombre técnico de nodo.
Technical name of node to be replaced.=Nombre técnico del nodo reemplazado.
Technical name of node to be used in place.=Nombre técnico del nodo de reemplazo.
Technical name of item to be replaced.=Nombre técnico del objeto reemplazado.
Technical name of item to be used in place.=Nombre técnico del objeto de reemplazo.
Ore technical name.=Nombre técnico de mineral.
Remove an entity from game.=Eliminar una entidad del juego.
Remove a node from game.=Eliminar un nodo del juego.
Replace an item in game.=Sustituir un objecto del juego.
Replace a node in game.=Sustituir un nodo del juego.
Find names of unknown nodes.=Encontrar los nombres de nodos desconocidos.
Remove an ore from game.=Eliminar un mineral del juego.
Missing parameter.=Parámetro extraviado.
Too many parameters.=Demasiados parámetros.
Radius must be a number.=El radio debe ser un número.
Cannot use unknown item "@1" as replacement.=El objeto "@1" es desonocido, no se puede utilizar como sustitución.
Cannot use unknown node "@1" as replacement.=El nodo "@1" es desonocido, no se puede utilizar como sustitución.
Replaced @1 nodes.=Nodos sustituidos: @1
Removed @1 nodes.=Se eliminaron @1 nodos.
Removed @1 entities.=Se eliminaron @1 entidades.
Found unknown nodes: @1=Se encontraron @1 nodos desconocidos.
No unknown nodes found.=No se encontraron nodos desconocidos.
Ore "@1" not found, not unregistering.=No se encontró el mineral "@1", se mantiene registrado.
Unregistered @1 ores (this will be undone after server restart).=Se anuló @1 minerales del registro.
Success!=¡Éxito!

View File

@ -1,4 +1,6 @@
# Translated by
# textdomain:cleaner
# Translators:
# chat commands
@ -12,6 +14,7 @@ new_node=
ore=
Usage:=
Params:=
default: @1=
Search radius.=
Entity technical name.=
Node technical name.=

View File

@ -1,4 +1,7 @@
local S = core.get_translator(cleaner.modname)
--- Cleans duplicate entries from indexed table.
--
-- @local
@ -66,9 +69,178 @@ local function update_world_data(t, data)
return false
end
local tool = {
modes = {
["cleaner:pencil"] = {"erase", "write", "swap"},
},
format_name = function(self, stack)
local iname = stack:get_name()
if iname == "cleaner:pencil_1" then
iname = "cleaner:pencil"
end
return iname
end,
set_mode = function(self, stack, mode, pname)
local iname = self:format_name(stack)
if not self.modes[iname] then
if pname then
core.chat_send_player(pname, iname .. ": " .. S("unknown mode: @1", mode))
end
cleaner.log("warning", iname .. ": unknown mode: " .. mode)
return stack
end
local imeta = stack:get_meta()
imeta:set_string("mode", mode)
if pname then
core.chat_send_player(pname, iname .. ": "
.. S("mode set to: @1", imeta:get_string("mode")))
end
local new_stack
if mode == "erase" then
new_stack = ItemStack("cleaner:pencil_1")
else
new_stack = ItemStack("cleaner:pencil")
end
local new_meta = new_stack:get_meta()
new_meta:from_table(imeta:to_table())
return new_stack
end,
next_mode = function(self, stack, pname)
local iname = self:format_name(stack)
local modes = self.modes[iname]
if not modes then
return false, stack, "modes for tool \"" .. stack:get_name() .. "\" not available."
end
local imeta = stack:get_meta()
local current_mode = imeta:get_string("mode")
if not current_mode or current_mode:trim() == "" then
return true, self:set_mode(stack, modes[1], pname)
end
local idx = 1
for _, m in ipairs(modes) do
if current_mode == m then
break
end
idx = idx + 1
end
return true, self:set_mode(stack, modes[idx+1] or modes[1], pname)
end,
set_node = function(self, stack, node, pname)
local imeta = stack:get_meta()
imeta:set_string("node", node)
if pname then
core.chat_send_player(pname, stack:get_name() .. ": "
.. S("node set to: @1", imeta:get_string("node")))
end
return stack
end,
}
tool.on_use = function(stack, user, pointed_thing)
if not user:is_player() then return end
local pname = user:get_player_name()
if not core.get_player_privs(pname).server then
core.chat_send_player(pname, S("You do not have permission to use this item. Missing privs: server"))
return stack
end
if sound_handle then
core.sound_stop(sound_handle)
sound_handle = nil
end
if pointed_thing.type == "node" then
local npos = core.get_pointed_thing_position(pointed_thing)
local imeta = stack:get_meta()
local mode = imeta:get_string("mode")
local new_node_name = imeta:get_string("node")
if mode == "erase" then
core.remove_node(npos)
sound_handle = core.sound_play("cleaner_pencil_erase", {object=user})
return stack
elseif core.registered_nodes[new_node_name] then
if mode == "swap" then
core.swap_node(npos, {name=new_node_name})
sound_handle = core.sound_play("cleaner_pencil_write", {object=user})
elseif mode == "write" then
local node_above = core.get_node_or_nil(pointed_thing.above)
if not node_above or node_above.name == "air" then
core.place_node(pointed_thing.above, {name=new_node_name})
sound_handle = core.sound_play("cleaner_pencil_write", {object=user})
else
core.chat_send_player(pname, S("Can't place node there."))
end
else
core.chat_send_player(pname, S("Unknown mode: @1", mode))
end
return stack
end
core.chat_send_player(pname, S("Cannot place unknown node: @1", new_node_name))
return stack
end
end
tool.on_secondary_use = function(stack, user, pointed_thing)
if not user:is_player() then return end
local pname = user:get_player_name()
if not core.get_player_privs(pname).server then
core.chat_send_player(pname, S("You do not have permission to use this item. Missing privs: @1", "server"))
return stack
end
local success, stack, msg = tool.next_mode(tool, stack, pname)
if not success then
core.chat_send_player(pname, msg)
end
return stack
end
tool.on_place = function(stack, placer, pointed_thing)
if not placer:is_player() then return end
local pname = placer:get_player_name()
if not core.get_player_privs(pname).server then
core.chat_send_player(pname, S("You do not have permission to use this item. Missing privs: @1", "server"))
return stack
end
if pointed_thing.type == "node" then
local node = core.get_node_or_nil(core.get_pointed_thing_position(pointed_thing))
if node then
stack = tool:set_node(stack, node.name, pname)
end
end
return stack
end
return {
clean_duplicates = clean_duplicates,
get_world_data = get_world_data,
update_world_data = update_world_data,
tool = tool,
}

View File

@ -75,12 +75,9 @@ core.register_lbm({
nodenames = {"group:to_replace"},
run_at_every_load = true,
action = function(pos, node)
core.remove_node(pos)
local new_node_name = cleaner.get_replace_nodes()[node.name]
local new_node = core.registered_nodes[new_node_name]
if new_node then
core.place_node(pos, new_node)
if core.registered_nodes[new_node_name] then
core.swap_node(pos, {name=new_node_name})
else
cleaner.log("error", "cannot replace with unregistered node \"" .. tostring(new_node_name) .. "\"")
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

View File

@ -0,0 +1,46 @@
--- Cleaner Tools
--
-- @topic tools
local S = core.get_translator(cleaner.modname)
local aux = dofile(cleaner.modpath .. "/misc_functions.lua")
local sound_handle
--- Master Pencil
--
-- @tool cleaner:pencil
-- @img cleaner_pencil.png
-- @privs server
-- @usage
-- place (right-click):
-- - when not pointing at a node, changes modes
-- - when pointing at a node, sets node to be used
--
-- use (left-click):
-- - executes action for current mode:
-- - erase: erases pointed node
-- - write: adds node
-- - swap: replaces pointed node
core.register_tool(cleaner.modname .. ":pencil", {
description = S("Master Pencil"),
inventory_image = "cleaner_pencil.png",
liquids_pointable = true,
on_use = aux.tool.on_use,
on_secondary_use = aux.tool.on_secondary_use,
on_place = aux.tool.on_place,
})
core.register_tool(cleaner.modname .. ":pencil_1", {
description = S("Master Pencil"),
inventory_image = "cleaner_pencil.png^[transformFXFY",
liquids_pointable = true,
groups = {not_in_creative_inventory=1},
on_use = aux.tool.on_use,
on_secondary_use = aux.tool.on_secondary_use,
on_place = aux.tool.on_place,
})