Builders no longer keep a real copy of the object they're "programmed" with. Also, add a "creative mode" configuration flag

This commit is contained in:
FaceDeer 2017-01-04 19:23:21 -07:00
parent d545593f27
commit 1ecb6964d9
5 changed files with 42 additions and 36 deletions

@ -24,8 +24,6 @@ Several general concepts are important when building more sophisticated diggers.
* Offset - The location at which a periodic module triggers is globally uniform. This is handy if you want to line up the nodes you're building (for example, placing pillars and a crosspiece every 4 nodes in a tunnel, or punching alcoves in a wall to place glass windows). If you wish to change how the pattern lines up, modify the "offset" setting. * Offset - The location at which a periodic module triggers is globally uniform. This is handy if you want to line up the nodes you're building (for example, placing pillars and a crosspiece every 4 nodes in a tunnel, or punching alcoves in a wall to place glass windows). If you wish to change how the pattern lines up, modify the "offset" setting.
Note that offset and period are calculated from the location of the *controller* node, which is shared across the whole array of modules, so it's not necessary to line up all of your builder heads in the same row or column.
* Shift-right-clicking - since most of the nodes of the digging machine have control screens associated with right-clicking, building additional nodes on top of them or rotating them with the screwdriver requires the shift key to be held down when right-clicking on them. * Shift-right-clicking - since most of the nodes of the digging machine have control screens associated with right-clicking, building additional nodes on top of them or rotating them with the screwdriver requires the shift key to be held down when right-clicking on them.
Detailed module guide Detailed module guide
@ -73,7 +71,7 @@ It can also serve as part of a lawnmower or tree-harvester.
Builder Head Builder Head
------------ ------------
A builder head is the most complex component of this system. It has period and offset properties, and also an inventory slot where you "program" it by placing an example of the node type that you want it to build. Only a single item is needed here, any additional items in this inventory stack will be shunted into the digger's general inventory (or ejected from the control node if there's no space for it). A builder head is the most complex component of this system. It has period and offset properties, and also an inventory slot where you "program" it by placing an example of the node type that you want it to build. The builder doesn't keep a real copy of the item, it just reads what you drop in here.
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. 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.

@ -1,14 +1,14 @@
dofile( minetest.get_modpath( "digtron" ) .. "/util.lua" ) dofile( minetest.get_modpath( "digtron" ) .. "/util.lua" )
dofile( minetest.get_modpath( "digtron" ) .. "/pointset.lua" ) dofile( minetest.get_modpath( "digtron" ) .. "/pointset.lua" )
dofile( minetest.get_modpath( "digtron" ) .. "/entities.lua" ) dofile( minetest.get_modpath( "digtron" ) .. "/entities.lua" )
dofile( minetest.get_modpath( "digtron" ) .. "/node_misc.lua" ) -- contains inventory and structure nodes dofile( minetest.get_modpath( "digtron" ) .. "/node_misc.lua" ) -- contains inventory and structure nodes
dofile( minetest.get_modpath( "digtron" ) .. "/node_diggers.lua" ) -- contains all diggers dofile( minetest.get_modpath( "digtron" ) .. "/node_diggers.lua" ) -- contains all diggers
dofile( minetest.get_modpath( "digtron" ) .. "/node_builders.lua" ) -- contains all builders (there's just one currently) dofile( minetest.get_modpath( "digtron" ) .. "/node_builders.lua" ) -- contains all builders (there's just one currently)
dofile( minetest.get_modpath( "digtron" ) .. "/node_controllers.lua" ) -- controllers dofile( minetest.get_modpath( "digtron" ) .. "/node_controllers.lua" ) -- controllers
dofile( minetest.get_modpath( "digtron" ) .."/recipes.lua" ) dofile( minetest.get_modpath( "digtron" ) .."/recipes.lua" )
digtron.creative_mode = false
digtron.cycle_time = 1 -- How many seconds a digtron waits between cycles. Auto-controllers can make this wait longer, but cannot make it shorter. digtron.cycle_time = 1 -- How many seconds a digtron waits between cycles. Auto-controllers can make this wait longer, but cannot make it shorter.
digtron.traction_factor = 3.0 -- How many digtron nodes can be moved for each adjacent solid node that the digtron has traction against digtron.traction_factor = 3.0 -- How many digtron nodes can be moved for each adjacent solid node that the digtron has traction against

@ -132,6 +132,16 @@ minetest.register_node("digtron:builder", {
digtron.remove_builder_item(pos) digtron.remove_builder_item(pos)
end, end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
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)
return 0
end,
-- "builder at pos, imagine that you're in test_pos. If you're willing and able to build from there, take the item you need from inventory. -- "builder at pos, imagine that you're in test_pos. If you're willing and able to build from there, take the item you need from inventory.
-- return the item you took and the inventory location you took it from so it can be put back after all the other builders have been tested. -- return the item you took and the inventory location you took it from so it can be put back after all the other builders have been tested.
-- If you couldn't get the item from inventory, return an error code so we can abort the cycle. -- If you couldn't get the item from inventory, return an error code so we can abort the cycle.
@ -168,15 +178,7 @@ minetest.register_node("digtron:builder", {
local inv = minetest.get_inventory({type="node", pos=pos}) local inv = minetest.get_inventory({type="node", pos=pos})
local item_stack = inv:get_stack("main", 1) local item_stack = inv:get_stack("main", 1)
local count = item_stack:get_count() if not item_stack:is_empty() then
if count ~= 0 then
if count > 1 then
-- player has put more than one item in the "program" slot. Wasteful. Move all the rest to the main inventory so it can be used.
item_stack:set_count(count - 1)
digtron.place_in_inventory(item_stack, inventory_positions, controller_pos)
item_stack:set_count(1)
inv:set_stack("main", 1, item_stack)
end
local source_location = digtron.take_from_inventory(item_stack:get_name(), inventory_positions) local source_location = digtron.take_from_inventory(item_stack:get_name(), inventory_positions)
if source_location ~= nil then if source_location ~= nil then
return 1, {item=item_stack, location=source_location} return 1, {item=item_stack, location=source_location}
@ -200,8 +202,17 @@ minetest.register_node("digtron:builder", {
if digtron.can_build_to(buildpos, protected_nodes, nodes_dug) then if digtron.can_build_to(buildpos, protected_nodes, nodes_dug) then
local inv = minetest.get_inventory({type="node", pos=pos}) local inv = minetest.get_inventory({type="node", pos=pos})
local item_stack = inv:get_stack("main", 1) local item_stack = inv:get_stack("main", 1)
local count = item_stack:get_count()
if not item_stack:is_empty() then if not item_stack:is_empty() then
if digtron.creative_mode then
local returned_stack, success = digtron.item_place_node(item_stack, player, buildpos, tonumber(build_facing))
if success == true then
nodes_dug:set(buildpos.x, buildpos.y, buildpos.z, false)
return true
end
return nil
end
local sourcepos = digtron.take_from_inventory(item_stack:get_name(), inventory_positions) local sourcepos = digtron.take_from_inventory(item_stack:get_name(), inventory_positions)
if sourcepos == nil then if sourcepos == nil then
-- item not in inventory! Need to sound the angry buzzer to let the player know, so return false. -- item not in inventory! Need to sound the angry buzzer to let the player know, so return false.
@ -220,10 +231,4 @@ minetest.register_node("digtron:builder", {
end end
end 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,
}) })

@ -180,7 +180,7 @@ local execute_cycle = function(pos, clicker)
-- So this should never happen. However, "should never happens" happen sometimes. So -- 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. -- 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 strange_failure = true
elseif build_return == true then elseif build_return == true and not digtron.creative_mode == true then
building_fuel_cost = building_fuel_cost + digtron.build_cost building_fuel_cost = building_fuel_cost + digtron.build_cost
end end
else else

@ -42,6 +42,8 @@ digtron.mark_diggable = function(pos, nodes_dug)
if target.name ~= "air" then if target.name ~= "air" then
local in_known_group = false local in_known_group = false
local material_cost = 0 local material_cost = 0
if digtron.creative_mode ~= true then
if minetest.get_item_group(target.name, "cracky") ~= 0 then if minetest.get_item_group(target.name, "cracky") ~= 0 then
in_known_group = true in_known_group = true
material_cost = math.max(material_cost, digtron.dig_cost_cracky) material_cost = math.max(material_cost, digtron.dig_cost_cracky)
@ -57,6 +59,7 @@ digtron.mark_diggable = function(pos, nodes_dug)
if not in_known_group then if not in_known_group then
material_cost = digtron.dig_cost_default material_cost = digtron.dig_cost_default
end end
end
return material_cost, minetest.get_node_drops(target.name, "") return material_cost, minetest.get_node_drops(target.name, "")
end end