From bfa9af888abb7b482095d81548194075be913556 Mon Sep 17 00:00:00 2001 From: FaceDeer Date: Fri, 27 Jan 2017 19:40:10 -0700 Subject: [PATCH] Add a "stop block" setting to auto-controller --- doc.lua | 6 ++++-- node_builders.lua | 3 ++- node_controllers.lua | 44 ++++++++++++++++++++++++++++++++++-------- util_execute_cycle.lua | 23 +++++++++++++++++++++- 4 files changed, 64 insertions(+), 12 deletions(-) diff --git a/doc.lua b/doc.lua index d9304cc..b72613c 100644 --- a/doc.lua +++ b/doc.lua @@ -18,7 +18,7 @@ digtron.doc.builder_usagehelp = "A builder head is the most complex component of 'When the "Save & Show" button is clicked the properties for period and offset will be saved, and markers will briefly be shown to indicate where the nearest spots corresponding to those values are. The builder will build its output at those locations provided it is moving along the matching axis.\n\n' .. 'The "output" side of a builder is the side with a black crosshair on it.\n\n' .. 'Builders also have a "facing" setting. If you haven\'t memorized the meaning of the 24 facing values yet, builder heads have a helpful "Read & Save" button to fill this value in for you. Simply build a temporary instance of the block in the output location in front of the builder, adjust it to the orientation you want using the screwdriver tool, and then when you click the "Read & Save" button the block\'s facing will be read and saved.\n\n' .. -"Note: if more than one builder tries to build into the same space simultaneously, it is not predictable which builder will take priority. You should arrange your builders to avoid this to get consistent results." +"Note: if more than one builder tries to build into the same space simultaneously, it is not predictable which builder will take priority. One will succeed and the other will fail. You should arrange your builders to avoid this for consistent results." -------------------------------------------------------------------- @@ -59,7 +59,9 @@ digtron.doc.controller_usagehelp = "Right-click on this module to make the diggi digtron.doc.auto_controller_longdesc = "A more sophisticated controller that includes the ability to set the number of cycles it will run for, as well as diagonal movement." digtron.doc.auto_controller_usagehelp = "An Auto-control module can be set to run for an arbitrary number of cycles. Once it's running, right-click on it again to interrupt its rampage. If anything interrupts it - the player's click, an undiggable obstruction, running out of fuel - it will remember the number of remaining cycles so that you can fix the problem and set it running again to complete the original plan.\n\n" .. "The digging machine will go in the direction that the control module is oriented.\n\n" .. -"Auto-controllers can also be set to move diagonally by setting the \"slope\" parameter to a non-zero value. The controller will then shunt the Digtron in the direction of the arrows painted on its sides every X steps it moves. The Digtron will trigger dig heads when it shunts to the side, but will not trigger builder modules or intermittent dig heads." +"Auto-controllers can also be set to move diagonally by setting the \"Slope\" parameter to a non-zero value. The controller will then shunt the Digtron in the direction of the arrows painted on its sides every X steps it moves. The Digtron will trigger dig heads when it shunts to the side, but will not trigger builder modules or intermittent dig heads. The \"Offset\" setting determines at what point the lateral motion will take place.\n\n" .. +"The \"Stop block\" inventory slot in an auto-controller allows you to program an auto-controller to treat certain block types as impenetrable obstructions. This can allow you to fence a Digtron in with something so you don't have to carefully count exactly how many steps it should take, for example.\n\n" .. +"Note that the Digtron detects an undiggable block by the item that would be produced when digging it. Setting cobble as the stop block will make both cobble and regular stone undiggable, but setting a block of regular stone (produced from cobble in a furnace) as the stop block will *not* stop a Digtron from digging regular stone (since digging regular stone produces cobble, not stone)." digtron.doc.pusher_longdesc = "A simplified controller that merely moves a Digtron around without triggering its builder or digger modules" digtron.doc.pusher_usagehelp = "Aka the \"can you rebuild it six inches to the left\" module. This is a much simplified control module that does not trigger the digger or builder heads when right-clicked, it only moves the digging machine. It's up to you to ensure there's space for it to move into.\n\n".. diff --git a/node_builders.lua b/node_builders.lua index eeffa7a..01186f4 100644 --- a/node_builders.lua +++ b/node_builders.lua @@ -62,7 +62,6 @@ minetest.register_node("digtron:builder", { "button_exit[6.4,0.5;1,0.1;read;Read &\nSave]" .. "tooltip[read;Reads the facing of the block currently in the build location,\nthen saves all settings]" .. "list[current_player;main;0,1.3;8,1;]" .. - "list[current_player;main;0,1.3;8,1;]" .. default.get_hotbar_bg(0,1.3) .. "list[current_player;main;0,2.5;8,3;8]" .. "listring[current_player;main]" .. @@ -154,6 +153,8 @@ minetest.register_node("digtron:builder", { end, allow_metadata_inventory_take = function(pos, listname, index, stack, player) + local inv = minetest.get_inventory({type="node", pos=pos}) + inv:set_stack(listname, index, ItemStack("")) return 0 end, diff --git a/node_controllers.lua b/node_controllers.lua index ac51fc7..c51b48f 100644 --- a/node_controllers.lua +++ b/node_controllers.lua @@ -71,22 +71,32 @@ minetest.register_node("digtron:controller", { -- Auto-controller --------------------------------------------------------------------------------------------------------------- -local auto_formspec = "size[3.5,2]" .. +local auto_formspec = "size[8,6.2]" .. default.gui_bg .. default.gui_bg_img .. default.gui_slots .. - "field[0.5,0.8;1,0.1;cycles;Cycles;${cycles}]" .. + "container[2.5,0]" .. + "field[0.0,0.8;1,0.1;cycles;Cycles;${cycles}]" .. "tooltip[cycles;When triggered, this controller will try to run for the given number of cycles.\nThe cycle count will decrement as it runs, so if it gets halted by a problem\nyou can fix the problem and restart.]" .. - "button_exit[1.2,0.5;1,0.1;set;Set]" .. + "button_exit[0.7,0.5;1,0.1;set;Set]" .. "tooltip[set;Saves the cycle setting without starting the controller running]" .. - "button_exit[2.2,0.5;1,0.1;execute;Set &\nExecute]" .. + "button_exit[1.7,0.5;1,0.1;execute;Set &\nExecute]" .. "tooltip[execute;Begins executing the given number of cycles]" .. - "field[0.5,2.0;1,0.1;slope;Slope;${slope}]" .. + "field[0.0,2.0;1,0.1;slope;Slope;${slope}]" .. "tooltip[slope;For diagonal digging. After every X nodes the auto controller moves forward,\nthe controller will add an additional cycle moving the digtron laterally in the\ndirection of the arrows on the side of this controller.\nSet to 0 for no lateral digging.]" .. - "field[1.5,2.0;1,0.1;offset;Offset;${offset}]" .. + "field[1.0,2.0;1,0.1;offset;Offset;${offset}]" .. "tooltip[offset;Sets the offset of the lateral motion defined in the Slope field.\nNote: this offset is relative to the controller's location.\nThe controller will move down when it reaches the indicated point.]" .. - "field[2.5,2.0;1,0.1;period;Delay;${period}]" .. - "tooltip[period;Number of seconds to wait between each cycle]" + "field[2.0,2.0;1,0.1;period;Delay;${period}]" .. + "tooltip[period;Number of seconds to wait between each cycle]" .. + "list[current_name;stop;3.0,0.7;1,1;]" .. + "label[3.0,1.5;Stop block]" .. + "container_end[]" .. + "list[current_player;main;0,2.3;8,1;]" .. + default.get_hotbar_bg(0,2.3) .. + "list[current_player;main;0,3.5;8,3;8]" .. + "listring[current_player;main]" .. + "listring[current_name;stop]" + -- Needed to make this global so that it could recurse into minetest.after digtron.auto_cycle = function(pos) @@ -185,8 +195,26 @@ minetest.register_node("digtron:auto_controller", { meta:set_int("offset", 0) meta:set_int("cycles", 0) meta:set_int("slope", 0) + + local inv = meta:get_inventory() + inv:set_size("stop", 1) end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if minetest.get_item_group(stack:get_name(), "digtron") ~= 0 then + return 0 -- pointless setting a Digtron node as a stop block + end + local inv = minetest.get_inventory({type="node", pos=pos}) + inv:set_stack(listname, index, stack:take_item(1)) + return 0 + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + local inv = minetest.get_inventory({type="node", pos=pos}) + inv:set_stack(listname, index, ItemStack("")) + return 0 + end, + on_receive_fields = function(pos, formname, fields, sender) local meta = minetest.get_meta(pos) local offset = tonumber(fields.offset) diff --git a/util_execute_cycle.lua b/util_execute_cycle.lua index c23c376..dde9e2d 100644 --- a/util_execute_cycle.lua +++ b/util_execute_cycle.lua @@ -76,6 +76,19 @@ local function move_player_test(layout, player) return false end +local function test_stop_block(pos, items) + local inv = minetest.get_inventory({type="node", pos=pos}) + local item_stack = inv:get_stack("stop", 1) + if not item_stack:is_empty() then + for _, item in pairs(items) do + if item == item_stack:get_name() then + return true + end + end + end + return false +end + -- returns newpos, status string, and a return code indicating why the method returned (so the auto-controller can keep trying if it's due to unloaded nodes) -- 0 - success -- 1 - failed due to unloaded nodes @@ -142,6 +155,10 @@ digtron.execute_dig_cycle = function(pos, clicker) end end + if test_stop_block(pos, items_dropped) then + can_move = false + end + if not can_move then -- mark this node as waiting, will clear this flag in digtron.cycle_time seconds minetest.get_meta(pos):set_string("waiting", "true") @@ -419,7 +436,11 @@ digtron.execute_downward_dig_cycle = function(pos, clicker) can_move = false end end - + + if test_stop_block(pos, items_dropped) then + can_move = false + end + if not can_move then -- mark this node as waiting, will clear this flag in digtron.cycle_time seconds minetest.get_meta(pos):set_string("waiting", "true")