summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.txt16
-rw-r--r--init.lua20
-rw-r--r--node_builders.lua25
-rw-r--r--node_controllers.lua71
-rw-r--r--node_diggers.lua19
-rw-r--r--node_misc.lua63
-rw-r--r--recipes.lua9
-rw-r--r--textures/digtron_fuelstore.pngbin0 -> 760 bytes
-rw-r--r--util.lua78
9 files changed, 249 insertions, 52 deletions
diff --git a/README.txt b/README.txt
index 86775f6..2bac154 100644
--- a/README.txt
+++ b/README.txt
@@ -45,6 +45,8 @@ Pusher Module
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.
+Since movement alone does not require fuel, a pusher module has no internal furnace.
+
Digger Head
-----------
@@ -77,6 +79,20 @@ Inventory modules are not required for a digging-only machine. If there's not en
Digging machines can have multiple inventory modules added to expand their capacity.
+Fuel Hopper Module
+------------------
+
+Digtrons have an appetite. Build operations and dig operations require a certain amount of fuel, and that fuel comes from fuel hopper modules. Note that movement does not require fuel, only digging and building.
+
+When a control unit is triggered, it will tally up how much fuel is required for the next cycle and then burn items from the fuel hopper until a sufficient amount of heat has been generated to power the operation. Any leftover heat will be retained by the control unit for use in the next cycle; this is the "heat remaining in controller furnace". This means you don't have to worry too much about what kinds of fuel you put in the hopper, none will be wasted (unless you dig away a control unit with some heat remaining in it, that heat does get wasted).
+
+The fuel costs for digging and building can be configured in the init.lua file. By default using one lump of coal as fuel a digtron can:
+
+* Build 40 nodes
+* Dig 40 stone nodes
+* Dig 60 wood nodes
+* Dig 80 dirt or sand nodes
+
Structural Module
-----------------
diff --git a/init.lua b/init.lua
index f30643f..58b6a19 100644
--- a/init.lua
+++ b/init.lua
@@ -8,15 +8,31 @@ dofile( minetest.get_modpath( "digtron" ) .. "/node_controllers.lua" ) -- contro
dofile( minetest.get_modpath( "digtron" ) .."/recipes.lua" )
-digtron.refractory = 1.0 -- How long a digtron waits between cycles.
+digtron.cycle_time = 1.0 -- How long a digtron waits between cycles.
digtron.traction_factor = 3.0 -- How many digtron nodes can be moved for each adjacent solid node that the digtron has traction against
+-- fuel costs. For comparison, in the default game:
+-- one default tree block is 30 units
+-- one coal lump is 40 units
+-- one coal block is 370 units (apparently it's slightly more productive making your coal lumps into blocks before burning)
+-- one book is 3 units
+
+local dig_cost_adjustment_factor = 0.5 -- across-the-board multiplier to make overall fuel costs easier to modify
+
+digtron.dig_cost_default = 1.0 * dig_cost_adjustment_factor -- how much fuel is required to dig a node if not in one of the following groups.
+-- If a node is in more than one of the following groups, the group with the maximum cost for that node is used.
+digtron.dig_cost_cracky = 2.0 * dig_cost_adjustment_factor -- eg, stone
+digtron.dig_cost_crumbly = 1.0 * dig_cost_adjustment_factor -- eg, dirt, sand
+digtron.dig_cost_choppy = 1.5 * dig_cost_adjustment_factor -- eg, wood
+
+digtron.build_cost = 1.0 -- how much fuel is required to build a node
+
-- digtron group numbers:
-- 1 - generic digtron node, nothing special is done with these. They're just dragged along.
-- 2 - inventory-holding digtron, has a "main" inventory that the digtron can add to and take from.
-- 3 - digger head, has an "execute_dig" method in its definition
-- 4 - builder head, has a "test_build" and "execute_build" method in its definition
-
+-- 5 - fuel-holding digtron, has a "main" invetory that the control node can draw fuel items from. Separate from general inventory, nothing gets put here automatically.
minetest.register_lbm({
name = "digtron:sand_digger_upgrade",
diff --git a/node_builders.lua b/node_builders.lua
index 52fee0b..0ad2ea6 100644
--- a/node_builders.lua
+++ b/node_builders.lua
@@ -63,9 +63,9 @@ minetest.register_node("digtron:builder", {
"list[current_player;main;0,2.5;8,3;8]" ..
"listring[current_player;main]"
)
- meta:set_string("period", 1)
- meta:set_string("offset", 0)
- meta:set_string("build_facing", 0)
+ meta:set_int("period", 1)
+ meta:set_int("offset", 0)
+ meta:set_int("build_facing", 0)
local inv = meta:get_inventory()
inv:set_size("main", 1)
@@ -76,21 +76,21 @@ minetest.register_node("digtron:builder", {
local period = tonumber(fields.period)
local offset = tonumber(fields.offset)
if period and period > 0 then
- meta:set_string("period", math.floor(tonumber(fields.period)))
+ meta:set_int("period", math.floor(tonumber(fields.period)))
end
if offset then
- meta:set_string("offset", math.floor(tonumber(fields.offset)))
+ meta:set_int("offset", math.floor(tonumber(fields.offset)))
end
if fields.read then
local meta = minetest.get_meta(pos)
local facing = minetest.get_node(pos).param2
local buildpos = digtron.find_new_pos(pos, facing)
- meta:set_string("build_facing", minetest.get_node(buildpos).param2)
+ meta:set_int("build_facing", minetest.get_node(buildpos).param2)
else
local build_facing = tonumber(fields.build_facing)
if build_facing and build_facing >= 0 and build_facing < 24 then
- meta:set_string("build_facing", math.floor(build_facing))
+ meta:set_int("build_facing", math.floor(build_facing))
end
end
end,
@@ -110,7 +110,7 @@ minetest.register_node("digtron:builder", {
local facing = minetest.get_node(pos).param2
local buildpos = digtron.find_new_pos(test_pos, facing)
- if (buildpos[controlling_coordinate] + meta:get_string("offset")) % meta:get_string("period") ~= 0 then
+ if (buildpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") ~= 0 then
--It's not the builder's turn to build right now.
return 0, nil
end
@@ -152,11 +152,11 @@ minetest.register_node("digtron:builder", {
execute_build = function(pos, player, inventory_positions, protected_nodes, nodes_dug, controlling_coordinate, controller_pos)
local meta = minetest.get_meta(pos)
- local build_facing = meta:get_string("build_facing")
+ local build_facing = meta:get_int("build_facing")
local facing = minetest.get_node(pos).param2
local buildpos = digtron.find_new_pos(pos, facing)
- if (buildpos[controlling_coordinate] + meta:get_string("offset")) % meta:get_string("period") ~= 0 then
+ if (buildpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") ~= 0 then
return nil
end
@@ -174,13 +174,14 @@ minetest.register_node("digtron:builder", {
if success == true then
--flag this node as *not* to be dug.
nodes_dug:set(buildpos.x, buildpos.y, buildpos.z, false)
+ return true
else
- --failed to build for some unknown reason. Put the item back in inventory.
+ --failed to build, target node probably obstructed. Put the item back in inventory.
digtron.place_in_specific_inventory(item_stack, sourcepos, inventory_positions, controller_pos)
+ return nil
end
end
end
- return true -- no errors were encountered that we should notify the player about
end,
can_dig = function(pos,player)
diff --git a/node_controllers.lua b/node_controllers.lua
index 87e5371..9f720bb 100644
--- a/node_controllers.lua
+++ b/node_controllers.lua
@@ -34,6 +34,12 @@ minetest.register_node("digtron:controller", {
fixed = controller_nodebox,
},
+ on_construct = function(pos)
+ local meta = minetest.env:get_meta(pos)
+ meta:set_float("fuel_burning", 0.0)
+ meta:set_string("infotext", "Heat remaining in controller furnace: 0")
+ end,
+
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local meta = minetest.get_meta(pos)
if meta:get_string("waiting") == "true" then
@@ -63,6 +69,7 @@ minetest.register_node("digtron:controller", {
local nodes_dug = Pointset.create()
local items_dropped = {}
+ local digging_fuel_cost = 0
-- 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
@@ -72,12 +79,13 @@ minetest.register_node("digtron:controller", {
local target = minetest.get_node(location)
local targetdef = minetest.registered_nodes[target.name]
if targetdef.execute_dig ~= nil then
- local dropped = targetdef.execute_dig(location, layout.protected, nodes_dug, controlling_coordinate)
+ local fuel_cost, dropped = targetdef.execute_dig(location, layout.protected, nodes_dug, controlling_coordinate)
if dropped ~= nil then
for _, itemname in pairs(dropped) do
table.insert(items_dropped, itemname)
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
@@ -96,9 +104,9 @@ minetest.register_node("digtron:controller", {
end
if not can_move then
- -- mark this node as waiting, will clear this flag in digtron.refractory seconds
+ -- mark this node as waiting, will clear this flag in digtron.cycle_time seconds
minetest.get_meta(pos):set_string("waiting", "true")
- minetest.after(digtron.refractory,
+ minetest.after(digtron.cycle_time,
function (pos)
minetest.get_meta(pos):set_string("waiting", nil)
end, pos
@@ -114,10 +122,13 @@ minetest.register_node("digtron:controller", {
-- ask each builder node if it can get what it needs from inventory to build this cycle.
-- This is a complicated test because each builder needs to actually *take* the item it'll
-- need from inventory, and then we put it all back afterward.
+ -- Note that this test may overestimate the amount of work that will actually need to be done so don't treat its fuel cost as authoritative.
local can_build = true
local test_build_return_code = nil
local test_build_return_item = nil
local test_items = {}
+ local test_fuel_items = {}
+ local test_build_fuel_cost = 0
for k, location in pairs(layout.builders) do
local target = minetest.get_node(location)
local targetdef = minetest.registered_nodes[target.name]
@@ -130,19 +141,34 @@ minetest.register_node("digtron:controller", {
end
if test_build_return_code == 1 then
table.insert(test_items, test_build_return_item)
+ test_build_fuel_cost = test_build_fuel_cost + digtron.build_cost
end
else
minetest.log(string.format("%s has builder group but is missing test_build method! This is an error in mod programming, file a bug.", targetdef.name))
end
end
+
+ local fuel_burning = meta:get_float("fuel_burning") -- get amount of burned fuel left over from last cycle
+ local test_fuel_needed = test_build_fuel_cost + digging_fuel_cost - fuel_burning
+ local test_fuel_burned = 0
+ if test_fuel_needed > 0 then
+ test_fuel_burned = digtron.burn(layout.fuelstores, test_fuel_needed, true)
+ end
+
+ --Put everything back where it came from
for k, item_return in pairs(test_items) do
- --Put everything back where it came from
digtron.place_in_specific_inventory(item_return.item, item_return.location, layout.inventories, layout.controller)
end
+ if test_fuel_needed > fuel_burning + test_fuel_burned then
+ minetest.sound_play("buzzer", {gain=0.5, pos=pos})
+ meta:set_string("infotext", "Digtron needs more fuel")
+ return -- abort, don't dig and don't build.
+ end
+
if not can_build then
minetest.get_meta(pos):set_string("waiting", "true")
- minetest.after(digtron.refractory,
+ minetest.after(digtron.cycle_time,
function (pos)
minetest.get_meta(pos):set_string("waiting", nil)
end, pos
@@ -181,18 +207,20 @@ minetest.register_node("digtron:controller", {
digtron.move_digtron(facing, layout.all, layout.extents, nodes_dug)
local oldpos = {x=pos.x, y=pos.y, z=pos.z}
pos = digtron.find_new_pos(pos, facing)
+ meta = minetest.get_meta(pos)
if move_player then
clicker:moveto(digtron.find_new_pos(player_pos, facing), true)
end
-- Start the delay before digtron can run again. Do this after moving the array or pos will be wrong.
minetest.get_meta(pos):set_string("waiting", "true")
- minetest.after(digtron.refractory,
+ minetest.after(digtron.cycle_time,
function (pos)
minetest.get_meta(pos):set_string("waiting", nil)
end, pos
)
+ local building_fuel_cost = 0
local strange_failure = false
-- execute_build on all digtron components that have one
for k, location in pairs(layout.builders) do
@@ -200,19 +228,36 @@ minetest.register_node("digtron:controller", {
local targetdef = minetest.registered_nodes[target.name]
if targetdef.execute_build ~= nil then
--using the old location of the controller as fallback so that any leftovers land with the rest of the digger output. Not that there should be any.
- if targetdef.execute_build(location, clicker, layout.inventories, layout.protected, nodes_dug, controlling_coordinate, oldpos) == false then
- -- Don't interrupt the build cycle as a whole, we've already moved so might as well try to complete as much as possible.
+ local build_return = targetdef.execute_build(location, clicker, layout.inventories, layout.protected, nodes_dug, controlling_coordinate, oldpos)
+ if build_return == false then
+ -- This happens if there's insufficient inventory, but we should have confirmed there was sufficient inventory during test phase.
+ -- So this should never happen. However, "should never happens" happen sometimes. So
+ -- don't interrupt the build cycle as a whole, we've already moved so might as well try to complete as much as possible.
strange_failure = true
+ elseif build_return == true then
+ building_fuel_cost = building_fuel_cost + digtron.build_cost
end
else
minetest.log(string.format("%s has builder group but is missing execute_build method! This is an error in mod programming, file a bug.", targetdef.name))
end
end
+
+ local status_text = ""
if strange_failure then
- -- We weren't able to detect this build failure ahead of time, so make a big noise now. This is strange, shouldn't happen often.
+ -- We weren't able to detect this build failure ahead of time, so make a big noise now. This is strange, shouldn't happen.
minetest.sound_play("dingding", {gain=1.0, pos=pos})
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
- meta:set_string("infotext", "Digtron unexpectedly failed to execute a build operation.")
+ status_text = "Digtron unexpectedly failed to execute one or more build operations, likely due to an inventory error.\n"
+ end
+
+ -- acutally burn the fuel needed
+ fuel_burning = fuel_burning - (digging_fuel_cost + building_fuel_cost)
+ if fuel_burning < 0 then
+ fuel_burning = fuel_burning + digtron.burn(layout.fuelstores, -fuel_burning, false)
+ end
+ meta:set_float("fuel_burning", fuel_burning)
+ if not strange_failure then
+ meta:set_string("infotext", status_text .. string.format("Heat remaining in controller furnace: %d", fuel_burning))
end
-- finally, dig out any nodes remaining to be dug. Some of these will have had their flag revoked because
@@ -292,9 +337,9 @@ minetest.register_node("digtron:pusher", {
end
if not can_move then
- -- mark this node as waiting, will clear this flag in digtron.refractory seconds
+ -- mark this node as waiting, will clear this flag in digtron.cycle_time seconds
meta:set_string("waiting", "true")
- minetest.after(digtron.refractory,
+ minetest.after(digtron.cycle_time,
function (pos)
minetest.get_meta(pos):set_string("waiting", nil)
end, pos
@@ -326,7 +371,7 @@ minetest.register_node("digtron:pusher", {
-- Start the delay before digtron can run again. Do this after moving the array or pos will be wrong.
minetest.get_meta(pos):set_string("waiting", "true")
- minetest.after(digtron.refractory,
+ minetest.after(digtron.cycle_time,
function (pos)
minetest.get_meta(pos):set_string("waiting", nil)
end, pos
diff --git a/node_diggers.lua b/node_diggers.lua
index 936c95a..676b86e 100644
--- a/node_diggers.lua
+++ b/node_diggers.lua
@@ -55,8 +55,8 @@ minetest.register_node("digtron:digger", {
"button_exit[2.2,0.5;1,0.1;set;Save]" ..
"tooltip[set;Saves settings]"
)
- meta:set_string("period", 1)
- meta:set_string("offset", 0)
+ meta:set_int("period", 1)
+ meta:set_int("offset", 0)
local inv = meta:get_inventory()
inv:set_size("main", 1)
@@ -67,24 +67,25 @@ minetest.register_node("digtron:digger", {
local period = tonumber(fields.period)
local offset = tonumber(fields.offset)
if period and period > 0 then
- meta:set_string("period", math.floor(tonumber(fields.period)))
+ meta:set_int("period", math.floor(tonumber(fields.period)))
end
if offset then
- meta:set_string("offset", math.floor(tonumber(fields.offset)))
+ meta:set_int("offset", math.floor(tonumber(fields.offset)))
end
end,
+ -- returns fuel_cost, item_produced
execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate)
local facing = minetest.get_node(pos).param2
local digpos = digtron.find_new_pos(pos, facing)
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
- return nil
+ return 0, nil
end
local meta = minetest.get_meta(pos)
- if (digpos[controlling_coordinate] + meta:get_string("offset")) % meta:get_string("period") ~= 0 then
- return nil
+ if (digpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") ~= 0 then
+ return 0, nil
end
return digtron.mark_diggable(digpos, nodes_dug)
@@ -134,7 +135,7 @@ minetest.register_node("digtron:soft_digger", {
local digpos = digtron.find_new_pos(pos, facing)
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
- return nil
+ return 0, nil
end
local target_node = minetest.get_node(digpos)
@@ -146,6 +147,6 @@ minetest.register_node("digtron:soft_digger", {
return digtron.mark_diggable(digpos, nodes_dug)
end
- return nil
+ return 0, nil
end,
}) \ No newline at end of file
diff --git a/node_misc.lua b/node_misc.lua
index c26d6a2..262ef6e 100644
--- a/node_misc.lua
+++ b/node_misc.lua
@@ -58,16 +58,17 @@ minetest.register_node("digtron:inventory",
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec",
- "size[8,9]" ..
+ "size[8,9.3]" ..
default.gui_bg ..
default.gui_bg_img ..
default.gui_slots ..
- "list[current_name;main;0,0.3;8,4;]" ..
- "list[current_player;main;0,4.85;8,1;]" ..
- "list[current_player;main;0,6.08;8,3;8]" ..
+ "label[0,0;Inventory items]" ..
+ "list[current_name;main;0,0.6;8,4;]" ..
+ "list[current_player;main;0,5.15;8,1;]" ..
+ "list[current_player;main;0,6.38;8,3;8]" ..
"listring[current_name;main]" ..
"listring[current_player;main]" ..
- default.get_hotbar_bg(0,4.85)
+ default.get_hotbar_bg(0,5.15)
)
local inv = meta:get_inventory()
inv:set_size("main", 8*4)
@@ -78,4 +79,56 @@ minetest.register_node("digtron:inventory",
local inv = meta:get_inventory()
return inv:is_empty("main")
end,
+})
+
+-- Fuel storage. Controller node draws fuel from here.
+-- Note that fuel stores are digtron group 5.
+minetest.register_node("digtron:fuelstore",
+{
+ description = "Digtron Fuel Hopper",
+ groups = {cracky = 3, stone = 1, digtron = 5},
+ drop = 'digtron:fuelstore',
+ paramtype2= 'facedir',
+ tiles = {"digtron_fuelstore.png"},
+
+ on_construct = function(pos)
+ local meta = minetest.get_meta(pos)
+ meta:set_string("formspec",
+ "size[8,9.3]" ..
+ default.gui_bg ..
+ default.gui_bg_img ..
+ default.gui_slots ..
+ "label[0,0;Fuel items]" ..
+ "list[current_name;main;0,0.6;8,4;]" ..
+ "list[current_player;main;0,5.15;8,1;]" ..
+ "list[current_player;main;0,6.38;8,3;8]" ..
+ "listring[current_name;main]" ..
+ "listring[current_player;main]" ..
+ default.get_hotbar_bg(0,5.15)
+ )
+ local inv = meta:get_inventory()
+ inv:set_size("main", 8*4)
+ end,
+
+ -- Only allow fuel items to be placed in here
+ allow_metadata_inventory_put = function(pos, listname, index, stack, player)
+ if minetest.is_protected(pos, player:get_player_name()) then
+ return 0
+ end
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ if listname == "main" then
+ if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then
+ return stack:get_count()
+ else
+ return 0
+ end
+ end
+ end,
+
+ can_dig = function(pos,player)
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ return inv:is_empty("main")
+ end,
}) \ No newline at end of file
diff --git a/recipes.lua b/recipes.lua
index e25f065..e8e8509 100644
--- a/recipes.lua
+++ b/recipes.lua
@@ -67,6 +67,15 @@ minetest.register_craft({
})
minetest.register_craft({
+ output = "digtron:fuelstore",
+ recipe = {
+ {"","default:furnace",""},
+ {"","digtron:digtron_core",""},
+ {"","",""}
+ }
+})
+
+minetest.register_craft({
output = "digtron:structure",
recipe = {
{"default:stick","","default:stick"},
diff --git a/textures/digtron_fuelstore.png b/textures/digtron_fuelstore.png
new file mode 100644
index 0000000..c161541
--- /dev/null
+++ b/textures/digtron_fuelstore.png
Binary files differ
diff --git a/util.lua b/util.lua
index 8d5ce5f..08bdb45 100644
--- a/util.lua
+++ b/util.lua
@@ -19,23 +19,41 @@ digtron.mark_diggable = function(pos, nodes_dug)
-- Don't *actually* dig the node yet, though, because if we dig a node with sand over it the sand will start falling
-- and then destroy whatever node we place there subsequently (either by a builder head or by moving a digtron node)
-- I don't like sand. It's coarse and rough and irritating and it gets everywhere. And it necessitates complicated dig routines.
- -- returns what will be dropped by digging these nodes.
+ -- returns fuel cost and what will be dropped by digging these nodes.
local target = minetest.get_node(pos)
-- prevent digtrons from being marked for digging.
if minetest.get_item_group(target.name, "digtron") ~= 0 then
- return nil
+ return 0, nil
end
local targetdef = minetest.registered_nodes[target.name]
if targetdef.can_dig == nil or targetdef.can_dig(pos, player) then
nodes_dug:set(pos.x, pos.y, pos.z, true)
if target.name ~= "air" then
- return minetest.get_node_drops(target.name, "")
+ local in_known_group = false
+ local material_cost = 0
+ if minetest.get_item_group(target.name, "cracky") ~= 0 then
+ in_known_group = true
+ material_cost = math.max(material_cost, digtron.dig_cost_cracky)
+ end
+ if minetest.get_item_group(target.name, "crumbly") ~= 0 then
+ in_known_group = true
+ material_cost = math.max(material_cost, digtron.dig_cost_crumbly)
+ end
+ if minetest.get_item_group(target.name, "choppy") ~= 0 then
+ in_known_group = true
+ material_cost = math.max(material_cost, digtron.dig_cost_choppy)
+ end
+ if not in_known_group then
+ material_cost = digtron.dig_cost_default
+ end
+
+ return material_cost, minetest.get_node_drops(target.name, "")
end
end
- return nil
+ return 0, nil
end
digtron.can_build_to = function(pos, protected_nodes, dug_nodes)
@@ -81,10 +99,12 @@ digtron.move_node = function(pos, newpos)
newinv:set_list("main", list)
newmeta:set_string("formspec", oldformspec)
- newmeta:set_string("offset", oldmeta:get_string("offset"))
- newmeta:set_string("period", oldmeta:get_string("period"))
- newmeta:set_string("build_facing", oldmeta:get_string("build_facing"))
-
+ newmeta:set_int("offset", oldmeta:get_int("offset"))
+ newmeta:set_int("period", oldmeta:get_int("period"))
+ newmeta:set_int("build_facing", oldmeta:get_int("build_facing"))
+ newmeta:set_float("fuel_burning", oldmeta:get_float("fuel_burning"))
+ newmeta:set_string("infotext", oldmeta:get_string("infotext"))
+
-- remove node from old position
minetest.remove_node(pos)
end
@@ -92,13 +112,12 @@ end
digtron.get_all_digtron_neighbours = function(pos, player)
-- returns table containing a list of all digtron node locations, lists of special digtron node types, a table of the coordinate extents of the digtron array, a Pointset of protected nodes, and a number to determine how many adjacent solid non-digtron nodes there are (for traction)
- --minetest.debug(string.format("digtron search started at component %d %d %d", pos.x, pos.y, pos.z))
-
local layout = {}
--initialize. We're assuming that the start position is a controller digtron, should be a safe assumption since only the controller node should call this
layout.traction = 0
layout.all = {}
layout.inventories = {}
+ layout.fuelstores = {}
layout.diggers = {}
layout.builders = {}
layout.extents = {}
@@ -148,7 +167,6 @@ digtron.get_all_digtron_neighbours = function(pos, player)
local group_number = minetest.get_item_group(node.name, "digtron")
if group_number > 0 then
- --minetest.debug(string.format("found digtron component at %d %d %d", testpos.x, testpos.y, testpos.z))
--found one. Add it to the digtrons output
table.insert(layout.all, testpos)
@@ -167,6 +185,8 @@ digtron.get_all_digtron_neighbours = function(pos, player)
table.insert(layout.diggers, testpos)
elseif group_number == 4 then
table.insert(layout.builders, testpos)
+ elseif group_number == 5 then
+ table.insert(layout.fuelstores, testpos)
end
--queue up potential new test points adjacent to this digtron node
@@ -309,4 +329,40 @@ digtron.get_controlling_coordinate = function(pos, facedir)
else
return "y"
end
+end
+
+-- Searches fuel store inventories for burnable items and burns them until target is reached or surpassed (or there's nothing left to burn). Returns the total fuel value burned
+-- if the "test" parameter is set to true, doesn't actually take anything out of inventories. We can get away with this sort of thing for fuel but not for builder inventory because there's just one
+-- controller node burning stuff, not multiple build heads drawing from inventories in turn. Much simpler.
+digtron.burn = function(fuelstore_positions, target, test)
+ local current_burned = 0
+ for k, location in pairs(fuelstore_positions) do
+ if current_burned > target then
+ break
+ end
+ local inv = minetest.get_inventory({type="node", pos=location})
+ local invlist = inv:get_list("main")
+ for i, itemstack in pairs(invlist) do
+ local fuel_per_item = minetest.get_craft_result({method="fuel", width=1, items={itemstack:peek_item(1)}}).time
+ if fuel_per_item ~= 0 then
+ local actual_burned = math.min(
+ math.ceil((target - current_burned)/fuel_per_item ), -- burn this many, if we can.
+ itemstack:get_count() -- how many we have at most.
+ )
+ if test ~= true then
+ -- don't bother recording the items if we're just testing, nothing is actually being removed.
+ itemstack:set_count(itemstack:get_count() - actual_burned)
+ end
+ current_burned = current_burned + actual_burned * fuel_per_item
+ end
+ if current_burned > target then
+ break
+ end
+ end
+ if test ~= true then
+ -- only update the list if we're doing this for real.
+ inv:set_list("main", invlist)
+ end
+ end
+ return current_burned
end \ No newline at end of file