diff options
author | FaceDeer <FaceDeer@users.noreply.github.com> | 2017-09-30 10:56:15 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-30 10:56:15 -0600 |
commit | 444411936cc85ba0ef9bfaad11f74544c24cb0b6 (patch) | |
tree | a58d3e8667a8e97e91c2b35e550d58fe3c211611 /nodes | |
parent | 3441a0d1da37087287fdaade7c8930480abe65e9 (diff) | |
parent | 860890b10061d76c5ea011fe0befca435be5f243 (diff) |
Merge pull request #8 from minetest-mods/cleanup
Cleanup
Diffstat (limited to 'nodes')
-rw-r--r-- | nodes/node_axle.lua | 64 | ||||
-rw-r--r-- | nodes/node_builders.lua | 297 | ||||
-rw-r--r-- | nodes/node_controllers.lua | 345 | ||||
-rw-r--r-- | nodes/node_crate.lua | 194 | ||||
-rw-r--r-- | nodes/node_diggers.lua | 479 | ||||
-rw-r--r-- | nodes/node_misc.lua | 141 | ||||
-rw-r--r-- | nodes/node_storage.lua | 284 | ||||
-rw-r--r-- | nodes/recipes.lua | 283 |
8 files changed, 2087 insertions, 0 deletions
diff --git a/nodes/node_axle.lua b/nodes/node_axle.lua new file mode 100644 index 0000000..99dda4b --- /dev/null +++ b/nodes/node_axle.lua @@ -0,0 +1,64 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +minetest.register_node("digtron:axle", { + description = S("Digtron Rotation Axle"), + _doc_items_longdesc = digtron.doc.axle_longdesc, + _doc_items_usagehelp = digtron.doc.axle_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1}, + drop = "digtron:axle", + sounds = digtron.metal_sounds, + paramtype = "light", + paramtype2= "facedir", + is_ground_content = false, + -- Aims in the +Z direction by default + tiles = { + "digtron_plate.png^digtron_axel_top.png", + "digtron_plate.png^digtron_axel_top.png", + "digtron_plate.png^digtron_axel_side.png", + "digtron_plate.png^digtron_axel_side.png", + "digtron_plate.png^digtron_axel_side.png", + "digtron_plate.png^digtron_axel_side.png", + }, + + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5, 0.3125, -0.3125, 0.5, 0.5, 0.3125}, -- Uppercap + {-0.5, -0.5, -0.3125, 0.5, -0.3125, 0.3125}, -- Lowercap + {-0.3125, 0.3125, -0.5, 0.3125, 0.5, -0.3125}, -- Uppercap_edge2 + {-0.3125, 0.3125, 0.3125, 0.3125, 0.5, 0.5}, -- Uppercap_edge1 + {-0.3125, -0.5, -0.5, 0.3125, -0.3125, -0.3125}, -- Lowercap_edge1 + {-0.3125, -0.5, 0.3125, 0.3125, -0.3125, 0.5}, -- Lowercap_edge2 + {-0.25, -0.3125, -0.25, 0.25, 0.3125, 0.25}, -- Axle + } + }, + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + if meta:get_string("waiting") == "true" then + -- Been too soon since last time the digtron rotated. + return + end + local image = DigtronLayout.create(pos, clicker) + image:rotate_layout_image(node.param2) + if image:can_write_layout_image() then + image:write_layout_image(clicker) + + minetest.sound_play("whirr", {gain=1.0, pos=pos}) + meta = minetest.get_meta(pos) + meta:set_string("waiting", "true") + meta:set_string("infotext", nil) + minetest.get_node_timer(pos):start(digtron.config.cycle_time*2) + else + minetest.sound_play("buzzer", {gain=1.0, pos=pos}) + meta:set_string("infotext", S("Digtron is obstructed.")) + end + end, + + on_timer = function(pos, elapsed) + minetest.get_meta(pos):set_string("waiting", nil) + end, +})
\ No newline at end of file diff --git a/nodes/node_builders.lua b/nodes/node_builders.lua new file mode 100644 index 0000000..ecb76cd --- /dev/null +++ b/nodes/node_builders.lua @@ -0,0 +1,297 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +-- Note: builders go in group 4 and have both test_build and execute_build methods. + +local displace_due_to_help_button = 1.0 +if minetest.get_modpath("doc") then + displace_due_to_help_button = 0.0 +end + +local builder_formspec = + "size[8,5.2]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;main;".. tostring(displace_due_to_help_button/2) ..",0;1,1;]" .. + "label[" .. tostring(displace_due_to_help_button/2).. ",0.8;" .. S("Block to build") .. "]" .. + "field[" .. tostring(displace_due_to_help_button + 1.3) ..",0.8;1,0.1;extrusion;" .. S("Extrusion") .. ";${extrusion}]" .. + "tooltip[extrusion;" .. S("Builder will extrude this many blocks in the direction it is facing.\nCan be set from 1 to @1.\nNote that Digtron won't build into unloaded map regions.", digtron.config.maximum_extrusion) .. "]" .. + "field[" .. tostring(displace_due_to_help_button + 2.3) ..",0.8;1,0.1;period;" .. S("Periodicity") .. ";${period}]" .. + "tooltip[period;" .. S("Builder will build once every n steps.\nThese steps are globally aligned, so all builders with the\nsame period and offset will build on the same location.") .. "]" .. + "field[" .. tostring(displace_due_to_help_button + 3.3) ..",0.8;1,0.1;offset;" .. S("Offset") .. ";${offset}]" .. + "tooltip[offset;" .. S("Offsets the start of periodicity counting by this amount.\nFor example, a builder with period 2 and offset 0 builds\nevery even-numbered block and one with period 2 and\noffset 1 builds every odd-numbered block.") .. "]" .. + "button_exit[" .. tostring(displace_due_to_help_button + 4.0) ..",0.5;1,0.1;set;" .. S("Save &\nShow") .. "]" .. + "tooltip[set;" .. S("Saves settings") .. "]" .. + "field[" .. tostring(displace_due_to_help_button + 5.3) .. ",0.8;1,0.1;build_facing;" .. S("Facing") .. ";${build_facing}]" .. + "tooltip[build_facing;" .. S("Value from 0-23. Not all block types make use of this.\nUse the 'Read & Save' button to copy the facing of the block\ncurrently in the builder output location.") .. "]" .. + "button_exit[" .. tostring(displace_due_to_help_button + 6.0) ..",0.5;1,0.1;read;" .. S("Read &\nSave") .. "]" .. + "tooltip[read;" .. S("Reads the facing of the block currently in the build location,\nthen saves all settings.") .. "]" .. + "list[current_player;main;0,1.3;8,1;]" .. + default.get_hotbar_bg(0,1.3) .. + "list[current_player;main;0,2.5;8,3;8]" .. + "listring[current_player;main]" .. + "listring[current_name;main]" + +if minetest.get_modpath("doc") then + builder_formspec = builder_formspec .. + "button_exit[7.0,0.5;1,0.1;help;" .. S("Help") .. "]" .. + "tooltip[help;" .. S("Show documentation about this block") .. "]" +end + +-- Builds objects in the targeted node. This is a complicated beastie. +minetest.register_node("digtron:builder", { + description = S("Digtron Builder Module"), + _doc_items_longdesc = digtron.doc.builder_longdesc, + _doc_items_usagehelp = digtron.doc.builder_usagehelp, + _digtron_formspec = builder_formspec, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 4}, + drop = "digtron:builder", + sounds = digtron.metal_sounds, + paramtype = "light", + paramtype2= "facedir", + is_ground_content = false, + tiles = { + "digtron_plate.png^[transformR90", + "digtron_plate.png^[transformR270", + "digtron_plate.png", + "digtron_plate.png^[transformR180", + "digtron_plate.png^digtron_builder.png", + "digtron_plate.png", + }, + + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.25, 0.3125, 0.3125, 0.25, 0.5, 0.5}, -- FrontFrame_top + {-0.25, -0.5, 0.3125, 0.25, -0.3125, 0.5}, -- FrontFrame_bottom + {0.3125, -0.25, 0.3125, 0.5, 0.25, 0.5}, -- FrontFrame_right + {-0.5, -0.25, 0.3125, -0.3125, 0.25, 0.5}, -- FrontFrame_left + {-0.5, 0.25, -0.5, -0.25, 0.5, 0.5}, -- edge_topright + {-0.5, -0.5, -0.5, -0.25, -0.25, 0.5}, -- edge_bottomright + {0.25, 0.25, -0.5, 0.5, 0.5, 0.5}, -- edge_topleft + {0.25, -0.5, -0.5, 0.5, -0.25, 0.5}, -- edge_bottomleft + {-0.25, 0.4375, -0.5, 0.25, 0.5, -0.4375}, -- backframe_top + {-0.25, -0.5, -0.5, 0.25, -0.4375, -0.4375}, -- backframe_bottom + {-0.5, -0.25, -0.5, -0.4375, 0.25, -0.4375}, -- backframe_left + {0.4375, -0.25, -0.5, 0.5, 0.25, -0.4375}, -- Backframe_right + {-0.0625, -0.3125, 0.3125, 0.0625, 0.3125, 0.375}, -- frontcross_vertical + {-0.3125, -0.0625, 0.3125, 0.3125, 0.0625, 0.375}, -- frontcross_horizontal + } + }, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", builder_formspec) + meta:set_int("period", 1) + meta:set_int("offset", 0) + meta:set_int("build_facing", 0) + meta:set_int("extrusion", 1) + + local inv = meta:get_inventory() + inv:set_size("main", 1) + end, + + on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + local period = tonumber(fields.period) + local offset = tonumber(fields.offset) + local build_facing = tonumber(fields.build_facing) + local extrusion = tonumber(fields.extrusion) + + if period and period > 0 then + meta:set_int("period", math.floor(tonumber(fields.period))) + else + period = meta:get_int("period") + end + if offset then + meta:set_int("offset", math.floor(tonumber(fields.offset))) + else + offset = meta:get_int("offset") + end + if build_facing and build_facing >= 0 and build_facing < 24 then + -- TODO: wallmounted facings only run from 0-5, a player could theoretically put a wallmounted item into the builder and then manually set the build facing to an invalid number + -- Should prevent that somehow. But not tonight. + meta:set_int("build_facing", math.floor(build_facing)) + end + if extrusion and extrusion > 0 and extrusion <= digtron.config.maximum_extrusion then + meta:set_int("extrusion", math.floor(tonumber(fields.extrusion))) + else + extrusion = meta:get_int("extrusion") + end + + if fields.set then + digtron.show_offset_markers(pos, offset, period) + + elseif fields.read then + local facing = minetest.get_node(pos).param2 + local buildpos = digtron.find_new_pos(pos, facing) + local target_node = minetest.get_node(buildpos) + if target_node.name ~= "air" and minetest.get_item_group(target_node.name, "digtron") == 0 then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local target_name = digtron.builder_read_item_substitutions[target_node.name] or target_node.name + inv:set_stack("main", 1, target_name) + meta:set_int("build_facing", target_node.param2) + end + end + + if fields.help and minetest.get_modpath("doc") then --check for mod in case someone disabled it after this digger was built + minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", "digtron:builder", true) + end + + digtron.update_builder_item(pos) + end, + + on_destruct = function(pos) + digtron.remove_builder_item(pos) + end, + + after_place_node = function(pos) + digtron.update_builder_item(pos) + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if minetest.get_item_group(stack:get_name(), "digtron") ~= 0 then + return 0 -- don't allow builders to be set to build Digtron nodes, they'll just clog the output. + end + 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) + local inv = minetest.get_inventory({type="node", pos=pos}) + inv:set_stack(listname, index, ItemStack("")) + 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. + -- 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're not supposed to build at all, or the location is obstructed, return 0 to let us know you're okay and we shouldn't abort." + + --return code and accompanying value: + -- 0, {} -- not supposed to build, no error + -- 1, {{itemstack, source inventory pos}, ...} -- can build, took items from inventory + -- 2, {{itemstack, source inventory pos}, ...}, itemstack -- was supposed to build, but couldn't get the item from inventory + -- 3, {} -- builder configuration error + test_build = function(pos, test_pos, inventory_positions, protected_nodes, nodes_dug, controlling_coordinate, controller_pos) + local meta = minetest.get_meta(pos) + local facing = minetest.get_node(pos).param2 + local buildpos = digtron.find_new_pos(test_pos, facing) + + 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, {} + end + + local extrusion_count = 0 + local extrusion_target = meta:get_int("extrusion") + if extrusion_target == nil or extrusion_target < 1 or extrusion_target > 100 then + extrusion_target = 1 -- failsafe + end + + local return_items = {} + + local inv = minetest.get_inventory({type="node", pos=pos}) + local item_stack = inv:get_stack("main", 1) + + if item_stack:is_empty() then + return 3, {} -- error code for "this builder's item slot is unset" + end + + while extrusion_count < extrusion_target do + if not digtron.can_move_to(buildpos, protected_nodes, nodes_dug) then + --using "can_move_to" instead of "can_build_to" test case in case the builder is pointed "backward", and will thus + --be building into the space that it's currently in and will be vacating after moving, or in case the builder is aimed + --sideways and a fellow digtron node was ahead of it (will also be moving out of the way). + + --If the player has built his digtron stupid (eg has another digtron node in the place the builder wants to build) this + --assumption is wrong, but I can't hold the player's hand through *every* possible bad design decision. Worst case, + --the digtron will think its inventory can't handle the next build step and abort the build when it actually could have + --managed one more cycle. That's not a bad outcome for a digtron array that was built stupidly to begin with. + return 1, return_items + end + + local source_location = digtron.take_from_inventory(item_stack:get_name(), inventory_positions) + if source_location ~= nil then + table.insert(return_items, {item=item_stack, location=source_location}) + else + return 2, return_items, item_stack -- error code for "needed an item but couldn't get it from inventory" + end + extrusion_count = extrusion_count + 1 + buildpos = digtron.find_new_pos(buildpos, facing) + end + + return 1, return_items + end, + + execute_build = function(pos, player, inventory_positions, protected_nodes, nodes_dug, controlling_coordinate, controller_pos) + local meta = minetest.get_meta(pos) + local build_facing = tonumber(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_int("offset")) % meta:get_int("period") ~= 0 then + return 0 + end + + local extrusion_count = 0 + local extrusion_target = meta:get_int("extrusion") + if extrusion_target == nil or extrusion_target < 1 or extrusion_target > 100 then + extrusion_target = 1 -- failsafe + end + local built_count = 0 + + local inv = minetest.get_inventory({type="node", pos=pos}) + local item_stack = inv:get_stack("main", 1) + if item_stack:is_empty() then + return built_count + end + + while extrusion_count < extrusion_target do + if not digtron.can_build_to(buildpos, protected_nodes, nodes_dug) then + return built_count + end + + local oldnode = minetest.get_node(buildpos) + + if not digtron.config.uses_resources then + local returned_stack, success = digtron.item_place_node(item_stack, player, buildpos, build_facing) + if success == true then + minetest.log("action", string.format("%s uses Digtron to build %s at (%d, %d, %d), displacing %s", player:get_player_name(), item_stack:get_name(), buildpos.x, buildpos.y, buildpos.z, oldnode.name)) + nodes_dug:set(buildpos.x, buildpos.y, buildpos.z, false) + built_count = built_count + 1 + else + return built_count + end + end + + local sourcepos = digtron.take_from_inventory(item_stack:get_name(), inventory_positions) + if sourcepos == nil then + -- item not in inventory! Need to sound the angry buzzer to let the player know, so return a negative number. + return (built_count + 1) * -1 + end + local returned_stack, success = digtron.item_place_node(item_stack, player, buildpos, build_facing) + if success == true then + minetest.log("action", string.format("%s uses Digtron to build %s at (%d, %d, %d), displacing %s", player:get_player_name(), item_stack:get_name(), buildpos.x, buildpos.y, buildpos.z, oldnode.name)) + --flag this node as *not* to be dug. + nodes_dug:set(buildpos.x, buildpos.y, buildpos.z, false) + digtron.award_item_built(item_stack:get_name(), player:get_player_name()) + built_count = built_count + 1 + else + --failed to build, target node probably obstructed. Put the item back in inventory. + --Should probably never reach this since we're guarding against can_build_to, above, but this makes things safe if we somehow do. + digtron.place_in_specific_inventory(item_stack, sourcepos, inventory_positions, controller_pos) + return built_count + end + + extrusion_count = extrusion_count + 1 + buildpos = digtron.find_new_pos(buildpos, facing) + end + return built_count + end, +})
\ No newline at end of file diff --git a/nodes/node_controllers.lua b/nodes/node_controllers.lua new file mode 100644 index 0000000..4382734 --- /dev/null +++ b/nodes/node_controllers.lua @@ -0,0 +1,345 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +local controller_nodebox ={ + {-0.3125, -0.3125, -0.3125, 0.3125, 0.3125, 0.3125}, -- Core + {-0.1875, 0.3125, -0.1875, 0.1875, 0.5, 0.1875}, -- +y_connector + {-0.1875, -0.5, -0.1875, 0.1875, -0.3125, 0.1875}, -- -y_Connector + {0.3125, -0.1875, -0.1875, 0.5, 0.1875, 0.1875}, -- +x_connector + {-0.5, -0.1875, -0.1875, -0.3125, 0.1875, 0.1875}, -- -x_connector + {-0.1875, -0.1875, 0.3125, 0.1875, 0.1875, 0.5}, -- +z_connector + {-0.5, 0.125, -0.5, -0.125, 0.5, -0.3125}, -- back_connector_3 + {0.125, 0.125, -0.5, 0.5, 0.5, -0.3125}, -- back_connector_1 + {0.125, -0.5, -0.5, 0.5, -0.125, -0.3125}, -- back_connector_2 + {-0.5, -0.5, -0.5, -0.125, -0.125, -0.3125}, -- back_connector_4 +} + +-- Master controller. Most complicated part of the whole system. Determines which direction a digtron moves and triggers all of its component parts. +minetest.register_node("digtron:controller", { + description = S("Digtron Control Module"), + _doc_items_longdesc = digtron.doc.controller_longdesc, + _doc_items_usagehelp = digtron.doc.controller_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand = 3, digtron = 1}, + drop = "digtron:controller", + sounds = digtron.metal_sounds, + paramtype = "light", + paramtype2= "facedir", + is_ground_content = false, + -- Aims in the +Z direction by default + tiles = { + "digtron_plate.png^[transformR90", + "digtron_plate.png^[transformR270", + "digtron_plate.png", + "digtron_plate.png^[transformR180", + "digtron_plate.png", + "digtron_plate.png^digtron_control.png", + }, + + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = controller_nodebox, + }, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_float("fuel_burning", 0.0) + meta:set_string("infotext", S("Heat remaining in controller furnace: @1", 0)) + end, + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + if meta:get_string("waiting") == "true" then + -- Been too soon since last time the digtron did a cycle. + return + end + + local newpos, status, return_code = digtron.execute_dig_cycle(pos, clicker) + + meta = minetest.get_meta(newpos) + if status ~= nil then + meta:set_string("infotext", status) + end + + -- Start the delay before digtron can run again. + minetest.get_meta(newpos):set_string("waiting", "true") + minetest.get_node_timer(newpos):start(digtron.config.cycle_time) + end, + + on_timer = function(pos, elapsed) + minetest.get_meta(pos):set_string("waiting", nil) + end, +}) + +-- Auto-controller +--------------------------------------------------------------------------------------------------------------- + +local auto_formspec = "size[8,6.2]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "container[2.0,0]" .. + "field[0.0,0.8;1,0.1;cycles;" .. S("Cycles").. ";${cycles}]" .. + "tooltip[cycles;" .. S("When triggered, this controller will try to run for the given number of cycles.\nThe cycle count will decrement as it runs, so if it gets halted by a problem\nyou can fix the problem and restart.").. "]" .. + "button_exit[0.7,0.5;1,0.1;set;" .. S("Set").. "]" .. + "tooltip[set;" .. S("Saves the cycle setting without starting the controller running").. "]" .. + "button_exit[1.7,0.5;1,0.1;execute;" .. S("Set &\nExecute").. "]" .. + "tooltip[execute;" .. S("Begins executing the given number of cycles").. "]" .. + "field[0.0,2.0;1,0.1;slope;" .. S("Slope").. ";${slope}]" .. + "tooltip[slope;" .. S("For diagonal digging. After moving forward this number of nodes the auto controller\nwill add an additional cycle moving the digtron laterally in the\ndirection of the arrows on the side of this controller.\nSet to 0 for no lateral digging.").. "]" .. + "field[1.0,2.0;1,0.1;offset;" .. S("Offset").. ";${offset}]" .. + "tooltip[offset;" .. S("Sets the offset of the lateral motion defined in the Slope field.\nNote: this offset is relative to the controller's location.\nThe controller will move laterally when it reaches the indicated point.").. "]" .. + "field[2.0,2.0;1,0.1;period;" .. S("Delay").. ";${period}]" .. + "tooltip[period;" .. S("Number of seconds to wait between each cycle").. "]" .. + "list[current_name;stop;3.0,0.7;1,1;]" .. + "label[3.0,1.5;" .. S("Stop block").. "]" .. + "container_end[]" .. + "list[current_player;main;0,2.3;8,1;]" .. + default.get_hotbar_bg(0,2.3) .. + "list[current_player;main;0,3.5;8,3;8]" .. + "listring[current_player;main]" .. + "listring[current_name;stop]" + +if minetest.get_modpath("doc") then + auto_formspec = auto_formspec .. + "button_exit[7.0,0.5;1,0.1;help;" .. S("Help") .. "]" .. + "tooltip[help;" .. S("Show documentation about this block").. "]" +end + +-- Needed to make this global so that it could recurse into minetest.after +digtron.auto_cycle = function(pos) + local node = minetest.get_node(pos) + local controlling_coordinate = digtron.get_controlling_coordinate(pos, node.param2) + local meta = minetest.get_meta(pos) + local player = minetest.get_player_by_name(meta:get_string("triggering_player")) + if player == nil or meta:get_string("waiting") == "true" then + return + end + + local cycle = meta:get_int("cycles") + local slope = meta:get_int("slope") + + if meta:get_string("lateral_done") ~= "true" and slope ~= 0 and (pos[controlling_coordinate] + meta:get_int("offset")) % slope == 0 then + --Do a downward dig cycle. Don't update the "cycles" count, these don't count towards that. + local newpos, status, return_code = digtron.execute_downward_dig_cycle(pos, player) + + if vector.equals(pos, newpos) then + status = status .. "\n" .. S("Cycles remaining: @1", cycle) .. "\n" .. S("Halted!") + meta:set_string("infotext", status) + if return_code == 1 then --return code 1 happens when there's unloaded nodes adjacent, just keep trying. + minetest.after(meta:get_int("period"), digtron.auto_cycle, newpos) + else + meta:set_string("formspec", auto_formspec) + end + else + meta = minetest.get_meta(newpos) + minetest.after(meta:get_int("period"), digtron.auto_cycle, newpos) + meta:set_string("infotext", status) + meta:set_string("lateral_done", "true") + end + return + end + + local newpos, status, return_code = digtron.execute_dig_cycle(pos, player) + + if vector.equals(pos, newpos) then + status = status .. "\n" .. S("Cycles remaining: @1", cycle) .. "\n" .. S("Halted!") + meta:set_string("infotext", status) + if return_code == 1 then --return code 1 happens when there's unloaded nodes adjacent, just keep trying. + minetest.after(meta:get_int("period"), digtron.auto_cycle, newpos) + else + meta:set_string("formspec", auto_formspec) + end + return + end + + meta = minetest.get_meta(newpos) + cycle = meta:get_int("cycles") - 1 + meta:set_int("cycles", cycle) + status = status .. "\n" .. S("Cycles remaining: @1", cycle) + meta:set_string("infotext", status) + meta:set_string("lateral_done", nil) + + if cycle > 0 then + minetest.after(meta:get_int("period"), digtron.auto_cycle, newpos) + else + meta:set_string("formspec", auto_formspec) + end +end + +minetest.register_node("digtron:auto_controller", { + description = S("Digtron Automatic Control Module"), + _doc_items_longdesc = digtron.doc.auto_controller_longdesc, + _doc_items_usagehelp = digtron.doc.auto_controller_usagehelp, + _digtron_formspec = auto_formspec, + groups = {cracky = 3, oddly_breakable_by_hand = 3, digtron = 1}, + drop = "digtron:auto_controller", + sounds = digtron.metal_sounds, + paramtype = "light", + paramtype2= "facedir", + is_ground_content = false, + -- Aims in the +Z direction by default + tiles = { + "digtron_plate.png^[transformR90^[colorize:" .. digtron.auto_controller_colorize, + "digtron_plate.png^[transformR270^[colorize:" .. digtron.auto_controller_colorize, + "digtron_plate.png^digtron_axel_side.png^[transformR270^[colorize:" .. digtron.auto_controller_colorize, + "digtron_plate.png^digtron_axel_side.png^[transformR270^[colorize:" .. digtron.auto_controller_colorize, + "digtron_plate.png^[colorize:" .. digtron.auto_controller_colorize, + "digtron_plate.png^digtron_control.png^[colorize:" .. digtron.auto_controller_colorize, + }, + + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = controller_nodebox, + }, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_float("fuel_burning", 0.0) + meta:set_string("infotext", S("Heat remaining in controller furnace: @1", 0)) + meta:set_string("formspec", auto_formspec) + -- Reusing offset and period to keep the digtron node-moving code simple, and the names still fit well + meta:set_int("period", digtron.config.cycle_time) + meta:set_int("offset", 0) + meta:set_int("cycles", 0) + meta:set_int("slope", 0) + + local inv = meta:get_inventory() + inv:set_size("stop", 1) + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if minetest.get_item_group(stack:get_name(), "digtron") ~= 0 then + return 0 -- pointless setting a Digtron node as a stop block + end + 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) + local inv = minetest.get_inventory({type="node", pos=pos}) + inv:set_stack(listname, index, ItemStack("")) + return 0 + end, + + on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + local offset = tonumber(fields.offset) + local period = tonumber(fields.period) + local slope = tonumber(fields.slope) + local cycles = tonumber(fields.cycles) + + if period and period > 0 then + meta:set_int("period", math.max(digtron.config.cycle_time, math.floor(period))) + end + + if offset then + meta:set_int("offset", offset) + end + + if slope and slope >= 0 then + meta:set_int("slope", slope) + end + + if cycles and cycles >= 0 then + meta:set_int("cycles", math.floor(cycles)) + if sender:is_player() and cycles > 0 then + meta:set_string("triggering_player", sender:get_player_name()) + if fields.execute then + meta:set_string("waiting", nil) + meta:set_string("formspec", nil) + digtron.auto_cycle(pos) + end + end + end + + if fields.set and slope and slope > 0 then + local node = minetest.get_node(pos) + local controlling_coordinate = digtron.get_controlling_coordinate(pos, node.param2) + + local newpos = pos + local markerpos = {x=newpos.x, y=newpos.y, z=newpos.z} + local x_pos = math.floor((newpos[controlling_coordinate]+offset)/slope)*slope - offset + markerpos[controlling_coordinate] = x_pos + minetest.add_entity(markerpos, "digtron:marker_vertical") + if x_pos >= newpos[controlling_coordinate] then + markerpos[controlling_coordinate] = x_pos - slope + minetest.add_entity(markerpos, "digtron:marker_vertical") + end + if x_pos <= newpos[controlling_coordinate] then + markerpos[controlling_coordinate] = x_pos + slope + minetest.add_entity(markerpos, "digtron:marker_vertical") + end + end + + if fields.help and minetest.get_modpath("doc") then --check for mod in case someone disabled it after this digger was built + minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", "digtron:auto_controller", true) + end + end, + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", meta:get_string("infotext") .. "\n" .. S("Interrupted!")) + meta:set_string("waiting", "true") + meta:set_string("formspec", auto_formspec) + end, + + on_timer = function(pos, elapsed) + minetest.get_meta(pos):set_string("waiting", nil) + end, +}) + +--------------------------------------------------------------------------------------------------------------- + +-- A much simplified control unit that only moves the digtron, and doesn't trigger the diggers or builders. +-- Handy for shoving a digtron to the side if it's been built a bit off. +minetest.register_node("digtron:pusher", { + description = S("Digtron Pusher Module"), + _doc_items_longdesc = digtron.doc.pusher_longdesc, + _doc_items_usagehelp = digtron.doc.pusher_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1}, + drop = "digtron:pusher", + sounds = digtron.metal_sounds, + paramtype = "light", + paramtype2= "facedir", + is_ground_content = false, + -- Aims in the +Z direction by default + tiles = { + "digtron_plate.png^[transformR90^[colorize:" .. digtron.pusher_controller_colorize, + "digtron_plate.png^[transformR270^[colorize:" .. digtron.pusher_controller_colorize, + "digtron_plate.png^[colorize:" .. digtron.pusher_controller_colorize, + "digtron_plate.png^[transformR180^[colorize:" .. digtron.pusher_controller_colorize, + "digtron_plate.png^[colorize:" .. digtron.pusher_controller_colorize, + "digtron_plate.png^digtron_control.png^[colorize:" .. digtron.pusher_controller_colorize, + }, + + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = controller_nodebox, + }, + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + if meta:get_string("waiting") == "true" then + -- Been too soon since last time the digtron did a cycle. + return + end + + local newpos, status_text, return_code = digtron.execute_move_cycle(pos, clicker) + meta = minetest.get_meta(newpos) + meta:set_string("infotext", status_text) + + -- Start the delay before digtron can run again. + minetest.get_meta(newpos):set_string("waiting", "true") + minetest.get_node_timer(newpos):start(digtron.config.cycle_time) + end, + + on_timer = function(pos, elapsed) + minetest.get_meta(pos):set_string("waiting", nil) + end, + +})
\ No newline at end of file diff --git a/nodes/node_crate.lua b/nodes/node_crate.lua new file mode 100644 index 0000000..7e30207 --- /dev/null +++ b/nodes/node_crate.lua @@ -0,0 +1,194 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +minetest.register_node("digtron:empty_crate", { + description = S("Digtron Crate (Empty)"), + _doc_items_longdesc = digtron.doc.empty_crate_longdesc, + _doc_items_usagehelp = digtron.doc.empty_crate_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand=3}, + drop = "digtron:empty_crate", + sounds = default.node_sound_wood_defaults(), + tiles = {"digtron_crate.png"}, + is_ground_content = false, + drawtype = "nodebox", + paramtype = "light", + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local layout = DigtronLayout.create(pos, clicker) + if layout.contains_protected_node then + local meta = minetest.get_meta(pos) + minetest.sound_play("buzzer", {gain=0.5, pos=pos}) + meta:set_string("infotext", S("Digtron can't be packaged, it contains protected blocks")) + -- no stealing other peoples' digtrons + return + end + + digtron.award_crate(layout, clicker:get_player_name()) + + local layout_string = layout:serialize() + + -- destroy everything. Note that this includes the empty crate, which will be bundled up with the layout. + for _, node_image in pairs(layout.all) do + minetest.remove_node(node_image.pos) + end + + -- Create the loaded crate node + minetest.set_node(pos, {name="digtron:loaded_crate", param1=node.param1, param2=node.param2}) + minetest.sound_play("machine1", {gain=1.0, pos=pos}) + + local meta = minetest.get_meta(pos) + meta:set_string("crated_layout", layout_string) + meta:set_string("title", S("Crated Digtron")) + meta:set_string("infotext", S("Crated Digtron")) + end, +}) + +local loaded_formspec + +if minetest.get_modpath("doc") then + loaded_formspec = + "size[4.1,1.5]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "field[0.3,0.5;4,0.5;title;" .. S("Digtron Name") .. ";${title}]" .. + "button_exit[0.0,1.2;1,0.1;save;" .. S("Save\nTitle") .. "]" .. + "tooltip[save;" .. S("Saves the title of this Digtron") .. "]" .. + "button_exit[1.0,1.2;1,0.1;show;" .. S("Show\nBlocks") .. "]" .. + "tooltip[show;" .. S("Shows which blocks the packed Digtron will occupy if unpacked") .. "]" .. + "button_exit[2.0,1.2;1,0.1;unpack;" .. S("Unpack") .. "]" .. + "tooltip[unpack;" .. S("Attempts to unpack the Digtron on this location") .. "]" .. + "button_exit[3.0,1.2;1,0.1;help;" .. S("Help") .. "]" .. + "tooltip[help;" .. S("Show documentation about this block") .. "]" +else + loaded_formspec = + "size[4,1.5]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "field[0.3,0.5;4,0.5;title;" .. S("Digtron Name") .. ";${title}]" .. + "button_exit[0.5,1.2;1,0.1;save;" .. S("Save\nTitle") .. "]" .. + "tooltip[show;" .. S("Saves the title of this Digtron") .. "]" .. + "button_exit[1.5,1.2;1,0.1;show;" .. S("Show\nBlocks") .. "]" .. + "tooltip[save;" .. S("Shows which blocks the packed Digtron will occupy if unpacked") .. "]" .. + "button_exit[2.5,1.2;1,0.1;unpack;" .. S("Unpack") .. "]" .. + "tooltip[unpack;" .. S("Attempts to unpack the Digtron on this location") .. "]" +end + +minetest.register_node("digtron:loaded_crate", { + description = S("Digtron Crate (Loaded)"), + _doc_items_longdesc = digtron.doc.loaded_crate_longdesc, + _doc_items_usagehelp = digtron.doc.loaded_crate_usagehelp, + _digtron_formspec = loaded_formspec, + groups = {cracky = 3, oddly_breakable_by_hand=3, not_in_creative_inventory=1, digtron_protected=1}, + stack_max = 1, + sounds = default.node_sound_wood_defaults(), + tiles = {"digtron_plate.png^digtron_crate.png"}, + is_ground_content = false, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", loaded_formspec) + end, + + on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + + if fields.unpack or fields.save or fields.show then + meta:set_string("title", fields.title) + meta:set_string("infotext", fields.title) + end + + if fields.help and minetest.get_modpath("doc") then --check for mod in case someone disabled it after this digger was built + minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", "digtron:loaded_crate", true) + end + + if not (fields.unpack or fields.show) then + return + end + + local layout_string = meta:get_string("crated_layout") + local layout = DigtronLayout.deserialize(layout_string) + + if layout == nil then + meta:set_string("infotext", meta:get_string("title") .. "\n" .. S("Unable to read layout from crate metadata, regrettably this Digtron may be corrupted or lost.")) + minetest.sound_play("buzzer", {gain=0.5, pos=pos}) + -- Something went horribly wrong + return + end + + local protected_node = false + local obstructed_node = false + + local pos_diff = vector.subtract(pos, layout.controller) + layout.controller = pos + for _, node_image in pairs(layout.all) do + node_image.pos = vector.add(pos_diff, node_image.pos) + if not vector.equals(pos, node_image.pos) then + if minetest.is_protected(node_image.pos, sender:get_player_name()) and not minetest.check_player_privs(sender, "protection_bypass") then + protected_node = true + minetest.add_entity(node_image.pos, "digtron:marker_crate_bad") + elseif not minetest.registered_nodes[minetest.get_node(node_image.pos).name].buildable_to then + obstructed_node = true + minetest.add_entity(node_image.pos, "digtron:marker_crate_bad") + else + minetest.add_entity(node_image.pos, "digtron:marker_crate_good") + end + end + end + + if not fields.unpack then + return + end + + if protected_node then + meta:set_string("infotext", meta:get_string("title") .. "\n" .. S("Unable to deploy Digtron due to protected blocks in target area")) + minetest.sound_play("buzzer", {gain=0.5, pos=pos}) + return + end + + if obstructed_node then + meta:set_string("infotext", meta:get_string("title") .. "\n" .. S("Unable to deploy Digtron due to obstruction in target area")) + minetest.sound_play("buzzer", {gain=0.5, pos=pos}) + return + end + + -- build digtron. Since the empty crate was included in the layout, that will overwrite this loaded crate and destroy it. + minetest.sound_play("machine2", {gain=1.0, pos=pos}) + layout:write_layout_image(sender) + end, + + on_dig = function(pos, node, player) + + local meta = minetest.get_meta(pos) + local to_serialize = {title=meta:get_string("title"), layout=meta:get_string("crated_layout")} + + local stack = ItemStack({name="digtron:loaded_crate", count=1, wear=0, metadata=minetest.serialize(to_serialize)}) + local inv = player:get_inventory() + local stack = inv:add_item("main", stack) + if stack:get_count() > 0 then + minetest.add_item(pos, stack) + end + -- call on_dignodes callback + minetest.remove_node(pos) + end, + + on_place = function(itemstack, placer, pointed_thing) + local pos = minetest.get_pointed_thing_position(pointed_thing, true) + local deserialized = minetest.deserialize(itemstack:get_metadata()) + if pos and deserialized then + minetest.set_node(pos, {name="digtron:loaded_crate"}) + local meta = minetest.get_meta(pos) + + meta:set_string("crated_layout", deserialized.layout) + meta:set_string("title", deserialized.title) + meta:set_string("infotext", deserialized.title) + meta:set_string("formspec", loaded_formspec) + + itemstack:take_item(1) + return itemstack + end + -- after-place callbacks + end, +})
\ No newline at end of file diff --git a/nodes/node_diggers.lua b/nodes/node_diggers.lua new file mode 100644 index 0000000..bf48f71 --- /dev/null +++ b/nodes/node_diggers.lua @@ -0,0 +1,479 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +-- Note: diggers go in group 3 and have an execute_dig method. + +local digger_nodebox = { + {-0.5, -0.5, 0, 0.5, 0.5, 0.4375}, -- Block + {-0.4375, -0.3125, 0.4375, 0.4375, 0.3125, 0.5}, -- Cutter1 + {-0.3125, -0.4375, 0.4375, 0.3125, 0.4375, 0.5}, -- Cutter2 + {-0.5, -0.125, -0.125, 0.5, 0.125, 0}, -- BackFrame1 + {-0.125, -0.5, -0.125, 0.125, 0.5, 0}, -- BackFrame2 + {-0.25, -0.25, -0.5, 0.25, 0.25, 0}, -- Drive +} + +local dual_digger_nodebox = { + {-0.5, -0.4375, 0, 0.5, 0.5, 0.4375}, -- Block + {-0.4375, -0.3125, 0.4375, 0.4375, 0.3125, 0.5}, -- Cutter1 + {-0.3125, -0.4375, 0.4375, 0.3125, 0.4375, 0.5}, -- Cutter2 + {-0.5, 0, -0.125, 0.5, 0.125, 0}, -- BackFrame1 + {-0.25, 0, -0.5, 0.25, 0.25, 0}, -- Drive + {-0.25, 0.25, -0.25, 0.25, 0.5, 0}, -- Upper_Drive + {-0.5, -0.4375, -0.5, 0.5, 0, 0.4375}, -- Lower_Block + {-0.3125, -0.5, -0.4375, 0.3125, -0.4375, 0.4375}, -- Lower_Cutter_1 + {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125}, -- Lower_Cutter_2 +} + +local intermittent_formspec = + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "field[0.5,0.8;1,0.1;period;" .. S("Periodicity") .. ";${period}]" .. + "tooltip[period;" .. S("Digger will dig once every n steps.\nThese steps are globally aligned, all diggers with\nthe same period and offset will dig on the same location.") .. "]" .. + "field[1.5,0.8;1,0.1;offset;" .. S("Offset") .. ";${offset}]" .. + "tooltip[offset;" .. S("Offsets the start of periodicity counting by this amount.\nFor example, a digger with period 2 and offset 0 digs\nevery even-numbered block and one with period 2 and\noffset 1 digs every odd-numbered block.") .. "]" .. + "button_exit[2.2,0.5;1,0.1;set;" .. S("Save &\nShow") .. "]" .. + "tooltip[set;" .. S("Saves settings") .. "]" + +if minetest.get_modpath("doc") then + intermittent_formspec = "size[4.5,1]" .. intermittent_formspec .. + "button_exit[3.2,0.5;1,0.1;help;" .. S("Help") .. "]" .. + "tooltip[help;" .. S("Show documentation about this block") .. "]" + else + intermittent_formspec = "size[3.5,1]" .. intermittent_formspec + end + +local intermittent_on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", intermittent_formspec) + meta:set_int("period", 1) + meta:set_int("offset", 0) +end + +local intermittent_on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + local period = tonumber(fields.period) + local offset = tonumber(fields.offset) + if period and period > 0 then + meta:set_int("period", math.floor(period)) + end + if offset then + meta:set_int("offset", math.floor(offset)) + end + if fields.help and minetest.get_modpath("doc") then --check for mod in case someone disabled it after this digger was built + local node_name = minetest.get_node(pos).name + minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", node_name, true) + end + if fields.set then + digtron.show_offset_markers(pos, offset, period) + end +end, + +-- Digs out nodes that are "in front" of the digger head. +minetest.register_node("digtron:digger", { + description = S("Digtron Digger Head"), + _doc_items_longdesc = digtron.doc.digger_longdesc, + _doc_items_usagehelp = digtron.doc.digger_usagehelp, + _digtron_formspec = intermittent_formspec, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 3}, + drop = "digtron:digger", + sounds = digtron.metal_sounds, + paramtype = "light", + paramtype2= "facedir", + is_ground_content = false, + drawtype="nodebox", + node_box = { + type = "fixed", + fixed = digger_nodebox, + }, + + -- Aims in the +Z direction by default + tiles = { + "digtron_plate.png^[transformR90", + "digtron_plate.png^[transformR270", + "digtron_plate.png", + "digtron_plate.png^[transformR180", + { + name = "digtron_digger_yb.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.0, + }, + }, + "digtron_plate.png^digtron_motor.png", + }, + + -- returns fuel_cost, item_produced + execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig) + 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 0, {} + end + + return digtron.mark_diggable(digpos, nodes_dug) + end, + + damage_creatures = function(player, pos, controlling_coordinate) + local facing = minetest.get_node(pos).param2 + digtron.damage_creatures(player, digtron.find_new_pos(pos, facing), 8) + end, +}) + +-- Digs out nodes that are "in front" of the digger head. +minetest.register_node("digtron:intermittent_digger", { + description = S("Digtron Intermittent Digger Head"), + _doc_items_longdesc = digtron.doc.intermittent_digger_longdesc, + _doc_items_usagehelp = digtron.doc.intermittent_digger_usagehelp, + _digtron_formspec = intermittent_formspec, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 3}, + drop = "digtron:intermittent_digger", + sounds = digtron.metal_sounds, + paramtype = "light", + paramtype2= "facedir", + is_ground_content = false, + drawtype="nodebox", + node_box = { + type = "fixed", + fixed = digger_nodebox, + }, + + -- Aims in the +Z direction by default + tiles = { + "digtron_plate.png^[transformR90", + "digtron_plate.png^[transformR270", + "digtron_plate.png", + "digtron_plate.png^[transformR180", + { + name = "digtron_digger_yb.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.0, + }, + }, + "digtron_plate.png^digtron_intermittent.png^digtron_motor.png", + }, + + on_construct = intermittent_on_construct, + + on_receive_fields = intermittent_on_receive_fields, + + -- returns fuel_cost, item_produced + execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig) + if lateral_dig == true then + return 0, {} + end + + 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 0, {} + end + + local meta = minetest.get_meta(pos) + if (digpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") ~= 0 then + return 0, {} + end + + return digtron.mark_diggable(digpos, nodes_dug) + end, + + damage_creatures = function(player, pos, controlling_coordinate) + local facing = minetest.get_node(pos).param2 + local targetpos = digtron.find_new_pos(pos, facing) + local meta = minetest.get_meta(pos) + if (targetpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") == 0 then + digtron.damage_creatures(player, targetpos, 8) + end + end +}) + +-- A special-purpose digger to deal with stuff like sand and gravel in the ceiling. It always digs (no periodicity or offset), but it only digs falling_block nodes +minetest.register_node("digtron:soft_digger", { + description = S("Digtron Soft Material Digger Head"), + _doc_items_longdesc = digtron.doc.soft_digger_longdesc, + _doc_items_usagehelp = digtron.doc.soft_digger_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 3}, + drop = "digtron:soft_digger", + sounds = digtron.metal_sounds, + paramtype = "light", + paramtype2= "facedir", + is_ground_content = false, + drawtype="nodebox", + node_box = { + type = "fixed", + fixed = digger_nodebox, + }, + + -- Aims in the +Z direction by default + tiles = { + "digtron_plate.png^[transformR90^[colorize:" .. digtron.soft_digger_colorize, + "digtron_plate.png^[transformR270^[colorize:" .. digtron.soft_digger_colorize, + "digtron_plate.png^[colorize:" .. digtron.soft_digger_colorize, + "digtron_plate.png^[transformR180^[colorize:" .. digtron.soft_digger_colorize, + { + name = "digtron_digger_yb.png^[colorize:" .. digtron.soft_digger_colorize, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.0, + }, + }, + "digtron_plate.png^digtron_motor.png^[colorize:" .. digtron.soft_digger_colorize, + }, + + execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig) + 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 0, {} + end + + if digtron.is_soft_material(digpos) then + return digtron.mark_diggable(digpos, nodes_dug) + end + + return 0, {} + end, + + damage_creatures = function(player, pos, controlling_coordinate) + local facing = minetest.get_node(pos).param2 + digtron.damage_creatures(player, digtron.find_new_pos(pos, facing), 4) + end, +}) + +minetest.register_node("digtron:intermittent_soft_digger", { + description = S("Digtron Intermittent Soft Material Digger Head"), + _doc_items_longdesc = digtron.doc.intermittent_soft_digger_longdesc, + _doc_items_usagehelp = digtron.doc.intermittent_soft_digger_usagehelp, + _digtron_formspec = intermittent_formspec, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 3}, + drop = "digtron:intermittent_soft_digger", + sounds = digtron.metal_sounds, + paramtype = "light", + paramtype2= "facedir", + is_ground_content = false, + drawtype="nodebox", + node_box = { + type = "fixed", + fixed = digger_nodebox, + }, + + -- Aims in the +Z direction by default + tiles = { + "digtron_plate.png^[transformR90^[colorize:" .. digtron.soft_digger_colorize, + "digtron_plate.png^[transformR270^[colorize:" .. digtron.soft_digger_colorize, + "digtron_plate.png^[colorize:" .. digtron.soft_digger_colorize, + "digtron_plate.png^[transformR180^[colorize:" .. digtron.soft_digger_colorize, + { + name = "digtron_digger_yb.png^[colorize:" .. digtron.soft_digger_colorize, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.0, + }, + }, + "digtron_plate.png^digtron_intermittent.png^digtron_motor.png^[colorize:" .. digtron.soft_digger_colorize, + }, + + on_construct = intermittent_on_construct, + + on_receive_fields = intermittent_on_receive_fields, + + execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig) + if lateral_dig == true then + return 0, {} + end + + 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 0, {} + end + + local meta = minetest.get_meta(pos) + if (digpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") ~= 0 then + return 0, {} + end + + if digtron.is_soft_material(digpos) then + return digtron.mark_diggable(digpos, nodes_dug) + end + + return 0, {} + end, + + damage_creatures = function(player, pos, controlling_coordinate) + local meta = minetest.get_meta(pos) + local facing = minetest.get_node(pos).param2 + local targetpos = digtron.find_new_pos(pos, facing) + if (targetpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") == 0 then + digtron.damage_creatures(player, targetpos, 4) + end + end, +}) + +-- Digs out nodes that are "in front" of the digger head and "below" the digger head (can be rotated). +minetest.register_node("digtron:dual_digger", { + description = S("Digtron Dual Digger Head"), + _doc_items_longdesc = digtron.doc.dual_digger_longdesc, + _doc_items_usagehelp = digtron.doc.dual_digger_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 3}, + drop = "digtron:dual_digger", + sounds = digtron.metal_sounds, + paramtype = "light", + paramtype2= "facedir", + is_ground_content = false, + drawtype="nodebox", + node_box = { + type = "fixed", + fixed = dual_digger_nodebox, + }, + + -- Aims in the +Z and -Y direction by default + tiles = { + "digtron_plate.png^digtron_motor.png", + { + name = "digtron_digger_yb.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.0, + }, + }, + "digtron_plate.png", + "digtron_plate.png^[transformR180", + { + name = "digtron_digger_yb.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.0, + }, + }, + "digtron_plate.png^digtron_motor.png", + }, + + -- returns fuel_cost, items_produced + execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig) + local facing = minetest.get_node(pos).param2 + local digpos = digtron.find_new_pos(pos, facing) + local digdown = digtron.find_new_pos_downward(pos, facing) + + local items = {} + local cost = 0 + + if protected_nodes:get(digpos.x, digpos.y, digpos.z) ~= true then + local forward_cost, forward_items = digtron.mark_diggable(digpos, nodes_dug) + for _, item in pairs(forward_items) do + table.insert(items, item) + end + cost = cost + forward_cost + end + if protected_nodes:get(digdown.x, digdown.y, digdown.z) ~= true then + local down_cost, down_items = digtron.mark_diggable(digdown, nodes_dug) + for _, item in pairs(down_items) do + table.insert(items, item) + end + cost = cost + down_cost + end + + return cost, items + end, + + damage_creatures = function(player, pos, controlling_coordinate) + local facing = minetest.get_node(pos).param2 + digtron.damage_creatures(player, digtron.find_new_pos(pos, facing), 8) + digtron.damage_creatures(player, digtron.find_new_pos_downward(pos, facing), 8) + end, +}) + +-- Digs out soft nodes that are "in front" of the digger head and "below" the digger head (can be rotated). +minetest.register_node("digtron:dual_soft_digger", { + description = S("Digtron Dual Soft Material Digger Head"), + _doc_items_longdesc = digtron.doc.dual_soft_digger_longdesc, + _doc_items_usagehelp = digtron.doc.dual_soft_digger_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 3}, + drop = "digtron:dual_soft_digger", + sounds = digtron.metal_sounds, + paramtype = "light", + paramtype2= "facedir", + is_ground_content = false, + drawtype="nodebox", + node_box = { + type = "fixed", + fixed = dual_digger_nodebox, + }, + + -- Aims in the +Z and -Y direction by default + tiles = { + "digtron_plate.png^digtron_motor.png^[colorize:" .. digtron.soft_digger_colorize, + { + name = "digtron_digger_yb.png^[colorize:" .. digtron.soft_digger_colorize, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.0, + }, + }, + "digtron_plate.png^[colorize:" .. digtron.soft_digger_colorize, + "digtron_plate.png^[transformR180^[colorize:" .. digtron.soft_digger_colorize, + { + name = "digtron_digger_yb.png^[colorize:" .. digtron.soft_digger_colorize, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.0, + }, + }, + "digtron_plate.png^digtron_motor.png^[colorize:" .. digtron.soft_digger_colorize, + }, + + -- returns fuel_cost, items_produced + execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig) + local facing = minetest.get_node(pos).param2 + local digpos = digtron.find_new_pos(pos, facing) + local digdown = digtron.find_new_pos_downward(pos, facing) + + local items = {} + local cost = 0 + + if protected_nodes:get(digpos.x, digpos.y, digpos.z) ~= true and digtron.is_soft_material(digpos) then + local forward_cost, forward_items = digtron.mark_diggable(digpos, nodes_dug) + for _, item in pairs(forward_items) do + table.insert(items, item) + end + cost = cost + forward_cost + end + if protected_nodes:get(digdown.x, digdown.y, digdown.z) ~= true and digtron.is_soft_material(digdown) then + local down_cost, down_items = digtron.mark_diggable(digdown, nodes_dug) + for _, item in pairs(down_items) do + table.insert(items, item) + end + cost = cost + down_cost + end + + return cost, items + end, + + damage_creatures = function(player, pos, controlling_coordinate) + local facing = minetest.get_node(pos).param2 + digtron.damage_creatures(player, digtron.find_new_pos(pos, facing), 4) + digtron.damage_creatures(player, digtron.find_new_pos_downward(pos, facing), 4) + end, +})
\ No newline at end of file diff --git a/nodes/node_misc.lua b/nodes/node_misc.lua new file mode 100644 index 0000000..e847045 --- /dev/null +++ b/nodes/node_misc.lua @@ -0,0 +1,141 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +-- A do-nothing "structural" node, to ensure all digtron nodes that are supposed to be connected to each other can be connected to each other. +minetest.register_node("digtron:structure", { + description = S("Digtron Structure"), + _doc_items_longdesc = digtron.doc.structure_longdesc, + _doc_items_usagehelp = digtron.doc.structure_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1}, + drop = "digtron:structure", + tiles = {"digtron_plate.png"}, + drawtype = "nodebox", + sounds = digtron.metal_sounds, + climbable = true, + walkable = false, + paramtype = "light", + is_ground_content = false, + node_box = { + type = "fixed", + fixed = { + {0.3125, 0.3125, -0.5, 0.5, 0.5, 0.5}, + {0.3125, -0.5, -0.5, 0.5, -0.3125, 0.5}, + {-0.5, 0.3125, -0.5, -0.3125, 0.5, 0.5}, + {-0.5, -0.5, -0.5, -0.3125, -0.3125, 0.5}, + {-0.3125, 0.3125, 0.3125, 0.3125, 0.5, 0.5}, + {-0.3125, -0.5, 0.3125, 0.3125, -0.3125, 0.5}, + {-0.5, -0.3125, 0.3125, -0.3125, 0.3125, 0.5}, + {0.3125, -0.3125, 0.3125, 0.5, 0.3125, 0.5}, + {-0.5, -0.3125, -0.5, -0.3125, 0.3125, -0.3125}, + {0.3125, -0.3125, -0.5, 0.5, 0.3125, -0.3125}, + {-0.3125, 0.3125, -0.5, 0.3125, 0.5, -0.3125}, + {-0.3125, -0.5, -0.5, 0.3125, -0.3125, -0.3125}, + } + }, +}) + +-- A modest light source that will move with the digtron, handy for working in a tunnel you aren't bothering to install permanent lights in. +minetest.register_node("digtron:light", { + description = S("Digtron Light"), + _doc_items_longdesc = digtron.doc.light_longdesc, + _doc_items_usagehelp = digtron.doc.light_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1}, + drop = "digtron:light", + tiles = {"digtron_plate.png^digtron_light.png"}, + drawtype = "nodebox", + paramtype = "light", + is_ground_content = false, + light_source = 10, + sounds = default.node_sound_glass_defaults(), + paramtype2 = "wallmounted", + node_box = { + type = "wallmounted", + wall_top = {-0.25, 0.3125, -0.25, 0.25, 0.5, 0.25}, + wall_bottom = {-0.25, -0.3125, -0.25, 0.25, -0.5, 0.25}, + wall_side = {-0.5, -0.25, -0.25, -0.1875, 0.25, 0.25}, + }, +}) + +-- A simple structural panel +minetest.register_node("digtron:panel", { + description = S("Digtron Panel"), + _doc_items_longdesc = digtron.doc.panel_longdesc, + _doc_items_usagehelp = digtron.doc.panel_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1}, + drop = "digtron:panel", + tiles = {"digtron_plate.png"}, + drawtype = "nodebox", + paramtype = "light", + is_ground_content = false, + sounds = digtron.metal_sounds, + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -0.375, 0.5}, + }, + collision_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -0.4375, 0.5}, + }, +}) + +-- A simple structural panel +minetest.register_node("digtron:edge_panel", { + description = S("Digtron Edge Panel"), + _doc_items_longdesc = digtron.doc.edge_panel_longdesc, + _doc_items_usagehelp = digtron.doc.edge_panel_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1}, + drop = "digtron:edge_panel", + tiles = {"digtron_plate.png"}, + drawtype = "nodebox", + paramtype = "light", + is_ground_content = false, + sounds = digtron.metal_sounds, + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0.375, 0.5, 0.5, 0.5}, + {-0.5, -0.5, -0.5, 0.5, -0.375, 0.375} + }, + }, + collision_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0.4375, 0.5, 0.5, 0.5}, + {-0.5, -0.5, -0.5, 0.5, -0.4375, 0.4375} + }, + }, + +}) + +minetest.register_node("digtron:corner_panel", { + description = S("Digtron Corner Panel"), + _doc_items_longdesc = digtron.doc.corner_panel_longdesc, + _doc_items_usagehelp = digtron.doc.corner_panel_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1}, + drop = "digtron:corner_panel", + tiles = {"digtron_plate.png"}, + drawtype = "nodebox", + paramtype = "light", + is_ground_content = false, + sounds = digtron.metal_sounds, + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0.375, 0.5, 0.5, 0.5}, + {-0.5, -0.5, -0.5, 0.5, -0.375, 0.375}, + {-0.5, -0.375, -0.5, -0.375, 0.5, 0.375}, + }, + }, + collision_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0.4375, 0.5, 0.5, 0.5}, + {-0.5, -0.5, -0.5, 0.5, -0.4375, 0.4375}, + {-0.5, -0.4375, -0.5, -0.4375, 0.5, 0.4375}, + }, + }, +})
\ No newline at end of file diff --git a/nodes/node_storage.lua b/nodes/node_storage.lua new file mode 100644 index 0000000..56d19aa --- /dev/null +++ b/nodes/node_storage.lua @@ -0,0 +1,284 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + + +local inventory_formspec = + "size[8,9.3]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "label[0,0;" .. S("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,5.15) + +-- Storage buffer. Builder nodes draw from this inventory and digger nodes deposit into it. +-- Note that inventories are digtron group 2. +minetest.register_node("digtron:inventory", { + description = S("Digtron Inventory Storage"), + _doc_items_longdesc = digtron.doc.inventory_longdesc, + _doc_items_usagehelp = digtron.doc.inventory_usagehelp, + _digtron_formspec = inventory_formspec, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 2, tubedevice = 1, tubedevice_receiver = 1}, + drop = "digtron:inventory", + sounds = digtron.metal_sounds, + paramtype2= "facedir", + drawtype = "nodebox", + paramtype = "light", + is_ground_content = false, + tiles = { + "digtron_plate.png^digtron_crossbrace.png", + "digtron_plate.png^digtron_crossbrace.png", + "digtron_plate.png^digtron_crossbrace.png^digtron_storage.png", + "digtron_plate.png^digtron_crossbrace.png^digtron_storage.png", + "digtron_plate.png^digtron_crossbrace.png^digtron_storage.png", + "digtron_plate.png^digtron_crossbrace.png^digtron_storage.png", + }, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", inventory_formspec) + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + end, + + can_dig = function(pos,player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:is_empty("main") + end, + + -- Pipeworks compatibility + ---------------------------------------------------------------- + + tube = (function() if minetest.get_modpath("pipeworks") then return { + insert_object = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:add_item("main", stack) + end, + can_insert = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:room_for_item("main", stack) + end, + input_inventory = "main", + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} + } end end)(), + + after_place_node = (function() if minetest.get_modpath("pipeworks") then return pipeworks.after_place end end)(), + after_dig_node = (function() if minetest.get_modpath("pipeworks") then return pipeworks.after_dig end end)() +}) + +local fuelstore_formspec = + "size[8,9.3]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "label[0,0;" .. S("Fuel items") .. "]" .. + "list[current_name;fuel;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;fuel]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,5.15) + +-- Fuel storage. Controller node draws fuel from here. +-- Note that fuel stores are digtron group 5. +minetest.register_node("digtron:fuelstore", { + description = S("Digtron Fuel Storage"), + _doc_items_longdesc = digtron.doc.fuelstore_longdesc, + _doc_items_usagehelp = digtron.doc.fuelstore_usagehelp, + _digtron_formspec = fuelstore_formspec, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 5, tubedevice = 1, tubedevice_receiver = 1}, + drop = "digtron:fuelstore", + sounds = digtron.metal_sounds, + paramtype2= "facedir", + drawtype = "nodebox", + paramtype = "light", + is_ground_content = false, + tiles = { + "digtron_plate.png^digtron_crossbrace.png^digtron_flammable.png", + "digtron_plate.png^digtron_crossbrace.png^digtron_flammable.png", + "digtron_plate.png^digtron_crossbrace.png^digtron_flammable.png^digtron_storage.png", + "digtron_plate.png^digtron_crossbrace.png^digtron_flammable.png^digtron_storage.png", + "digtron_plate.png^digtron_crossbrace.png^digtron_flammable.png^digtron_storage.png", + "digtron_plate.png^digtron_crossbrace.png^digtron_flammable.png^digtron_storage.png", + }, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", fuelstore_formspec) + local inv = meta:get_inventory() + inv:set_size("fuel", 8*4) + end, + + -- Only allow fuel items to be placed in fuel + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if listname == "fuel" then + if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then + return stack:get_count() + else + return 0 + end + end + return 0 + end, + + can_dig = function(pos,player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:is_empty("fuel") + end, + + -- Pipeworks compatibility + ---------------------------------------------------------------- + + tube = (function() if minetest.get_modpath("pipeworks") then return { + insert_object = function(pos, node, stack, direction) + if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:add_item("fuel", stack) + end + return stack + end, + can_insert = function(pos, node, stack, direction) + if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:room_for_item("fuel", stack) + end + return false + end, + input_inventory = "fuel", + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} + } end end)(), + + after_place_node = (function() if minetest.get_modpath("pipeworks") then return pipeworks.after_place end end)(), + after_dig_node = (function() if minetest.get_modpath("pipeworks")then return pipeworks.after_dig end end)() +}) + +local combined_storage_formspec = + "size[8,9.9]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "label[0,0;" .. S("Inventory items") .. "]" .. + "list[current_name;main;0,0.6;8,3;]" .. + "label[0,3.5;" .. S("Fuel items") .. "]" .. + "list[current_name;fuel;0,4.1;8,1;]" .. + "list[current_player;main;0,5.75;8,1;]" .. + "list[current_player;main;0,6.98;8,3;8]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,5.75) + + +-- Combined storage. Group 6 has both an inventory and a fuel store +minetest.register_node("digtron:combined_storage", { + description = S("Digtron Combined Storage"), + _doc_items_longdesc = digtron.doc.combined_storage_longdesc, + _doc_items_usagehelp = digtron.doc.combined_storage_usagehelp, + _digtron_formspec = combined_storage_formspec, + groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 6, tubedevice = 1, tubedevice_receiver = 1}, + drop = "digtron:combined_storage", + sounds = digtron.metal_sounds, + paramtype2= "facedir", + drawtype = "nodebox", + paramtype = "light", + is_ground_content = false, + tiles = { + "digtron_plate.png^digtron_crossbrace.png^digtron_flammable_small.png^[transformR180^digtron_flammable_small.png", + "digtron_plate.png^digtron_crossbrace.png^digtron_flammable_small.png^[transformR180^digtron_flammable_small.png", "digtron_plate.png^digtron_crossbrace.png^digtron_flammable_small.png^digtron_storage.png", + "digtron_plate.png^digtron_crossbrace.png^digtron_flammable_small.png^digtron_storage.png", + "digtron_plate.png^digtron_crossbrace.png^digtron_flammable_small.png^digtron_storage.png", + "digtron_plate.png^digtron_crossbrace.png^digtron_flammable_small.png^digtron_storage.png", + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", combined_storage_formspec) + local inv = meta:get_inventory() + inv:set_size("main", 8*3) + inv:set_size("fuel", 8*1) + end, + + -- Only allow fuel items to be placed in fuel + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if listname == "fuel" then + if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then + return stack:get_count() + else + return 0 + end + end + return stack:get_count() -- otherwise, allow all drops + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + if to_list == "main" then + return count + end + + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(from_list, from_index) + if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then + return stack:get_count() + end + return 0 + end, + + can_dig = function(pos,player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:is_empty("fuel") and inv:is_empty("main") + end, + + -- Pipeworks compatibility + ---------------------------------------------------------------- + tube = (function() if minetest.get_modpath("pipeworks") then return { + insert_object = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 and direction.y == 1 then + return inv:add_item("fuel", stack) + end + return inv:add_item("main", stack) + end, + can_insert = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 and direction.y == 1 then + return inv:room_for_item("fuel", stack) + end + return inv:room_for_item("main", stack) + end, + input_inventory = "main", + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} + } end end)(), + + after_place_node = (function() if minetest.get_modpath("pipeworks") then return pipeworks.after_place end end)(), + after_dig_node = (function() if minetest.get_modpath("pipeworks") then return pipeworks.after_dig end end)() +}) + +-- Hopper compatibility +if minetest.get_modpath("hopper") and hopper ~= nil and hopper.add_container ~= nil then + hopper:add_container({ + {"top", "digtron:inventory", "main"}, + {"bottom", "digtron:inventory", "main"}, + {"side", "digtron:inventory", "main"}, + + {"top", "digtron:fuelstore", "fuel"}, + {"bottom", "digtron:fuelstore", "fuel"}, + {"side", "digtron:fuelstore", "fuel"}, + + {"top", "digtron:combined_storage", "main"}, + {"bottom", "digtron:combined_storage", "main"}, + {"side", "digtron:combined_storage", "fuel"}, + }) +end diff --git a/nodes/recipes.lua b/nodes/recipes.lua new file mode 100644 index 0000000..9895971 --- /dev/null +++ b/nodes/recipes.lua @@ -0,0 +1,283 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +minetest.register_craftitem("digtron:digtron_core", { + description = S("Digtron Core"), + inventory_image = "digtron_core.png", + _doc_items_longdesc = digtron.doc.core_longdesc, + _doc_items_usagehelp = digtron.doc.core_usagehelp, +}) + +minetest.register_craft({ + output = "digtron:digtron_core", + recipe = { + {"","default:steel_ingot",""}, + {"default:steel_ingot","default:mese_crystal_fragment","default:steel_ingot"}, + {"","default:steel_ingot",""} + } +}) + +minetest.register_craft({ + output = "digtron:controller", + recipe = { + {"","default:mese_crystal",""}, + {"default:mese_crystal","digtron:digtron_core","default:mese_crystal"}, + {"","default:mese_crystal",""} + } +}) + +minetest.register_craft({ + output = "digtron:auto_controller", + recipe = { + {"default:mese_crystal","default:mese_crystal","default:mese_crystal"}, + {"default:mese_crystal","digtron:digtron_core","default:mese_crystal"}, + {"default:mese_crystal","default:mese_crystal","default:mese_crystal"} + } +}) + +minetest.register_craft({ + output = "digtron:builder", + recipe = { + {"","default:mese_crystal_fragment",""}, + {"default:mese_crystal_fragment","digtron:digtron_core","default:mese_crystal_fragment"}, + {"","default:mese_crystal_fragment",""} + } +}) + +minetest.register_craft({ + output = "digtron:light", + recipe = { + {"","default:torch",""}, + {"","digtron:digtron_core",""}, + {"","",""} + } +}) + +minetest.register_craft({ + output = "digtron:digger", + recipe = { + {"","default:diamond",""}, + {"default:diamond","digtron:digtron_core","default:diamond"}, + {"","default:diamond",""} + } +}) + +minetest.register_craft({ + output = "digtron:soft_digger", + recipe = { + {"","default:steel_ingot",""}, + {"default:steel_ingot","digtron:digtron_core","default:steel_ingot"}, + {"","default:steel_ingot",""} + } +}) + +minetest.register_craft({ + output = "digtron:inventory", + recipe = { + {"","default:chest",""}, + {"","digtron:digtron_core",""}, + {"","",""} + } +}) + +minetest.register_craft({ + output = "digtron:fuelstore", + recipe = { + {"","default:furnace",""}, + {"","digtron:digtron_core",""}, + {"","",""} + } +}) + +minetest.register_craft({ + output = "digtron:combined_storage", + recipe = { + {"","default:furnace",""}, + {"","digtron:digtron_core",""}, + {"","default:chest",""} + } +}) + +minetest.register_craft({ + output = "digtron:pusher", + recipe = { + {"","default:coal_lump",""}, + {"default:coal_lump","digtron:digtron_core","default:coal_lump"}, + {"","default:coal_lump",""} + } +}) + +minetest.register_craft({ + output = "digtron:axle", + recipe = { + {"default:coal_lump","default:coal_lump","default:coal_lump"}, + {"default:coal_lump","digtron:digtron_core","default:coal_lump"}, + {"default:coal_lump","default:coal_lump","default:coal_lump"} + } +}) + +minetest.register_craft({ + output = "digtron:empty_crate", + recipe = { + {"","default:chest",""}, + {"","digtron:digtron_core",""}, + {"","default:mese_crystal",""} + } +}) + +-- Structural + +minetest.register_craft({ + output = "digtron:structure", + recipe = { + {"group:stick","","group:stick"}, + {"","digtron:digtron_core",""}, + {"group:stick","","group:stick"} + } +}) + +minetest.register_craft({ + output = "digtron:panel", + recipe = { + {"","",""}, + {"","digtron:digtron_core",""}, + {"","default:steel_ingot",""} + } +}) + +minetest.register_craft({ + output = "digtron:edge_panel", + recipe = { + {"","",""}, + {"","digtron:digtron_core","default:steel_ingot"}, + {"","default:steel_ingot",""} + } +}) + +minetest.register_craft({ + output = "digtron:corner_panel", + recipe = { + {"","",""}, + {"","digtron:digtron_core","default:steel_ingot"}, + {"","default:steel_ingot","default:steel_ingot"} + } +}) + +-- For swapping digger types +minetest.register_craft({ + output = "digtron:digger", + recipe = { + {"digtron:intermittent_digger"}, + } +}) +minetest.register_craft({ + output = "digtron:intermittent_digger", + recipe = { + {"digtron:digger"}, + } +}) +minetest.register_craft({ + output = "digtron:soft_digger", + recipe = { + {"digtron:intermittent_soft_digger"}, + } +}) +minetest.register_craft({ + output = "digtron:intermittent_soft_digger", + recipe = { + {"digtron:soft_digger"}, + } +}) + +minetest.register_craft({ + output = "digtron:dual_soft_digger", + type = "shapeless", + recipe = {"digtron:soft_digger", "digtron:soft_digger"}, +}) +minetest.register_craft({ + output = "digtron:dual_digger", + type = "shapeless", + recipe = {"digtron:digger", "digtron:digger"}, +}) +minetest.register_craft({ + output = "digtron:soft_digger 2", + recipe = { + {"digtron:dual_soft_digger"}, + } +}) +minetest.register_craft({ + output = "digtron:digger 2", + recipe = { + {"digtron:dual_digger"}, + } +}) + +-- And some recycling reactions to get digtron cores out of the "cheap" parts: + +minetest.register_craft({ + output = "digtron:digtron_core", + recipe = { + {"digtron:structure"}, + } +}) +minetest.register_craft({ + output = "digtron:digtron_core", + recipe = { + {"digtron:panel"}, + } +}) +minetest.register_craft({ + output = "digtron:digtron_core", + recipe = { + {"digtron:corner_panel"}, + } +}) +minetest.register_craft({ + output = "digtron:digtron_core", + recipe = { + {"digtron:edge_panel"}, + } +}) + +minetest.register_craft({ + output = "digtron:digtron_core", + recipe = { + {"digtron:inventory"}, + } +}) + +minetest.register_craft({ + output = "digtron:digtron_core", + recipe = { + {"digtron:fuelstore"}, + } +}) + +minetest.register_craft({ + output = "digtron:digtron_core", + recipe = { + {"digtron:combined_storage"}, + } +}) + +minetest.register_craft({ + output = "digtron:digtron_core", + recipe = { + {"digtron:light"}, + } +}) + +minetest.register_craft({ + output = "digtron:digtron_core", + recipe = { + {"digtron:pusher"}, + } +}) + +minetest.register_craft({ + output = "digtron:digtron_core", + recipe = { + {"digtron:axle"}, + } +})
\ No newline at end of file |