From 3f9ca87269b2e77cb323fec3b516c8d0dee4c94b Mon Sep 17 00:00:00 2001 From: Hans von Smacker <32678859+h-v-smacker@users.noreply.github.com> Date: Wed, 24 May 2023 09:00:00 +0300 Subject: [PATCH] Master builder node (#60) * broken layout check * broken layout check * broken layout check * introducing master builder module * fix drops for mb --------- Co-authored-by: h-v-smacker --- nodes/node_builders.lua | 202 +++++++++++++++++++++++++--- nodes/node_crate.lua | 2 +- nodes/recipes.lua | 20 +++ textures/digtron_master_builder.png | Bin 0 -> 245 bytes 4 files changed, 206 insertions(+), 18 deletions(-) create mode 100644 textures/digtron_master_builder.png diff --git a/nodes/node_builders.lua b/nodes/node_builders.lua index a9d783d..4d17667 100644 --- a/nodes/node_builders.lua +++ b/nodes/node_builders.lua @@ -73,8 +73,8 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields) return end local pos = minetest.string_to_pos(formname:sub(16, -1)) - - local meta = minetest.get_meta(pos) + + local meta = minetest.get_meta(pos) local period = tonumber(fields.period) local offset = tonumber(fields.offset) local build_facing = tonumber(fields.build_facing) @@ -108,20 +108,86 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields) extrusion = meta:get_int("extrusion") end - if fields.set then - digtron.show_offset_markers(pos, offset, period) + local nodename = minetest.get_node_or_nil(pos).name + + -- Master builder: bulk operations on all builders, layout cycling + if nodename == "digtron:master_builder" then + + if fields.set then + -- copy current settings to all builders + local layout = DigtronLayout.create(pos, sender) + + if layout.builders ~= nil then + + local inv = meta:get_inventory() + local target_item = inv:get_stack("main",1) + local target_item_name = target_item:get_name() + + if target_item_name ~= "air" and minetest.get_item_group(target_item_name, "digtron") == 0 then + + for k, location in pairs(layout.builders) do - elseif fields.read then - local facing = minetest.get_node(pos).param2 - local buildpos = digtron.find_new_pos(pos, facing) - local target_node = minetest.get_node(buildpos) - if target_node.name ~= "air" and minetest.get_item_group(target_node.name, "digtron") == 0 then - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - local target_name = digtron.builder_read_item_substitutions[target_node.name] or target_node.name - inv:set_stack("main", 1, target_name) - meta:set_int("build_facing", target_node.param2) + local target = minetest.get_node(location.pos) + local target_meta = minetest.get_meta(location.pos) + target_meta:set_int("period", meta:get_int("period")) + target_meta:set_int("offset", meta:get_int("offset")) + target_meta:set_int("build_facing", meta:get_int("build_facing")) + target_meta:set_int("extrusion", meta:get_int("extrusion")) + + local target_inv = target_meta:get_inventory() + target_inv:set_stack("main", 1, target_item_name) + + digtron.update_builder_item(location.pos) + end + end + end + + elseif fields.read then + + -- make all builders perform read&save + local layout = DigtronLayout.create(pos, sender) + + if layout.builders ~= nil then + for k, location in pairs(layout.builders) do + + local target = minetest.get_node(location.pos) + local facing = minetest.get_node(location.pos).param2 + local buildpos = digtron.find_new_pos(location.pos, facing) + local target_node = minetest.get_node(buildpos) + if target_node.name ~= "air" and minetest.get_item_group(target_node.name, "digtron") == 0 then + local meta = minetest.get_meta(location.pos) + local inv = meta:get_inventory() + local target_name = digtron.builder_read_item_substitutions[target_node.name] or target_node.name + inv:set_stack("main", 1, target_name) + meta:set_int("build_facing", target_node.param2) + digtron.update_builder_item(location.pos) + end + + end + + end end + + + -- regular builder: changes apply only to itself + else + + if fields.set then + digtron.show_offset_markers(pos, offset, period) + + elseif fields.read then + local facing = minetest.get_node(pos).param2 + local buildpos = digtron.find_new_pos(pos, facing) + local target_node = minetest.get_node(buildpos) + if target_node.name ~= "air" and minetest.get_item_group(target_node.name, "digtron") == 0 then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local target_name = digtron.builder_read_item_substitutions[target_node.name] or target_node.name + inv:set_stack("main", 1, target_name) + meta:set_int("build_facing", target_node.param2) + end + end + end if fields.help and minetest.get_modpath("doc") then --check for mod in case someone disabled it after this digger was built @@ -136,14 +202,14 @@ end) minetest.register_node("digtron:builder", { description = S("Digtron Builder Module"), _doc_items_longdesc = digtron.doc.builder_longdesc, - _doc_items_usagehelp = digtron.doc.builder_usagehelp, + _doc_items_usagehelp = digtron.doc.builder_usagehelp, groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 4}, drop = "digtron:builder", sounds = digtron.metal_sounds, paramtype = "light", paramtype2= "facedir", is_ground_content = false, - tiles = { + tiles = { "digtron_plate.png^[transformR90", "digtron_plate.png^[transformR270", "digtron_plate.png", @@ -354,4 +420,106 @@ minetest.register_node("digtron:builder", { end return built_count end, -}) \ No newline at end of file +}) + +-- Master builder node +-- Does not build anything, but can set all other builders to a certain item +-- OR make all other builders perform read & save operation. +-- First function is handy e.g. for farming combines, the second is handy for templates. +-- The formspec is reused, but the buttons are behaving differently from regular builder: +-- Save and show -> propagate settings from master builder to all builders +-- Read and save -> perform read&save on all builders + +minetest.register_node("digtron:master_builder", { + description = S("Digtron Master Builder Module"), + _doc_items_longdesc = digtron.doc.builder_longdesc, + _doc_items_usagehelp = digtron.doc.builder_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand = 3, digtron = 1}, + drop = "digtron:master_builder", + sounds = digtron.metal_sounds, + paramtype = "light", + paramtype2= "facedir", + is_ground_content = false, + tiles = { + "digtron_plate.png^[transformR90^digtron_master_builder.png^[colorize:" .. digtron.auto_controller_colorize, + "digtron_plate.png^[transformR270^digtron_master_builder.png^[colorize:" .. digtron.auto_controller_colorize, + "digtron_plate.png^digtron_master_builder.png^[colorize:" .. digtron.auto_controller_colorize, + "digtron_plate.png^[transformR180^digtron_master_builder.png^[colorize:" .. digtron.auto_controller_colorize, + "digtron_plate.png^digtron_master_builder.png^[colorize:" .. digtron.auto_controller_colorize, + "digtron_plate.png^digtron_master_builder.png^[colorize:" .. digtron.auto_controller_colorize, + }, + + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {0.3125, 0.3125, -0.5, 0.5, 0.5, 0.5}, + {0.3125, -0.5, -0.5, 0.5, -0.3125, 0.5}, + {-0.5, 0.3125, -0.5, -0.3125, 0.5, 0.5}, + {-0.5, -0.5, -0.5, -0.3125, -0.3125, 0.5}, + {-0.3125, 0.3125, 0.3125, 0.3125, 0.5, 0.5}, + {-0.3125, -0.5, 0.3125, 0.3125, -0.3125, 0.5}, + {-0.5, -0.3125, 0.3125, -0.3125, 0.3125, 0.5}, + {0.3125, -0.3125, 0.3125, 0.5, 0.3125, 0.5}, + {-0.5, -0.3125, -0.5, -0.3125, 0.3125, -0.3125}, + {0.3125, -0.3125, -0.5, 0.5, 0.3125, -0.3125}, + {-0.3125, 0.3125, -0.5, 0.3125, 0.5, -0.3125}, + {-0.3125, -0.5, -0.5, 0.3125, -0.3125, -0.3125}, + } + }, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_int("period", 1) + meta:set_int("offset", 0) + meta:set_int("build_facing", 0) + meta:set_int("extrusion", 1) + + local inv = meta:get_inventory() + inv:set_size("main", 1) + end, + + on_rightclick = builder_on_rightclick, + + on_destruct = function(pos) + digtron.remove_builder_item(pos) + end, + + after_place_node = function(pos) + digtron.update_builder_item(pos) + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local stack_name = stack:get_name() + + if minetest.get_item_group(stack_name, "digtron") ~= 0 then + return 0 -- don't allow builders to be set to build Digtron nodes, they'll just clog the output. + end + + local stack_def = minetest.registered_nodes[stack_name] + if not stack_def and not digtron.whitelisted_on_place(stack_name) then + return 0 -- don't allow craft items unless their on_place is whitelisted. + end + + node_inventory_table.pos = pos + local inv = minetest.get_inventory(node_inventory_table) + inv:set_stack(listname, index, stack:take_item(1)) + + -- If we're adding a wallmounted item and the build facing is greater than 5, reset it to 0 + local meta = minetest.get_meta(pos) + if stack_def ~= nil and stack_def.paramtype2 == "wallmounted" and tonumber(meta:get_int("build_facing")) > 5 then + meta:set_int("build_facing", 0) + end + + return 0 + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + node_inventory_table.pos = pos + local inv = minetest.get_inventory(node_inventory_table) + inv:set_stack(listname, index, ItemStack("")) + return 0 + end, + + +}) diff --git a/nodes/node_crate.lua b/nodes/node_crate.lua index 5fa4f69..d0dc7fd 100644 --- a/nodes/node_crate.lua +++ b/nodes/node_crate.lua @@ -392,4 +392,4 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) loaded_on_recieve(pos, fields, player, true) return true end -end) +end) \ No newline at end of file diff --git a/nodes/recipes.lua b/nodes/recipes.lua index 313c4a9..a907cbf 100644 --- a/nodes/recipes.lua +++ b/nodes/recipes.lua @@ -45,6 +45,26 @@ minetest.register_craft({ } }) +if minetest.get_modpath("technic") then + minetest.register_craft({ + output = "digtron:master_builder", + recipe = { + {"","technic:control_logic_unit",""}, + {"","digtron:digtron_core",""}, + {"","",""} + } + }) +else + minetest.register_craft({ + output = "digtron:master_builder", + recipe = { + {"","default:mese",""}, + {"","digtron:digtron_core",""}, + {"","",""} + } + }) +end + minetest.register_craft({ output = "digtron:light", recipe = { diff --git a/textures/digtron_master_builder.png b/textures/digtron_master_builder.png new file mode 100644 index 0000000000000000000000000000000000000000..25f731c4636d073e4dcd8510f44d13f8402978cd GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP-H=BS7o5O{O&p@FjPZ!4!i_=FZ8*&{`;BoygYunH+ zXghKB>Ntmmix+=kiB*wRQtdk$^#7A%#mR8t2i!+Fm>evd8Dfq-V7buy@bkT!!Aap= zvDX%C_w^P$v*JfsHs>1AGdmvd=j>n+KGen%#eM8IFK3^#!R6+hpRI