add unique id to template/handle

This commit is contained in:
BuckarooBanzay 2024-09-23 10:34:17 +02:00
parent 575b2a8c4a
commit 50f59ba6e7
6 changed files with 117 additions and 38 deletions

View File

@ -23,4 +23,29 @@ function pick_and_place.get_formatted_size(pos1, pos2)
pos2 = pos2 or pos1
pos1, pos2 = pick_and_place.sort_pos(pos1, pos2)
return minetest.pos_to_string(vector.add(vector.subtract(pos2, pos1), 1))
end
function pick_and_place.create_id()
local template = "xxxxxx"
return string.gsub(template, '[x]', function ()
return string.format('%x', math.random(0, 0xf))
end)
end
-- returns the outer corners for the handle nodes
function pick_and_place.get_outer_corners(pos1, pos2)
pos1, pos2 = pick_and_place.sort_pos(pos1, pos2)
pos1 = vector.subtract(pos1, 1)
pos2 = vector.add(pos2, 1)
return {
{ x=pos1.x, y=pos1.y, z=pos1.z },
{ x=pos1.x, y=pos1.y, z=pos2.z },
{ x=pos1.x, y=pos2.y, z=pos1.z },
{ x=pos1.x, y=pos2.y, z=pos2.z },
{ x=pos2.x, y=pos1.y, z=pos1.z },
{ x=pos2.x, y=pos1.y, z=pos2.z },
{ x=pos2.x, y=pos2.y, z=pos1.z },
{ x=pos2.x, y=pos2.y, z=pos2.z }
}
end

View File

@ -1,22 +1,4 @@
-- returns the outer corners for the handle nodes
local function get_outer_corners(pos1, pos2)
pos1, pos2 = pick_and_place.sort_pos(pos1, pos2)
pos1 = vector.subtract(pos1, 1)
pos2 = vector.add(pos2, 1)
return {
{ x=pos1.x, y=pos1.y, z=pos1.z },
{ x=pos1.x, y=pos1.y, z=pos2.z },
{ x=pos1.x, y=pos2.y, z=pos1.z },
{ x=pos1.x, y=pos2.y, z=pos2.z },
{ x=pos2.x, y=pos1.y, z=pos1.z },
{ x=pos2.x, y=pos1.y, z=pos2.z },
{ x=pos2.x, y=pos2.y, z=pos1.z },
{ x=pos2.x, y=pos2.y, z=pos2.z }
}
end
-- true if already in removal function (disables recursion through on_destruct)
local in_removal = false
@ -47,7 +29,7 @@ function pick_and_place.remove_handles(handle_pos)
in_removal = true
pos1, pos2 = pick_and_place.sort_pos(pos1, pos2)
for _, hpos in ipairs(get_outer_corners(pos1, pos2)) do
for _, hpos in ipairs(pick_and_place.get_outer_corners(pos1, pos2)) do
local hnode = minetest.get_node(hpos)
if hnode.name == "pick_and_place:handle" then
local hmeta = minetest.get_meta(hpos)
@ -64,13 +46,14 @@ function pick_and_place.remove_handles(handle_pos)
end
-- sets handle nodes where possible
function pick_and_place.configure(pos1, pos2, name)
function pick_and_place.configure(pos1, pos2, name, id)
pos1, pos2 = pick_and_place.sort_pos(pos1, pos2)
id = id or pick_and_place.create_id()
pick_and_place.register_template(name, pos1, pos2)
for _, cpos in ipairs(get_outer_corners(pos1, pos2)) do
for _, cpos in ipairs(pick_and_place.get_outer_corners(pos1, pos2)) do
local node = minetest.get_node(cpos)
if node.name == "air" then
if node.name == "air" or node.name == "pick_and_place:handle" then
minetest.set_node(cpos, { name = "pick_and_place:handle" })
local meta = minetest.get_meta(cpos)
@ -81,7 +64,8 @@ function pick_and_place.configure(pos1, pos2, name)
meta:set_string("pos1", minetest.pos_to_string(rel_pos1))
meta:set_string("pos2", minetest.pos_to_string(rel_pos2))
meta:set_string("name", name)
meta:set_string("infotext", name)
meta:set_string("id", id)
meta:set_string("infotext", pick_and_place.get_handle_infotext(meta))
end
end
end

View File

@ -1,4 +1,4 @@
local FORMSPEC_NAME = "pick_and_place:configure"
local FORMSPEC_NAME = "pick_and_place:configure_tool"
-- playername -> pos (if pos1 selected)
local pos1 = {}

View File

@ -1,4 +1,4 @@
function pick_and_place.create_tool(pos1, pos2, name)
function pick_and_place.create_tool(pos1, pos2, name, id)
local size = vector.add(vector.subtract(pos2, pos1), 1)
local tool = ItemStack("pick_and_place:place 1")
@ -10,8 +10,9 @@ function pick_and_place.create_tool(pos1, pos2, name)
local encoded_schematic = pick_and_place.encode_schematic(schematic)
tool_meta:set_string("schematic", encoded_schematic)
-- set name
-- set name and id
tool_meta:set_string("name", name)
tool_meta:set_string("id", id)
-- add rotation info (with respect to original in-world build)
tool_meta:set_int("rotation", 0)
@ -24,13 +25,14 @@ end
function pick_and_place.update_placement_tool_description(tool_meta)
local name = tool_meta:get_string("name")
local id = tool_meta:get_string("id")
local size_str = tool_meta:get_string("size")
local schematic = tool_meta:get_string("schematic")
local rotation = tool_meta:get_int("rotation")
local desc = string.format(
"Placement tool '%s' (%d bytes, rotation: %d°, size: %s)",
name or "", #schematic, rotation, size_str
"Placement tool '%s' / '%s' (%d bytes, rotation: %d°, size: %s)",
name or "", id or "", #schematic, rotation, size_str
)
tool_meta:set_string("description", desc)
end

View File

@ -7,7 +7,7 @@ mtt.emerge_area(pos1, pos2)
mtt.register("create_tool and rotate", function(callback)
minetest.set_node(pos1, { name = "default:mese" })
local tool = pick_and_place.create_tool(pos1, pos2, "my build")
local tool = pick_and_place.create_tool(pos1, pos2, "my build", "1234")
assert(tool)
local meta = tool:get_meta()
assert(meta:get_string("description"))

View File

@ -1,12 +1,16 @@
local FORMSPEC_NAME = "pick_and_place:handle_node"
-- returns the absolute positions and name for the handle
-- TODO: a better name perhaps?
function pick_and_place.get_template_data_from_handle(pos)
local meta = minetest.get_meta(pos)
function pick_and_place.get_template_data_from_handle(pos, meta)
-- relative positions
local rel_pos1 = minetest.string_to_pos(meta:get_string("pos1"))
local rel_pos2 = minetest.string_to_pos(meta:get_string("pos2"))
local name = meta:get_string("name")
local id = meta:get_string("id")
if id == "" then
id = pick_and_place.create_id()
end
if not rel_pos1 or not rel_pos2 then
-- not configured
@ -17,24 +21,80 @@ function pick_and_place.get_template_data_from_handle(pos)
local pos1 = vector.add(pos, rel_pos1)
local pos2 = vector.add(pos, rel_pos2)
return pos1, pos2, name
return pos1, pos2, name, id
end
local function on_rightclick(pos, _, _, itemstack)
function pick_and_place.get_handle_infotext(meta)
return "Handle name: '" .. meta:get_string("name") .. "' id: '" .. meta:get_string("id") .. "'"
end
-- migrate
local function migrate_handle(pos, meta)
if meta:get_string("id") == "" then
-- legacy node without id, reconfigure
local pos1, pos2, name, id = pick_and_place.get_template_data_from_handle(pos, meta)
pick_and_place.configure(pos1, pos2, name, id)
meta:set_string("infotext", pick_and_place.get_handle_infotext(meta))
end
end
local function on_punch(pos, _, puncher)
local itemstack = puncher:get_wielded_item()
if not itemstack:is_empty() then
-- not an empty hand
return
end
local pos1, pos2, name = pick_and_place.get_template_data_from_handle(pos)
local meta = minetest.get_meta(pos)
migrate_handle(pos, meta)
local pos1, pos2, name, id = pick_and_place.get_template_data_from_handle(pos, meta)
if not pos1 or not pos2 then
return
end
return pick_and_place.create_tool(pos1, pos2, name)
itemstack = pick_and_place.create_tool(pos1, pos2, name, id)
puncher:set_wielded_item(itemstack)
end
local function get_formspec(meta)
return [[
size[10,1]
real_coordinates[true]
field[0.1,0.1;7,0.8;name;Name;]] .. meta:get_string("name") .. [[]
button_exit[7.1,0.1;2.5,0.8;save;Save]
]]
end
-- playername -> node position for formspec
local fs_pos = {}
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= FORMSPEC_NAME then
return false
end
if not fields.save and not fields.key_enter_field then
return true
end
local playername = player:get_player_name()
local pos = fs_pos[playername]
if not pos then
return true
end
local meta = minetest.get_meta(pos)
local pos1, pos2, _, id = pick_and_place.get_template_data_from_handle(pos, meta)
-- reconfigure handles
pick_and_place.configure(pos1, pos2, fields.name, id)
return true
end)
minetest.register_node("pick_and_place:handle", {
description = "Pick and place handle",
tiles = {"pick_and_place.png"},
@ -42,7 +102,13 @@ minetest.register_node("pick_and_place:handle", {
use_texture_alpha = "blend",
paramtype = "light",
sunlight_propagates = true,
on_rightclick = on_rightclick,
on_rightclick = function(pos, _, clicker)
local meta = minetest.get_meta(pos)
local playername = clicker:get_player_name()
fs_pos[playername] = pos
minetest.show_formspec(playername, FORMSPEC_NAME, get_formspec(meta))
end,
on_punch = on_punch,
on_destruct = pick_and_place.remove_handles,
drop = "",
groups = {
@ -57,7 +123,9 @@ minetest.register_lbm({
nodenames = {"pick_and_place:handle"},
run_at_every_load = true,
action = function(pos)
local pos1, pos2, name = pick_and_place.get_template_data_from_handle(pos)
local meta = minetest.get_meta(pos)
migrate_handle(pos, meta)
local pos1, pos2, name = pick_and_place.get_template_data_from_handle(pos, meta)
pick_and_place.register_template(name, pos1, pos2)
end
})