mirror of
https://github.com/minetest-mods/digtron.git
synced 2024-12-22 12:22:22 +01:00
Adding fuel usage
Adding fuel usage for digging and building. Fuel storage hopper module added to hold fuel.
This commit is contained in:
parent
12748d2f89
commit
47e42801d2
16
README.txt
16
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
|
||||
-----------------
|
||||
|
||||
|
20
init.lua
20
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",
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
for k, item_return in pairs(test_items) do
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -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,
|
||||
})
|
@ -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)
|
||||
@ -79,3 +80,55 @@ minetest.register_node("digtron: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,
|
||||
})
|
@ -66,6 +66,15 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "digtron:fuelstore",
|
||||
recipe = {
|
||||
{"","default:furnace",""},
|
||||
{"","digtron:digtron_core",""},
|
||||
{"","",""}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "digtron:structure",
|
||||
recipe = {
|
||||
|
BIN
textures/digtron_fuelstore.png
Normal file
BIN
textures/digtron_fuelstore.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 760 B |
76
util.lua
76
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,9 +99,11 @@ 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)
|
||||
@ -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
|
||||
@ -310,3 +330,39 @@ digtron.get_controlling_coordinate = function(pos, facedir)
|
||||
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
|
Loading…
Reference in New Issue
Block a user