From 51c5e9b6417b807ea3b7890240bd2ea43e8a297a Mon Sep 17 00:00:00 2001 From: FaceDeer Date: Sat, 14 Jan 2017 16:58:37 -0700 Subject: [PATCH] Diagonal movement setting for the auto-controller. --- class_layout.lua | 64 ++++++----------- init.lua | 30 ++++++++ node_axle.lua | 2 +- node_controllers.lua | 98 +++++++++++++++++++++----- node_diggers.lua | 20 ++++-- util.lua | 8 ++- util_execute_cycle.lua | 156 ++++++++++++++++++++++++++++++++++++++--- 7 files changed, 296 insertions(+), 82 deletions(-) diff --git a/class_layout.lua b/class_layout.lua index c39c9ad..3b3b739 100644 --- a/class_layout.lua +++ b/class_layout.lua @@ -260,48 +260,20 @@ end ----------------------------------------------------------------------------------------------- -- Translation -function DigtronLayout.move_layout_image(self, facing, player_name) +function DigtronLayout.move_layout_image(self, dir) local extents = self.extents - local dir = digtron.facedir_to_dir_map[facing] - local increment - local filter - if dir == 1 then -- z+ - filter = "z" - increment = 1 - extents.max_z = extents.max_z + 1 - extents.min_z = extents.min_z + 1 - elseif dir == 2 then -- x+ - filter = "x" - increment = 1 - extents.max_x = extents.max_x + 1 - extents.min_x = extents.min_x + 1 - elseif dir == 3 then -- z- - filter = "z" - increment = -1 - extents.max_z = extents.max_z - 1 - extents.min_z = extents.min_z - 1 - elseif dir == 4 then -- x- - filter = "x" - increment = -1 - extents.max_x = extents.max_x - 1 - extents.min_x = extents.min_x - 1 - elseif dir == 5 then -- y- - filter = "y" - increment = -1 - extents.max_y = extents.max_y - 1 - extents.min_y = extents.min_y - 1 - elseif dir == 6 then -- y+ - filter = "y" - increment = 1 - extents.max_y = extents.max_y + 1 - extents.min_y = extents.min_y + 1 - end - + + extents.max_x = extents.max_x + dir.x + extents.min_x = extents.min_x + dir.x + extents.max_y = extents.max_y + dir.y + extents.min_y = extents.min_y + dir.y + extents.max_z = extents.max_z + dir.z + extents.min_z = extents.min_z + dir.z + for k, node_image in pairs(self.all) do self.old_pos_pointset:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, true) - node_image.pos[filter] = node_image.pos[filter] + increment + node_image.pos = vector.add(node_image.pos, dir) self.nodes_dug:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, false) -- we've moved a digtron node into this space, mark it so that we don't dig it. - -- TODO: log end end @@ -325,14 +297,17 @@ function DigtronLayout.can_write_layout_image(self) return true end -function DigtronLayout.write_layout_image(self) +function DigtronLayout.write_layout_image(self, player) -- destroy the old digtron local oldpos, _ = self.old_pos_pointset:pop() while oldpos ~= nil do - local old_def = minetest.registered_nodes[minetest.get_node(oldpos).name] - minetest.remove_node(oldpos) + local old_node = minetest.get_node(oldpos) + local old_meta = minetest.get_meta(oldpos) + local old_def = minetest.registered_nodes[old_node.name] + minetest.remove_node(oldpos) + minetest.log("action", string.format("%s removes Digtron component %s at (%d, %d, %d)", player:get_player_name(), old_node.name, oldpos.x, oldpos.y, oldpos.z)) if old_def.after_dig_node ~= nil then - old_def.after_dig_node(oldpos) + old_def.after_dig_node(oldpos, old_node, old_meta, player) end oldpos, _ = self.old_pos_pointset:pop() end @@ -340,11 +315,12 @@ function DigtronLayout.write_layout_image(self) -- create the new one for k, node_image in pairs(self.all) do minetest.add_node(node_image.pos, node_image.node) - minetest.get_meta(node_image.pos):from_table(node_image.meta) + minetest.get_meta(node_image.pos):from_table(node_image.meta) + minetest.log("action", string.format("%s adds Digtron component %s at (%d, %d, %d)", player:get_player_name(), node_image.node.name, node_image.pos.x, node_image.pos.y, node_image.pos.z)) local new_def = minetest.registered_nodes[node_image.node.name] if new_def.after_place_node ~= nil then - new_def.after_place_node(node_image.pos) + new_def.after_place_node(node_image.pos, player) end end end diff --git a/init.lua b/init.lua index 3ae536f..94eb79e 100644 --- a/init.lua +++ b/init.lua @@ -79,4 +79,34 @@ minetest.register_lbm({ default.get_hotbar_bg(0,5.15) ) end +}) + +minetest.register_lbm({ + name = "digtron:autocontroller_lateral_upgrade", + nodenames = {"digtron:auto_controller"}, + action = function(pos, node) + local meta = minetest.get_meta(pos) + local cycles = meta:get_int("offset") + meta:set_int("cycles", cycles) + meta:set_int("offset", 0) + meta:set_int("slope", 0) + meta:set_string("formspec", + "size[3.5,2]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "field[0.5,0.8;1,0.1;cycles;Cycles;${cycles}]" .. + "tooltip[cycles;When triggered, this controller will try to run for the given number of cycles. The cycle count will decrement as it runs, so if it gets halted by a problem you can fix the problem and restart.]" .. + "button_exit[1.2,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]" .. + "tooltip[execute;Begins executing the given number of cycles]" .. + "field[0.5,2.0;1,0.1;slope;Slope;${slope}]" .. + "tooltip[slope;For diagonal digging. After every X nodes the auto controller moves forward, the controller will add an additional cycle moving the digtron laterally in the direction of the arrows on the side of this controller. Set to 0 for no lateral digging.]" .. + "field[1.5,2.0;1,0.1;offset;Offset;${offset}]" .. + "tooltip[offset;Sets the offset of the lateral motion defined in the Slope field. Note: this offset is relative to the controller's location. The 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]" + ) + end }) \ No newline at end of file diff --git a/node_axle.lua b/node_axle.lua index ab36c97..de221b3 100644 --- a/node_axle.lua +++ b/node_axle.lua @@ -39,7 +39,7 @@ minetest.register_node("digtron:axle", { local image = DigtronLayout.create(pos, clicker) image:rotate_layout_image(node.param2) if image:can_write_layout_image() then - image:write_layout_image() + image:write_layout_image(clicker) minetest.sound_play("whirr", {gain=1.0, pos=pos}) meta = minetest.get_meta(pos) diff --git a/node_controllers.lua b/node_controllers.lua index 9efa804..8e68721 100644 --- a/node_controllers.lua +++ b/node_controllers.lua @@ -69,32 +69,60 @@ minetest.register_node("digtron:controller", { -- Auto-controller --------------------------------------------------------------------------------------------------------------- -local auto_formspec = "size[4.5,1]" .. +local auto_formspec = "size[3.5,2]" .. default.gui_bg .. default.gui_bg_img .. default.gui_slots .. - "field[0.5,0.8;1,0.1;offset;Cycles;${offset}]" .. - "tooltip[offset;When triggered, this controller will try to run for the given number of cycles. The cycle count will decrement as it runs, so if it gets halted by a problem you can fix the problem and restart.]" .. - "field[1.5,0.8;1,0.1;period;Period;${period}]" .. - "tooltip[period;Number of seconds to wait between each cycle]" .. - "button_exit[2.2,0.5;1,0.1;set;Set]" .. + "field[0.5,0.8;1,0.1;cycles;Cycles;${cycles}]" .. + "tooltip[cycles;When triggered, this controller will try to run for the given number of cycles. The cycle count will decrement as it runs, so if it gets halted by a problem you can fix the problem and restart.]" .. + "button_exit[1.2,0.5;1,0.1;set;Set]" .. "tooltip[set;Saves the cycle setting without starting the controller running]" .. - "button_exit[3.2,0.5;1,0.1;execute;Set &\nExecute]" .. - "tooltip[execute;Begins executing the given number of cycles]" - + "button_exit[2.2,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}]" .. + "tooltip[slope;For diagonal digging. After every X nodes the auto controller moves forward, the controller will add an additional cycle moving the digtron laterally in the direction of the arrows on the side of this controller. Set to 0 for no lateral digging.]" .. + "field[1.5,2.0;1,0.1;offset;Offset;${offset}]" .. + "tooltip[offset;Sets the offset of the lateral motion defined in the Slope field. Note: this offset is relative to the controller's location. The 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]" + -- Needed to make this global so that it could recurse into minetest.after digtron.auto_cycle = function(pos) + local node = minetest.get_node(pos) + local controlling_coordinate = digtron.get_controlling_coordinate(pos, node.param2) local meta = minetest.get_meta(pos) local player = minetest.get_player_by_name(meta:get_string("triggering_player")) if player == nil or meta:get_string("waiting") == "true" then return end + + local cycle = meta:get_int("cycles") + local slope = meta:get_int("slope") + + if meta:get_string("lateral_done") ~= "true" and slope ~= 0 and (pos[controlling_coordinate] + meta:get_int("offset")) % slope == 0 then + --Do a downward dig cycle. Don't update the "cycles" count, these don't count towards that. + local newpos, status, return_code = digtron.execute_downward_dig_cycle(pos, player) + + if vector.equals(pos, newpos) then + status = status .. string.format("\nCycles remaining: %d\nHalted!", cycle) + meta:set_string("infotext", status) + if return_code == 1 then --return code 1 happens when there's unloaded nodes adjacent, just keep trying. + minetest.after(meta:get_int("period"), digtron.auto_cycle, newpos) + else + meta:set_string("formspec", auto_formspec) + end + else + meta = minetest.get_meta(newpos) + minetest.after(meta:get_int("period"), digtron.auto_cycle, newpos) + meta:set_string("infotext", status) + meta:set_string("lateral_done", "true") + end + return + end local newpos, status, return_code = digtron.execute_dig_cycle(pos, player) - local cycle = 0 if vector.equals(pos, newpos) then - cycle = meta:get_int("offset") status = status .. string.format("\nCycles remaining: %d\nHalted!", cycle) meta:set_string("infotext", status) if return_code == 1 then --return code 1 happens when there's unloaded nodes adjacent, just keep trying. @@ -106,10 +134,11 @@ digtron.auto_cycle = function(pos) end meta = minetest.get_meta(newpos) - cycle = meta:get_int("offset") - 1 - meta:set_int("offset", cycle) + cycle = meta:get_int("cycles") - 1 + meta:set_int("cycles", cycle) status = status .. string.format("\nCycles remaining: %d", cycle) meta:set_string("infotext", status) + meta:set_string("lateral_done", nil) if cycle > 0 then minetest.after(meta:get_int("period"), digtron.auto_cycle, newpos) @@ -130,8 +159,8 @@ minetest.register_node("digtron:auto_controller", { tiles = { "digtron_plate.png^[transformR90^digtron_auto_control_tint.png", "digtron_plate.png^[transformR270^digtron_auto_control_tint.png", - "digtron_plate.png^digtron_auto_control_tint.png", - "digtron_plate.png^[transformR180^digtron_auto_control_tint.png", + "digtron_plate.png^digtron_axel_side.png^[transformR270^digtron_auto_control_tint.png", + "digtron_plate.png^digtron_axel_side.png^[transformR270^digtron_auto_control_tint.png", "digtron_plate.png^digtron_auto_control_tint.png", "digtron_plate.png^digtron_control.png^digtron_auto_control_tint.png", }, @@ -150,28 +179,59 @@ minetest.register_node("digtron:auto_controller", { -- Reusing offset and period to keep the digtron node-moving code simple, and the names still fit well meta:set_int("period", digtron.cycle_time) meta:set_int("offset", 0) + meta:set_int("cycles", 0) + meta:set_int("slope", 0) end, on_receive_fields = function(pos, formname, fields, sender) local meta = minetest.get_meta(pos) local offset = tonumber(fields.offset) local period = tonumber(fields.period) + local slope = tonumber(fields.slope) + local cycles = tonumber(fields.cycles) if period and period > 0 then meta:set_int("period", math.max(digtron.cycle_time, math.floor(period))) end + + if offset then + meta:set_int("offset", offset) + end - if offset and offset >= 0 then - meta:set_int("offset", math.floor(offset)) - if sender:is_player() and offset > 0 then + if slope and slope >= 0 then + meta:set_int("slope", slope) + end + + if cycles and cycles >= 0 then + meta:set_int("cycles", math.floor(cycles)) + if sender:is_player() and cycles > 0 then meta:set_string("triggering_player", sender:get_player_name()) if fields.execute then meta:set_string("waiting", nil) meta:set_string("formspec", nil) - digtron.auto_cycle(pos) + digtron.auto_cycle(pos) end end end + + if fields.set and slope and slope > 0 then + local node = minetest.get_node(pos) + local controlling_coordinate = digtron.get_controlling_coordinate(pos, node.param2) + + local newpos = pos --digtron.find_new_pos(pos, minetest.get_node(pos).param2) + local markerpos = {x=newpos.x, y=newpos.y, z=newpos.z} + local x_pos = math.floor((newpos[controlling_coordinate]+offset)/slope)*slope - offset + markerpos[controlling_coordinate] = x_pos + minetest.add_entity(markerpos, "digtron:marker_vertical") + if x_pos >= newpos[controlling_coordinate] then + markerpos[controlling_coordinate] = x_pos - slope + minetest.add_entity(markerpos, "digtron:marker_vertical") + end + if x_pos <= newpos[controlling_coordinate] then + markerpos[controlling_coordinate] = x_pos + slope + minetest.add_entity(markerpos, "digtron:marker_vertical") + end + end end, on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) diff --git a/node_diggers.lua b/node_diggers.lua index 8f410c2..ded88e4 100644 --- a/node_diggers.lua +++ b/node_diggers.lua @@ -85,7 +85,7 @@ minetest.register_node("digtron:digger", { }, -- returns fuel_cost, item_produced - execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate) + execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig) local facing = minetest.get_node(pos).param2 local digpos = digtron.find_new_pos(pos, facing) @@ -140,7 +140,11 @@ minetest.register_node("digtron:intermittent_digger", { on_receive_fields = intermittent_on_receive_fields, -- returns fuel_cost, item_produced - execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate) + execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig) + if lateral_dig == true then + return 0, {} + end + local facing = minetest.get_node(pos).param2 local digpos = digtron.find_new_pos(pos, facing) @@ -199,7 +203,7 @@ minetest.register_node("digtron:soft_digger", { "digtron_plate.png^digtron_motor.png^[colorize:#88880030", }, - execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate) + execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig) local facing = minetest.get_node(pos).param2 local digpos = digtron.find_new_pos(pos, facing) @@ -256,7 +260,11 @@ minetest.register_node("digtron:intermittent_soft_digger", { on_receive_fields = intermittent_on_receive_fields, - execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate) + execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig) + if lateral_dig == true then + return 0, {} + end + local facing = minetest.get_node(pos).param2 local digpos = digtron.find_new_pos(pos, facing) @@ -328,7 +336,7 @@ minetest.register_node("digtron:dual_digger", { }, -- returns fuel_cost, items_produced - execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate) + execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig) local facing = minetest.get_node(pos).param2 local digpos = digtron.find_new_pos(pos, facing) local digdown = digtron.find_new_pos_downward(pos, facing) @@ -403,7 +411,7 @@ minetest.register_node("digtron:dual_soft_digger", { }, -- returns fuel_cost, items_produced - execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate) + execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig) local facing = minetest.get_node(pos).param2 local digpos = digtron.find_new_pos(pos, facing) local digdown = digtron.find_new_pos_downward(pos, facing) diff --git a/util.lua b/util.lua index c6b2cc9..b0588e3 100644 --- a/util.lua +++ b/util.lua @@ -19,16 +19,18 @@ digtron.find_new_pos = function(pos, facing) return vector.add(pos, dir) end -digtron.find_new_pos_downward = function(pos, facing) - local downdir = ( +digtron.facedir_to_down_dir = function(facing) + return ( {[0]={x=0, y=-1, z=0}, {x=0, y=0, z=-1}, {x=0, y=0, z=1}, {x=-1, y=0, z=0}, {x=1, y=0, z=0}, {x=0, y=1, z=0}})[math.floor(facing/4)] - return vector.add(pos, downdir) +end +digtron.find_new_pos_downward = function(pos, facing) + return vector.add(pos, digtron.facedir_to_down_dir(facing)) end digtron.mark_diggable = function(pos, nodes_dug) diff --git a/util_execute_cycle.lua b/util_execute_cycle.lua index e029692..fdb74b8 100644 --- a/util_execute_cycle.lua +++ b/util_execute_cycle.lua @@ -98,7 +98,6 @@ digtron.execute_dig_cycle = function(pos, clicker) end local facing = minetest.get_node(pos).param2 - local move_dir = minetest.facedir_to_dir(facing) local controlling_coordinate = digtron.get_controlling_coordinate(pos, facing) ---------------------------------------------------------------------------------------------------------------------- @@ -121,7 +120,7 @@ digtron.execute_dig_cycle = function(pos, clicker) table.insert(items_dropped, itemname) end if digtron.particle_effects then - table.insert(particle_systems, dig_dust(vector.add(location.pos, move_dir), target.param2)) + table.insert(particle_systems, dig_dust(digtron.find_new_pos(location.pos, facing), target.param2)) end end digging_fuel_cost = digging_fuel_cost + fuel_cost @@ -236,8 +235,8 @@ digtron.execute_dig_cycle = function(pos, clicker) end --move the array - layout:move_layout_image(facing, clicker:get_player_name()) - layout:write_layout_image() + layout:move_layout_image(minetest.facedir_to_dir(facing)) + layout:write_layout_image(clicker) local oldpos = {x=pos.x, y=pos.y, z=pos.z} pos = digtron.find_new_pos(pos, facing) meta = minetest.get_meta(pos) @@ -332,10 +331,8 @@ digtron.execute_move_cycle = function(pos, clicker) local move_player = move_player_test(layout, clicker) -- test if any digtrons are obstructed by non-digtron nodes - layout:move_layout_image(facing, clicker:get_player_name()) - local can_move = layout:can_write_layout_image(clicker) - - if not can_move then + layout:move_layout_image(minetest.facedir_to_dir(facing)) + if not layout:can_write_layout_image() then -- mark this node as waiting, will clear this flag in digtron.cycle_time seconds minetest.get_meta(pos):set_string("waiting", "true") minetest.get_node_timer(pos):start(digtron.cycle_time) @@ -347,10 +344,151 @@ digtron.execute_move_cycle = function(pos, clicker) minetest.sound_play("truck", {gain=1.0, pos=pos}) --move the array - layout:write_layout_image() + layout:write_layout_image(clicker) pos = digtron.find_new_pos(pos, facing) if move_player then clicker:moveto(digtron.find_new_pos(clicker:getpos(), facing), true) end return pos, "", 0 +end + +-- Simplified version of the dig cycle that moves laterally relative to the controller's orientation ("downward") +-- Does the dig portion of the cycle, but skips the build portion. +-- 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 +-- 2 - failed due to insufficient traction +-- 3 - obstructed by undiggable node +-- 4 - insufficient fuel +digtron.execute_downward_dig_cycle = function(pos, clicker) + local meta = minetest.get_meta(pos) + local fuel_burning = meta:get_float("fuel_burning") -- get amount of burned fuel left over from last cycle + local status_text = string.format("Heat remaining in controller furnace: %d", fuel_burning) + + local layout = DigtronLayout.create(pos, clicker) + + local status_text, return_code = neighbour_test(layout, status_text) + if return_code ~= 0 then + return pos, status_text, return_code + end + + local facing = minetest.get_node(pos).param2 + local controlling_coordinate = digtron.get_controlling_coordinate(pos, facing) + + ---------------------------------------------------------------------------------------------------------------------- + + local items_dropped = {} + local digging_fuel_cost = 0 + local particle_systems = {} + + -- execute the execute_dig method on all digtron components that have one + -- This builds a set of nodes that will be dug and returns a list of products that will be generated + -- but doesn't actually dig the nodes yet. That comes later. + -- If we dug them now, sand would fall and some digtron nodes would die. + for k, location in pairs(layout.diggers) do + local target = minetest.get_node(location.pos) + local targetdef = minetest.registered_nodes[target.name] + if targetdef.execute_dig ~= nil then + local fuel_cost, dropped = targetdef.execute_dig(location.pos, layout.protected, layout.nodes_dug, controlling_coordinate, true) + if table.getn(dropped) > 0 then + for _, itemname in pairs(dropped) do + table.insert(items_dropped, itemname) + end + if digtron.particle_effects then + table.insert(particle_systems, dig_dust(digtron.find_new_pos_downward(location.pos, facing), target.param2)) + end + end + digging_fuel_cost = digging_fuel_cost + fuel_cost + else + minetest.log(string.format("%s has digger group but is missing execute_dig method! This is an error in mod programming, file a bug.", targetdef.name)) + end + end + + ---------------------------------------------------------------------------------------------------------------------- + + -- test if any digtrons are obstructed by non-digtron nodes that haven't been marked + -- as having been dug. + local can_move = true + for _, location in pairs(layout.all) do + local newpos = digtron.find_new_pos_downward(location.pos, facing) + if not digtron.can_move_to(newpos, layout.protected, layout.nodes_dug) then + can_move = false + end + 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") + minetest.get_node_timer(pos):start(digtron.cycle_time) + minetest.sound_play("squeal", {gain=1.0, pos=pos}) + minetest.sound_play("buzzer", {gain=0.5, pos=pos}) + return pos, "Digtron is obstructed.\n" .. status_text, 3 --Abort, don't dig and don't build. + end + + ---------------------------------------------------------------------------------------------------------------------- + + -- All tests passed, ready to go for real! + minetest.sound_play("construction", {gain=1.0, pos=pos}) + + -- if the player is standing within the array or next to it, move him too. + local move_player = move_player_test(layout, clicker) + + -- damage the weak flesh + if digtron.diggers_damage_creatures then + for k, location in pairs(layout.diggers) do + local target = minetest.get_node(location.pos) + local targetdef = minetest.registered_nodes[target.name] + if targetdef.damage_creatures ~= nil then + targetdef.damage_creatures(clicker, location.pos, controlling_coordinate) + end + end + end + + --move the array + layout:move_layout_image(digtron.facedir_to_down_dir(facing)) + layout:write_layout_image(clicker) + local oldpos = {x=pos.x, y=pos.y, z=pos.z} + pos = digtron.find_new_pos_downward(pos, facing) + meta = minetest.get_meta(pos) + if move_player then + clicker:moveto(digtron.find_new_pos_downward(clicker:getpos(), facing), true) + end + + -- store or drop the products of the digger heads + for _, itemname in pairs(items_dropped) do + digtron.place_in_inventory(itemname, layout.inventories, oldpos) + end + + local status_text = "" + + -- acutally burn the fuel needed + fuel_burning = fuel_burning - digging_fuel_cost + if digtron.particle_effects then + table.insert(particle_systems, burn_smoke(pos, digging_fuel_cost)) + end + if fuel_burning < 0 then + fuel_burning = fuel_burning + digtron.burn(layout.fuelstores, -fuel_burning, false) + end + meta:set_float("fuel_burning", fuel_burning) + status_text = status_text .. string.format("Heat remaining in controller furnace: %d", fuel_burning) + + -- Eyecandy + for _, particles in pairs(particle_systems) do + minetest.add_particlespawner(particles) + end + + -- finally, dig out any nodes remaining to be dug. Some of these will have had their flag revoked because + -- a builder put something there or because they're another digtron node. + local node_to_dig, whether_to_dig = layout.nodes_dug:pop() + while node_to_dig ~= nil do + if whether_to_dig == true then + minetest.log("action", string.format("%s uses Digtron to dig %s at (%d, %d, %d)", clicker:get_player_name(), minetest.get_node(node_to_dig).name, node_to_dig.x, node_to_dig.y, node_to_dig.z)) + minetest.remove_node(node_to_dig) + end + -- all of the digtron's nodes wind up in nodes_dug, so this is an ideal place to stick + -- a check to make sand fall after the digtron has passed. + --minetest.check_for_falling({x=node_to_dig.x, y=node_to_dig.y+1, z=node_to_dig.z}) + node_to_dig, whether_to_dig = layout.nodes_dug:pop() + end + return pos, status_text, 0 end \ No newline at end of file