extrusion, and account for diggers/builders pointing at the same target node

This commit is contained in:
FaceDeer 2019-08-26 19:36:27 -06:00
parent 256ec951e2
commit a410187d3a
5 changed files with 79 additions and 56 deletions

@ -18,8 +18,8 @@ minetest.register_entity("digtron:marker", {
}, },
on_activate = function(self, staticdata) on_activate = function(self, staticdata)
minetest.after(5.0, minetest.after(5.0,
function(self) function(self)
self.object:remove() self.object:remove()
end, end,
self) self)
@ -101,8 +101,8 @@ minetest.register_entity("digtron:marker_crate_good", {
}, },
on_activate = function(self, staticdata) on_activate = function(self, staticdata)
minetest.after(digtron.config.marker_crate_good_duration, minetest.after(digtron.config.marker_crate_good_duration,
function(self) function(self)
self.object:remove() self.object:remove()
end, end,
self) self)
@ -128,8 +128,8 @@ minetest.register_entity("digtron:marker_crate_bad", {
}, },
on_activate = function(self, staticdata) on_activate = function(self, staticdata)
minetest.after(digtron.config.marker_crate_bad_duration, minetest.after(digtron.config.marker_crate_bad_duration,
function(self) function(self)
self.object:remove() self.object:remove()
end, end,
self) self)

@ -195,7 +195,7 @@ local refresh_adjacent = function(digtron_id)
local layout = retrieve_layout(digtron_id) local layout = retrieve_layout(digtron_id)
if layout == nil then return nil end if layout == nil then return nil end
local adjacent = {} local adjacent = {} -- all adjacent nodes. TODO: if implementing traction wheels, won't be needed
local adjacent_to_diggers = {} local adjacent_to_diggers = {}
local adjacent_to_builders = {} local adjacent_to_builders = {}
for hash, data in pairs(layout) do for hash, data in pairs(layout) do
@ -207,22 +207,30 @@ local refresh_adjacent = function(digtron_id)
end end
if minetest.get_item_group(data.node.name, "digtron") == 3 then if minetest.get_item_group(data.node.name, "digtron") == 3 then
local potential_target = hash + cardinal_dirs_hash[facedir_to_dir_index(data.node.param2)] local dir_hash = cardinal_dirs_hash[facedir_to_dir_index(data.node.param2)]
if layout[potential_target] == nil then local potential_target = hash + dir_hash -- pointed at this hash
if layout[potential_target] == nil then -- not pointed at another Digtron node
local fields = data.meta.fields local fields = data.meta.fields
adjacent_to_diggers[potential_target] = {period = fields.period, offset = fields.offset} adjacent_to_diggers[hash] = {
period = fields.period,
offset = fields.offset,
dir_hash = dir_hash,
}
end end
end end
if minetest.get_item_group(data.node.name, "digtron") == 4 then if minetest.get_item_group(data.node.name, "digtron") == 4 then
local potential_target = hash + cardinal_dirs_hash[facedir_to_dir_index(data.node.param2)] local dir_hash = cardinal_dirs_hash[facedir_to_dir_index(data.node.param2)]
local potential_target = hash + dir_hash
if layout[potential_target] == nil then if layout[potential_target] == nil then
local fields = data.meta.fields local fields = data.meta.fields
adjacent_to_builders[potential_target] = { -- TODO: trace extrusion and if it intersects Digtron layout cap it there.
adjacent_to_builders[hash] = {
period = tonumber(fields.period) or 1, period = tonumber(fields.period) or 1,
offset = tonumber(fields.offset) or 0, offset = tonumber(fields.offset) or 0,
item = fields.item, item = fields.item,
facing = tonumber(fields.facing) or 0, facing = tonumber(fields.facing) or 0, -- facing of built node
extrusion = tonumber(fields.extrusion) or 1, extrusion = tonumber(fields.extrusion) or 1,
dir_hash = dir_hash, -- Record in table form, it'll be more convenient for use later
} }
end end
end end
@ -267,7 +275,7 @@ table.insert(dispose_callbacks, invalidate_layout_cache)
digtron.assemble = function(root_pos, player_name) digtron.assemble = function(root_pos, player_name)
local node = minetest.get_node(root_pos) local node = minetest.get_node(root_pos)
-- TODO: a more generic test? Not needed with the more generic controller design, as far as I can tell. There's only going to be the one type of controller. -- TODO: a more generic test? Not needed with the more generic controller design, as far as I can tell. There's only going to be the one type of controller.
if node.name ~= "digtron:controller" then if node.name ~= "digtron:controller" then
-- Called on an incorrect node -- Called on an incorrect node
minetest.log("error", "[Digtron] digtron.assemble called with pos " .. minetest.pos_to_string(root_pos) minetest.log("error", "[Digtron] digtron.assemble called with pos " .. minetest.pos_to_string(root_pos)
.. " but the node at this location was " .. node.name) .. " but the node at this location was " .. node.name)
@ -313,7 +321,6 @@ digtron.assemble = function(root_pos, player_name)
return nil return nil
end end
-- Process inventories specially -- Process inventories specially
-- TODO Builder inventory gets turned into an itemname in a special key in the builder's meta
-- fuel and main get added to corresponding detached inventory lists -- fuel and main get added to corresponding detached inventory lists
for listname, items in pairs(current_meta_table.inventory) do for listname, items in pairs(current_meta_table.inventory) do
local count = #items local count = #items
@ -457,8 +464,6 @@ digtron.disassemble = function(digtron_id, player_name)
minetest.swap_node(node_pos, {name=node_def._digtron_disassembled_node, param2=node.param2}) minetest.swap_node(node_pos, {name=node_def._digtron_disassembled_node, param2=node.param2})
end end
-- TODO: special handling for builder node inventories
-- Ensure node metadata fields are all set, too -- Ensure node metadata fields are all set, too
for field, value in pairs(data.meta.fields) do for field, value in pairs(data.meta.fields) do
node_meta:set_string(field, value) node_meta:set_string(field, value)
@ -625,7 +630,7 @@ local predict_dig = function(digtron_id, player_name)
local cost = 0 local cost = 0
for target_hash, digger_data in pairs(retrieve_all_digger_targets(digtron_id)) do for target_hash, digger_data in pairs(retrieve_all_digger_targets(digtron_id)) do
local target_pos = minetest.get_position_from_hash(target_hash + root_hash) local target_pos = minetest.get_position_from_hash(target_hash + root_hash + digger_data.dir_hash)
local target_node = minetest.get_node(target_pos) local target_node = minetest.get_node(target_pos)
local target_name = target_node.name local target_name = target_node.name
local targetdef = minetest.registered_nodes[target_name] local targetdef = minetest.registered_nodes[target_name]
@ -753,37 +758,41 @@ local predict_build = function(digtron_id, new_pos, player_name, ignore_nodes)
local cost = 0 local cost = 0
for target_hash, builder_data in pairs(retrieve_all_builder_targets(digtron_id)) do for target_hash, builder_data in pairs(retrieve_all_builder_targets(digtron_id)) do
local target_pos = minetest.get_position_from_hash(target_hash + root_hash) local absolute_hash = target_hash + root_hash
local target_node = minetest.get_node(target_pos) local dir_hash = builder_data.dir_hash
local target_name = target_node.name for i = 1, builder_data.extrusion do
local targetdef = minetest.registered_nodes[target_name] local target_pos = minetest.get_position_from_hash(absolute_hash + i * dir_hash)
--TODO periodicity/offset test local target_node = minetest.get_node(target_pos)
if local target_name = target_node.name
ignore_hashes[target_hash] or local targetdef = minetest.registered_nodes[target_name]
(targetdef ~= nil --TODO periodicity/offset test
and targetdef.buildable_to if
and not minetest.is_protected(target_pos, player_name) ignore_hashes[target_hash] or
) (targetdef ~= nil
then and targetdef.buildable_to
local item = builder_data.item and not minetest.is_protected(target_pos, player_name)
local facing = builder_data.facing )
then
local removed_item = predictive_inv:remove_item("main", ItemStack(item)) local item = builder_data.item
if removed_item:get_count() < 1 then local facing = builder_data.facing
missing_items[item] = (missing_items[item] or 0) + 1
local removed_item = predictive_inv:remove_item("main", ItemStack(item))
if removed_item:get_count() < 1 then
missing_items[item] = (missing_items[item] or 0) + 1
end
if digtron.config.uses_resources then
cost = cost + digtron.config.build_cost
end
table.insert(built_nodes, {
pos = target_pos,
node = {name=item, param2=facing },
old_node = target_node,
})
else
break -- extrusion reached an obstacle
end end
if digtron.config.uses_resources then
cost = cost + digtron.config.build_cost
end
-- TODO handle extrusion
table.insert(built_nodes, {
pos = target_pos,
node = {name=item, param2=facing },
old_node = target_node,
})
end end
end end

@ -120,7 +120,7 @@ local builder_on_rightclick = function(pos, node, clicker, itemstack, pointed_th
local digtron_id = meta:get_string("digtron_id") local digtron_id = meta:get_string("digtron_id")
if digtron_id ~= "" then if digtron_id ~= "" then
minetest.sound_play({name = "digtron_error", gain = 0.1}, {to_player=player_name}) minetest.sound_play({name = "digtron_error", gain = 0.1}, {to_player=player_name})
minetest.chat_send_player(player_name, "This Digtron is active, interact with it via the controller node.") minetest.chat_send_player(player_name, S("This Digtron is active, interact with it via the controller node."))
return return
end end
@ -149,6 +149,8 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields)
local facing = tonumber(fields.facing) local facing = tonumber(fields.facing)
local extrusion = tonumber(fields.extrusion) local extrusion = tonumber(fields.extrusion)
local item = meta:get_string("item")
if period and period > 0 then if period and period > 0 then
meta:set_int("period", math.floor(period)) meta:set_int("period", math.floor(period))
else else
@ -160,7 +162,7 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields)
offset = meta:get_int("offset") offset = meta:get_int("offset")
end end
if facing and facing >= 0 and facing < 24 then if facing and facing >= 0 and facing < 24 then
local target_item = ItemStack(meta:get_string("item")) local target_item = ItemStack(item)
if target_item:get_definition().paramtype2 == "wallmounted" then if target_item:get_definition().paramtype2 == "wallmounted" then
if facing < 6 then if facing < 6 then
meta:set_int("facing", facing) meta:set_int("facing", facing)
@ -199,6 +201,14 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields)
minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", "digtron:builder", true) minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", "digtron:builder", true)
end end
local item_def = minetest.registered_items[item]
local item_desc = "Nothing"
if item_def then
item_desc = item_def.description
end
meta:set_string("infotext", S("Builder for @1\nperiod @2, offset @3, extrusion @4", item_desc, period, offset, extrusion))
digtron.update_builder_item(pos) digtron.update_builder_item(pos)
end) end)
@ -246,8 +256,8 @@ minetest.register_node("digtron:builder", {
on_construct = function(pos) on_construct = function(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_int("period", 1) meta:set_int("period", 1)
meta:set_int("offset", 0) meta:set_int("offset", 0)
meta:set_int("facing", 0) meta:set_int("facing", 0)
meta:set_int("extrusion", 1) meta:set_int("extrusion", 1)
end, end,

@ -32,7 +32,7 @@ local update_infotext = function(meta)
if period < 1 then period = 1 end if period < 1 then period = 1 end
local offset = meta:get_int("offset") local offset = meta:get_int("offset")
meta:set_string("infotext", S("Digger period @1 offset @2", period, offset)) meta:set_string("infotext", S("Digger\nperiod @1, offset @2", period, offset))
end end
minetest.register_node("digtron:digger", { minetest.register_node("digtron:digger", {
@ -119,6 +119,10 @@ minetest.register_node("digtron:digger_static",{
on_blast = digtron.on_blast, on_blast = digtron.on_blast,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local returnstack, success = digtron.on_rightclick(pos, node, clicker, itemstack, pointed_thing)
if returnstack then
return returnstack, success
end
if clicker == nil then return end if clicker == nil then return end
local player_name = clicker:get_player_name() local player_name = clicker:get_player_name()
player_interacting_with_digtron_pos[player_name] = pos player_interacting_with_digtron_pos[player_name] = pos

@ -70,7 +70,7 @@ minetest.register_node("digtron:inventory", {
get_inventory_formspec(pos, player_name)) get_inventory_formspec(pos, player_name))
else else
minetest.sound_play({name = "digtron_error", gain = 0.1}, {to_player=player_name}) minetest.sound_play({name = "digtron_error", gain = 0.1}, {to_player=player_name})
minetest.chat_send_player(clicker:get_player_name(), "This Digtron is active, interact with it via the controller node.") minetest.chat_send_player(clicker:get_player_name(), S("This Digtron is active, interact with it via the controller node."))
end end
end, end,
@ -175,7 +175,7 @@ minetest.register_node("digtron:fuelstore", {
get_fuelstore_formspec(pos, player_name)) get_fuelstore_formspec(pos, player_name))
else else
minetest.sound_play({name = "digtron_error", gain = 0.1}, {to_player=player_name}) minetest.sound_play({name = "digtron_error", gain = 0.1}, {to_player=player_name})
minetest.chat_send_player(clicker:get_player_name(), "This Digtron is active, interact with it via the controller node.") minetest.chat_send_player(clicker:get_player_name(), S("This Digtron is active, interact with it via the controller node."))
end end
end, end,
@ -302,7 +302,7 @@ minetest.register_node("digtron:combined_storage", {
get_combined_formspec(pos, player_name)) get_combined_formspec(pos, player_name))
else else
minetest.sound_play({name = "digtron_error", gain = 0.1}, {to_player=player_name}) minetest.sound_play({name = "digtron_error", gain = 0.1}, {to_player=player_name})
minetest.chat_send_player(clicker:get_player_name(), "This Digtron is active, interact with it via the controller node.") minetest.chat_send_player(clicker:get_player_name(), S("This Digtron is active, interact with it via the controller node."))
end end
end, end,
-- --