From c02a7fde5993ba6db76fe77300c066a2d37ca2fe Mon Sep 17 00:00:00 2001 From: Buckaroo Banzai <39065740+BuckarooBanzay@users.noreply.github.com> Date: Thu, 29 Feb 2024 19:26:34 +0100 Subject: [PATCH] schematic replacements (#2) * schematic replacements * wip * fixes --------- Co-authored-by: BuckarooBanzay --- handle_node.lua | 3 +- init.lua | 1 + replacement.lua | 89 +++++++++++++++++++++++++++++++++++++++++++++++++ serialize.lua | 19 ++++++++++- 4 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 replacement.lua diff --git a/handle_node.lua b/handle_node.lua index c13b648..52873ec 100644 --- a/handle_node.lua +++ b/handle_node.lua @@ -34,6 +34,7 @@ minetest.register_node("pick_and_place:handle", { on_rightclick = on_rightclick, drop = "", groups = { - oddly_breakable_by_hand = 3 + oddly_breakable_by_hand = 3, + not_in_creative_inventory = 1 } }) diff --git a/init.lua b/init.lua index aa10ceb..7fdafcb 100644 --- a/init.lua +++ b/init.lua @@ -8,6 +8,7 @@ dofile(MP .. "/schematic_rotate.lua") dofile(MP .. "/schematic_flip.lua") dofile(MP .. "/schematic_orient.lua") dofile(MP .. "/schematic_transpose.lua") +dofile(MP .. "/replacement.lua") dofile(MP .. "/pointed.lua") dofile(MP .. "/configure.lua") dofile(MP .. "/remove.lua") diff --git a/replacement.lua b/replacement.lua new file mode 100644 index 0000000..f5ae79e --- /dev/null +++ b/replacement.lua @@ -0,0 +1,89 @@ + +local function update_formspec(meta) + local group = meta:get_string("group") + + meta:set_string("formspec", [[ + size[10,8.3] + real_coordinates[true] + field[0.1,0.4;8.8,0.8;group;Group;]] .. group .. [[] + button_exit[9,0.4;0.9,0.8;set;Set] + list[context;main;0.1,1.4;8,1;] + list[current_player;main;0.1,3;8,4;] + listring[] + ]]) + + local txt = "Replacement node" + if group and group ~= "" then + txt = txt .. " (group: '" .. group .. "')" + end + meta:set_string("infotext", txt) +end + +minetest.register_node("pick_and_place:replacement", { + description = "Replacement node", + tiles = {"pick_and_place.png^[colorize:#ff0000"}, + drawtype = "allfaces", + use_texture_alpha = "blend", + paramtype = "light", + sunlight_propagates = true, + groups = { + oddly_breakable_by_hand = 3 + }, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("main", 8) + + update_formspec(meta) + end, + + on_receive_fields = function(pos, _, fields) + if fields.set then + local meta = minetest.get_meta(pos) + meta:set_string("group", fields.group) + update_formspec(meta) + end + end +}) + +function pick_and_place.get_replacement_nodeid(ctx, metadata) + local group = metadata.fields.group + local selected_name + if group and group ~= "" and ctx[group] then + -- group placement + selected_name = metadata.inventory.main[ctx[group]] + else + -- random placement + local replacement_names = {} + for _, name in ipairs(metadata.inventory.main) do + if name ~= "" then + table.insert(replacement_names, name) + end + end + + if #replacement_names == 0 then + -- no replacement + return + end + + local i = math.random(#replacement_names) + selected_name = replacement_names[i] + + -- set group context + if group and group ~= "" then + ctx[group] = i + end + end + + local stack = ItemStack(selected_name) + local nodename = stack:get_name() + + if not minetest.registered_nodes[nodename] then + -- node not found + return + end + + local nodeid = minetest.get_content_id(nodename) + return nodeid +end \ No newline at end of file diff --git a/serialize.lua b/serialize.lua index 9f2cc01..063ab40 100644 --- a/serialize.lua +++ b/serialize.lua @@ -1,4 +1,5 @@ local air_cid = minetest.get_content_id("air") +local replacement_cid = minetest.get_content_id("pick_and_place:replacement") function pick_and_place.serialize(pos1, pos2) local manip = minetest.get_voxel_manip() @@ -68,6 +69,7 @@ function pick_and_place.deserialize(pos1, encoded_data) local node_data = manip:get_data() local param2 = manip:get_param2_data() + local ctx = {} local j = 1 for z=pos1.z,pos2.z do for y=pos1.y,pos2.y do @@ -75,7 +77,22 @@ function pick_and_place.deserialize(pos1, encoded_data) local i = area:index(x,y,z) local nodeid = schematic.node_id_data[j] - if nodeid ~= air_cid then + if nodeid == replacement_cid then + -- replacement placement + local abs_pos = {x=x, y=y, z=z} + local rel_pos = vector.subtract(abs_pos, pos1) + local pos_str = minetest.pos_to_string(rel_pos) + local metadata = schematic.metadata[pos_str] + local repl_id = pick_and_place.get_replacement_nodeid(ctx, metadata) + if repl_id then + -- set new node + node_data[i] = repl_id + param2[i] = schematic.param2_data[j] + -- clear metadata + schematic.metadata[pos_str] = nil + end + elseif nodeid ~= air_cid then + -- normal placement node_data[i] = nodeid param2[i] = schematic.param2_data[j] end