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)
minetest.after(5.0,
function(self)
minetest.after(5.0,
function(self)
self.object:remove()
end,
self)
@ -101,8 +101,8 @@ minetest.register_entity("digtron:marker_crate_good", {
},
on_activate = function(self, staticdata)
minetest.after(digtron.config.marker_crate_good_duration,
function(self)
minetest.after(digtron.config.marker_crate_good_duration,
function(self)
self.object:remove()
end,
self)
@ -128,8 +128,8 @@ minetest.register_entity("digtron:marker_crate_bad", {
},
on_activate = function(self, staticdata)
minetest.after(digtron.config.marker_crate_bad_duration,
function(self)
minetest.after(digtron.config.marker_crate_bad_duration,
function(self)
self.object:remove()
end,
self)

@ -195,7 +195,7 @@ local refresh_adjacent = function(digtron_id)
local layout = retrieve_layout(digtron_id)
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_builders = {}
for hash, data in pairs(layout) do
@ -207,22 +207,30 @@ local refresh_adjacent = function(digtron_id)
end
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)]
if layout[potential_target] == nil then
local dir_hash = cardinal_dirs_hash[facedir_to_dir_index(data.node.param2)]
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
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
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
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,
offset = tonumber(fields.offset) or 0,
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,
dir_hash = dir_hash, -- Record in table form, it'll be more convenient for use later
}
end
end
@ -267,7 +275,7 @@ table.insert(dispose_callbacks, invalidate_layout_cache)
digtron.assemble = function(root_pos, player_name)
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.
if node.name ~= "digtron:controller" then
if node.name ~= "digtron:controller" then
-- Called on an incorrect node
minetest.log("error", "[Digtron] digtron.assemble called with pos " .. minetest.pos_to_string(root_pos)
.. " but the node at this location was " .. node.name)
@ -313,7 +321,6 @@ digtron.assemble = function(root_pos, player_name)
return nil
end
-- 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
for listname, items in pairs(current_meta_table.inventory) do
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})
end
-- TODO: special handling for builder node inventories
-- Ensure node metadata fields are all set, too
for field, value in pairs(data.meta.fields) do
node_meta:set_string(field, value)
@ -625,7 +630,7 @@ local predict_dig = function(digtron_id, player_name)
local cost = 0
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_name = target_node.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
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 target_node = minetest.get_node(target_pos)
local target_name = target_node.name
local targetdef = minetest.registered_nodes[target_name]
--TODO periodicity/offset test
if
ignore_hashes[target_hash] or
(targetdef ~= nil
and targetdef.buildable_to
and not minetest.is_protected(target_pos, player_name)
)
then
local item = builder_data.item
local facing = builder_data.facing
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
local absolute_hash = target_hash + root_hash
local dir_hash = builder_data.dir_hash
for i = 1, builder_data.extrusion do
local target_pos = minetest.get_position_from_hash(absolute_hash + i * dir_hash)
local target_node = minetest.get_node(target_pos)
local target_name = target_node.name
local targetdef = minetest.registered_nodes[target_name]
--TODO periodicity/offset test
if
ignore_hashes[target_hash] or
(targetdef ~= nil
and targetdef.buildable_to
and not minetest.is_protected(target_pos, player_name)
)
then
local item = builder_data.item
local facing = builder_data.facing
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
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

@ -120,7 +120,7 @@ local builder_on_rightclick = function(pos, node, clicker, itemstack, pointed_th
local digtron_id = meta:get_string("digtron_id")
if digtron_id ~= "" then
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
end
@ -149,6 +149,8 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields)
local facing = tonumber(fields.facing)
local extrusion = tonumber(fields.extrusion)
local item = meta:get_string("item")
if period and period > 0 then
meta:set_int("period", math.floor(period))
else
@ -160,7 +162,7 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields)
offset = meta:get_int("offset")
end
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 facing < 6 then
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)
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)
end)
@ -246,8 +256,8 @@ minetest.register_node("digtron:builder", {
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_int("period", 1)
meta:set_int("offset", 0)
meta:set_int("period", 1)
meta:set_int("offset", 0)
meta:set_int("facing", 0)
meta:set_int("extrusion", 1)
end,

@ -32,7 +32,7 @@ local update_infotext = function(meta)
if period < 1 then period = 1 end
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
minetest.register_node("digtron:digger", {
@ -119,6 +119,10 @@ minetest.register_node("digtron:digger_static",{
on_blast = digtron.on_blast,
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
local player_name = clicker:get_player_name()
player_interacting_with_digtron_pos[player_name] = pos

@ -70,7 +70,7 @@ minetest.register_node("digtron:inventory", {
get_inventory_formspec(pos, player_name))
else
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,
@ -175,7 +175,7 @@ minetest.register_node("digtron:fuelstore", {
get_fuelstore_formspec(pos, player_name))
else
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,
@ -302,7 +302,7 @@ minetest.register_node("digtron:combined_storage", {
get_combined_formspec(pos, player_name))
else
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,
--