diff --git a/entities.lua b/entities.lua index 28a830f..5b1fe03 100644 --- a/entities.lua +++ b/entities.lua @@ -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) diff --git a/functions.lua b/functions.lua index 6aeebcf..2a8bb22 100644 --- a/functions.lua +++ b/functions.lua @@ -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 diff --git a/nodes/node_builder.lua b/nodes/node_builder.lua index ef201bb..e6ba720 100644 --- a/nodes/node_builder.lua +++ b/nodes/node_builder.lua @@ -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, diff --git a/nodes/node_digger.lua b/nodes/node_digger.lua index 24bdbdc..903234d 100644 --- a/nodes/node_digger.lua +++ b/nodes/node_digger.lua @@ -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 diff --git a/nodes/node_storage.lua b/nodes/node_storage.lua index e4be73d..1bd5dae 100644 --- a/nodes/node_storage.lua +++ b/nodes/node_storage.lua @@ -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, --