mirror of
https://codeberg.org/AntumLuanti/mod-cleaner.git
synced 2025-03-15 04:41:22 +00:00
Add pencil tool for erasing, adding, & swapping nodes
This commit is contained in:
parent
84d3960664
commit
6b211cf5f6
9 changed files with 231 additions and 5 deletions
|
@ -6,7 +6,11 @@ A [Minetest][] mod that can be used to remove/replace unknown entities, nodes, &
|
||||||
|
|
||||||
### Licensing:
|
### 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:
|
### Requirements:
|
||||||
|
|
||||||
|
|
6
TODO.txt
6
TODO.txt
|
@ -4,5 +4,9 @@ TODO:
|
||||||
- update inventories when items are replaced:
|
- update inventories when items are replaced:
|
||||||
- creative
|
- creative
|
||||||
- storage (chests, etc.)
|
- storage (chests, etc.)
|
||||||
- add admin tool for replacing/removing nodes
|
|
||||||
- add LBM when removing an item if it is a node
|
- add LBM when removing an item if it is a node
|
||||||
|
- make pencil image flip when mode set to "erase"
|
||||||
|
- 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)
|
||||||
|
|
|
@ -14,6 +14,8 @@ v1.2
|
||||||
- all types are loaded from <world_path>/cleaner.json file
|
- all types are loaded from <world_path>/cleaner.json file
|
||||||
- added localization support
|
- added localization support
|
||||||
- added Spanish localization
|
- added Spanish localization
|
||||||
|
- added pencil tool for erasing, adding, & swapping nodes
|
||||||
|
- added "cleaner" chat command for managing pencil tool settings
|
||||||
|
|
||||||
v1.1
|
v1.1
|
||||||
----
|
----
|
||||||
|
|
54
chat.lua
54
chat.lua
|
@ -7,6 +7,8 @@
|
||||||
local S = core.get_translator(cleaner.modname)
|
local S = core.get_translator(cleaner.modname)
|
||||||
|
|
||||||
|
|
||||||
|
local aux = dofile(cleaner.modpath .. "/misc_functions.lua")
|
||||||
|
|
||||||
local function pos_list(ppos, radius)
|
local function pos_list(ppos, radius)
|
||||||
local plist = {}
|
local plist = {}
|
||||||
|
|
||||||
|
@ -457,3 +459,55 @@ if cleaner.unsafe then
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
end
|
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 = stack:get_name()
|
||||||
|
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,
|
||||||
|
})
|
||||||
|
|
111
init.lua
111
init.lua
|
@ -1,6 +1,7 @@
|
||||||
--[[ Cleaner mod
|
|
||||||
License: MIT
|
--- Cleaner
|
||||||
]]
|
--
|
||||||
|
-- @topic tools
|
||||||
|
|
||||||
|
|
||||||
cleaner = {}
|
cleaner = {}
|
||||||
|
@ -49,3 +50,107 @@ local scripts = {
|
||||||
for _, script in ipairs(scripts) do
|
for _, script in ipairs(scripts) do
|
||||||
dofile(cleaner.modpath .. "/" .. script .. ".lua")
|
dofile(cleaner.modpath .. "/" .. script .. ".lua")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local S = core.get_translator(cleaner.modname)
|
||||||
|
|
||||||
|
|
||||||
|
local sound_handle
|
||||||
|
|
||||||
|
--- Master Pencil
|
||||||
|
--
|
||||||
|
-- @tool cleaner:pencil
|
||||||
|
-- @img cleaner_pencil.png
|
||||||
|
-- @privs server
|
||||||
|
core.register_tool(cleaner.modname .. ":pencil", {
|
||||||
|
description = S("Master Pencil"),
|
||||||
|
inventory_image = "cleaner_pencil.png",
|
||||||
|
liquids_pointable = true,
|
||||||
|
on_use = function(itemstack, 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 itemstack
|
||||||
|
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 = itemstack: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 itemstack
|
||||||
|
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})
|
||||||
|
return itemstack
|
||||||
|
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
|
||||||
|
|
||||||
|
return itemstack
|
||||||
|
else
|
||||||
|
core.chat_send_player(pname, S("Unknown mode: @1", mode))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
core.chat_send_player(pname, S("Cannot place unknown node: @1", new_node_name))
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
on_secondary_use = function(itemstack, 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 itemstack
|
||||||
|
end
|
||||||
|
|
||||||
|
local imeta = itemstack:get_meta()
|
||||||
|
local mode = imeta:get_string("mode")
|
||||||
|
if mode == "erase" or mode == "" then
|
||||||
|
mode = "write"
|
||||||
|
elseif mode == "write" then
|
||||||
|
mode = "swap"
|
||||||
|
else
|
||||||
|
mode = "erase"
|
||||||
|
end
|
||||||
|
|
||||||
|
return aux.tool:set_mode(itemstack, mode, pname)
|
||||||
|
end,
|
||||||
|
on_place = function(itemstack, 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 itemstack
|
||||||
|
end
|
||||||
|
|
||||||
|
if pointed_thing.type == "node" then
|
||||||
|
local node = core.get_node_or_nil(core.get_pointed_thing_position(pointed_thing))
|
||||||
|
if node then
|
||||||
|
itemstack = aux.tool:set_node(itemstack, node.name, pname)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return itemstack
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
|
||||||
|
local S = core.get_translator(cleaner.modname)
|
||||||
|
|
||||||
|
|
||||||
--- Cleans duplicate entries from indexed table.
|
--- Cleans duplicate entries from indexed table.
|
||||||
--
|
--
|
||||||
-- @local
|
-- @local
|
||||||
|
@ -66,9 +69,63 @@ local function update_world_data(t, data)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local tool = {
|
||||||
|
modes = {
|
||||||
|
erase = true,
|
||||||
|
write = true,
|
||||||
|
swap = true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
tool.set_mode = function(self, stack, mode, pname)
|
||||||
|
local iname = stack:get_name()
|
||||||
|
|
||||||
|
if not self.modes[mode] 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
|
||||||
|
|
||||||
|
--[[ FIXME: want to flip item image when mode is set to "erase"
|
||||||
|
local new_item = table.copy(core.registered_nodes[iname])
|
||||||
|
if mode == "erase" then
|
||||||
|
new_item.inventory_image = "cleaner_pencil.png^[transformFXFY"
|
||||||
|
else
|
||||||
|
new_item.inventory_image = "cleaner_pencil.png"
|
||||||
|
end
|
||||||
|
|
||||||
|
local new_stack = ItemStack(new_item)
|
||||||
|
]]
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
return stack
|
||||||
|
end
|
||||||
|
|
||||||
|
tool.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
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
clean_duplicates = clean_duplicates,
|
clean_duplicates = clean_duplicates,
|
||||||
get_world_data = get_world_data,
|
get_world_data = get_world_data,
|
||||||
update_world_data = update_world_data,
|
update_world_data = update_world_data,
|
||||||
|
tool = tool,
|
||||||
}
|
}
|
||||||
|
|
BIN
sounds/cleaner_pencil_erase.ogg
Normal file
BIN
sounds/cleaner_pencil_erase.ogg
Normal file
Binary file not shown.
BIN
sounds/cleaner_pencil_write.ogg
Normal file
BIN
sounds/cleaner_pencil_write.ogg
Normal file
Binary file not shown.
BIN
textures/cleaner_pencil.png
Normal file
BIN
textures/cleaner_pencil.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 255 B |
Loading…
Add table
Reference in a new issue