From 7bf4898160499bd1792445e8db261b81cf2b0afb Mon Sep 17 00:00:00 2001 From: Joachim Stolberg Date: Sun, 28 Apr 2019 21:34:21 +0200 Subject: [PATCH] restructured --- basic_machines/autocrafter.lua | 415 +++++++++++++++++++++++++ basic_machines/basalt.lua | 85 +++++ basic_machines/blackhole.lua | 65 ++++ basic_machines/forceload.lua | 218 +++++++++++++ basic_machines/gravelsieve.lua | 46 +-- basic_machines/grinder.lua | 3 +- basic_machines/mark.lua | 93 ++++++ basic_machines/pusher.lua | 2 +- basis/junction.lua | 4 +- basis/lib.lua | 42 +++ init.lua | 16 +- iron_age/hammer.lua | 16 +- iron_age/recipes.lua | 7 - power/electric_cable.lua | 10 +- sounds/techage_steamengine.ogg | Bin 10875 -> 12427 bytes steam_engine/cylinder.lua | 24 -- steam_engine/flywheel.lua | 26 ++ {steam_engine => test}/battery.lua | 0 {electric => test}/consumer.lua | 0 {electric => test}/generator.lua | 0 {basic_machines => test}/perf_test.lua | 0 {electric => test}/test.lua | 0 textures/techage_appl_autocrafter.png | Bin 0 -> 238 bytes textures/techage_appl_autocrafter4.png | Bin 0 -> 388 bytes textures/techage_appl_blackhole.png | Bin 0 -> 171 bytes tools/repairkit.lua | 92 ++++++ {basis => tools}/trowel.lua | 17 +- 27 files changed, 1091 insertions(+), 90 deletions(-) create mode 100644 basic_machines/autocrafter.lua create mode 100644 basic_machines/basalt.lua create mode 100644 basic_machines/blackhole.lua create mode 100644 basic_machines/forceload.lua create mode 100644 basic_machines/mark.lua rename {steam_engine => test}/battery.lua (100%) rename {electric => test}/consumer.lua (100%) rename {electric => test}/generator.lua (100%) rename {basic_machines => test}/perf_test.lua (100%) rename {electric => test}/test.lua (100%) create mode 100644 textures/techage_appl_autocrafter.png create mode 100644 textures/techage_appl_autocrafter4.png create mode 100644 textures/techage_appl_blackhole.png create mode 100644 tools/repairkit.lua rename {basis => tools}/trowel.lua (88%) diff --git a/basic_machines/autocrafter.lua b/basic_machines/autocrafter.lua new file mode 100644 index 0000000..e357030 --- /dev/null +++ b/basic_machines/autocrafter.lua @@ -0,0 +1,415 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + The autocrafter is derived from pipeworks: + Copyright (C) 2004 Sam Hocevar WTFPL + + TA2/TA3/TA4 Autocrafter + +]]-- + +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta +-- Techage Related Data +local TRD = function(pos) return (minetest.registered_nodes[minetest.get_node(pos).name] or {}).techage end + +-- Load support for intllib. +local MP = minetest.get_modpath("techage") +local I,_ = dofile(MP.."/intllib.lua") + +local STANDBY_TICKS = 10 +local COUNTDOWN_TICKS = 10 +local CYCLE_TIME = 4 + +local function formspec(self, pos, mem) + return "size[8,9.2]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "list[context;recipe;0,0;3,3;]".. + "image[2.9,1;1,1;techage_form_arrow.png]".. + "image[3.8,0;1,1;"..techage.get_power_image(pos, mem).."]".. + "list[context;output;3.8,1;1,1;]".. + "image_button[3.8,2;1,1;".. self:get_state_button_image(mem) ..";state_button;]".. + "list[context;src;0,3.2;8,2;]".. + "list[context;dst;5,0;3,3;]".. + "list[current_player;main;0,5.4;8,4;]" .. + "listring[current_player;main]".. + "listring[context;src]" .. + "listring[current_player;main]".. + "listring[context;dst]" .. + "listring[current_player;main]".. + default.get_hotbar_bg(0, 4) +end + +local function count_index(invlist) + local index = {} + for _, stack in pairs(invlist) do + if not stack:is_empty() then + local stack_name = stack:get_name() + index[stack_name] = (index[stack_name] or 0) + stack:get_count() + end + end + return index +end + +-- caches some recipe data +local autocrafterCache = {} + +local function get_craft(pos, inventory, hash) + hash = hash or minetest.hash_node_position(pos) + local craft = autocrafterCache[hash] + if not craft then + local recipe = inventory:get_list("recipe") + local output, decremented_input = minetest.get_craft_result( + {method = "normal", width = 3, items = recipe}) + craft = {recipe = recipe, consumption=count_index(recipe), + output = output, decremented_input = decremented_input} + autocrafterCache[hash] = craft + end + return craft +end + +local function autocraft(pos, trd, mem, inventory, craft) + if not craft then return false end + local output_item = craft.output.item + + -- check if we have enough room in dst + if not inventory:room_for_item("dst", output_item) then + trd.State:blocked(pos, mem) + return + end + local consumption = craft.consumption + local inv_index = count_index(inventory:get_list("src")) + -- check if we have enough material available + for itemname, number in pairs(consumption) do + if (not inv_index[itemname]) or inv_index[itemname] < number then + trd.State:idle(pos, mem) + return + end + end + -- consume material + for itemname, number in pairs(consumption) do + for i = 1, number do -- We have to do that since remove_item does not work if count > stack_max + inventory:remove_item("src", ItemStack(itemname)) + end + end + + -- craft the result into the dst inventory and add any "replacements" as well + inventory:add_item("dst", output_item) + for i = 1, 9 do + inventory:add_item("dst", craft.decremented_input.items[i]) + end + + trd.State:keep_running(pos, mem, COUNTDOWN_TICKS) +end + + +local function keep_running(pos, elapsed) + local mem = tubelib2.get_mem(pos) + local trd = TRD(pos) + local inv = M(pos):get_inventory() + local craft = get_craft(pos, inv) + local output_item = craft.output.item + autocraft(pos, trd, mem, inv, craft) + return trd.State:is_active(mem) +end + +-- note, that this function assumes allready being updated to virtual items +-- and doesn't handle recipes with stacksizes > 1 +local function after_recipe_change(pos, inventory) + local mem = tubelib2.get_mem(pos) + local trd = TRD(pos) + -- if we emptied the grid, there's no point in keeping it running or cached + if inventory:is_empty("recipe") then + autocrafterCache[minetest.hash_node_position(pos)] = nil + inventory:set_stack("output", 1, "") + trd.State:stop(pos, mem) + return + end + local recipe = inventory:get_list("recipe") + + local hash = minetest.hash_node_position(pos) + local craft = autocrafterCache[hash] + + if craft then + -- check if it changed + local cached_recipe = craft.recipe + for i = 1, 9 do + if recipe[i]:get_name() ~= cached_recipe[i]:get_name() then + autocrafterCache[hash] = nil -- invalidate recipe + craft = nil + break + end + end + end + + craft = craft or get_craft(pos, inventory, hash) + local output_item = craft.output.item + inventory:set_stack("output", 1, output_item) + trd.State:stop(pos, mem) +end + +-- clean out unknown items and groups, which would be handled like unknown items in the crafting grid +-- if minetest supports query by group one day, this might replace them +-- with a canonical version instead +local function normalize(item_list) + for i = 1, #item_list do + local name = item_list[i] + if not minetest.registered_items[name] then + item_list[i] = "" + end + end + return item_list +end + +local function on_output_change(pos, inventory, stack) + if not stack then + inventory:set_list("output", {}) + inventory:set_list("recipe", {}) + else + local input = minetest.get_craft_recipe(stack:get_name()) + if not input.items or input.type ~= "normal" then return end + local items, width = normalize(input.items), input.width + local item_idx, width_idx = 1, 1 + for i = 1, 9 do + if width_idx <= width then + inventory:set_stack("recipe", i, items[item_idx]) + item_idx = item_idx + 1 + else + inventory:set_stack("recipe", i, ItemStack("")) + end + width_idx = (width_idx < 3) and (width_idx + 1) or 1 + end + -- we'll set the output slot in after_recipe_change to the actual result of the new recipe + end + after_recipe_change(pos, inventory) +end + + +local function allow_metadata_inventory_put(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + local inv = minetest.get_meta(pos):get_inventory() + local trd = TRD(pos) + if listname == "recipe" then + stack:set_count(1) + inv:set_stack(listname, index, stack) + after_recipe_change(pos, inv) + return 0 + elseif listname == "output" then + on_output_change(pos, inv, stack) + return 0 + elseif listname == "src" and trd.State:get_state(M(pos)) == techage.STANDBY then + trd.State:start(pos, M(pos)) + end + return stack:get_count() +end + +local function allow_metadata_inventory_take(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end +-- upgrade_autocrafter(pos) + local inv = minetest.get_meta(pos):get_inventory() + if listname == "recipe" then + inv:set_stack(listname, index, ItemStack("")) + after_recipe_change(pos, inv) + return 0 + elseif listname == "output" then + on_output_change(pos, inv, nil) + return 0 + end + return stack:get_count() +end + +local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + local inv = minetest.get_meta(pos):get_inventory() + local stack = inv:get_stack(from_list, from_index) + + if to_list == "output" then + on_output_change(pos, inv, stack) + return 0 + elseif from_list == "output" then + on_output_change(pos, inv, nil) + if to_list ~= "recipe" then + return 0 + end -- else fall through to recipe list handling + end + + if from_list == "recipe" or to_list == "recipe" then + if from_list == "recipe" then + inv:set_stack(from_list, from_index, ItemStack("")) + end + if to_list == "recipe" then + stack:set_count(1) + inv:set_stack(to_list, to_index, stack) + end + after_recipe_change(pos, inv) + return 0 + end + + return count +end + +local function on_receive_fields(pos, formname, fields, player) + if minetest.is_protected(pos, player:get_player_name()) then + return + end + local mem = tubelib2.get_mem(pos) + TRD(pos).State:state_button_event(pos, mem, fields) +end + +local function can_dig(pos, player) + if minetest.is_protected(pos, player:get_player_name()) then + return false + end + local inv = M(pos):get_inventory() + return inv:is_empty("dst") and inv:is_empty("src") +end + +local tiles = {} +-- '#' will be replaced by the stage number +-- '{power}' will be replaced by the power PNG +tiles.pas = { + -- up, down, right, left, back, front + "techage_filling_ta#.png^techage_appl_autocrafter.png^techage_frame_ta#_top.png", + "techage_filling_ta#.png^techage_frame_ta#.png", + "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_outp.png", + "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_inp.png", + "techage_filling_ta#.png^techage_appl_autocrafter.png^techage_frame_ta#.png", + "techage_filling_ta#.png^techage_appl_autocrafter.png^techage_frame_ta#.png", +} +tiles.act = { + -- up, down, right, left, back, front + { + image = "techage_filling4_ta#.png^techage_appl_autocrafter4.png^techage_frame4_ta#_top.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.5, + }, + }, + "techage_filling_ta#.png^techage_frame_ta#.png", + "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_outp.png", + "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_inp.png", + { + image = "techage_filling4_ta#.png^techage_appl_autocrafter4.png^techage_frame4_ta#.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.5, + }, + }, + { + image = "techage_filling4_ta#.png^techage_appl_autocrafter4.png^techage_frame4_ta#.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.5, + }, + }, +} +tiles.def = { + -- up, down, right, left, back, front + "techage_filling_ta#.png^techage_appl_autocrafter.png^techage_frame_ta#_top.png", + "techage_filling_ta#.png^techage_frame_ta#.png", + "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_outp.png^techage_appl_defect.png", + "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_inp.png^techage_appl_defect.png", + "techage_filling_ta#.png^techage_appl_autocrafter.png^techage_frame_ta#.png^techage_appl_defect.png", + "techage_filling_ta#.png^techage_appl_autocrafter.png^techage_frame_ta#.png^techage_appl_defect.png", +} + +local tubing = { + on_pull_item = function(pos, in_dir, num) + local meta = minetest.get_meta(pos) + if meta:get_int("pull_dir") == in_dir then + local inv = M(pos):get_inventory() + return techage.get_items(inv, "dst", num) + end + end, + on_push_item = function(pos, in_dir, stack) + local meta = minetest.get_meta(pos) + if meta:get_int("push_dir") == in_dir or in_dir == 5 then + local inv = M(pos):get_inventory() + return techage.put_items(inv, "src", stack) + end + end, + on_unpull_item = function(pos, in_dir, stack) + local meta = minetest.get_meta(pos) + if meta:get_int("pull_dir") == in_dir then + local inv = M(pos):get_inventory() + return techage.put_items(inv, "dst", stack) + end + end, + on_recv_message = function(pos, topic, payload) + local resp = TRD(pos).State:on_receive_message(pos, topic, payload) + if resp then + return resp + else + return "unsupported" + end + end, + on_node_load = function(pos) + TRD(pos).State:on_node_load(pos) + end, + on_node_repair = function(pos) + return TRD(pos).State:on_node_repair(pos) + end, +} + +local node_name_ta2, node_name_ta3, node_name_ta4 = + techage.register_consumer("autocrafter", I("Autocrafter"), tiles, { + drawtype = "normal", + cycle_time = CYCLE_TIME, + standby_ticks = STANDBY_TICKS, + has_item_meter = true, + aging_factor = 10, + formspec = formspec, + tubing = tubing, + after_place_node = function(pos, placer) + local inv = M(pos):get_inventory() + inv:set_size("src", 2*8) + inv:set_size("recipe", 3*3) + inv:set_size("dst", 3*3) + inv:set_size("output", 1) + end, + can_dig = can_dig, + node_timer = keep_running, + on_receive_fields = on_receive_fields, + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, + groups = {choppy=2, cracky=2, crumbly=2}, + sounds = default.node_sound_wood_defaults(), + num_items = {0,1,2,4}, + power_consumption = {0,2,3,4}, + }) + +minetest.register_craft({ + output = node_name_ta2, + recipe = { + {"group:wood", "default:diamond", "group:wood"}, + {"techage:tubeS", "basic_materials:gear_steel", "techage:tubeS"}, + {"group:wood", "techage:iron_ingot", "group:wood"}, + }, +}) diff --git a/basic_machines/basalt.lua b/basic_machines/basalt.lua new file mode 100644 index 0000000..f61c5a4 --- /dev/null +++ b/basic_machines/basalt.lua @@ -0,0 +1,85 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + Basalt as result from the lava/water generator + +]]-- + + +-- Replace default:stone with techage:basalt which is less valuable for ore generation. +default.cool_lava = function(pos, node) + if node.name == "default:lava_source" then + minetest.set_node(pos, {name = "default:obsidian"}) + else -- Lava flowing + minetest.set_node(pos, {name = "techage:basalt_stone"}) + end + minetest.sound_play("default_cool_lava", + {pos = pos, max_hear_distance = 16, gain = 0.25}) +end + +minetest.register_node("techage:basalt_stone", { + description = "Basalt Stone", + tiles = {"default_stone.png^[brighten"}, + groups = {cracky = 3, stone = 1}, + drop = "default:silver_sand", + sounds = default.node_sound_stone_defaults(), +}) +minetest.register_node("techage:basalt_stone_brick", { + description = "Basalt Stone Brick", + paramtype2 = "facedir", + place_param2 = 0, + tiles = {"default_stone_brick.png^[brighten"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("techage:basalt_stone_block", { + description = "Basalt Stone Block", + tiles = {"default_stone_block.png^[brighten"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("techage:basalt_gravel", { + description = "Basalt Gravel", + tiles = {"default_gravel.png^[brighten"}, + groups = {crumbly = 2, falling_node = 1}, + sounds = default.node_sound_gravel_defaults(), +}) + +minetest.register_node("techage:sieved_basalt_gravel", { + description = "Sieved Basalt Gravel", + tiles = {"default_gravel.png^[brighten"}, + groups = {crumbly = 2, falling_node = 1, not_in_creative_inventory=1}, + sounds = default.node_sound_gravel_defaults(), +}) + +minetest.register_craft({ + output = "techage:basalt_stone_brick 4", + recipe = { + {"techage:basalt_stone", "techage:basalt_stone"}, + {"techage:basalt_stone", "techage:basalt_stone"}, + } +}) + +minetest.register_craft({ + output = "techage:basalt_stone_block 9", + recipe = { + {"techage:basalt_stone", "techage:basalt_stone", "techage:basalt_stone"}, + {"techage:basalt_stone", "techage:basalt_stone", "techage:basalt_stone"}, + {"techage:basalt_stone", "techage:basalt_stone", "techage:basalt_stone"}, + } +}) + +techage.add_grinder_recipe({input="techage:basalt_stone", output="techage:basalt_gravel"}) +techage.add_grinder_recipe({input="techage:basalt_gravel", output="default:clay"}) +techage.add_grinder_recipe({input="techage:sieved_basalt_gravel", output="default:clay"}) diff --git a/basic_machines/blackhole.lua b/basic_machines/blackhole.lua new file mode 100644 index 0000000..f99fff2 --- /dev/null +++ b/basic_machines/blackhole.lua @@ -0,0 +1,65 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + The autocrafter is derived from pipeworks: + Copyright (C) 2004 Sam Hocevar WTFPL + + All items disappear. + +]]-- + +minetest.register_node("techage:blackhole", { + description = "Techage Black Hole", + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta3.png^techage_frame_ta3.png", + "techage_filling_ta3.png^techage_frame_ta3.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_blackhole.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_blackhole.png^techage_appl_inp.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_blackhole.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_blackhole.png", + }, + + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + local node = minetest.get_node(pos) + meta:set_int("push_dir", techage.side_to_indir("L", node.param2)) + meta:set_string("infotext","Techage Black Hole (let items disappear)") + end, + + on_rotate = screwdriver.disallow, + paramtype2 = "facedir", + groups = {choppy=2, cracky=2, crumbly=2}, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), +}) + + + +minetest.register_craft({ + output = "techage:blackhole", + recipe = { + {"group:wood", "", "group:wood"}, + {"tubelib:tubeS", "default:coal_lump", ""}, + {"group:wood", "", "group:wood"}, + }, +}) + +techage.register_node("techage:blackhole", {}, { + on_pull_item = nil, -- not needed + on_unpull_item = nil, -- not needed + + on_push_item = function(pos, in_dir, stack) + local meta = minetest.get_meta(pos) + if meta:get_int("push_dir") == in_dir then + return true + end + end, +}) diff --git a/basic_machines/forceload.lua b/basic_machines/forceload.lua new file mode 100644 index 0000000..0f214bb --- /dev/null +++ b/basic_machines/forceload.lua @@ -0,0 +1,218 @@ +--[[ + + Tube Library + ============ + + Copyright (C) 2017-2019 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + forceload.lua: + +]]-- + +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta + +local function calc_area(pos) + local xpos = (math.floor(pos.x / 16) * 16) + local ypos = (math.floor(pos.y / 16) * 16) + local zpos = (math.floor(pos.z / 16) * 16) + local pos1 = {x=xpos, y=ypos, z=zpos} + local pos2 = {x=xpos+15, y=ypos+15, z=zpos+15} + return pos1, pos2 +end + +local function in_list(list, x) + local pos1 = calc_area(x) + for _,v in ipairs(list) do + local pos2 = calc_area(v) + if vector.equals(pos1, pos2) then return true end + end + return false +end + +local function remove_list_elem(list, x) + local n = nil + for idx, v in ipairs(list) do + if vector.equals(v, x) then + n = idx + break + end + end + if n then + table.remove(list, n) + end + return list +end + +local function chat(player, text) + minetest.chat_send_player(player:get_player_name(), "[Tubelib] "..text) +end + +local function get_node_lvm(pos) + local node = minetest.get_node_or_nil(pos) + if node then + return node + end + local vm = minetest.get_voxel_manip() + local MinEdge, MaxEdge = vm:read_from_map(pos, pos) + local data = vm:get_data() + local param2_data = vm:get_param2_data() + local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge}) + local idx = area:index(pos.x, pos.y, pos.z) + node = { + name = minetest.get_name_from_content_id(data[idx]), + param2 = param2_data[idx] + } + return node +end + +local function add_pos(pos, player) + local lPos = minetest.deserialize(player:get_attribute("tubelib_forceload_blocks")) or {} + if not in_list(lPos, pos) and #lPos < tubelib.max_num_forceload_blocks then + lPos[#lPos+1] = pos + player:set_attribute("tubelib_forceload_blocks", minetest.serialize(lPos)) + return true + end + return false +end + +local function del_pos(pos, player) + local lPos = minetest.deserialize(player:get_attribute("tubelib_forceload_blocks")) or {} + lPos = remove_list_elem(lPos, pos) + player:set_attribute("tubelib_forceload_blocks", minetest.serialize(lPos)) +end + +local function get_pos_list(player) + return minetest.deserialize(player:get_attribute("tubelib_forceload_blocks")) or {} +end + +local function set_pos_list(player, lPos) + player:set_attribute("tubelib_forceload_blocks", minetest.serialize(lPos)) +end + +local function get_data(pos, player) + local pos1, pos2 = calc_area(pos) + local num = #minetest.deserialize(player:get_attribute("tubelib_forceload_blocks")) or 0 + local max = tubelib.max_num_forceload_blocks + return pos1, pos2, num, max +end + +local function formspec(player) + local lPos = get_pos_list(player) + local tRes = {} + tRes[1] = "size[7,9]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "label[0,0;List of your Forceload Blocks:]" + + for idx,pos in ipairs(lPos) do + local pos1, pos2 = calc_area(pos) + local ypos = 0.2 + idx * 0.4 + tRes[#tRes+1] = "label[0,"..ypos..";"..idx.."]" + tRes[#tRes+1] = "label[0.8,"..ypos..";"..S(pos1).."]" + tRes[#tRes+1] = "label[3.2,"..ypos..";to]" + tRes[#tRes+1] = "label[4,"..ypos..";"..S(pos2).."]" + end + return table.concat(tRes) +end + + +minetest.register_node("tubelib:forceload", { + description = "Tubelib Forceload Block", + tiles = { + -- up, down, right, left, back, front + 'tubelib_front.png', + 'tubelib_front.png', + { + image = "tubelib_forceload.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.5, + }, + }, + }, + + after_place_node = function(pos, placer, itemstack) + if add_pos(pos, placer) then + minetest.forceload_block(pos, true) + local pos1, pos2, num, max = get_data(pos, placer) + M(pos):set_string("infotext", "Area "..S(pos1).." to "..S(pos2).." loaded!\n".. + "Punch the block to make the area visible.") + chat(placer, "Area ("..num.."/"..max..") "..S(pos1).." to "..S(pos2).." loaded!") + tubelib.mark_region(placer:get_player_name(), pos1, pos2) + M(pos):set_string("owner", placer:get_player_name()) + else + chat(placer, "Area already loaded or max. number of Forceload Blocks reached!") + minetest.remove_node(pos) + return itemstack + end + end, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + local player = minetest.get_player_by_name(oldmetadata.fields.owner) + if player then + del_pos(pos, player) + end + minetest.forceload_free_block(pos, true) + tubelib.unmark_region(oldmetadata.fields.owner) + end, + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if M(pos):get_string("owner") == clicker:get_player_name() or + minetest.check_player_privs(clicker:get_player_name(), "server") then + local s = formspec(clicker) + minetest.show_formspec(clicker:get_player_name(), "tubelib:forceload", s) + end + end, + + on_punch = function(pos, node, puncher, pointed_thing) + local pos1, pos2 = calc_area(pos) + tubelib.switch_region(puncher:get_player_name(), pos1, pos2) + end, + + paramtype = "light", + sunlight_propagates = true, + groups = {choppy=2, cracky=2, crumbly=2, + not_in_creative_inventory = tubelib.max_num_forceload_blocks == 0 and 1 or 0}, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), +}) + + +if tubelib.max_num_forceload_blocks > 0 then + minetest.register_craft({ + output = "tubelib:forceload", + recipe = { + {"group:wood", "", "group:wood"}, + {"", "basic_materials:energy_crystal_simple", ""}, + {"group:wood", "tubelib:wlanchip", "group:wood"}, + }, + }) +end + +minetest.register_on_joinplayer(function(player) + local lPos = {} + for _,pos in ipairs(get_pos_list(player)) do + local node = get_node_lvm(pos) + if node.name == "tubelib:forceload" then + minetest.forceload_block(pos, true) + lPos[#lPos+1] = pos + end + end + set_pos_list(player, lPos) +end) + +minetest.register_on_leaveplayer(function(player) + for _,pos in ipairs(get_pos_list(player)) do + minetest.forceload_free_block(pos, true) + end +end) diff --git a/basic_machines/gravelsieve.lua b/basic_machines/gravelsieve.lua index c6db90b..cb57faa 100644 --- a/basic_machines/gravelsieve.lua +++ b/basic_machines/gravelsieve.lua @@ -76,41 +76,47 @@ end -- determine ore based on the calculated probability -local function get_random_ore() +local function get_random_gravel_ore() for ore, probability in pairs(techage.ore_probability) do if math.random(probability) == 1 then - local item = ItemStack(ore) - return item + return ItemStack(ore) end end + if math.random(2) == 1 then + return ItemStack("default:gravel") + else + return ItemStack("techage:sieved_gravel") + end +end + +local function get_random_basalt_ore() + if math.random(40) == 1 then + return ItemStack("default:coal_lump") + elseif math.random(40) == 1 then + return ItemStack("default:iron_lump") + elseif math.random(2) == 1 then + return ItemStack("techage:basalt_gravel") + else + return ItemStack("techage:sieved_basalt_gravel") + end end local function sieving(pos, trd, mem, inv) - local gravel = ItemStack("default:gravel") - - if not inv:contains_item("src", gravel) then + local src, dst + if inv:contains_item("src", ItemStack("techage:basalt_gravel")) then + dst, src = get_random_basalt_ore(), ItemStack("techage:basalt_gravel") + elseif inv:contains_item("src", ItemStack("default:gravel")) then + dst, src = get_random_gravel_ore(), ItemStack("default:gravel") + else trd.State:idle(pos, mem) return end - - local dst = get_random_ore() - if not dst then - -- move gravel or sieved gravel to dst - mem.gravel_cnt = (mem.gravel_cnt or 0) + 1 - if (mem.gravel_cnt % 2) == 0 then - dst = gravel - else - dst = ItemStack("techage:sieved_gravel") - end - end if not inv:room_for_item("dst", dst) then - --trd.State:blocked(pos, mem) trd.State:idle(pos, mem) return end - inv:add_item("dst", dst) - inv:remove_item("src", gravel) + inv:remove_item("src", src) trd.State:keep_running(pos, mem, COUNTDOWN_TICKS) end diff --git a/basic_machines/grinder.lua b/basic_machines/grinder.lua index bd6a496..7854256 100644 --- a/basic_machines/grinder.lua +++ b/basic_machines/grinder.lua @@ -283,9 +283,8 @@ techage.add_grinder_recipe({input="default:cobble", output="default:gravel"}) techage.add_grinder_recipe({input="default:desert_cobble", output="default:gravel"}) techage.add_grinder_recipe({input="default:mossycobble", output="default:gravel"}) techage.add_grinder_recipe({input="default:gravel", output="default:sand"}) -techage.add_grinder_recipe({input="gravelsieve:sieved_gravel", output="default:sand"}) +techage.add_grinder_recipe({input="techage:sieved_gravel", output="default:sand"}) techage.add_grinder_recipe({input="default:coral_skeleton", output="default:silver_sand"}) -techage.add_grinder_recipe({input="tubelib:basalt_stone", output="default:silver_sand"}) if minetest.global_exists("skytest") then techage.add_grinder_recipe({input="default:desert_sand", output="skytest:dust"}) diff --git a/basic_machines/mark.lua b/basic_machines/mark.lua new file mode 100644 index 0000000..73328db --- /dev/null +++ b/basic_machines/mark.lua @@ -0,0 +1,93 @@ +--[[ + + Tube Library + ============ + + Copyright (C) 2019 Joachim Stolberg + Code derived from wordedit (sfan5, Anthony Zhang (Uberi/Temperest), and Brett O'Donnell (cornernote)) + + LGPLv2.1+ + See LICENSE.txt for more information + + mark.lua: + +]]-- + +local marker_region = {} + +function tubelib.unmark_region(name) + if marker_region[name] ~= nil then --marker already exists + --wip: make the area stay loaded somehow + for _, entity in ipairs(marker_region[name]) do + entity:remove() + end + marker_region[name] = nil + end +end + +function tubelib.mark_region(name, pos1, pos2) + + tubelib.unmark_region(name) + + local thickness = 0.2 + local sizex, sizey, sizez = (1 + pos2.x - pos1.x) / 2, (1 + pos2.y - pos1.y) / 2, (1 + pos2.z - pos1.z) / 2 + local markers = {} + + --XY plane markers + for _, z in ipairs({pos1.z - 0.5, pos2.z + 0.5}) do + local marker = minetest.add_entity({x=pos1.x + sizex - 0.5, y=pos1.y + sizey - 0.5, z=z}, "tubelib:region_cube") + if marker ~= nil then + marker:set_properties({ + visual_size={x=sizex * 2, y=sizey * 2}, + collisionbox = {-sizex, -sizey, -thickness, sizex, sizey, thickness}, + }) + marker:get_luaentity().player_name = name + table.insert(markers, marker) + end + end + + --YZ plane markers + for _, x in ipairs({pos1.x - 0.5, pos2.x + 0.5}) do + local marker = minetest.add_entity({x=x, y=pos1.y + sizey - 0.5, z=pos1.z + sizez - 0.5}, "tubelib:region_cube") + if marker ~= nil then + marker:set_properties({ + visual_size={x=sizez * 2, y=sizey * 2}, + collisionbox = {-thickness, -sizey, -sizez, thickness, sizey, sizez}, + }) + marker:setyaw(math.pi / 2) + marker:get_luaentity().player_name = name + table.insert(markers, marker) + end + end + + marker_region[name] = markers +end + +function tubelib.switch_region(name, pos1, pos2) + if marker_region[name] ~= nil then --marker already exists + tubelib.unmark_region(name) + else + tubelib.mark_region(name, pos1, pos2) + end +end + +minetest.register_entity(":tubelib:region_cube", { + initial_properties = { + visual = "upright_sprite", + visual_size = {x=1.1, y=1.1}, + textures = {"tubelib_cube.png"}, + use_texture_alpha = true, + visual_size = {x=10, y=10}, + physical = false, + }, + on_step = function(self, dtime) + if marker_region[self.player_name] == nil then + self.object:remove() + return + end + end, + on_punch = function(self, hitter) + tubelib.unmark_region(self.player_name) + end, +}) + diff --git a/basic_machines/pusher.lua b/basic_machines/pusher.lua index 3490f53..5af0531 100644 --- a/basic_machines/pusher.lua +++ b/basic_machines/pusher.lua @@ -42,7 +42,7 @@ local function pushing(pos, trd, meta, mem) local push_dir = meta:get_int("push_dir") local items = techage.pull_items(pos, pull_dir, trd.num_items) if items ~= nil then - if techage.push_items(pos, push_dir, items) == false then + if techage.push_items(pos, push_dir, items) ~= true then -- place item back techage.unpull_items(pos, pull_dir, items) trd.State:blocked(pos, mem) diff --git a/basis/junction.lua b/basis/junction.lua index 3691ae7..143551d 100644 --- a/basis/junction.lua +++ b/basis/junction.lua @@ -63,11 +63,13 @@ function techage.register_junction(name, size, boxes, network, node) node.is_ground_content = false node.drop = name.."0" - minetest.register_node(name..idx, node) + minetest.register_node(name..idx, table.copy(node)) network:add_secondary_node_names({name..idx}) end end + + function techage.junction_type(conn) local val = 0 for idx = 1,6 do diff --git a/basis/lib.lua b/basis/lib.lua index 34c6377..07b1d2d 100644 --- a/basis/lib.lua +++ b/basis/lib.lua @@ -1,3 +1,26 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + Helper functions + +]]-- + +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta + +-- Load support for intllib. +local MP = minetest.get_modpath("techage") +local I,_ = dofile(MP.."/intllib.lua") + function techage.range(val, min, max) val = tonumber(val) if val < min then return min end @@ -12,3 +35,22 @@ function techage.one_of(val, selection) return selection[1] end +-- +-- Functions used to hide electric cable and biogas pipes +-- +-- Overridden method of tubelib2! +function techage.get_primary_node_param2(pos, dir) + local npos = vector.add(pos, tubelib2.Dir6dToVector[dir or 0]) + local param2 = M(npos):get_int("tl2_param2") + if param2 ~= 0 then + return param2, npos + end +end + +-- Overridden method of tubelib2! +function techage.is_primary_node(pos, dir) + local npos = vector.add(pos, tubelib2.Dir6dToVector[dir or 0]) + local param2 = M(npos):get_int("tl2_param2") + return param2 ~= 0 +end + diff --git a/init.lua b/init.lua index 43b3553..01ca74f 100644 --- a/init.lua +++ b/init.lua @@ -25,13 +25,16 @@ else dofile(MP.."/basis/guide.lua") -- construction guide dofile(MP.."/basis/power.lua") -- power distribution dofile(MP.."/basis/node_states.lua") -- state model - dofile(MP.."/basis/trowel.lua") -- hidden networks dofile(MP.."/basis/junction.lua") -- network junction box dofile(MP.."/basis/tubes.lua") -- tubelib replacement dofile(MP.."/basis/command.lua") -- tubelib replacement dofile(MP.."/basis/consumer.lua") -- consumer base model dofile(MP.."/basis/firebox.lua") -- common firebox functions - + + -- Tools + dofile(MP.."/tools/trowel.lua") + --dofile(MP.."/tools/repairkit.lua") + -- Power networks dofile(MP.."/power/drive_axle.lua") dofile(MP.."/power/steam_pipe.lua") @@ -62,15 +65,19 @@ else dofile(MP.."/steam_engine/flywheel.lua") dofile(MP.."/steam_engine/gearbox.lua") dofile(MP.."/steam_engine/consumer.lua") - dofile(MP.."/steam_engine/battery.lua") -- Basic Machines dofile(MP.."/basic_machines/pusher.lua") + dofile(MP.."/basic_machines/blackhole.lua") dofile(MP.."/basic_machines/legacy_nodes.lua") dofile(MP.."/basic_machines/grinder.lua") dofile(MP.."/basic_machines/distributor.lua") dofile(MP.."/basic_machines/gravelsieve.lua") dofile(MP.."/basic_machines/chest.lua") + dofile(MP.."/basic_machines/autocrafter.lua") + if techage.basalt_stone_enabled then + dofile(MP.."/basic_machines/basalt.lua") + end -- Coal power station dofile(MP.."/coal_power_station/firebox.lua") @@ -82,8 +89,9 @@ else + dofile(MP.."/test/battery.lua") --dofile(MP.."/test/test.lua") - --dofile(MP.."/test/generator.lua") + dofile(MP.."/test/generator.lua") --dofile(MP.."/test/consumer.lua") diff --git a/iron_age/hammer.lua b/iron_age/hammer.lua index 62a12a6..80fc415 100644 --- a/iron_age/hammer.lua +++ b/iron_age/hammer.lua @@ -38,7 +38,7 @@ minetest.register_tool("techage:hammer_bronze", { full_punch_interval = 1.0, max_drop_level=1, groupcaps={ - cracky = {times={[1]=5.00, [2]=2.0, [3]=1.0}, uses=30, maxlevel=2}, + cracky = {times={[1]=5.00, [2]=2.0, [3]=1.0}, uses=50, maxlevel=2}, }, damage_groups = {fleshy=4}, }, @@ -57,7 +57,7 @@ minetest.register_tool("techage:hammer_steel", { full_punch_interval = 1.0, max_drop_level=1, groupcaps={ - cracky = {times={[1]=4.00, [2]=1.60, [3]=0.80}, uses=30, maxlevel=2}, + cracky = {times={[1]=4.00, [2]=1.60, [3]=0.80}, uses=60, maxlevel=2}, }, damage_groups = {fleshy=4}, }, @@ -76,7 +76,7 @@ minetest.register_tool("techage:hammer_mese", { full_punch_interval = 0.9, max_drop_level=3, groupcaps={ - cracky = {times={[1]=2.4, [2]=1.2, [3]=0.60}, uses=40, maxlevel=3}, + cracky = {times={[1]=2.4, [2]=1.2, [3]=0.60}, uses=80, maxlevel=3}, }, damage_groups = {fleshy=5}, }, @@ -95,7 +95,7 @@ minetest.register_tool("techage:hammer_diamond", { full_punch_interval = 0.9, max_drop_level=3, groupcaps={ - cracky = {times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=40, maxlevel=3}, + cracky = {times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=100, maxlevel=3}, }, damage_groups = {fleshy=5}, }, @@ -108,7 +108,7 @@ minetest.register_tool("techage:hammer_diamond", { }) minetest.register_craft({ - output = "techage:hammer_bronze", + output = "techage:hammer_bronze 2", recipe = { {"default:bronze_ingot", "group:stick", "default:bronze_ingot"}, {"default:bronze_ingot", "group:stick", "default:bronze_ingot"}, @@ -116,7 +116,7 @@ minetest.register_craft({ } }) minetest.register_craft({ - output = "techage:hammer_steel", + output = "techage:hammer_steel 2", recipe = { {"default:steel_ingot", "group:stick", "default:steel_ingot"}, {"default:steel_ingot", "group:stick", "default:steel_ingot"}, @@ -124,7 +124,7 @@ minetest.register_craft({ } }) minetest.register_craft({ - output = "techage:hammer_mese", + output = "techage:hammer_mese 2", recipe = { {"default:mese_crystal", "group:stick", "default:mese_crystal"}, {"default:mese_crystal", "group:stick", "default:mese_crystal"}, @@ -132,7 +132,7 @@ minetest.register_craft({ } }) minetest.register_craft({ - output = "techage:hammer_diamond", + output = "techage:hammer_diamond 2", recipe = { {"default:diamond", "group:stick", "default:diamond"}, {"default:diamond", "group:stick", "default:diamond"}, diff --git a/iron_age/recipes.lua b/iron_age/recipes.lua index 4bf4416..9591eb3 100644 --- a/iron_age/recipes.lua +++ b/iron_age/recipes.lua @@ -26,13 +26,6 @@ techage.ironage_register_recipe({ time = 8, }) -techage.ironage_register_recipe({ - output = "default:clay", - recipe = {"techage:sieved_gravel"}, - heat = 3, - time = 3, -}) - techage.ironage_register_recipe({ output = "techage:iron_ingot", recipe = {"default:iron_lump"}, diff --git a/power/electric_cable.lua b/power/electric_cable.lua index 65523b4..09c20fc 100644 --- a/power/electric_cable.lua +++ b/power/electric_cable.lua @@ -21,7 +21,6 @@ local M = minetest.get_meta local MP = minetest.get_modpath("techage") local I,_ = dofile(MP.."/intllib.lua") - local Cable = tubelib2.Tube:new({ dirs_to_check = {1,2,3,4,5,6}, max_tube_length = 1000, @@ -128,7 +127,8 @@ minetest.register_node("techage:electric_cableA", { paramtype = "light", sunlight_propagates = true, is_ground_content = false, - groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, techage_trowel = 1}, + groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, + techage_trowel = 1, not_in_creative_inventory = 1}, sounds = default.node_sound_defaults(), drop = "techage:electric_cableS", }) @@ -148,17 +148,13 @@ local Boxes = { } techage.register_junction("techage:electric_junction", 2/8, Boxes, techage.ElectricCable, { - description = "Electricity Junction Box", + description = I("TA4 Electricity Junction Box"), tiles = {"techage_electric_junction.png"}, groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, techage_trowel = 1}, sounds = default.node_sound_defaults(), techage = { power_network = techage.ElectricCable, }, - description = "Electricity Junction Box", - tiles = {"techage_electric_junction.png"}, - groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, techage_trowel = 1}, - sounds = default.node_sound_defaults(), after_place_node = distributor.after_place_node, after_dig_node = distributor.after_dig_node, diff --git a/sounds/techage_steamengine.ogg b/sounds/techage_steamengine.ogg index ad98cd90052536a19281c87f7a643fc31df49bbf..649a3de5202327c4a20a9d746f37ad265f2505be 100644 GIT binary patch delta 8917 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 CPX1&7 delta 7353 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 Ar~m)} diff --git a/steam_engine/cylinder.lua b/steam_engine/cylinder.lua index ed4b022..6cec750 100644 --- a/steam_engine/cylinder.lua +++ b/steam_engine/cylinder.lua @@ -53,19 +53,10 @@ local function start_cylinder(pos, on) if on and mem.running then consumer.turn_power_on(pos, POWER_CONSUMPTION) swap_node(pos, "techage:cylinder_on") - mem.handle = minetest.sound_play("techage_steamengine", { - pos = pos, - max_hear_distance = 4, - gain = 0.7, - loop = true}) return true else consumer.turn_power_on(pos, 0) swap_node(pos, "techage:cylinder") - if mem.handle then - minetest.sound_stop(mem.handle) - mem.handle = nil - end end return false end @@ -164,18 +155,3 @@ minetest.register_craft({ {"default:wood", "techage:iron_ingot", "basic_materials:steel_bar"}, }, }) - -minetest.register_lbm({ - label = "[techage] Steam engine sound", - name = "techage:steam_engine", - nodenames = {"techage:cylinder_on"}, - run_at_every_load = true, - action = function(pos, node) - local mem = tubelib2.get_mem(pos) - mem.handle = minetest.sound_play("techage_steamengine", { - pos = pos, - max_hear_distance = 4, - gain = 0.7, - loop = true}) - end -}) diff --git a/steam_engine/flywheel.lua b/steam_engine/flywheel.lua index 774a44c..f4f1d7e 100644 --- a/steam_engine/flywheel.lua +++ b/steam_engine/flywheel.lua @@ -56,13 +56,28 @@ local function can_start(pos, mem, state) return start_cylinder(pos, true) end +local function play_sound(pos) + local mem = tubelib2.get_mem(pos) + mem.handle = minetest.sound_play("techage_steamengine", { + pos = pos, + gain = 0.5, + max_hear_distance = 10}) + minetest.after(2, play_sound, pos) +end + local function start_node(pos, mem, state) + print("start_node") generator.turn_power_on(pos, POWER_CAPACITY) + play_sound(pos) end local function stop_node(pos, mem, state) start_cylinder(pos, false) generator.turn_power_on(pos, 0) + if mem.handle then + minetest.sound_stop(mem.handle) + mem.handle = nil + end end local State = techage.NodeStates:new({ @@ -248,3 +263,14 @@ minetest.register_craft({ {"default:wood", "techage:iron_ingot", "basic_materials:steel_bar"}, }, }) + +minetest.register_lbm({ + label = "[techage] Steam engine sound", + name = "techage:steam_engine", + nodenames = {"techage:flywheel_on"}, + run_at_every_load = true, + action = function(pos, node) + play_sound(pos) + end +}) + diff --git a/steam_engine/battery.lua b/test/battery.lua similarity index 100% rename from steam_engine/battery.lua rename to test/battery.lua diff --git a/electric/consumer.lua b/test/consumer.lua similarity index 100% rename from electric/consumer.lua rename to test/consumer.lua diff --git a/electric/generator.lua b/test/generator.lua similarity index 100% rename from electric/generator.lua rename to test/generator.lua diff --git a/basic_machines/perf_test.lua b/test/perf_test.lua similarity index 100% rename from basic_machines/perf_test.lua rename to test/perf_test.lua diff --git a/electric/test.lua b/test/test.lua similarity index 100% rename from electric/test.lua rename to test/test.lua diff --git a/textures/techage_appl_autocrafter.png b/textures/techage_appl_autocrafter.png new file mode 100644 index 0000000000000000000000000000000000000000..763e7bcaf92e37db95c0a6e76960a0d58f136bb5 GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&pI^MTSpCY;~DOE>Ni2)5S3);&8G}^*5cv4oqrojBJbf zBuWpgV2JfVH&w|^(=jA5L~c#`DCC7XMsm# zF#`j)FbFd;%$g$s6l5>)^mS!_%p$`l&;2;Iyqtl7QP9)HF{I+w+u62!O%4KX>Am6~ z)Z`kDTr0jIrKRovkTa)qZn}ZuN1-wmv#u`tMC&yRj5ZyTGJ4{>JznG9CjAZ8jKLzU zC6UZ8cL2?ANW9B>P$lE*f{yZynXC#*Lg$=4FK>}@pMAnIyO#abrk$dK6Q9iZGv{U5 zf;IleMQ8U-U0E%us3@caL=X3?n#|z_8Ug|h{~Egf9Y`{pdfRmMvDa_!S$^Kf^8ED5 z!e!OrZ>pc|>Pz$JXaS_@n8HysBZjKknJG!mk}uQfY-szopr0749k AwEzGB literal 0 HcmV?d00001 diff --git a/textures/techage_appl_blackhole.png b/textures/techage_appl_blackhole.png new file mode 100644 index 0000000000000000000000000000000000000000..b85a201ffbaa67893d28001c715e16185a6c8abd GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&pI^MTXy6@SP~@9H5Yer;B4q#NoHs9R(R2IG8sU{ad@R zbMnFF5XZD%w_d%=d6!zrFf}Cxs1gbac5`oeSb2bbjx8Iv_gPs_kg%t#pUXO@geCwy C1TYQ& literal 0 HcmV?d00001 diff --git a/tools/repairkit.lua b/tools/repairkit.lua new file mode 100644 index 0000000..4aba31e --- /dev/null +++ b/tools/repairkit.lua @@ -0,0 +1,92 @@ +--[[ + + Tube Library + ============ + + Copyright (C) 2017-2018 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + repairkit.lua: +]]-- + +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta + +local function destroy_node(itemstack, placer, pointed_thing) + if pointed_thing.type == "node" then + local pos = pointed_thing.under + if not minetest.is_protected(pos, placer:get_player_name()) then + M(pos):set_int("tubelib_aging", 999999) + end + end +end + +local function repair_node(itemstack, user, pointed_thing) + local pos = pointed_thing.under + if pos then + if tubelib.repair_node(pos) then + minetest.chat_send_player(user:get_player_name(), "[Tubelib] Node repaired") + itemstack:take_item() + return itemstack + end + end + return +end + +local function read_state(itemstack, user, pointed_thing) + local pos = pointed_thing.under + if pos then + local number = tubelib.get_node_number(pos) + if number then + local state = tubelib.send_request(number, "state", nil) + local counter = tubelib.send_request(number, "counter", nil) + local aging = tubelib.send_request(number, "aging", nil) + if state and counter and aging then + if type(counter) ~= "number" then counter = "unknown" end + minetest.chat_send_player(user:get_player_name(), "[Tubelib] state ="..state..", counter = "..counter..", aging = "..aging) + end + end + end +end + +minetest.register_craftitem("tubelib:repairkit", { + description = "Tubelib Repair Kit", + inventory_image = "tubelib_repairkit.png", + wield_image = "tubelib_repairkit.png^[transformR270", + groups = {cracky=1, book=1}, + on_use = repair_node, + node_placement_prediction = "", +}) + + +minetest.register_node("tubelib:end_wrench", { + description = "Tubelib End Wrench (use = read status, place = destroy)", + inventory_image = "tubelib_end_wrench.png", + wield_image = "tubelib_end_wrench.png", + groups = {cracky=1, book=1}, + on_use = read_state, + on_place = destroy_node, + node_placement_prediction = "", +}) + +minetest.register_craft({ + output = "tubelib:repairkit", + recipe = { + {"", "basic_materials:gear_steel", ""}, + {"", "tubelib:end_wrench", ""}, + {"", "basic_materials:oil_extract", ""}, + }, +}) + +minetest.register_craft({ + output = "tubelib:end_wrench 4", + recipe = { + {"", "", "default:steel_ingot"}, + {"", "default:tin_ingot", ""}, + {"default:steel_ingot", "", ""}, + }, +}) diff --git a/basis/trowel.lua b/tools/trowel.lua similarity index 88% rename from basis/trowel.lua rename to tools/trowel.lua index 3553530..8a82e33 100644 --- a/basis/trowel.lua +++ b/tools/trowel.lua @@ -24,22 +24,6 @@ local I,_ = dofile(MP.."/intllib.lua") -- used by other tools: dug_node[player_name] = pos techage.dug_node = {} --- Overridden method of tubelib2! -function techage.get_primary_node_param2(pos, dir) - local npos = vector.add(pos, tubelib2.Dir6dToVector[dir or 0]) - local param2 = M(npos):get_int("tl2_param2") - if param2 ~= 0 then - return param2, npos - end -end - --- Overridden method of tubelib2! -function techage.is_primary_node(pos, dir) - local npos = vector.add(pos, tubelib2.Dir6dToVector[dir or 0]) - local param2 = M(npos):get_int("tl2_param2") - return param2 ~= 0 -end - -- Determine if one node in the surrounding is a hidden tube/cable/pipe local function other_hidden_nodes(pos, node_name) return M({x=pos.x+1, y=pos.y, z=pos.z}):get_string(node_name) ~= "" or @@ -112,6 +96,7 @@ minetest.register_on_dignode(function(pos, oldnode, digger) techage.ElectricCable:after_dig_node(pos, oldnode, digger) techage.BiogasPipe:after_dig_node(pos, oldnode, digger) else + -- store pos for other tools without own 'register_on_dignode' techage.dug_node[digger:get_player_name()] = pos end end)