diff --git a/README.md b/README.md index 1693545..000e45d 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,12 @@ ta4_jetpack requires the modpack 3d_armor. 3d_armor is itself a modpack and can' ### History +#### 2022-01-28 + +Updated Mods: +- techage (fusion reactor added) + + #### 2022-01-04 Updated Mods: diff --git a/autobahn/init.lua b/autobahn/init.lua index 7ae3ce3..6f529ba 100644 --- a/autobahn/init.lua +++ b/autobahn/init.lua @@ -104,7 +104,7 @@ local function control_player(player_name) if player then local pos = player:get_pos() if pos then - --pos.y = math.floor(pos.y) + pos.y = math.floor(pos.y) local node = minetest.get_node(pos) if string.sub(node.name,1,13) == "autobahn:node" then minetest.after(0.5, control_player, player_name) @@ -114,7 +114,13 @@ local function control_player(player_name) if string.sub(node.name,1,13) == "autobahn:node" then minetest.after(0.5, control_player, player_name) else - reset_player_privs(player) + pos.y = pos.y + 2 + node = minetest.get_node(pos) + if string.sub(node.name,1,13) == "autobahn:node" then + minetest.after(0.5, control_player, player_name) + else + reset_player_privs(player) + end end end end diff --git a/basic_materials/.gitmodules b/basic_materials/.gitmodules new file mode 100644 index 0000000..55d4b48 --- /dev/null +++ b/basic_materials/.gitmodules @@ -0,0 +1,3 @@ +[submodule "sound_api_core"] + path = sound_api_core + url = https://github.com/mt-mods/sound_api_core.git diff --git a/basic_materials/.luacheckrc b/basic_materials/.luacheckrc index 55879b0..8f13b09 100644 --- a/basic_materials/.luacheckrc +++ b/basic_materials/.luacheckrc @@ -1,30 +1,7 @@ -std = "lua51+minetest" -unused_args = false -allow_defined_top = true -max_line_length = 999 - -stds.minetest = { - read_globals = { - "DIR_DELIM", - "minetest", - "core", - "dump", - "vector", - "nodeupdate", - "VoxelManip", - "VoxelArea", - "PseudoRandom", - "ItemStack", - "default", - table = { - fields = { - "copy", - }, - }, - } +globals = { + "minetest", "basic_materials", } read_globals = { - "default", - "moreores", -} + "default", +} \ No newline at end of file diff --git a/basic_materials/aliases.lua b/basic_materials/aliases.lua new file mode 100644 index 0000000..30185f4 --- /dev/null +++ b/basic_materials/aliases.lua @@ -0,0 +1,34 @@ +minetest.register_alias("homedecor:plastic_sheeting", "basic_materials:plastic_sheet") +minetest.register_alias("homedecor:plastic_strips", "basic_materials:plastic_strip") +minetest.register_alias("homedecor:empty_spool", "basic_materials:empty_spool") +minetest.register_alias("homedecor:oil_extract", "basic_materials:oil_extract") +minetest.register_alias("homedecor:paraffin", "basic_materials:paraffin") +minetest.register_alias("homedecor:plastic_base", "basic_materials:paraffin") +minetest.register_alias("homedecor:terracotta_base", "basic_materials:terracotta_base") +minetest.register_alias("gloopblocks:wet_cement", "basic_materials:wet_cement") +minetest.register_alias("gloopblocks:cement", "basic_materials:cement_block") +minetest.register_alias("technic:concrete", "basic_materials:concrete_block") +minetest.register_alias("homedecor:ic", "basic_materials:ic") +minetest.register_alias("homedecor:motor", "basic_materials:motor") +minetest.register_alias("technic:motor", "basic_materials:motor") +minetest.register_alias("homedecor:heating_element", "basic_materials:heating_element") +minetest.register_alias("homedecor:power_crystal", "basic_materials:energy_crystal_simple") +minetest.register_alias("homedecor:copper_wire", "basic_materials:copper_wire") +minetest.register_alias("technic:fine_copper_wire", "basic_materials:copper_wire") +minetest.register_alias("technic:fine_silver_wire", "basic_materials:silver_wire") +minetest.register_alias("technic:fine_gold_wire", "basic_materials:gold_wire") +minetest.register_alias("homedecor:steel_wire", "basic_materials:steel_wire") +minetest.register_alias("homedecor:brass_ingot", "basic_materials:brass_ingot") +minetest.register_alias("technic:brass_ingot", "basic_materials:brass_ingot") +minetest.register_alias("technic:brass_block", "basic_materials:brass_block") +minetest.register_alias("homedecor:copper_strip", "basic_materials:copper_strip") +minetest.register_alias("homedecor:steel_strip", "basic_materials:steel_strip") +minetest.register_alias("homedecor:chainlink_brass", "basic_materials:chainlink_brass") +minetest.register_alias("chains:chain", "basic_materials:chain_steel") +minetest.register_alias("chains:chain_brass", "basic_materials:chain_brass") +minetest.register_alias("pipeworks:gear", "basic_materials:gear_steel") +minetest.register_alias("technic:rebar", "basic_materials:steel_bar") + +minetest.register_alias_force("mesecons_materials:silicon", "basic_materials:silicon") +minetest.register_alias_force("glooptest:chainlink", "basic_materials:chainlink_steel") +minetest.register_alias_force("homedecor:chainlink_steel", "basic_materials:chainlink_steel") \ No newline at end of file diff --git a/basic_materials/craftitems.lua b/basic_materials/craftitems.lua new file mode 100644 index 0000000..553a974 --- /dev/null +++ b/basic_materials/craftitems.lua @@ -0,0 +1,130 @@ +local S = minetest.get_translator("basic_materials") + +minetest.register_craftitem("basic_materials:plastic_sheet", { + description = S("Plastic sheet"), + inventory_image = "basic_materials_plastic_sheet.png", +}) + +minetest.register_craftitem("basic_materials:plastic_strip", { + description = S("Plastic strips"), + groups = { strip = 1 }, + inventory_image = "basic_materials_plastic_strip.png", +}) + +minetest.register_craftitem("basic_materials:empty_spool", { + description = S("Empty wire spool"), + inventory_image = "basic_materials_empty_spool.png" +}) + +minetest.register_craftitem("basic_materials:oil_extract", { + description = S("Oil extract"), + inventory_image = "basic_materials_oil_extract.png", +}) + +minetest.register_craftitem("basic_materials:paraffin", { + description = S("Unprocessed paraffin"), + inventory_image = "basic_materials_paraffin.png", +}) + +minetest.register_craftitem("basic_materials:terracotta_base", { + description = S("Uncooked Terracotta Base"), + inventory_image = "basic_materials_terracotta_base.png", +}) + +minetest.register_craftitem("basic_materials:wet_cement", { + description = S("Wet Cement"), + inventory_image = "basic_materials_wet_cement.png", +}) + +minetest.register_craftitem("basic_materials:silicon", { + description = S("Silicon lump"), + inventory_image = "basic_materials_silicon.png", +}) + +minetest.register_craftitem("basic_materials:ic", { + description = S("Simple Integrated Circuit"), + inventory_image = "basic_materials_ic.png", +}) + +minetest.register_craftitem("basic_materials:motor", { + description = S("Simple Motor"), + inventory_image = "basic_materials_motor.png", +}) + +minetest.register_craftitem("basic_materials:heating_element", { + description = S("Heating element"), + inventory_image = "basic_materials_heating_element.png", +}) + +minetest.register_craftitem("basic_materials:energy_crystal_simple", { + description = S("Simple energy crystal"), + inventory_image = "basic_materials_energy_crystal.png", +}) + +minetest.register_craftitem("basic_materials:steel_wire", { + description = S("Spool of steel wire"), + groups = { wire = 1 }, + inventory_image = "basic_materials_steel_wire.png" +}) + +minetest.register_craftitem("basic_materials:copper_wire", { + description = S("Spool of copper wire"), + groups = { wire = 1 }, + inventory_image = "basic_materials_copper_wire.png" +}) + +minetest.register_craftitem("basic_materials:silver_wire", { + description = S("Spool of silver wire"), + groups = { wire = 1 }, + inventory_image = "basic_materials_silver_wire.png" +}) + +minetest.register_craftitem("basic_materials:gold_wire", { + description = S("Spool of gold wire"), + groups = { wire = 1 }, + inventory_image = "basic_materials_gold_wire.png" +}) + +minetest.register_craftitem("basic_materials:steel_strip", { + description = S("Steel Strip"), + groups = { strip = 1 }, + inventory_image = "basic_materials_steel_strip.png" +}) + +minetest.register_craftitem("basic_materials:copper_strip", { + description = S("Copper Strip"), + groups = { strip = 1 }, + inventory_image = "basic_materials_copper_strip.png" +}) + +minetest.register_craftitem("basic_materials:steel_bar", { + description = S("Steel Bar"), + inventory_image = "basic_materials_steel_bar.png", +}) + +minetest.register_craftitem("basic_materials:chainlink_brass", { + description = S("Chainlinks (brass)"), + groups = { chainlinks = 1 }, + inventory_image = "basic_materials_chainlink_brass.png" +}) + +minetest.register_craftitem("basic_materials:chainlink_steel", { + description = S("Chainlinks (steel)"), + groups = { chainlinks = 1 }, + inventory_image = "basic_materials_chainlink_steel.png" +}) + +minetest.register_craftitem("basic_materials:brass_ingot", { + description = S("Brass Ingot"), + inventory_image = "basic_materials_brass_ingot.png", +}) + +minetest.register_craftitem("basic_materials:gear_steel", { + description = S("Steel gear"), + inventory_image = "basic_materials_gear_steel.png" +}) + +minetest.register_craftitem("basic_materials:padlock", { + description = S("Padlock"), + inventory_image = "basic_materials_padlock.png" +}) \ No newline at end of file diff --git a/basic_materials/crafts.lua b/basic_materials/crafts.lua new file mode 100644 index 0000000..20e92cb --- /dev/null +++ b/basic_materials/crafts.lua @@ -0,0 +1,303 @@ +--craft recipes +minetest.register_craft({ + output = "basic_materials:chainlink_brass 12", + recipe = { + {"", "basic_materials:brass_ingot", "basic_materials:brass_ingot"}, + { "basic_materials:brass_ingot", "", "basic_materials:brass_ingot" }, + { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "" }, + }, +}) + +minetest.register_craft({ + output = 'basic_materials:chain_steel 2', + recipe = { + {"basic_materials:chainlink_steel"}, + {"basic_materials:chainlink_steel"}, + {"basic_materials:chainlink_steel"} + } +}) + +minetest.register_craft({ + output = 'basic_materials:chain_brass 2', + recipe = { + {"basic_materials:chainlink_brass"}, + {"basic_materials:chainlink_brass"}, + {"basic_materials:chainlink_brass"} + } +}) + +minetest.register_craft( { + type = "shapeless", + output = "basic_materials:brass_ingot 9", + recipe = { "basic_materials:brass_block" }, +}) + +minetest.register_craft( { + output = "basic_materials:brass_block", + recipe = { + { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "basic_materials:brass_ingot" }, + { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "basic_materials:brass_ingot" }, + { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "basic_materials:brass_ingot" }, + }, +}) + +minetest.register_craft( { + output = "basic_materials:plastic_strip 9", + recipe = { + { "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" } + }, +}) + +minetest.register_craft( { + output = "basic_materials:empty_spool 3", + recipe = { + { "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" }, + { "", "basic_materials:plastic_sheet", "" }, + { "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" } + }, +}) + +minetest.register_craft({ + type = "shapeless", + output = "basic_materials:oil_extract 2", + recipe = {"group:leaves", "group:leaves", "group:leaves", "group:leaves", "group:leaves", "group:leaves"} +}) + +--cooking recipes +minetest.register_craft({ + type = "cooking", + output = "basic_materials:plastic_sheet", + recipe = "basic_materials:paraffin", +}) + +minetest.register_craft({ + type = "cooking", + output = "basic_materials:paraffin", + recipe = "basic_materials:oil_extract", +}) + +minetest.register_craft({ + type = "cooking", + output = "basic_materials:cement_block", + recipe = "basic_materials:wet_cement", + cooktime = 8 +}) + +--fuel recipes +minetest.register_craft({ + type = "fuel", + recipe = "basic_materials:plastic_sheet", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "basic_materials:oil_extract", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "basic_materials:paraffin", + burntime = 30, +}) + +if minetest.get_modpath("default") then + minetest.register_craft({ + output = 'basic_materials:concrete_block 6', + recipe = { + {'group:sand', 'basic_materials:wet_cement', 'default:gravel'}, + {'basic_materials:steel_bar', 'basic_materials:wet_cement', 'basic_materials:steel_bar'}, + {'default:gravel', 'basic_materials:wet_cement', 'group:sand'}, + } + }) + + minetest.register_craft( { + output = "basic_materials:motor 2", + recipe = { + { "default:mese_crystal_fragment", "basic_materials:copper_wire", "basic_materials:plastic_sheet" }, + { "default:copper_ingot", "default:steel_ingot", "default:steel_ingot" }, + { "default:mese_crystal_fragment", "basic_materials:copper_wire", "basic_materials:plastic_sheet" } + }, + replacements = { + { "basic_materials:copper_wire", "basic_materials:empty_spool" }, + { "basic_materials:copper_wire", "basic_materials:empty_spool" }, + } + }) + + minetest.register_craft( { + output = "basic_materials:heating_element 2", + recipe = { + { "default:copper_ingot", "default:mese_crystal_fragment", "default:copper_ingot" } + }, + }) + + minetest.register_craft({ + --type = "shapeless", + output = "basic_materials:energy_crystal_simple 2", + recipe = { + { "default:mese_crystal_fragment", "default:torch", "default:mese_crystal_fragment" }, + { "default:diamond", "default:gold_ingot", "default:diamond" } + }, + }) + + minetest.register_craft( { + output = "basic_materials:copper_wire 2", + type = "shapeless", + recipe = { + "default:copper_ingot", + "basic_materials:empty_spool", + "basic_materials:empty_spool", + }, + }) + + minetest.register_craft( { + output = "basic_materials:gold_wire 2", + type = "shapeless", + recipe = { + "default:gold_ingot", + "basic_materials:empty_spool", + "basic_materials:empty_spool", + }, + }) + + minetest.register_craft( { + output = "basic_materials:steel_wire 2", + type = "shapeless", + recipe = { + "default:steel_ingot", + "basic_materials:empty_spool", + "basic_materials:empty_spool", + }, + }) + + minetest.register_craft( { + output = "basic_materials:steel_strip 12", + recipe = { + { "", "default:steel_ingot", "" }, + { "default:steel_ingot", "", "" }, + }, + }) + + minetest.register_craft( { + output = "basic_materials:copper_strip 12", + recipe = { + { "", "default:copper_ingot", "" }, + { "default:copper_ingot", "", "" }, + }, + }) + + minetest.register_craft( { + output = "basic_materials:steel_bar 6", + recipe = { + { "", "", "default:steel_ingot" }, + { "", "default:steel_ingot", "" }, + { "default:steel_ingot", "", "" }, + }, + }) + + minetest.register_craft( { + output = "basic_materials:padlock 2", + recipe = { + { "basic_materials:steel_bar" }, + { "default:steel_ingot" }, + { "default:steel_ingot" }, + }, + }) + + minetest.register_craft({ + output = "basic_materials:chainlink_steel 12", + recipe = { + {"", "default:steel_ingot", "default:steel_ingot"}, + { "default:steel_ingot", "", "default:steel_ingot" }, + { "default:steel_ingot", "default:steel_ingot", "" }, + }, + }) + + minetest.register_craft( { + output = "basic_materials:gear_steel 6", + recipe = { + { "", "default:steel_ingot", "" }, + { "default:steel_ingot","basic_materials:chainlink_steel", "default:steel_ingot" }, + { "", "default:steel_ingot", "" } + }, + }) + + if minetest.get_modpath("bucket") then + minetest.register_craft( { + type = "shapeless", + output = "basic_materials:terracotta_base 8", + recipe = { + "bucket:bucket_water", + "default:clay_lump", + "default:gravel", + }, + replacements = { {"bucket:bucket_water", "bucket:bucket_empty"}, }, + }) + + if minetest.get_modpath("dye") then + minetest.register_craft({ + type = "shapeless", + output = "basic_materials:wet_cement 3", + recipe = { + "default:dirt", + "dye:dark_grey", + "dye:dark_grey", + "dye:dark_grey", + "bucket:bucket_water" + }, + replacements = {{'bucket:bucket_water', 'bucket:bucket_empty'},}, + }) + end + end + + if minetest.get_modpath("mesecons_materials") then + minetest.register_craft( { + output = "mesecons_materials:silicon 4", + recipe = { + { "default:sand", "default:sand" }, + { "default:sand", "default:steel_ingot" }, + }, + }) + + minetest.register_craft( { + output = "basic_materials:ic 4", + recipe = { + { "mesecons_materials:silicon", "mesecons_materials:silicon" }, + { "mesecons_materials:silicon", "default:copper_ingot" }, + }, + }) + end + + if not minetest.get_modpath("moreores") then + -- Without moreores, there still should be a way to create brass. + minetest.register_craft( { + output = "basic_materials:brass_ingot 9", + recipe = { + {"default:copper_ingot", "default:tin_ingot", "default:copper_ingot"}, + {"default:gold_ingot", "default:copper_ingot", "default:gold_ingot"}, + {"default:copper_ingot", "default:tin_ingot", "default:copper_ingot"}, + }, + }) + elseif minetest.get_modpath("moreores") then + minetest.register_craft( { + output = "basic_materials:silver_wire 2", + type = "shapeless", + recipe = { + "moreores:silver_ingot", + "basic_materials:empty_spool", + "basic_materials:empty_spool", + }, + }) + + minetest.register_craft( { + type = "shapeless", + output = "basic_materials:brass_ingot 3", + recipe = { + "default:copper_ingot", + "default:copper_ingot", + "moreores:silver_ingot", + }, + }) + end +end \ No newline at end of file diff --git a/basic_materials/electrical-electronic.lua b/basic_materials/electrical-electronic.lua deleted file mode 100644 index 91fac4e..0000000 --- a/basic_materials/electrical-electronic.lua +++ /dev/null @@ -1,86 +0,0 @@ --- Translation support -local S = minetest.get_translator("basic_materials") - --- items - -minetest.register_craftitem("basic_materials:silicon", { - description = S("Silicon lump"), - inventory_image = "basic_materials_silicon.png", -}) - -minetest.register_craftitem("basic_materials:ic", { - description = S("Simple Integrated Circuit"), - inventory_image = "basic_materials_ic.png", -}) - -minetest.register_craftitem("basic_materials:motor", { - description = S("Simple Motor"), - inventory_image = "basic_materials_motor.png", -}) - -minetest.register_craftitem("basic_materials:heating_element", { - description = S("Heating element"), - inventory_image = "basic_materials_heating_element.png", -}) - -minetest.register_craftitem("basic_materials:energy_crystal_simple", { - description = S("Simple energy crystal"), - inventory_image = "basic_materials_energy_crystal.png", -}) - --- crafts - -minetest.register_craft( { - output = "mesecons_materials:silicon 4", - recipe = { - { "default:sand", "default:sand" }, - { "default:sand", "default:steel_ingot" }, - }, -}) - -minetest.register_craft( { - output = "basic_materials:ic 4", - recipe = { - { "mesecons_materials:silicon", "mesecons_materials:silicon" }, - { "mesecons_materials:silicon", "default:copper_ingot" }, - }, -}) - -minetest.register_craft( { - output = "basic_materials:motor 2", - recipe = { - { "default:mese_crystal_fragment", "basic_materials:copper_wire", "basic_materials:plastic_sheet" }, - { "default:copper_ingot", "default:steel_ingot", "default:steel_ingot" }, - { "default:mese_crystal_fragment", "basic_materials:copper_wire", "basic_materials:plastic_sheet" } - }, - replacements = { - { "basic_materials:copper_wire", "basic_materials:empty_spool" }, - { "basic_materials:copper_wire", "basic_materials:empty_spool" }, - } -}) - -minetest.register_craft( { - output = "basic_materials:heating_element 2", - recipe = { - { "default:copper_ingot", "default:mese_crystal_fragment", "default:copper_ingot" } - }, -}) - -minetest.register_craft({ - --type = "shapeless", - output = "basic_materials:energy_crystal_simple 2", - recipe = { - { "default:mese_crystal_fragment", "default:torch", "default:mese_crystal_fragment" }, - { "default:diamond", "default:gold_ingot", "default:diamond" } - }, -}) - --- aliases - -minetest.register_alias("homedecor:ic", "basic_materials:ic") -minetest.register_alias("homedecor:motor", "basic_materials:motor") -minetest.register_alias("technic:motor", "basic_materials:motor") -minetest.register_alias("homedecor:heating_element", "basic_materials:heating_element") -minetest.register_alias("homedecor:power_crystal", "basic_materials:energy_crystal_simple") - -minetest.register_alias_force("mesecons_materials:silicon", "basic_materials:silicon") diff --git a/basic_materials/init.lua b/basic_materials/init.lua index 348c059..ad5ea10 100644 --- a/basic_materials/init.lua +++ b/basic_materials/init.lua @@ -4,12 +4,11 @@ -- This mod supplies all those little random craft items that everyone always -- seems to need, such as metal bars (ala rebar), plastic, wire, and so on. -local modpath = minetest.get_modpath("basic_materials") - basic_materials = {} basic_materials.mod = { author = "Vanessa Dannenberg" } +basic_materials.modpath = minetest.get_modpath("basic_materials") -dofile(modpath.."/metals.lua") -dofile(modpath.."/plastics.lua") -dofile(modpath.."/electrical-electronic.lua") -dofile(modpath.."/misc.lua") +dofile(basic_materials.modpath .. "/nodes.lua") +dofile(basic_materials.modpath .. "/craftitems.lua") +dofile(basic_materials.modpath .. "/crafts.lua") +dofile(basic_materials.modpath .. "/aliases.lua") \ No newline at end of file diff --git a/basic_materials/metals.lua b/basic_materials/metals.lua deleted file mode 100644 index 0a3243b..0000000 --- a/basic_materials/metals.lua +++ /dev/null @@ -1,300 +0,0 @@ --- Translation support -local S = minetest.get_translator("basic_materials") - --- items - -minetest.register_craftitem("basic_materials:steel_wire", { - description = S("Spool of steel wire"), - groups = { wire = 1 }, - inventory_image = "basic_materials_steel_wire.png" -}) - -minetest.register_craftitem("basic_materials:copper_wire", { - description = S("Spool of copper wire"), - groups = { wire = 1 }, - inventory_image = "basic_materials_copper_wire.png" -}) - -minetest.register_craftitem("basic_materials:silver_wire", { - description = S("Spool of silver wire"), - groups = { wire = 1 }, - inventory_image = "basic_materials_silver_wire.png" -}) - -minetest.register_craftitem("basic_materials:gold_wire", { - description = S("Spool of gold wire"), - groups = { wire = 1 }, - inventory_image = "basic_materials_gold_wire.png" -}) - -minetest.register_craftitem("basic_materials:steel_strip", { - description = S("Steel Strip"), - groups = { strip = 1 }, - inventory_image = "basic_materials_steel_strip.png" -}) - -minetest.register_craftitem("basic_materials:copper_strip", { - description = S("Copper Strip"), - groups = { strip = 1 }, - inventory_image = "basic_materials_copper_strip.png" -}) - -minetest.register_craftitem("basic_materials:steel_bar", { - description = S("Steel Bar"), - inventory_image = "basic_materials_steel_bar.png", -}) - -minetest.register_craftitem("basic_materials:chainlink_brass", { - description = S("Chainlinks (brass)"), - groups = { chainlinks = 1 }, - inventory_image = "basic_materials_chainlink_brass.png" -}) - -minetest.register_craftitem("basic_materials:chainlink_steel", { - description = S("Chainlinks (steel)"), - groups = { chainlinks = 1 }, - inventory_image = "basic_materials_chainlink_steel.png" -}) - -minetest.register_craftitem("basic_materials:brass_ingot", { - description = S("Brass Ingot"), - inventory_image = "basic_materials_brass_ingot.png", -}) - -minetest.register_craftitem("basic_materials:gear_steel", { - description = S("Steel gear"), - inventory_image = "basic_materials_gear_steel.png" -}) - -minetest.register_craftitem("basic_materials:padlock", { - description = S("Padlock"), - inventory_image = "basic_materials_padlock.png" -}) - --- nodes - -local chains_sbox = { - type = "fixed", - fixed = { -0.1, -0.5, -0.1, 0.1, 0.5, 0.1 } -} - -minetest.register_node("basic_materials:chain_steel", { - description = S("Chain (steel, hanging)"), - drawtype = "mesh", - mesh = "basic_materials_chains.obj", - tiles = {"basic_materials_chain_steel.png"}, - walkable = false, - climbable = true, - sunlight_propagates = true, - paramtype = "light", - inventory_image = "basic_materials_chain_steel_inv.png", - groups = {cracky=3}, - selection_box = chains_sbox, -}) - -minetest.register_node("basic_materials:chain_brass", { - description = S("Chain (brass, hanging)"), - drawtype = "mesh", - mesh = "basic_materials_chains.obj", - tiles = {"basic_materials_chain_brass.png"}, - walkable = false, - climbable = true, - sunlight_propagates = true, - paramtype = "light", - inventory_image = "basic_materials_chain_brass_inv.png", - groups = {cracky=3}, - selection_box = chains_sbox, -}) - -minetest.register_node("basic_materials:brass_block", { - description = S("Brass Block"), - tiles = { "basic_materials_brass_block.png" }, - is_ground_content = false, - groups = {cracky=1, level=2}, - sounds = default.node_sound_metal_defaults() -}) - --- crafts - -minetest.register_craft( { - output = "basic_materials:copper_wire 2", - type = "shapeless", - recipe = { - "default:copper_ingot", - "basic_materials:empty_spool", - "basic_materials:empty_spool", - }, -}) - -minetest.register_craft( { - output = "basic_materials:silver_wire 2", - type = "shapeless", - recipe = { - "moreores:silver_ingot", - "basic_materials:empty_spool", - "basic_materials:empty_spool", - }, -}) - -minetest.register_craft( { - output = "basic_materials:gold_wire 2", - type = "shapeless", - recipe = { - "default:gold_ingot", - "basic_materials:empty_spool", - "basic_materials:empty_spool", - }, -}) - -minetest.register_craft( { - output = "basic_materials:steel_wire 2", - type = "shapeless", - recipe = { - "default:steel_ingot", - "basic_materials:empty_spool", - "basic_materials:empty_spool", - }, -}) - -minetest.register_craft( { - output = "basic_materials:steel_strip 12", - recipe = { - { "", "default:steel_ingot", "" }, - { "default:steel_ingot", "", "" }, - }, -}) - -minetest.register_craft( { - output = "basic_materials:copper_strip 12", - recipe = { - { "", "default:copper_ingot", "" }, - { "default:copper_ingot", "", "" }, - }, -}) - -minetest.register_craft( { - output = "basic_materials:steel_bar 6", - recipe = { - { "", "", "default:steel_ingot" }, - { "", "default:steel_ingot", "" }, - { "default:steel_ingot", "", "" }, - }, -}) - -minetest.register_craft( { - output = "basic_materials:padlock 2", - recipe = { - { "basic_materials:steel_bar" }, - { "default:steel_ingot" }, - { "default:steel_ingot" }, - }, -}) - -minetest.register_craft({ - output = "basic_materials:chainlink_steel 12", - recipe = { - {"", "default:steel_ingot", "default:steel_ingot"}, - { "default:steel_ingot", "", "default:steel_ingot" }, - { "default:steel_ingot", "default:steel_ingot", "" }, - }, -}) - -minetest.register_craft({ - output = "basic_materials:chainlink_brass 12", - recipe = { - {"", "basic_materials:brass_ingot", "basic_materials:brass_ingot"}, - { "basic_materials:brass_ingot", "", "basic_materials:brass_ingot" }, - { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "" }, - }, -}) - -minetest.register_craft({ - output = 'basic_materials:chain_steel 2', - recipe = { - {"basic_materials:chainlink_steel"}, - {"basic_materials:chainlink_steel"}, - {"basic_materials:chainlink_steel"} - } -}) - -minetest.register_craft({ - output = 'basic_materials:chain_brass 2', - recipe = { - {"basic_materials:chainlink_brass"}, - {"basic_materials:chainlink_brass"}, - {"basic_materials:chainlink_brass"} - } -}) - -minetest.register_craft( { - output = "basic_materials:gear_steel 6", - recipe = { - { "", "default:steel_ingot", "" }, - { "default:steel_ingot","basic_materials:chainlink_steel", "default:steel_ingot" }, - { "", "default:steel_ingot", "" } - }, -}) - -minetest.register_craft( { - type = "shapeless", - output = "basic_materials:brass_ingot 3", - recipe = { - "default:copper_ingot", - "default:copper_ingot", - "moreores:silver_ingot", - }, -}) - -if not minetest.get_modpath("moreores") then - -- Without moreores, there still should be a way to create brass. - minetest.register_craft( { - output = "basic_materials:brass_ingot 9", - recipe = { - {"default:copper_ingot", "default:tin_ingot", "default:copper_ingot"}, - {"default:gold_ingot", "default:copper_ingot", "default:gold_ingot"}, - {"default:copper_ingot", "default:tin_ingot", "default:copper_ingot"}, - }, - }) -end - -minetest.register_craft( { - type = "shapeless", - output = "basic_materials:brass_ingot 9", - recipe = { "basic_materials:brass_block" }, -}) - -minetest.register_craft( { - output = "basic_materials:brass_block", - recipe = { - { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "basic_materials:brass_ingot" }, - { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "basic_materials:brass_ingot" }, - { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "basic_materials:brass_ingot" }, - }, -}) - --- aliases - -minetest.register_alias("homedecor:copper_wire", "basic_materials:copper_wire") -minetest.register_alias("technic:fine_copper_wire", "basic_materials:copper_wire") -minetest.register_alias("technic:fine_silver_wire", "basic_materials:silver_wire") -minetest.register_alias("technic:fine_gold_wire", "basic_materials:gold_wire") - -minetest.register_alias("homedecor:steel_wire", "basic_materials:steel_wire") - -minetest.register_alias("homedecor:brass_ingot", "basic_materials:brass_ingot") -minetest.register_alias("technic:brass_ingot", "basic_materials:brass_ingot") -minetest.register_alias("technic:brass_block", "basic_materials:brass_block") - -minetest.register_alias("homedecor:copper_strip", "basic_materials:copper_strip") -minetest.register_alias("homedecor:steel_strip", "basic_materials:steel_strip") - -minetest.register_alias_force("glooptest:chainlink", "basic_materials:chainlink_steel") -minetest.register_alias_force("homedecor:chainlink_steel", "basic_materials:chainlink_steel") -minetest.register_alias("homedecor:chainlink_brass", "basic_materials:chainlink_brass") -minetest.register_alias("chains:chain", "basic_materials:chain_steel") -minetest.register_alias("chains:chain_brass", "basic_materials:chain_brass") - -minetest.register_alias("pipeworks:gear", "basic_materials:gear_steel") - -minetest.register_alias("technic:rebar", "basic_materials:steel_bar") - diff --git a/basic_materials/misc.lua b/basic_materials/misc.lua deleted file mode 100644 index 0012897..0000000 --- a/basic_materials/misc.lua +++ /dev/null @@ -1,126 +0,0 @@ --- Translation support -local S = minetest.get_translator("basic_materials") - --- items - -minetest.register_craftitem("basic_materials:oil_extract", { - description = S("Oil extract"), - inventory_image = "basic_materials_oil_extract.png", -}) - -minetest.register_craftitem("basic_materials:paraffin", { - description = S("Unprocessed paraffin"), - inventory_image = "basic_materials_paraffin.png", -}) - -minetest.register_craftitem("basic_materials:terracotta_base", { - description = S("Uncooked Terracotta Base"), - inventory_image = "basic_materials_terracotta_base.png", -}) - -minetest.register_craftitem("basic_materials:wet_cement", { - description = S("Wet Cement"), - inventory_image = "basic_materials_wet_cement.png", -}) - --- nodes - -minetest.register_node("basic_materials:cement_block", { - description = S("Cement"), - tiles = {"basic_materials_cement_block.png"}, - is_ground_content = true, - groups = {cracky=2}, - sounds = default.node_sound_stone_defaults(), -}) - -minetest.register_node("basic_materials:concrete_block", { - description = S("Concrete Block"), - tiles = {"basic_materials_concrete_block.png",}, - groups = {cracky=1, level=2, concrete=1}, - sounds = default.node_sound_stone_defaults(), -}) - --- crafts - -minetest.register_craft({ - type = "shapeless", - output = "basic_materials:oil_extract 2", - recipe = { - "group:leaves", - "group:leaves", - "group:leaves", - "group:leaves", - "group:leaves", - "group:leaves" - } -}) - -minetest.register_craft({ - type = "cooking", - output = "basic_materials:paraffin", - recipe = "basic_materials:oil_extract", -}) - -minetest.register_craft({ - type = "fuel", - recipe = "basic_materials:oil_extract", - burntime = 30, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "basic_materials:paraffin", - burntime = 30, -}) - -minetest.register_craft( { - type = "shapeless", - output = "basic_materials:terracotta_base 8", - recipe = { - "bucket:bucket_water", - "default:clay_lump", - "default:gravel", - }, - replacements = { {"bucket:bucket_water", "bucket:bucket_empty"}, }, -}) - -minetest.register_craft({ - type = "shapeless", - output = "basic_materials:wet_cement 3", - recipe = { - "default:dirt", - "dye:dark_grey", - "dye:dark_grey", - "dye:dark_grey", - "bucket:bucket_water" - }, - replacements = {{'bucket:bucket_water', 'bucket:bucket_empty'},}, -}) - -minetest.register_craft({ - type = "cooking", - output = "basic_materials:cement_block", - recipe = "basic_materials:wet_cement", - cooktime = 8 -}) - -minetest.register_craft({ - output = 'basic_materials:concrete_block 6', - recipe = { - {'group:sand', 'basic_materials:wet_cement', 'default:gravel'}, - {'basic_materials:steel_bar', 'basic_materials:wet_cement', 'basic_materials:steel_bar'}, - {'default:gravel', 'basic_materials:wet_cement', 'group:sand'}, - } -}) - --- aliases - -minetest.register_alias("homedecor:oil_extract", "basic_materials:oil_extract") -minetest.register_alias("homedecor:paraffin", "basic_materials:paraffin") -minetest.register_alias("homedecor:plastic_base", "basic_materials:paraffin") -minetest.register_alias("homedecor:terracotta_base", "basic_materials:terracotta_base") - -minetest.register_alias("gloopblocks:wet_cement", "basic_materials:wet_cement") -minetest.register_alias("gloopblocks:cement", "basic_materials:cement_block") - -minetest.register_alias("technic:concrete", "basic_materials:concrete_block") diff --git a/basic_materials/mod.conf b/basic_materials/mod.conf index 7234bfe..aeffb54 100644 --- a/basic_materials/mod.conf +++ b/basic_materials/mod.conf @@ -1,4 +1,3 @@ name = basic_materials -depends = default -optional_depends = moreores +optional_depends = moreores, default, mesecons_materials, dye, bucket, fl_stone, fl_trees, mcl_sounds min_minetest_version = 5.2.0 diff --git a/basic_materials/nodes.lua b/basic_materials/nodes.lua new file mode 100644 index 0000000..01f9553 --- /dev/null +++ b/basic_materials/nodes.lua @@ -0,0 +1,54 @@ +local S = minetest.get_translator("basic_materials") +local sound_api = dofile(basic_materials.modpath .. "/sound_api_core/init.lua") +local chains_sbox = {type = "fixed",fixed = { -0.1, -0.5, -0.1, 0.1, 0.5, 0.1 }} + +minetest.register_node("basic_materials:cement_block", { + description = S("Cement"), + tiles = {"basic_materials_cement_block.png"}, + is_ground_content = true, + groups = {cracky=2, dig_stone = 1}, + sounds = sound_api.node_sound_stone_defaults(), +}) + +minetest.register_node("basic_materials:concrete_block", { + description = S("Concrete Block"), + tiles = {"basic_materials_concrete_block.png",}, + groups = {cracky=1, concrete=1, dig_stone = 1}, + sounds = sound_api.node_sound_stone_defaults(), +}) + +minetest.register_node("basic_materials:chain_steel", { + description = S("Chain (steel, hanging)"), + drawtype = "mesh", + mesh = "basic_materials_chains.obj", + tiles = {"basic_materials_chain_steel.png"}, + walkable = false, + climbable = true, + sunlight_propagates = true, + paramtype = "light", + inventory_image = "basic_materials_chain_steel_inv.png", + groups = {cracky=3, dig_stone = 1}, + selection_box = chains_sbox, +}) + +minetest.register_node("basic_materials:chain_brass", { + description = S("Chain (brass, hanging)"), + drawtype = "mesh", + mesh = "basic_materials_chains.obj", + tiles = {"basic_materials_chain_brass.png"}, + walkable = false, + climbable = true, + sunlight_propagates = true, + paramtype = "light", + inventory_image = "basic_materials_chain_brass_inv.png", + groups = {cracky=3, dig_stone = 1}, + selection_box = chains_sbox, +}) + +minetest.register_node("basic_materials:brass_block", { + description = S("Brass Block"), + tiles = { "basic_materials_brass_block.png" }, + is_ground_content = false, + groups = {cracky=1, dig_stone = 1}, + sounds = sound_api.node_sound_metal_defaults() +}) diff --git a/basic_materials/plastics.lua b/basic_materials/plastics.lua deleted file mode 100644 index e29af53..0000000 --- a/basic_materials/plastics.lua +++ /dev/null @@ -1,56 +0,0 @@ --- Translation support -local S = minetest.get_translator("basic_materials") - --- items - -minetest.register_craftitem("basic_materials:plastic_sheet", { - description = S("Plastic sheet"), - inventory_image = "basic_materials_plastic_sheet.png", -}) - -minetest.register_craftitem("basic_materials:plastic_strip", { - description = S("Plastic strips"), - groups = { strip = 1 }, - inventory_image = "basic_materials_plastic_strip.png", -}) - -minetest.register_craftitem("basic_materials:empty_spool", { - description = S("Empty wire spool"), - inventory_image = "basic_materials_empty_spool.png" -}) - --- crafts - -minetest.register_craft({ - type = "cooking", - output = "basic_materials:plastic_sheet", - recipe = "basic_materials:paraffin", -}) - -minetest.register_craft({ - type = "fuel", - recipe = "basic_materials:plastic_sheet", - burntime = 30, -}) - -minetest.register_craft( { - output = "basic_materials:plastic_strip 9", - recipe = { - { "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" } - }, -}) - -minetest.register_craft( { - output = "basic_materials:empty_spool 3", - recipe = { - { "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" }, - { "", "basic_materials:plastic_sheet", "" }, - { "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" } - }, -}) - --- aliases - -minetest.register_alias("homedecor:plastic_sheeting", "basic_materials:plastic_sheet") -minetest.register_alias("homedecor:plastic_strips", "basic_materials:plastic_strip") -minetest.register_alias("homedecor:empty_spool", "basic_materials:empty_spool") diff --git a/hyperloop/door.lua b/hyperloop/door.lua index c21600e..e21154d 100644 --- a/hyperloop/door.lua +++ b/hyperloop/door.lua @@ -73,6 +73,7 @@ end -- door command based on the station data table function hyperloop.open_pod_door(tStation) if tStation ~= nil then + tStation.facedir = tStation.facedir or 0 local door_pos = hyperloop.new_pos(tStation.pos, tStation.facedir, "1F1L", 1) local door_facedir = (tStation.facedir + 1) % 4 door_command(door_pos, door_facedir, "open") @@ -82,6 +83,7 @@ end -- door command based on the station data table function hyperloop.close_pod_door(tStation) if tStation ~= nil then + tStation.facedir = tStation.facedir or 0 local door_pos = hyperloop.new_pos(tStation.pos, tStation.facedir, "1F1L", 1) local door_facedir = (tStation.facedir + 1) % 4 door_command(door_pos, door_facedir, "close") @@ -91,6 +93,7 @@ end -- door command based on the station data table function hyperloop.animate_pod_door(tStation) if tStation ~= nil then + tStation.facedir = tStation.facedir or 0 local door_pos = hyperloop.new_pos(tStation.pos, tStation.facedir, "1F1L", 1) local door_facedir = (tStation.facedir + 1) % 4 door_command(door_pos, door_facedir, "animate") diff --git a/hyperloop/elevator.lua b/hyperloop/elevator.lua index 94ac74d..e1985f1 100644 --- a/hyperloop/elevator.lua +++ b/hyperloop/elevator.lua @@ -21,7 +21,7 @@ local NS = hyperloop.NS -- To store elevator floors and formspecs local Cache = {} - +local PlayerNameTags = {} local kPLAYER_OVER_GROUND = 0.5 ------------------------------------------------------------------------------- @@ -381,8 +381,9 @@ local function on_arrival_floor(tDeparture, tArrival, player_name, snd) if player ~= nil then tArrival.pos.y = tArrival.pos.y - kPLAYER_OVER_GROUND player:set_pos(tArrival.pos) - if tArrival.attributes then - player:set_nametag_attributes(tArrival.attributes) + if PlayerNameTags[player_name] then + player:set_nametag_attributes(PlayerNameTags[player_name]) + PlayerNameTags[player_name] = nil end tArrival.pos.y = tArrival.pos.y + kPLAYER_OVER_GROUND end @@ -395,10 +396,8 @@ local function on_travel(tDeparture, tArrival, player_name, seconds) door_command(tDeparture.pos, tDeparture.facedir, "darken", false) door_command(tArrival.pos, tArrival.facedir, "darken", false) if player ~= nil then - tArrival.attributes = player:get_nametag_attributes() + PlayerNameTags[player_name] = player:get_nametag_attributes() player:set_nametag_attributes({text = " "}) - else - tArrival.attributes = nil end local snd = minetest.sound_play("ele_norm", { pos = tDeparture.pos, diff --git a/hyperloop/seat.lua b/hyperloop/seat.lua index 95ee396..3d7cc94 100644 --- a/hyperloop/seat.lua +++ b/hyperloop/seat.lua @@ -21,6 +21,7 @@ local NS = hyperloop.NS local I, _ = dofile( minetest.get_modpath("hyperloop").."/intllib.lua") local Stations = hyperloop.Stations +local PlayerNameTags = {} local function enter_display(tStation, text) -- determine position @@ -76,8 +77,9 @@ local function on_arrival(tDeparture, tArrival, player_name, sound) player:set_look_yaw(yaw) end -- set player name again - if tArrival.attributes then - player:set_nametag_attributes(tArrival.attributes) + if PlayerNameTags[player_name] then + player:set_nametag_attributes(PlayerNameTags[player_name]) + PlayerNameTags[player_name] = nil end end -- play arrival sound @@ -136,10 +138,11 @@ end local function on_start_travel(pos, node, clicker) -- arrival data local meta = M(pos) + local player_name = clicker:get_player_name() local tDeparture, departure_pos = hyperloop.get_base_station(pos) local arrival_pos = hyperloop.get_arrival(departure_pos) if arrival_pos == nil then - minetest.chat_send_player(clicker:get_player_name(), S("[Hyperloop] No booking entered!")) + minetest.chat_send_player(player_name, S("[Hyperloop] No booking entered!")) return end local tArrival = hyperloop.get_station(arrival_pos) @@ -160,8 +163,8 @@ local function on_start_travel(pos, node, clicker) clicker:set_pos(pos) -- rotate player to look in move direction clicker:set_look_horizontal(hyperloop.facedir_to_rad(tDeparture.facedir)) - -- hide player name - tArrival.attributes = clicker:get_nametag_attributes() + -- hide player name + PlayerNameTags[player_name] = clicker:get_nametag_attributes() clicker:set_nametag_attributes({text = " "}) -- activate display @@ -188,7 +191,7 @@ local function on_start_travel(pos, node, clicker) hyperloop.close_pod_door(tDeparture) atime = atime - 7 -- substract start/arrival time - minetest.after(4.9, on_travel, tDeparture, tArrival, clicker:get_player_name(), atime) + minetest.after(4.9, on_travel, tDeparture, tArrival, player_name, atime) end -- Hyperloop Seat diff --git a/minecart/buffer.lua b/minecart/buffer.lua index d871046..8e3b4da 100644 --- a/minecart/buffer.lua +++ b/minecart/buffer.lua @@ -37,7 +37,7 @@ local function remote_station_name(pos) end end -local function on_punch(pos, node, puncher) +function minecart.update_buffer_infotext(pos) local name = M(pos):get_string("name") local dest = remote_station_name(pos) if dest then @@ -45,6 +45,10 @@ local function on_punch(pos, node, puncher) else M(pos):set_string("infotext", name .. ": " .. S("Not connected!")) end +end + +local function on_punch(pos, node, puncher) + minecart.update_buffer_infotext(pos) M(pos):set_string("formspec", formspec(pos)) minetest.get_node_timer(pos):start(CYCLE_TIME) diff --git a/minecart/recording.lua b/minecart/recording.lua index 5b93fee..326450b 100644 --- a/minecart/recording.lua +++ b/minecart/recording.lua @@ -125,6 +125,7 @@ function minecart.stop_recording(self, pos, force_exit) local length = speed * self.runtime local fmt = S("[minecart] Speed = %u m/s, Time = %u s, Route length = %u m") minetest.chat_send_player(self.driver, string.format(fmt, speed, self.runtime, length)) + minecart.update_buffer_infotext(self.start_pos) end elseif #self.checkpoints <= 3 then minetest.chat_send_player(self.driver, S("[minecart] Your route is too short to record!")) diff --git a/networks/README.md b/networks/README.md index f9dd8b3..2628d3f 100644 --- a/networks/README.md +++ b/networks/README.md @@ -125,3 +125,6 @@ Required: tubelib2 **2021-09-18 V0.10** - Add support for colored cables (PR #1 by Thomas--S) + +**2022-01-06 V0.11** +- Support for junction rotation added diff --git a/networks/control.lua b/networks/control.lua index 87060d8..18df054 100644 --- a/networks/control.lua +++ b/networks/control.lua @@ -7,7 +7,7 @@ AGPL v3 See LICENSE.txt for more information - + Control API to control other network nodes which have a control interface ]]-- @@ -40,13 +40,13 @@ end -- } function networks.control.register_nodes(names, control_callbacks) assert(type(control_callbacks) == "table") - + for _, name in ipairs(names) do minetest.override_item(name, {control = control_callbacks}) end end --- Send a message with 'topic' string and any 'payload 'to all 'tlib2' network +-- Send a message with 'topic' string and any 'payload 'to all 'tlib2' network -- nodes of type 'node_type'. -- Function returns the number of nodes the message was sent to. function networks.control.send(pos, tlib2, outdir, node_type, topic, payload) @@ -63,7 +63,7 @@ function networks.control.send(pos, tlib2, outdir, node_type, topic, payload) return cnt end --- Send a request with 'topic' string to all 'tlib2' network +-- Send a request with 'topic' string to all 'tlib2' network -- nodes of type 'node_type'. -- Function returns a list with all responses. function networks.control.request(pos, tlib2, outdir, node_type, topic) diff --git a/networks/hidden.lua b/networks/hidden.lua index e7549b1..c3d55c3 100644 --- a/networks/hidden.lua +++ b/networks/hidden.lua @@ -95,7 +95,7 @@ function networks.hide_node(pos, node, placer) local inv = placer:get_inventory() local stack = inv:get_stack("main", 1) local taken = stack:take_item(1) - + if taken:get_count() == 1 and tFillingMaterial[taken:get_name()] then local meta = M(pos) meta:set_string("netw_name", node.name) diff --git a/networks/init.lua b/networks/init.lua index 2f30edb..82786b5 100644 --- a/networks/init.lua +++ b/networks/init.lua @@ -13,10 +13,10 @@ networks = {} -- Version for compatibility checks, see readme.md/history -networks.version = 0.10 +networks.version = 0.11 -if not minetest.global_exists("tubelib2") or tubelib2.version < 2.1 then - minetest.log("error", "[networks] Networks requires tubelib2 version 2.1 or newer!") +if not minetest.global_exists("tubelib2") or tubelib2.version < 2.2 then + minetest.log("error", "[networks] Networks requires tubelib2 version 2.2 or newer!") return end @@ -36,4 +36,4 @@ if minetest.settings:get_bool("networks_test_enabled") == true then local Cable = dofile(MP .. "/test/test_power.lua") assert(loadfile(MP .. "/test/test_control.lua"))(Cable) dofile(MP .. "/test/test_tool.lua") -end \ No newline at end of file +end diff --git a/networks/junction.lua b/networks/junction.lua index 8832a59..ce052b9 100644 --- a/networks/junction.lua +++ b/networks/junction.lua @@ -10,19 +10,22 @@ ]]-- +local SideToDir = {B=1, R=2, F=3, L=4, D=5, U=6} +local tubelib2_dir_to_side = tubelib2.dir_to_side + local function bit(p) return 2 ^ (p - 1) -- 1-based indexing end -- Typical call: if hasbit(x, bit(3)) then ... local function hasbit(x, p) - return x % (p + p) >= p + return x % (p + p) >= p end local function setbit(x, p) return hasbit(x, p) and x or x + p end - + local function get_node_box(val, size, boxes) local fixed = {{-size, -size, -size, size, size, size}} for i = 1,6 do @@ -65,20 +68,6 @@ function networks.register_junction(name, size, boxes, tlib2, node, index) return names end -local SideToDir = {B=1, R=2, F=3, L=4} -local function dir_to_dir2(dir, param2) - if param2 == 0 then - return dir - elseif param2 == 1 then - return ({4,1,2,3,5,6})[dir] - elseif param2 == 2 then - return ({3,4,1,2,5,6})[dir] - elseif param2 == 3 then - return ({2,3,4,1,5,6})[dir] - end - return dir -end - function networks.junction_type(pos, network, default_side, param2) local connected = function(self, pos, dir) if network:is_primary_node(pos, dir) then @@ -96,7 +85,7 @@ function networks.junction_type(pos, network, default_side, param2) val = setbit(val, bit(SideToDir[default_side])) end for dir = 1,6 do - local dir2 = dir_to_dir2(dir, param2) + local dir2 = SideToDir[tubelib2_dir_to_side(dir, param2 or 0)] if network.force_to_use_tubes then if connected(network, pos, dir) then val = setbit(val, bit(dir2)) @@ -107,10 +96,13 @@ function networks.junction_type(pos, network, default_side, param2) if connected(network, pos, dir) then val = setbit(val, bit(dir2)) elseif network:is_secondary_node(pos, dir) then - val = setbit(val, bit(dir2)) + local node = network:get_secondary_node(pos, dir) + if network:is_valid_dir(node, networks.Flip[dir]) then + val = setbit(val, bit(dir2)) + end end end end return val -end +end diff --git a/networks/liquid.lua b/networks/liquid.lua index 9e53097..59f2f8e 100644 --- a/networks/liquid.lua +++ b/networks/liquid.lua @@ -7,7 +7,7 @@ AGPL v3 See LICENSE.txt for more information - + Liquid API for liquid pumping and storing nodes ]]-- @@ -42,8 +42,8 @@ end -- capa = CAPACITY, -- peek = function(pos, indir), -- returns: liquid name -- put = function(pos, indir, name, amount), -- returns: liquid leftover or 0 --- take = function(pos, indir, name, amount), -- returns: taken, name --- untake = function(pos, indir, name, amount), -- returns: leftover +-- take = function(pos, indir, name, amount), -- returns: taken, name +-- untake = function(pos, indir, name, amount), -- returns: leftover -- } function networks.liquid.register_nodes(names, tlib2, node_type, valid_sides, liquid_callbacks) if node_type == "pump" then @@ -57,14 +57,14 @@ function networks.liquid.register_nodes(names, tlib2, node_type, valid_sides, li else error("parameter error") end - + if node_type == "tank" then assert(type(liquid_callbacks) == "table") end - + tlib2:add_secondary_node_names(names) networks.registered_networks.liquid[tlib2.tube_type] = tlib2 - + for _, name in ipairs(names) do local ndef = minetest.registered_nodes[name] local tbl = ndef.networks or {} @@ -136,7 +136,7 @@ function networks.liquid.take(pos, tlib2, outdir, name, amount, show_debug_cube) end taken, name = liq.take(item.pos, item.indir, name, amount) if taken and name and taken > 0 then - break + break end end end @@ -188,7 +188,7 @@ function networks.liquid.srv_put(nvm, name, amount, capa) assert(name) assert(amount and amount >= 0) assert(capa and capa > 0) - + nvm.liquid = nvm.liquid or {} amount = amount or 0 if not nvm.liquid.name then @@ -211,7 +211,7 @@ end function networks.liquid.srv_take(nvm, name, amount) assert(amount and amount >= 0) - + nvm.liquid = nvm.liquid or {} amount = amount or 0 if not name or nvm.liquid.name == name then @@ -220,7 +220,7 @@ function networks.liquid.srv_take(nvm, name, amount) if nvm.liquid.amount > amount then nvm.liquid.amount = nvm.liquid.amount - amount return amount, name - else + else local rest = nvm.liquid.amount local name = nvm.liquid.name nvm.liquid.amount = 0 diff --git a/networks/networks.lua b/networks/networks.lua index f569773..1b44459 100644 --- a/networks/networks.lua +++ b/networks/networks.lua @@ -27,6 +27,8 @@ local NumNodes = 0 -- Used to determine the number of network nodes local Flip = tubelib2.Turn180Deg local get_nodename = networks.get_nodename local get_node = networks.get_node +local tubelib2_get_pos = tubelib2.get_pos +local tubelib2_side_to_dir = tubelib2.side_to_dir ------------------------------------------------------------------------------- -- Debugging @@ -48,7 +50,7 @@ local function netw_num(netID) end return DbgNetIDs[netID] end - + local function network_nodes(netID, network) local tbl = {} for node_type,table in pairs(network or {}) do @@ -99,7 +101,7 @@ minetest.register_entity("networks:marker_cube", { -- Helper ------------------------------------------------------------------------------- -- return the networks table from the node definition -local function net_def(pos, netw_type) +local function net_def(pos, netw_type) local ndef = minetest.registered_nodes[get_nodename(pos)] if ndef and ndef.networks then return ndef.networks[netw_type] @@ -107,12 +109,12 @@ local function net_def(pos, netw_type) error("Node " .. get_nodename(pos) .. " at ".. P2S(pos) .. " has no 'ndef.networks'") end -local function net_def2(pos, node_name, netw_type) +local function net_def2(pos, node_name, netw_type) local ndef = minetest.registered_nodes[node_name] if ndef and ndef.networks then return ndef.networks[netw_type] end - return net_def(pos, netw_type) + return net_def(pos, netw_type) end -- Don't allow direct connections between to nodes of the same type @@ -255,7 +257,7 @@ local function collect_network_nodes(pos, tlib2, outdir) local t = minetest.get_us_time() Route = {} NumNodes = 0 - pos_already_reached(pos) + pos_already_reached(pos) local netw = {} local node = N(pos) local netw_type = tlib2.tube_type @@ -341,7 +343,7 @@ local function set_netID(pos, outdir, netID) local hash = minetest.hash_node_position(pos) NetIDs[hash] = NetIDs[hash] or {} NetIDs[hash][outdir] = netID -end +end local function get_netID(pos, outdir) local hash = minetest.hash_node_position(pos) @@ -410,7 +412,7 @@ networks.Flip = tubelib2.Turn180Deg -- networks.net_def(pos, netw_type) networks.net_def = net_def --- sides: outdir: +-- sides: outdir: -- U -- | B -- | / 6 (N) @@ -426,6 +428,17 @@ networks.net_def = net_def -- F | -- D -- + +-- Determine the pos relative to the given 'pos', 'param2' +-- and the path based on 'sides' like "FUL" +function networks.get_relpos(pos, sides, param2) + local pos1 = {x = pos.x, y = pos.y, z = pos.z} + for side in sides:gmatch(".") do + pos1 = tubelib2_get_pos(pos1, tubelib2_side_to_dir(side, param2)) + end + return pos1 +end + -- networks.side_to_outdir(pos, side) networks.side_to_outdir = side_to_outdir @@ -445,9 +458,9 @@ networks.network_nodes = network_nodes networks.get_network = get_network -- return the networks table from the node definition --- networks.net_def(pos, netw_type) +-- networks.net_def(pos, netw_type) networks.net_def = net_def - + -- Function returns {outdir} or all node dirs with connections -- networks.get_outdirs(pos, tlib2, outdir) networks.get_outdirs = get_outdirs @@ -472,11 +485,11 @@ function networks.determine_netID(pos, tlib2, outdir) assert(outdir) local netID = get_netID(pos, outdir) if netID and Networks[tlib2.tube_type] and Networks[tlib2.tube_type][netID] then - return netID + return netID elseif netID == 0 then return -- no network available end - + local netw = collect_network_nodes(pos, tlib2, outdir) if netw.num_nodes > 1 then netID = determine_netID(netw) diff --git a/networks/observer.lua b/networks/observer.lua index f6676a9..319ba2e 100644 --- a/networks/observer.lua +++ b/networks/observer.lua @@ -29,4 +29,4 @@ function networks.node_observer(tag, pos, tbl1, tbl2) print("##### Node_observer (" .. (minetest.get_gametime() % 100) .. "): '" .. N(pos).name .. "' - " .. tag) print("tbl1", dump(tbl1), "\ntbl2", dump(tbl2)) end -end \ No newline at end of file +end diff --git a/networks/power.lua b/networks/power.lua index 45433d4..c817c76 100644 --- a/networks/power.lua +++ b/networks/power.lua @@ -7,7 +7,7 @@ AGPL v3 See LICENSE.txt for more information - + Power API for power consuming and generating nodes ]]-- @@ -26,8 +26,8 @@ networks.registered_networks.power = {} local DEFAULT_DATA = { curr_load = 0, -- network storage value max_capa = 0, -- network storage capacity - consumed = 0, -- consumed power by consumers - provided = 0, -- provided power by generators + consumed = 0, -- consumed power by consumers + provided = 0, -- provided power by generators available = 0, -- max. available generator power netw_num = 0, -- network number } @@ -75,7 +75,7 @@ local function get_power_data(pos, tlib2, outdir, netID) max_perf = max_perf, -- max. available power consumed = 0, -- consumed power provided = 0, -- provided power - available = 0, -- available power + available = 0, -- available power num_nodes = netw.num_nodes, } return Power[netID] @@ -101,10 +101,10 @@ function networks.power.register_nodes(names, tlib2, node_type, valid_sides) else error("parameter error") end - + tlib2:add_secondary_node_names(names) networks.registered_networks.power[tlib2.tube_type] = tlib2 - + for _, name in ipairs(names) do local ndef = minetest.registered_nodes[name] local tbl = ndef.networks or {} @@ -193,12 +193,12 @@ function networks.power.provide_power(pos, tlib2, outdir, amount, cp1, cp2) local pwr = Power[netID] or get_power_data(pos, tlib2, outdir, netID) local x = pwr.curr_load / pwr.max_capa OBS("provide_power", pos, {outdir = outdir, amount = amount}, pwr) - + pwr.available = pwr.available + amount amount = math.min(amount, pwr.max_capa - pwr.curr_load) cp1 = cp1 or 0.8 cp2 = cp2 or 1.0 - + if x < cp1 then -- charge with full power pwr.curr_load = pwr.curr_load + amount pwr.provided = pwr.provided + amount @@ -273,7 +273,7 @@ function networks.power.transfer_duplex(pos, netw1, outdir1, netw2, outdir2, amo local pwr2 = Power[netID2] or get_power_data(pos, netw2, outdir2, netID2) local lvl = pwr1.curr_load / pwr1.max_capa - pwr2.curr_load / pwr2.max_capa local moved - + pwr2.available = pwr2.available + amount pwr1.available = pwr1.available + amount if lvl > 0 then @@ -294,13 +294,13 @@ function networks.power.transfer_duplex(pos, netw1, outdir1, netw2, outdir2, amo pwr1.provided = (pwr1.provided or 0) + moved else moved = 0 - end + end OBS("transfer_duplex", pos, pwr1, pwr2) return { - curr_load1 = pwr1.curr_load, - curr_load2 = pwr2.curr_load, - max_capa1 = pwr1.max_capa, - max_capa2 = pwr2.max_capa, + curr_load1 = pwr1.curr_load, + curr_load2 = pwr2.curr_load, + max_capa1 = pwr1.max_capa, + max_capa2 = pwr2.max_capa, moved = moved} end end @@ -317,7 +317,7 @@ function networks.power.transfer_simplex(pos, netw1, outdir1, netw2, outdir2, am local pwr2 = Power[netID2] or get_power_data(pos, netw2, outdir2, netID2) local lvl = pwr1.curr_load / pwr1.max_capa - pwr2.curr_load / pwr2.max_capa local moved - + pwr2.available = pwr2.available + amount if lvl > 0 then -- transfer from netw1 to netw2 @@ -329,13 +329,13 @@ function networks.power.transfer_simplex(pos, netw1, outdir1, netw2, outdir2, am pwr2.provided = (pwr2.provided or 0) + moved else moved = 0 - end + end OBS("transfer_simplex", pos, pwr1, pwr2) return { - curr_load1 = pwr1.curr_load, - curr_load2 = pwr2.curr_load, - max_capa1 = pwr1.max_capa, - max_capa2 = pwr2.max_capa, + curr_load1 = pwr1.curr_load, + curr_load2 = pwr2.curr_load, + max_capa1 = pwr1.max_capa, + max_capa2 = pwr2.max_capa, moved = moved} end end @@ -347,7 +347,7 @@ function networks.power.turn_switch_on(pos, tlib2, name_off, name_on) local node = N(pos) local meta = M(pos) local changed = false - + if node.name == name_off then node.name = name_on changed = true @@ -356,14 +356,14 @@ function networks.power.turn_switch_on(pos, tlib2, name_off, name_on) else return false end - + if meta:contains("netw_param2") then meta:set_int("netw_param2", meta:get_int("netw_param2_copy")) - else + else node.param2 = meta:get_int("netw_param2_copy") end meta:set_int("netw_param2_copy", 0) - + if changed then minetest.swap_node(pos, node) end @@ -376,7 +376,7 @@ function networks.power.turn_switch_off(pos, tlib2, name_off, name_on) local node = N(pos) local meta = M(pos) local changed = false - + if node.name == name_on then node.name = name_off changed = true @@ -385,18 +385,18 @@ function networks.power.turn_switch_off(pos, tlib2, name_off, name_on) else return false end - + if meta:contains("netw_param2") then meta:set_int("netw_param2_copy", meta:get_int("netw_param2")) --meta:set_int("netw_param2", 0) - else + else meta:set_int("netw_param2_copy", node.param2) end - + if changed then minetest.swap_node(pos, node) end - + if meta:contains("netw_param2") then node.param2 = meta:get_int("netw_param2") end @@ -426,8 +426,8 @@ function networks.power.get_network_data(pos, tlib2, outdir) local res = { curr_load = pwr.curr_load, -- network storage value max_capa = pwr.max_capa, -- network storage capacity - consumed = consumed, -- consumed power by consumers - provided = provided, -- provided power by generators + consumed = consumed, -- consumed power by consumers + provided = provided, -- provided power by generators available = available, -- max. available generator power netw_num = networks.netw_num(netID), -- network number } diff --git a/networks/test/test_control.lua b/networks/test/test_control.lua index 6c8bb0c..3fd2fa3 100644 --- a/networks/test/test_control.lua +++ b/networks/test/test_control.lua @@ -37,7 +37,7 @@ minetest.register_node("networks:client", { local outdir = networks.side_to_outdir(pos, "F") M(pos):set_int("outdir", outdir) M(pos):set_string("infotext", "off") - Cable:after_place_node(pos, {outdir}) + Cable:after_place_node(pos, {outdir}) tubelib2.init_mem(pos) end, after_dig_node = function(pos, oldnode, oldmetadata) @@ -89,7 +89,7 @@ minetest.register_node("networks:server_off", { "networks_sto.png^[colorize:#F05100:60", }, after_place_node = function(pos) - Cable:after_place_node(pos) + Cable:after_place_node(pos) end, after_dig_node = function(pos) Cable:after_dig_node(pos) @@ -108,13 +108,13 @@ minetest.register_node("networks:server_on", { "networks_sto.png^[colorize:#F05100:60", }, after_place_node = function(pos) - Cable:after_place_node(pos) + Cable:after_place_node(pos) end, after_dig_node = function(pos) Cable:after_dig_node(pos) end, paramtype = "light", - light_source = 8, + light_source = 8, paramtype2 = "facedir", drop = "networks:server_off", groups = {crumbly = 2, cracky = 2, snappy = 2, not_in_creative_inventory = 1}, diff --git a/networks/test/test_liquid.lua b/networks/test/test_liquid.lua index 7f15328..7259898 100644 --- a/networks/test/test_liquid.lua +++ b/networks/test/test_liquid.lua @@ -26,9 +26,9 @@ local liquid = networks.liquid ------------------------------------------------------------------------------- local Pipe = tubelib2.Tube:new({ dirs_to_check = {1,2,3,4,5,6}, - max_tube_length = 100, + max_tube_length = 100, tube_type = "liq", - primary_node_names = {"networks:pipeS", "networks:pipeA", "networks:valve_on"}, + primary_node_names = {"networks:pipeS", "networks:pipeA", "networks:valve_on"}, secondary_node_names = {}, -- Names will be added via 'liquids.register_nodes' after_place_tube = function(pos, param2, tube_type, num_tubes, tbl) local name = minetest.get_node(pos).name @@ -212,7 +212,7 @@ end local function after_place_node(pos) local outdir = networks.side_to_outdir(pos, "B") M(pos):set_int("outdir", outdir) - Pipe:after_place_node(pos, {outdir}) + Pipe:after_place_node(pos, {outdir}) M(pos):set_string("infotext", "off") tubelib2.init_mem(pos) end @@ -261,7 +261,7 @@ minetest.register_node("networks:pump_on", { on_timer = pumping, on_rightclick = on_rightclick, paramtype = "light", - light_source = 8, + light_source = 8, paramtype2 = "facedir", diggable = false, drop = "", @@ -289,7 +289,7 @@ local function register_tank(name, description, liquid_name, liquid_amount) 'networks_tank.png^[colorize:#007577:60', }, after_place_node = function(pos) - Pipe:after_place_node(pos) + Pipe:after_place_node(pos) local mem = tubelib2.init_mem(pos) mem.liquid = {} mem.liquid.name = liquid_name @@ -319,7 +319,7 @@ register_tank("networks:tank1", "Water Tank", "water", STORAGE_CAPA) register_tank("networks:tank2", "Milk Tank", "milk", STORAGE_CAPA) register_tank("networks:tank3", "Empty Tank", nil, 0) -liquid.register_nodes({"networks:tank1", "networks:tank2", "networks:tank3"}, +liquid.register_nodes({"networks:tank1", "networks:tank2", "networks:tank3"}, Pipe, "tank", nil, { capa = STORAGE_CAPA, peek = function(pos, indir) @@ -375,7 +375,7 @@ minetest.register_node("networks:valve_on", { on_rightclick = function(pos, node, clicker) if liquid.turn_valve_off(pos, Pipe, "networks:valve_off", "networks:valve_on") then minetest.sound_play("doors_glass_door_open", { - pos = pos, + pos = pos, gain = 1, max_hear_distance = 5}) end @@ -409,7 +409,7 @@ minetest.register_node("networks:valve_off", { on_rightclick = function(pos, node, clicker) if liquid.turn_valve_on(pos, Pipe, "networks:valve_off", "networks:valve_on") then minetest.sound_play("doors_glass_door_open", { - pos = pos, + pos = pos, gain = 1, max_hear_distance = 5}) end diff --git a/networks/test/test_power.lua b/networks/test/test_power.lua index 033d9f2..0179c2a 100644 --- a/networks/test/test_power.lua +++ b/networks/test/test_power.lua @@ -38,9 +38,9 @@ local power = networks.power ------------------------------------------------------------------------------- local Cable = tubelib2.Tube:new({ dirs_to_check = {1,2,3,4,5,6}, - max_tube_length = 100, + max_tube_length = 100, tube_type = "pwr", - primary_node_names = {"networks:cableS", "networks:cableA", "networks:switch_on"}, + primary_node_names = {"networks:cableS", "networks:cableA", "networks:switch_on"}, secondary_node_names = {}, -- Names will be added via 'power.register_nodes' after_place_tube = function(pos, param2, tube_type, num_tubes, tbl) local name = minetest.get_node(pos).name @@ -85,7 +85,7 @@ if HIDDEN then "default:mese", "default:diamondblock", }) -end +end -- Use global callback instead of node related functions Cable:register_on_tube_update2(function(pos, outdir, tlib2, node) @@ -215,7 +215,7 @@ minetest.register_node("networks:generator", { after_place_node = function(pos) local outdir = networks.side_to_outdir(pos, "F") M(pos):set_int("outdir", outdir) - Cable:after_place_node(pos, {outdir}) + Cable:after_place_node(pos, {outdir}) M(pos):set_string("infotext", "off") tubelib2.init_mem(pos) end, @@ -251,7 +251,7 @@ minetest.register_node("networks:generator", { local mem = tubelib2.get_mem(pos) if mem.running then -- generator storage capa = 2 * performance - return {level = (mem.load or 0) / GEN_MAX, perf = GEN_MAX, capa = GEN_MAX * 2} + return {level = (mem.load or 0) / GEN_MAX, perf = GEN_MAX, capa = GEN_MAX * 2} end end, paramtype2 = "facedir", @@ -281,7 +281,7 @@ minetest.register_node("networks:storage", { after_place_node = function(pos) local outdir = networks.side_to_outdir(pos, "F") M(pos):set_int("outdir", outdir) - Cable:after_place_node(pos, {outdir}) + Cable:after_place_node(pos, {outdir}) tubelib2.init_mem(pos) M(pos):set_string("infotext", "off") end, @@ -384,7 +384,7 @@ end minetest.register_node("networks:consumer", { description = "Consumer", tiles = {'networks_con.png^[colorize:#000000:50'}, - + on_timer = function(pos, elapsed) local consumed = power.consume_power(pos, Cable, nil, CON_MAX) if consumed == CON_MAX then @@ -418,7 +418,7 @@ minetest.register_node("networks:consumer_on", { after_place_node = after_place_node, after_dig_node = after_dig_node, paramtype = "light", - light_source = minetest.LIGHT_MAX, + light_source = minetest.LIGHT_MAX, paramtype2 = "facedir", diggable = false, drop = "", @@ -464,7 +464,7 @@ minetest.register_node("networks:switch_on", { on_rightclick = function(pos, node, clicker) if power.turn_switch_off(pos, Cable, "networks:switch_off", "networks:switch_on") then minetest.sound_play("doors_glass_door_open", { - pos = pos, + pos = pos, gain = 1, max_hear_distance = 5}) end @@ -498,7 +498,7 @@ minetest.register_node("networks:switch_off", { on_rightclick = function(pos, node, clicker) if power.turn_switch_on(pos, Cable, "networks:switch_off", "networks:switch_on") then minetest.sound_play("doors_glass_door_open", { - pos = pos, + pos = pos, gain = 1, max_hear_distance = 5}) end @@ -538,7 +538,7 @@ local function replace_node(itemstack, placer, pointed_thing) end if res then minetest.sound_play("default_dig_snappy", { - pos = pos, + pos = pos, gain = 1, max_hear_distance = 5}) elseif placer and placer.get_player_name then @@ -571,15 +571,15 @@ minetest.register_chatcommand("power_data", { local data = power.get_network_data(pos, Cable) if data then local s = string.format("Netw %u: generated = %u/%u, consumed = %u, storage load = %u/%u", - data.netw_num, round(data.provided), - data.available, round(data.consumed), + data.netw_num, round(data.provided), + data.available, round(data.consumed), round(data.curr_load), round(data.max_capa)) return true, s end return false, "No valid node position!" - + end }) return Cable - + diff --git a/networks/test/test_tool.lua b/networks/test/test_tool.lua index a370b6f..5a4a862 100644 --- a/networks/test/test_tool.lua +++ b/networks/test/test_tool.lua @@ -52,24 +52,32 @@ local function print_sides(pos, api, netw_type) print("# " .. api .. " - " .. netw_type .. " dirs: " .. table.concat(t, ", ")) end -local function print_power_network_data(pos, api, netw, netw_type) +local function print_power_network_data(pos, api, netw_type, outdir) local tlib2 = networks.registered_networks[api][netw_type] - local outdir = netw[netw_type].ntype == "junc" and 0 or nil local data = power.get_network_data(pos, tlib2, outdir) + local netw = networks.get_network_table(pos, tlib2, outdir) if netw then - print("- Number of network nodes: " .. (netw.num_nodes or 0)) - print("- Number of generators: " .. #(netw.gen or {})) - print("- Number of consumers: " .. #(netw.con or {})) - print("- Number of storage systems: " .. #(netw.sto or {})) - end + print(" - Number of network nodes: " .. (netw.num_nodes or 0)) + print(" - Number of generators: " .. #(netw.gen or {})) + print(" - Number of consumers: " .. #(netw.con or {})) + print(" - Number of storage systems: " .. #(netw.sto or {})) + end if data then - local s = string.format("- Netw %u: generated = %u/%u, consumed = %u, storage load = %u/%u", - data.netw_num, round(data.provided), - data.available, round(data.consumed), + local s = string.format(" - Netw %u: generated = %u/%u, consumed = %u, storage load = %u/%u", + data.netw_num, round(data.provided), + data.available, round(data.consumed), round(data.curr_load), round(data.max_capa)) print(s) - else - print("- Node has no '" .. netw_type .. "' network!!!") + end +end + +local function print_liquid_network_data(pos, api, netw_type, outdir) + local tlib2 = networks.registered_networks[api][netw_type] + local netw = networks.get_network_table(pos, tlib2, outdir) + if netw then + print(" - Number of network nodes: " .. (netw.num_nodes or 0)) + print(" - Number of pumps: " .. #(netw.pump or {})) + print(" - Number of tanks: " .. #(netw.tank or {})) end end @@ -80,9 +88,14 @@ local function print_netID(pos, api, netw_type) local s = tubelib2.dir_to_string(outdir) if netID then print("- " .. s .. ": netwNum for '" .. netw_type .. "': " .. networks.netw_num(netID)) + if api == "liquid" then + print_liquid_network_data(pos, api, netw_type, outdir) + elseif api == "power" then + print_power_network_data(pos, api, netw_type, outdir) + end else print("- " .. s .. ": Node has no '" .. netw_type .. "' netID!!!") - end + end end end @@ -105,36 +118,45 @@ local function print_valid_sides(name, api, netw_type) end end +local function print_connected_nodes(pos, api, netw_type) + local tlib2 = networks.registered_networks[api][netw_type] + for outdir = 1,6 do + local destpos, indir = tlib2:get_connected_node_pos(pos, outdir) + if destpos and tlib2:connected(destpos) then + local s1 = tubelib2.dir_to_string(outdir) + local s2 = tubelib2.dir_to_string(indir) + local node = minetest.get_node(destpos) + print("- " .. s1 .. ": Node connected to " .. node.name .. " at " .. P2S(destpos) .. " from " .. s2) + end + end +end + -- debug print of node related data local function debug_print(pos) local node = minetest.get_node(pos) local ndef = minetest.registered_nodes[node.name] - + if not NetwTypes then collect_netw_types() end - + if not ndef.networks then print("No networks node!!!") return end - + print("########## " .. node.name .. " ###########") - + for netw_type,api in pairs(NetwTypes) do if ndef.networks[netw_type] then print_sides(pos, api, netw_type) - if api == "power" then - print_power_network_data(pos, api, ndef.networks, netw_type) - elseif api == "liquid" then - --print_liquid_network_data(pos, api, netw_type) - end print_netID(pos, api, netw_type) print_secondary_node(pos, api, netw_type) print_valid_sides(node.name, api, netw_type) + print_connected_nodes(pos, api, netw_type) end end - + print("#####################") end diff --git a/techage/README.md b/techage/README.md index 69914bd..42ee4f0 100644 --- a/techage/README.md +++ b/techage/README.md @@ -26,7 +26,7 @@ In contrast to TechPack, the resources are more limited and it is much more diff ### License -Copyright (C) 2019-2021 Joachim Stolberg +Copyright (C) 2019-2022 Joachim Stolberg Code: Licensed under the GNU AGPL version 3 or later. See LICENSE.txt Textures: CC BY-SA 3.0 @@ -80,6 +80,9 @@ Available worlds will be converted to 'lsqlite3', but there is no way back, so: ### History +**2022-01-22 V1.07** +- TA5 fusion reactor added + **2022-01-03 V1.06** - TA5 teleport blocks added - Many improvements diff --git a/techage/basic_machines/concentrator.lua b/techage/basic_machines/concentrator.lua index 40e836d..cba0f58 100644 --- a/techage/basic_machines/concentrator.lua +++ b/techage/basic_machines/concentrator.lua @@ -3,7 +3,7 @@ TechAge ======= - Copyright (C) 2019-2021 Joachim Stolberg + Copyright (C) 2019-2022 Joachim Stolberg AGPL v3 See LICENSE.txt for more information @@ -54,6 +54,12 @@ local names = networks.register_junction("techage:concentrator", 2/8, Boxes, Tub local name = "techage:concentrator"..networks.junction_type(pos, Tube, "R", node.param2) minetest.swap_node(pos, {name = name, param2 = node.param2}) end, + ta_rotate_node = function(pos, node, new_param2) + Tube:after_dig_node(pos) + minetest.swap_node(pos, {name = node.name, param2 = new_param2}) + Tube:after_place_node(pos) + M(pos):set_int("push_dir", techage.side_to_outdir("R", new_param2)) + end, after_dig_node = function(pos, oldnode, oldmetadata, digger) Tube:after_dig_node(pos) end, @@ -93,6 +99,12 @@ names = networks.register_junction("techage:ta4_concentrator", 2/8, Boxes, Tube, local name = "techage:ta4_concentrator"..networks.junction_type(pos, Tube, "R", node.param2) minetest.swap_node(pos, {name = name, param2 = node.param2}) end, + ta_rotate_node = function(pos, node, new_param2) + Tube:after_dig_node(pos) + minetest.swap_node(pos, {name = node.name, param2 = new_param2}) + Tube:after_place_node(pos) + M(pos):set_int("push_dir", techage.side_to_outdir("R", new_param2)) + end, after_dig_node = function(pos, oldnode, oldmetadata, digger) Tube:after_dig_node(pos) end, diff --git a/techage/basic_machines/consumer.lua b/techage/basic_machines/consumer.lua index b75fd0d..ff2eb18 100644 --- a/techage/basic_machines/consumer.lua +++ b/techage/basic_machines/consumer.lua @@ -229,6 +229,7 @@ function techage.register_consumer(base_name, inv_name, tiles, tNode, validState on_metadata_inventory_move = tNode.on_metadata_inventory_move, on_metadata_inventory_put = tNode.on_metadata_inventory_put, on_metadata_inventory_take = tNode.on_metadata_inventory_take, + ta_rotate_node = tNode.ta_rotate_node, paramtype = tNode.paramtype, paramtype2 = "facedir", @@ -269,6 +270,7 @@ function techage.register_consumer(base_name, inv_name, tiles, tNode, validState on_metadata_inventory_move = tNode.on_metadata_inventory_move, on_metadata_inventory_put = tNode.on_metadata_inventory_put, on_metadata_inventory_take = tNode.on_metadata_inventory_take, + ta_rotate_node = tNode.ta_rotate_node, paramtype = tNode.paramtype, paramtype2 = "facedir", diff --git a/techage/basic_machines/pusher.lua b/techage/basic_machines/pusher.lua index 9568d8a..fd03895 100644 --- a/techage/basic_machines/pusher.lua +++ b/techage/basic_machines/pusher.lua @@ -197,7 +197,7 @@ local tiles = {} -- '{power}' will be replaced by the power PNG tiles.pas = { "techage_filling_ta#.png^techage_frame_ta#_top.png^techage_appl_arrow.png", - "techage_filling_ta#.png^techage_frame_ta#.png", + "techage_filling_ta#.png^techage_frame_ta#_bottom.png^techage_appl_arrow.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_appl_pusher.png^[transformR180]^techage_frame_ta#.png", @@ -206,7 +206,7 @@ tiles.pas = { tiles.act = { -- up, down, right, left, back, front "techage_filling_ta#.png^techage_frame_ta#_top.png^techage_appl_arrow.png", - "techage_filling_ta#.png^techage_frame_ta#.png", + "techage_filling_ta#.png^techage_frame_ta#_bottom.png^techage_appl_arrow.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", { @@ -277,7 +277,14 @@ local node_name_ta2, node_name_ta3, node_name_ta4 = M(pos):set_string("formspec", ta4_formspec(CRD(pos).State, pos, nvm)) end end, - + ta_rotate_node = function(pos, node, new_param2) + Tube:after_dig_node(pos) + minetest.swap_node(pos, {name = node.name, param2 = new_param2}) + Tube:after_place_node(pos) + local meta = M(pos) + meta:set_int("pull_dir", techage.side_to_outdir("L", new_param2)) + meta:set_int("push_dir", techage.side_to_outdir("R", new_param2)) + end, allow_metadata_inventory_put = allow_metadata_inventory_put, allow_metadata_inventory_take = allow_metadata_inventory_take, on_rightclick = on_rightclick, diff --git a/techage/basis/command.lua b/techage/basis/command.lua index a32f218..f2b4362 100644 --- a/techage/basis/command.lua +++ b/techage/basis/command.lua @@ -28,6 +28,7 @@ local NodeDef = techage.NodeDef local Tube = techage.Tube local is_cart_available = minecart.is_nodecart_available local techage_counting_hit = techage.counting_hit +local tubelib2_side_to_dir = tubelib2.side_to_dir ------------------------------------------------------------------- -- Database @@ -125,11 +126,7 @@ end local SideToDir = {B=1, R=2, F=3, L=4, D=5, U=6} local function side_to_dir(side, param2) - local dir = SideToDir[side] - if dir < 5 then - dir = (((dir - 1) + (param2 % 4)) % 4) + 1 - end - return dir + return tubelib2_side_to_dir(side, param2) end techage.side_to_outdir = side_to_dir diff --git a/techage/basis/fly_lib.lua b/techage/basis/fly_lib.lua index b20a6ae..4ae48b2 100644 --- a/techage/basis/fly_lib.lua +++ b/techage/basis/fly_lib.lua @@ -242,9 +242,8 @@ local function attach_objects(pos, offs, parent, yoffs) local dir = vector.subtract(obj:get_pos(), pos) local entity = obj:get_luaentity() if entity then - if entity.name == "__builtin:item" then -- dropped items - --obj:set_attach(objref, "", {x=0, y=0, z=0}, {x=0, y=0, z=0}, true) -- hier kracht es - elseif entity.name ~= "techage:move_item" then + local mod = entity.name:gmatch("(.-):")() + if techage.RegisteredMobsMods[mod] then dir.y = dir.y + yoffs attach_single_object(parent, obj, dir) end @@ -694,11 +693,11 @@ function flylib.rotate_nodes(pos, posses1, rot) for i, pos1 in ipairs(posses1) do local node = techage.get_node_lvm(pos1) if rot == "l" then - param2 = techage.param2_turn_left(node.param2) - elseif rot == "r" then param2 = techage.param2_turn_right(node.param2) + elseif rot == "r" then + param2 = techage.param2_turn_left(node.param2) else - param2 = techage.param2_turn_left(techage.param2_turn_left(node.param2)) + param2 = techage.param2_turn_right(techage.param2_turn_right(node.param2)) end if not minetest.is_protected(pos1, owner) and is_simple_node(pos1) then minetest.remove_node(pos1) diff --git a/techage/basis/lib.lua b/techage/basis/lib.lua index 99deec8..d47f5ac 100644 --- a/techage/basis/lib.lua +++ b/techage/basis/lib.lua @@ -80,13 +80,56 @@ function techage.facedir_to_rotation(facedir) end function techage.param2_turn_left(param2) - return (RotationViaYAxis[param2] or RotationViaYAxis[0])[1] + return (RotationViaYAxis[param2] or RotationViaYAxis[0])[2] end function techage.param2_turn_right(param2) - return (RotationViaYAxis[param2] or RotationViaYAxis[0])[2] + return (RotationViaYAxis[param2] or RotationViaYAxis[0])[1] end +-- Roll a block in north direction (south is vice versa) +local RollNorth = { + {0,4,22,8}, + {1,5,23,9}, + {2,6,20,10}, + {3,7,21,11}, + {12,13,14,15}, + {16,19,18,17}, +} +-- Roll a block in east direction (west is vice versa) +local RollEast = { + {0,12,20,16}, + {1,13,21,17}, + {2,14,22,18}, + {3,15,23,19}, + {4,7,6,5}, + {8,9,10,11}, +} + +-- Generate a table for all facedir and param2 values: +-- TurnUp[facedir][param2] = new_param2 +local TurnUp = {[0] = {}, {}, {}, {}} + +for i = 1,6 do + for j = 1,4 do + local idx = RollNorth[i][j] + TurnUp[0][idx] = RollNorth[i][j == 4 and 1 or j + 1] -- north + TurnUp[2][idx] = RollNorth[i][j == 1 and 4 or j - 1] -- south + + idx = RollEast[i][j] + TurnUp[1][idx] = RollEast[i][j == 4 and 1 or j + 1] -- east + TurnUp[3][idx] = RollEast[i][j == 1 and 4 or j - 1] -- west + end +end + +-- facedir is from the players (0..3) +-- param2 is from the node (0..23) +function techage.param2_turn_up(facedir, param2) + return TurnUp[facedir % 4][param2 % 24] +end + + + ------------------------------------------------------------------------------- -- Rotate nodes around the center ------------------------------------------------------------------------------- @@ -221,25 +264,6 @@ function techage.get_node_lvm(pos) return {name="ignore", param2=0} 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 - function techage.is_air_like(name) local ndef = minetest.registered_nodes[name] if ndef and ndef.buildable_to then @@ -462,6 +486,14 @@ function techage.wrench_tooltip(x, y) "tooltip["..x..","..y..";0.5,0.5;"..tooltip..";#0C3D32;#FFFFFF]" end +techage.RegisteredMobsMods = {} + +-- Register mobs mods for the move/fly controllers +function techage.register_mobs_mods(mod) + techage.RegisteredMobsMods[mod] = true +end + + ------------------------------------------------------------------------------- -- Terminal history buffer ------------------------------------------------------------------------------- @@ -547,3 +579,50 @@ function techage.set_expoints(player, ex_points) end end end + +------------------------------------------------------------------------------- +-- Scheduler for a table-based, cyclic call of functions +------------------------------------------------------------------------------- +local TABLE_SIZE = 256 +techage.scheduler = {} + +local function add_to_table(tbl, i, func) + while i < TABLE_SIZE do + if not tbl[i] then + tbl[i] = func + return i + 1 + end + i = i + 1 + end + return i +end + +function techage.scheduler.init(pos) + local mem = techage.get_mem(pos) + mem.sched_idx = 0 +end + +-- tFunc : (empty) table of functions +-- call_rate : (2,4,8,16,32,64 or 128) +-- offset : 0-128 +-- func : function to be called +function techage.scheduler.register(tFunc, call_rate, offset, func) + local i= 0 + while i < TABLE_SIZE do + if (i % call_rate) == offset then + i = add_to_table(tFunc, i, func) + else + i = i + 1 + end + end + return tFunc +end + +-- tFunc : table of functions +-- default : default function (optional) +-- Returns a function to be called be the callee +function techage.scheduler.get(pos, tFunc, default) + local mem = techage.get_mem(pos) + mem.sched_idx = ((mem.sched_idx or 0) + 1) % TABLE_SIZE + return tFunc[mem.sched_idx] or default or function() end +end diff --git a/techage/basis/liquid_lib.lua b/techage/basis/liquid_lib.lua index 25acfd3..34a7e37 100644 --- a/techage/basis/liquid_lib.lua +++ b/techage/basis/liquid_lib.lua @@ -190,7 +190,7 @@ local function fill_on_punch(nvm, empty_container, item_count, puncher) end local function legacy_items(full_container, item_count) - if full_container == "techage:hydrogen" then + if full_container == "techage:isobutane" then return {container = "", size = item_count, inv_item = full_container} elseif full_container == "techage:oil_source" then return {container = "", size = item_count, inv_item = full_container} diff --git a/techage/basis/submenu.lua b/techage/basis/submenu.lua index 5ee9fb2..4c248dc 100644 --- a/techage/basis/submenu.lua +++ b/techage/basis/submenu.lua @@ -221,7 +221,7 @@ end function techage.menu.generate_formspec(pos, ndef, form_def, player_name) local meta = minetest.get_meta(pos) - local number = techage.get_node_number(pos) + local number = techage.get_node_number(pos) or "-" local mem = techage.get_mem(pos) mem.star = ((mem.star or 0) + 1) % 2 local star = mem.star == 1 and "*" or "" diff --git a/techage/doc/guide.lua b/techage/doc/guide.lua index 61a8445..3f5e1a4 100644 --- a/techage/doc/guide.lua +++ b/techage/doc/guide.lua @@ -15,6 +15,8 @@ local function tooltip(item) return "", name elseif img == "10x10" then -- huge image for the plan? return "10x10", name + elseif img == "5x4" then -- huge image for the plan? + return "5x4", name end local ndef = minetest.registered_nodes[name] if ndef and ndef.description then @@ -40,12 +42,17 @@ local function plan(images) tbl[#tbl+1] = "label["..x_offs..","..y_offs..";"..S("Top view").."]" elseif img == "side_view" then tbl[#tbl+1] = "label["..x_offs..","..y_offs..";"..S("Side view").."]" + elseif img == "sectional_view" then + tbl[#tbl+1] = "label["..x_offs..","..y_offs..";"..S("Sectional view").."]" elseif img == "" then img = tooltip -- use tooltip for bigger image tbl[#tbl+1] = "image["..x_offs..","..y_offs..";2.2,2.2;"..img.."]" elseif img == "10x10" then img = tooltip -- use tooltip for bigger image tbl[#tbl+1] = "image["..x_offs..","..y_offs..";10,10;"..img.."]" + elseif img == "5x4" then + img = tooltip -- use tooltip for bigger image + tbl[#tbl+1] = "image["..x_offs..","..y_offs..";5,4;"..img.."]" elseif string.find(img, ":") then tbl[#tbl+1] = "item_image["..x_offs..","..y_offs..";1,1;"..img.."]" else diff --git a/techage/doc/items.lua b/techage/doc/items.lua index de6dc6c..abad424 100644 --- a/techage/doc/items.lua +++ b/techage/doc/items.lua @@ -85,6 +85,7 @@ techage.Items = { ta3_powerswitchbox = "techage:powerswitch_box", ta3_powerterminal = "techage:ta3_power_terminal", ta3_trowel = "techage:trowel", + ta3_screwdriver = "techage:screwdriver", ta3_tinygenerator = "techage:tiny_generator", ta3_akkublock = "techage:ta3_akku", ta3_furnace = "techage:ta3_furnace_pas", @@ -203,13 +204,18 @@ techage.Items = { ta4_autocrafter = "techage:ta4_autocrafter_pas", ta4_recipeblock = "techage:ta4_recipeblock", ---------------------------- + techage_ta5 = "techage:ta5_fr_nucleus", ta5_flycontroller = "techage:ta5_flycontroller", ta5_aichip = "techage:ta5_aichip", ta5_tele_pipe = "techage:ta5_tele_pipe", ta5_tele_tube = "techage:ta5_tele_tube", ta5_chest = "techage:ta5_hl_chest", ta5_tank = "techage:ta5_hl_tank", - + ta5_magnet = "techage:ta5_magnet1", + ta5_pump = "techage:ta5_pump", + ta5_fr_shell = "techage:ta5_fr_shell", + ta5_fr_nucleus = "techage:ta5_fr_nucleus", + ta5_fr_controller = "techage:ta5_fr_controller_pas", } function techage.add_manual_items(table_with_items) diff --git a/techage/doc/manual_DE.lua b/techage/doc/manual_DE.lua index 3ef0398..0ea121b 100644 --- a/techage/doc/manual_DE.lua +++ b/techage/doc/manual_DE.lua @@ -139,6 +139,7 @@ techage.manual_DE.aTitel = { "3,TechAge Programmer", "3,TechAge Kelle / Trowel", "3,TA3 Bohrgestängezange / TA3 Drill Pipe Wrench", + "3,Techage Schraubendreher", "1,TA4: Gegenwart", "2,Windkraftanlage", "3,TA4 Windkraftanlage / Wind Turbine", @@ -229,7 +230,13 @@ techage.manual_DE.aTitel = { "3,TA4 Recycler", "1,TA5: Zukunft", "2,Energiequellen", - "3,TA5 Fusionsreaktor (geplant)", + "3,TA5 Fusionsreaktor", + "4,TA5 Fusionreaktor Magnet", + "4,TA5 Pumpe", + "4,TA5 Wärmetauscher", + "4,TA5 Fusionreaktor Controller", + "4,TA5 Fusionreaktor Hülle", + "4,TA5 Fusionreaktor Kern", "2,Energiespeicher", "3,TA5 Hybrid-Speicher (geplant)", "2,Logik Blöcke", @@ -1268,6 +1275,15 @@ techage.manual_DE.aText = { "\n".. "\n".. "\n", + "Der Techage Schraubendreher dient als Ersatz für den normalen Schraubendreher. Es besitzt folgende Funktionen:\n".. + "\n".. + " - Linksklick: Den Block nach links drehen\n".. + " - Rechtsklick: Die sichtbare Seite des Blockes nach oben drehen\n".. + " - Shift+Linksklick: Ausrichtung des angeklickten Blockes speichern\n".. + " - Shift+Rechtsklick: Die gespeicherte Ausrichtung auf den angeklickten Block anwenden\n".. + "\n".. + "\n".. + "\n", "Regenerative Energiequellen wie Wind\\, Sonne und Biokraft helfen dir\\, das Ölzeitalter zu verlassen. Mit modernen Technologien und intelligenten Maschinen machst du dich auf in die Zukunft.\n".. "\n".. "\n".. @@ -1985,7 +2001,48 @@ techage.manual_DE.aText = { "\n".. "\n", "", - "", + "Kernfusion bedeutet das Verschmelzen zweier Atomkerne. Dabei können\\, je nach Reaktion\\, große Mengen von Energie freigesetzt werden. Kernfusionen\\, bei denen Energie frei wird\\, laufen in Form von Kettenreaktionen ab. Sie sind die Quelle der Energie der Sterne\\, zum Beispiel auch unserer Sonne. Ein Fusionsreaktor wandelt die Energie\\, die bei einer kontrollierten Kernfusion frei wird\\, in elektrischen Strom um.\n".. + "\n".. + "*Wie funktionieren ein Fusionsreaktor?*\n".. + "\n".. + "Ein Fusionsreaktor funktioniert nach dem klassischen Prinzip eines Wärmekraftwerks: Wasser wird erhitzt und treibt eine Dampfturbine an\\, deren Bewegungsenergie von einem Generator in Strom gewandelt wird.\n".. + "\n".. + "Ein Fusionskraftwerk benötigt zunächst eine hohe Menge an Energie\\, da ein Plasma erzeugt werden muss. „Plasma“ nennt man den vierten Zustand von Stoffen\\, nach fest\\, flüssig und gasförmig. Dafür wird viel Strom benötigt. Erst durch diese extreme Energiekonzentration zündet die Fusionsreaktion und mit der abgegebenen Wärme wird über den Wärmetauscher Strom erzeugt. Der Generator liefert dann 800 ku an Strom.\n".. + "\n".. + "Der Plan rechts zeigt einen Schnitt durch den Fusionsreaktor.\n".. + "\n".. + "Für den Betrieb des Fusionsreaktors werden 60 Erfahrungspunkte benötigt. Der Fusionsreaktur muss komplett in einem Forceload Block Bereich aufgebaut werden.\n".. + "\n".. + "\n".. + "\n", + "Für den Aufbau des Fusionsreaktor werden insgesamt 60 TA5 Fusionreaktor Magnete benötigt. Diese bilden den Ring\\, in dem sich das Plasma bildet. Der TA5 Fusionsreaktor Magnete benötigt Strom und hat zwei Anschlüsse für die Kühlung.\n".. + "\n".. + "Es gibt zwei Typen von Magneten\\, so dass auch alle Seiten des Magnets\\, die zum Plasmaring zeigen\\, mit einem Hitzeschild geschützt werden können.\n".. + "\n".. + "Bei den Eckmagneten auf der Innenseite des Rings ist jeweils eine Anschlussseite verdeckt (Strom oder Kühlung) und kann daher nicht angeschlossen werden. Dies ist technisch nicht machbar und hat daher keinen Einfluß auf die Funktion des Fusionsreaktor. \n".. + "\n".. + "\n".. + "\n", + "Die Pumpe wird benötigt\\, um den Kühlkreislauf mit Isobutan zu füllen. Es werden ca. 350 Einheiten Isobutan benötigt.\n".. + "\n".. + "\n".. + "\n", + "Der TA5 Wärmetauscher wird benötigt\\, um die im Fusionsreaktor erzeugte Hitze zuerst in Dampf und dann in Strom umzuwandeln. Der Wärmetauscher selbst benötigt dazu 5 ku Strom. Der Aufbau gleicht dem Wärmetauscher des Energiespeichers aus TA4.\n".. + "\n".. + "\n".. + "\n", + "Über den TA5 Fusionreaktor Controller wird der Fusionreaktors eingeschaltet. Dabei muss zuerst die Kühlung/Wärmetauscher und dann der Controller eingeschaltet werden. Es dauert ca. 2 min\\, bis der Reaktor in Gang kommt und Strom liefert. Der Fusionreaktor und damit der Controller benötigt 400 ku an Strom\\, um das Plasma aufrecht zu erhalten.\n".. + "\n".. + "\n".. + "\n", + "Der komplette Reaktor muss mit einer Hülle umgeben werden\\, die den enormen Druck\\, den die Magnete auf das Plasma ausüben\\, abfängt und die Umgebung vor Strahlung schützt. Ohne diese Hülle kann der Reaktor nicht gestartet werden. Mit der TechAge Kelle können auch Stromkabel und Kühlleitungen des Fusionreaktors in die Hülle integriert werden.\n".. + "\n".. + "\n".. + "\n", + "Der Kern muss in der Mitte des Reaktors sitzen. Siehe Abbildung unter \"TA5 Fusionsreaktor\". Auch hierfür wird die TechAge Kelle benötigt.\n".. + "\n".. + "\n".. + "\n", "", "", "", @@ -2198,6 +2255,7 @@ techage.manual_DE.aItemName = { "ta3_programmer", "ta3_trowel", "ta3_drill_pipe_wrench", + "ta3_screwdriver", "techage_ta4", "", "ta4_windturbine", @@ -2289,6 +2347,12 @@ techage.manual_DE.aItemName = { "techage_ta5", "", "", + "ta5_magnet", + "ta5_pump", + "", + "ta5_fr_controller", + "ta5_fr_shell", + "ta5_fr_nucleus", "", "", "", @@ -2446,6 +2510,7 @@ techage.manual_DE.aPlanTable = { "", "", "", + "", "ta4_windturbine", "", "", @@ -2535,6 +2600,12 @@ techage.manual_DE.aPlanTable = { "", "", "", + "ta5_fusion_reactor", + "", + "", + "ta5_heatexchanger", + "", + "", "", "", "", @@ -2552,3 +2623,4 @@ techage.manual_DE.aPlanTable = { "", "", } + diff --git a/techage/doc/manual_EN.lua b/techage/doc/manual_EN.lua index 024086f..0abb1d6 100644 --- a/techage/doc/manual_EN.lua +++ b/techage/doc/manual_EN.lua @@ -139,6 +139,7 @@ techage.manual_EN.aTitel = { "3,TechAge Programmer", "3,TechAge Trowel / Trowel", "3,TA3 drill pipe wrench", + "3,Techage Screwdriver", "1,TA4: Present", "2,Wind Turbine", "3,TA4 Wind Turbine", @@ -229,7 +230,13 @@ techage.manual_EN.aTitel = { "3,TA4 Recycler", "1,TA5: Future", "2,Energy Sources", - "3,TA5 Fusion Reactor (planned)", + "3,TA5 Fusion Reactor", + "4,TA5 Fusion Reactor Magnet", + "4,TA5 Pump", + "4,TA5 Heat Exchanger", + "4,TA5 Fusion Reactor Controller", + "4,TA5 Fusion Reactor Shell", + "4,TA5 Fusion Reactor Core", "2,Energy Storage", "3,TA5 Hybrid Storage (planned)", "2,Logic blocks", @@ -1266,6 +1273,15 @@ techage.manual_EN.aText = { "\n".. "\n".. "\n", + "The Techage Screwdriver serves as a replacement for the normal screwdriver. It has the following functions:\n".. + "\n".. + " - Left click: turn the block to the left\n".. + " - Right click: turn the visible side of the block upwards\n".. + " - Shift + left click: save the alignment of the clicked block\n".. + " - Shift + right click: apply the saved alignment to the clicked block\n".. + "\n".. + " \n".. + "\n", "Renewable energy sources such as wind\\, sun and biofuels help you to leave the oil age. With modern technologies and intelligent machines you set out into the future.\n".. "\n".. "\n".. @@ -1982,7 +1998,48 @@ techage.manual_EN.aText = { "\n".. "\n", "", - "", + "Nuclear fusion means the fusing of two atomic nuclei. Depending on the reaction\\, large amounts of energy can be released. Nuclear fusions\\, in which energy is released\\, take place in the form of chain reactions. They are the source of the energy of the stars\\, including our sun\\, for example. A fusion reactor converts the energy released during controlled nuclear fusion into electricity.\n".. + "\n".. + "*How ​​do fusion reactors work?*\n".. + "\n".. + "A fusion reactor works according to the classic principle of a thermal power plant: water is heated and drives a steam turbine\\, whose kinetic energy is converted into electricity by a generator.\n".. + "\n".. + "A fusion power plant initially requires a large amount of energy\\, since a plasma has to be generated. \"Plasma\" is the name given to the fourth state of matter\\, after solid\\, liquid and gaseous. This requires a lot of electricity. Only through this extreme concentration of energy does the fusion reaction ignite and the heat given off is used to generate electricity via the heat exchanger. The generator then delivers 800 ku of electricity.\n".. + "\n".. + "The plan on the right shows a section through the fusion reactor.\n".. + "\n".. + "60 experience points are required to operate the fusion reactor. The fusion reactor must be built entirely in a forceload block area.\n".. + "\n".. + "\n".. + "\n", + "A total of 60 TA5 Fusion Reactor Magnets are required to set up the fusion reactor. These form the ring in which the plasma forms. The TA5 Fusion Reactor Magnets requires power and has two ports for cooling.\n".. + "\n".. + "There are two types of magnets\\, so all sides of the magnet that face the plasma ring can also be protected with a heat shield.\n".. + "\n".. + "With the corner magnets on the inside of the ring\\, one connection side is covered (power or cooling) and can therefore not be connected. This is technically not feasible and therefore has no influence on the function of the fusion reactor. \n".. + "\n".. + "\n".. + "\n", + "The pump is required to fill the cooling circuit with isobutane. About 350 units of isobutane are required.\n".. + "\n".. + "\n".. + "\n", + "The TA5 Heat Exchanger is required to convert the heat generated in the fusion reactor first to steam and then to electricity. The Heat Exchanger itself requires 5 ku electricity. The structure is similar to the Heat Exchanger of the energy store from TA4.\n".. + "\n".. + "\n".. + "\n", + "The fusion reactor is switched on via the TA5 Fusion Reactor Controller. The cooling/Heat Exchanger must be switched on first and then the controller. It takes about 2 minutes for the reactor to start up and supply electricity. The fusion reactor and thus the controller requires 400 ku of electricity to maintain the plasma.\n".. + "\n".. + "\n".. + "\n", + "The entire reactor must be surrounded by a shell that absorbs the enormous pressure that the magnets exert on the plasma and protects the environment from radiation. Without this shell\\, the reactor cannot be started. With the TechAge Trowel\\, power cables and cooling pipes of the fusion reactor can also be integrated into the shell.\n".. + "\n".. + "\n".. + "\n", + "The core must sit in the center of the reactor. See illustration under \"TA5 Fusion Reactor\". The TechAge Trowel is also required for this.\n".. + "\n".. + "\n".. + "\n", "", "", "", @@ -2193,6 +2250,7 @@ techage.manual_EN.aItemName = { "ta3_programmer", "ta3_trowel", "ta3_drill_pipe_wrench", + "ta3_screwdriver", "techage_ta4", "", "ta4_windturbine", @@ -2284,6 +2342,12 @@ techage.manual_EN.aItemName = { "techage_ta5", "", "", + "ta5_magnet", + "ta5_pump", + "", + "ta5_fr_controller", + "ta5_fr_shell", + "ta5_fr_nucleus", "", "", "", @@ -2440,6 +2504,7 @@ techage.manual_EN.aPlanTable = { "", "", "", + "", "ta4_windturbine", "", "", @@ -2529,6 +2594,12 @@ techage.manual_EN.aPlanTable = { "", "", "", + "ta5_fusion_reactor", + "", + "", + "ta5_heatexchanger", + "", + "", "", "", "", @@ -2545,3 +2616,4 @@ techage.manual_EN.aPlanTable = { "", "", } + diff --git a/techage/doc/plans.lua b/techage/doc/plans.lua index 6934d54..3cf0476 100644 --- a/techage/doc/plans.lua +++ b/techage/doc/plans.lua @@ -25,9 +25,11 @@ local IMG42 = {"", "techage_ta4_solar.png"} local IMG43 = {"", "techage_reactor_inv.png"} local IMG44 = {"", "techage_ta4_filter.png"} local IMG45 = {"10x10", "techage_collider_plan.png"} +local IMG46 = {"5x4", "techage_fusion_reactor.png"} local TOP_V = {"top_view", ""} local SIDEV = {"side_view", ""} +local SECTV = {"sectional_view", ""} -- -- TA1: Coal Pile @@ -513,6 +515,52 @@ techage.ConstructionPlans["ta5_teleport"] = { {false, TANK4, PIPEH, TELEP, false, ARROW, false, TELEP, PUMP4, TANK4, false}, } +-- +-- TA5 Fusion Reactor +-- +local SHELL = {"techage_reactor_shell.png", "techage:ta5_fr_shell"} +local NUCLS = {"techage_reactor_shell.png^techage_collider_detector_core.png", "techage:ta5_fr_nucleus"} +local MAGN1 = {"techage_collider_magnet.png^techage_steel_tiles_top3.png", "techage:ta5_magnet1"} +local MAGN2 = {"techage_collider_magnet.png^techage_steel_tiles_top3.png^[transformR90]", "techage:ta5_magnet1"} +local MAGN3 = {"techage_collider_magnet.png^techage_steel_tiles_top3.png^[transformR180]", "techage:ta5_magnet1"} +local MAGN4 = {"techage_collider_magnet.png^techage_steel_tiles_top3.png^[transformR270]", "techage:ta5_magnet1"} + +techage.ConstructionPlans["ta5_fusion_reactor"] = { + {false, false, false, false, false, false, IMG46, false, false, false, false}, + {false, false, false, false, false, false, false, false, false, false, false}, + {false, false, false, false, false, false, false, false, false, false, false}, + {false, false, false, false, false, false, false, false, false, false, false}, + {false, SECTV, false, false, false, false, false, false, false, false, false}, + {false, false, SHELL, SHELL, SHELL, false, SHELL, SHELL, SHELL, false, false}, + {false, SHELL, SHELL, MAGN3, SHELL, SHELL, SHELL, MAGN3, SHELL, SHELL, false}, + {false, SHELL, MAGN4, false, MAGN2, NUCLS, MAGN4, false, MAGN2, SHELL, false}, + {false, SHELL, SHELL, MAGN1, SHELL, SHELL, SHELL, MAGN1, SHELL, SHELL, false}, + {false, false, SHELL, SHELL, SHELL, false, SHELL, SHELL, SHELL, false, false}, +} + +-- +-- TA5 Heat Exchanger +-- +local PIPEG = {"techage_ta5_gaspipe.png", "techage:ta5_pipe1S"} +local PIPEB = {"techage_ta5_gaspipeB.png", "techage:ta5_pipe2S"} +local HEX51 = {"techage_filling_ta4.png^techage_frameT_ta5.png^techage_appl_ribsT.png", "techage:ta5_heatexchanger3"} +local HEX52 = {"techage_filling_ta4.png^techage_frameM_ta4.png^techage_appl_ribsB.png", "techage:ta5_heatexchanger2"} +local HEX53 = {"techage_filling_ta4.png^techage_frameB_ta4.png^techage_appl_hole_electric.png", "techage:ta5_heatexchanger1"} +local TURB5 = {"techage_filling_ta4.png^techage_appl_turbine.png^techage_frame_ta5.png", "techage:ta5_turbine"} +local GENE5 = {"techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_generator.png^[transformFX]", "techage:ta5_generator"} + +techage.ConstructionPlans["ta5_heatexchanger"] = { + {false, false, false, false, SIDEV, false, false, false}, + {false, false, false, false, false, false, false, false}, + {false, false, false, false, false, false, false, false}, + {false, false, PIPEG, PIPEG, HEX51, PIPEH, PN270, false}, + {false, false, false, false, HEX52, false, PIPEV, false}, + {false, false, PIPEB, PIPEB, HEX53, PIPEH, TURB5, GENE5}, + {false, false, false, false, false, false, false, false}, + {false, false, false, false, false, false, false, false}, +} + + function techage.add_manual_plans(table_with_plans) for name, tbl in pairs(table_with_plans) do techage.ConstructionPlans[name] = tbl diff --git a/techage/fusion_reactor/controller.lua b/techage/fusion_reactor/controller.lua new file mode 100644 index 0000000..848cdaf --- /dev/null +++ b/techage/fusion_reactor/controller.lua @@ -0,0 +1,283 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2022 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA5 Fusion Reactor Controller + +]]-- + +-- for lazy programmers +local S2P = minetest.string_to_pos +local P2S = minetest.pos_to_string +local M = minetest.get_meta +local S = techage.S + +local Cable = techage.ElectricCable +local sched = techage.scheduler +local power = networks.power +local control = networks.control + +local CYCLE_TIME = 2 +local STANDBY_TICKS = 0 +local COUNTDOWN_TICKS = 1 +local PWR_NEEDED = 400 +local EXPECTED_PLASMA_NUM = 56 +local EXPECTED_SHELL_NUM = 56 +local EXPECTED_MAGNET_NUM = 56 +local CALL_RATE1 = 16 -- 2s * 16 = 32s +local CALL_RATE2 = 8 -- 2s * 8 = 16s +local DESCRIPTION = S("TA5 Fusion Reactor Controller") +local EX_POINTS = 60 + +local function count_trues(t) + local cnt = 0 + for _,v in ipairs(t) do + if v then + cnt = cnt + 1 + end + end + return cnt +end + +local function nucleus(t) + if #t == 4 then + if vector.equals(t[1], t[2]) and vector.equals(t[3], t[4]) then + return true + end + end + return S("Nucleus detection error") +end + +local tSched = {} + +sched.register(tSched, CALL_RATE1, 0, function(pos, outdir) + local resp = control.request(pos, Cable, outdir, "con", "connect") + local cnt = count_trues(resp) + if cnt ~= EXPECTED_MAGNET_NUM then + return S("Magnet detection error\n(@1% found / 100% expected)", math.floor(cnt* 100 / EXPECTED_MAGNET_NUM)) + end + return true + end) + +sched.register(tSched, CALL_RATE1, 1, function(pos, outdir) + local resp = control.request(pos, Cable, outdir, "con", "test_plasma") + local cnt = count_trues(resp) + if cnt ~= EXPECTED_PLASMA_NUM then + return S("Plasma ring shape error") + end + return true + end) + +sched.register(tSched, CALL_RATE1, 2, function(pos, outdir) + local resp = control.request(pos, Cable, outdir, "con", "test_shell") + local cnt = count_trues(resp) + if cnt ~= EXPECTED_SHELL_NUM then + return S("Shell shape error\n(@1% found / 100% expected)", math.floor(cnt* 100 / EXPECTED_SHELL_NUM)) + end + return true + end) + +sched.register(tSched, CALL_RATE1, 3, function(pos, outdir) + local resp = control.request(pos, Cable, outdir, "con", "test_nucleus") + return nucleus(resp) + end) + +sched.register(tSched, CALL_RATE2, 4, function(pos, outdir) + local resp = control.request(pos, Cable, outdir, "con", "inc_power") + local cnt = count_trues(resp) + --print("inc_power", cnt) + if cnt < 52 then + return S("Cooling failed") + end + return true + end) + +local function can_start(pos, nvm) + local outdir = networks.side_to_outdir(pos, "L") + if not power.power_available(pos, Cable, outdir) then + return S("No power") + end + outdir = networks.side_to_outdir(pos, "R") + control.request(pos, Cable, outdir, "con", "rst_power") + for i = 0,4 do + local res = tSched[i](pos, outdir) + if res ~= true then return res end + end + return true +end + +local function start_node(pos, nvm) + sched.init(pos) + local outdir = networks.side_to_outdir(pos, "R") + control.send(pos, Cable, outdir, "con", "on") + sched.init(pos) +end + +local function stop_node(pos, nvm) + local outdir = networks.side_to_outdir(pos, "R") + control.send(pos, Cable, outdir, "con", "off") +end + +local function formspec(self, pos, nvm) + return "size[5,3]".. + "box[0,-0.1;4.8,0.5;#c6e8ff]" .. + "label[0.2,-0.1;" .. minetest.colorize( "#000000", DESCRIPTION) .. "]" .. + "image_button[2,1.5;1,1;".. self:get_state_button_image(nvm) ..";state_button;]".. + "tooltip[2,1.5;1,1;"..self:get_state_tooltip(nvm).."]" +end + +local State = techage.NodeStates:new({ + node_name_passive = "techage:ta5_fr_controller_pas", + node_name_active = "techage:ta5_fr_controller_act", + cycle_time = CYCLE_TIME, + infotext_name = DESCRIPTION, + standby_ticks = STANDBY_TICKS, + can_start = can_start, + start_node = start_node, + stop_node = stop_node, + formspec_func = formspec, +}) + +local function after_place_node(pos, placer, itemstack) + local nvm = techage.get_nvm(pos) + local meta = M(pos) + local own_num = techage.add_node(pos, "techage:ta5_fr_controller_pas") + State:node_init(pos, nvm, own_num) + meta:set_string("owner", placer:get_player_name()) + Cable:after_place_node(pos) +end + +local function consume_power(pos, nvm, outdir) + if techage.needs_power(nvm) then + local taken = power.consume_power(pos, Cable, outdir, PWR_NEEDED) + if techage.is_running(nvm) then + if taken < PWR_NEEDED then + State:nopower(pos, nvm, "No power") + stop_node(pos, nvm) + else + return true -- keep running + end + end + end +end + +local function node_timer(pos) + local nvm = techage.get_nvm(pos) + local outdir = networks.side_to_outdir(pos, "L") + if consume_power(pos, nvm, outdir) then + local resp = sched.get(pos, tSched, function() + return true end)(pos, networks.Flip[outdir]) + if resp ~= true then + State:fault(pos, nvm, resp) + stop_node(pos, nvm) + else + State:keep_running(pos, nvm, COUNTDOWN_TICKS) + end + end + return State:is_active(nvm) +end + +local function after_dig_node(pos, oldnode, oldmetadata) + Cable:after_dig_node(pos) + techage.remove_node(pos, oldnode, oldmetadata) + techage.del_mem(pos) +end + +local function on_receive_fields(pos, formname, fields, player) + if minetest.is_protected(pos, player:get_player_name()) then + return + end + + if techage.get_expoints(player) >= EX_POINTS then + local nvm = techage.get_nvm(pos) + State:state_button_event(pos, nvm, fields) + --M(pos):set_string("formspec", formspec(State, pos, nvm)) + end +end + +minetest.register_node("techage:ta5_fr_controller_pas", { + description = S("TA5 Fusion Reactor Controller"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta5_top.png^techage_appl_arrow.png", + "techage_filling_ta4.png^techage_frame_ta4_bottom.png", + "techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_hole_electric.png", + "techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_hole_electric.png", + "techage_filling_ta4.png^techage_appl_plasma.png^techage_frame_ta5.png", + "techage_filling_ta4.png^techage_appl_plasma.png^techage_frame_ta5.png", + }, + after_place_node = after_place_node, + on_timer = node_timer, + after_dig_node = after_dig_node, + on_receive_fields = on_receive_fields, + drawtype = "nodebox", + paramtype2 = "facedir", + groups = {choppy=2, cracky=2, crumbly=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +minetest.register_node("techage:ta5_fr_controller_act", { + description = S("TA5 Fusion Reactor Controller"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta5_top.png^techage_appl_arrow.png", + "techage_filling_ta4.png^techage_frame_ta4_bottom.png", + "techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_hole_electric.png", + "techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_hole_electric.png", + { + image = "techage_filling4_ta4.png^techage_appl_plasma4.png^techage_frame4_ta5.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 64, + aspect_h = 64, + length = 0.5, + }, + }, + { + image = "techage_filling4_ta4.png^techage_appl_plasma4.png^techage_frame4_ta5.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 64, + aspect_h = 64, + length = 0.5, + }, + }, + }, + after_place_node = after_place_node, + on_timer = node_timer, + after_dig_node = after_dig_node, + on_receive_fields = on_receive_fields, + drawtype = "nodebox", + paramtype2 = "facedir", + groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1}, + drop = "", + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +techage.register_node({"techage:ta5_fr_controller_pas", "techage:ta5_fr_controller_act"}, { + on_recv_message = function(pos, src, topic, payload) + return State:on_receive_message(pos, topic, payload) + end, +}) + +power.register_nodes({"techage:ta5_fr_controller_pas", "techage:ta5_fr_controller_act"}, Cable, "con", {"L", "R"}) + +minetest.register_craft({ + output = "techage:ta5_fr_controller_pas", + recipe = { + {'techage:aluminum', 'basic_materials:gold_wire', 'default:steel_ingot'}, + {'techage:electric_cableS', 'techage:ta5_aichip2', 'techage:electric_cableS'}, + {'default:steel_ingot', 'default:diamond', 'techage:aluminum'}, + }, +}) + diff --git a/techage/fusion_reactor/gas_pipe.lua b/techage/fusion_reactor/gas_pipe.lua new file mode 100644 index 0000000..108164d --- /dev/null +++ b/techage/fusion_reactor/gas_pipe.lua @@ -0,0 +1,331 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2022 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA5 Gas Pipes + +]]-- + +-- for lazy programmers +local S2P = minetest.string_to_pos +local P2S = minetest.pos_to_string +local M = minetest.get_meta +local S = techage.S + +local MAX_PIPE_LENGHT = 100 + +local liquid = networks.liquid + +local Pipe = tubelib2.Tube:new({ + dirs_to_check = {1,2,3,4,5,6}, + max_tube_length = MAX_PIPE_LENGHT, + show_infotext = false, + force_to_use_tubes = false, + tube_type = "pipe3", + primary_node_names = { + "techage:ta5_pipe1S", "techage:ta5_pipe1A", + "techage:ta5_pipe2S", "techage:ta5_pipe2A", + }, + secondary_node_names = {}, + after_place_tube = function(pos, param2, tube_type, num_tubes) + local name = minetest.get_node(pos).name + if not networks.hidden_name(pos) then + local name = minetest.get_node(pos).name + if name == "techage:ta5_pipe1S" or name == "techage:ta5_pipe1A" then + minetest.swap_node(pos, {name = "techage:ta5_pipe1"..tube_type, param2 = param2 % 32}) + else + minetest.swap_node(pos, {name = "techage:ta5_pipe2"..tube_type, param2 = param2 % 32}) + end + end + M(pos):set_int("netw_param2", param2) + end, +}) + +-- Enable hidden cables +networks.use_metadata(Pipe) + +-- Use global callback instead of node related functions +Pipe:register_on_tube_update2(function(pos, outdir, tlib2, node) + liquid.update_network(pos, outdir, tlib2, node) +end) + +minetest.register_node("techage:ta5_pipe1S", { + description = S("TA5 Pipe"), + tiles = { + "techage_ta5_gaspipe.png^[transformR90^[colorize:#000080:160", + "techage_ta5_gaspipe.png^[transformR90^[colorize:#000080:160", + "techage_ta5_gaspipe.png^[colorize:#000080:160", + "techage_ta5_gaspipe.png^[colorize:#000080:160", + "techage_ta5_gaspipe_hole2.png^[colorize:#000080:160", + "techage_ta5_gaspipe_hole2.png^[colorize:#000080:160", + }, + + after_place_node = function(pos, placer, itemstack, pointed_thing) + if not Pipe:after_place_tube(pos, placer, pointed_thing) then + minetest.remove_node(pos) + return true + end + return false + end, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Pipe:after_dig_tube(pos, oldnode, oldmetadata) + end, + + paramtype2 = "facedir", -- important! + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-1/16, -1/16, -8/16, 1/16, 1/16, 8/16}, + }, + }, + on_rotate = screwdriver.disallow, -- important! + paramtype = "light", + use_texture_alpha = techage.CLIP, + sunlight_propagates = true, + is_ground_content = false, + groups = {crumbly = 2, cracky = 2, snappy = 2, techage_trowel = 1}, + sounds = default.node_sound_metal_defaults(), +}) + +minetest.register_node("techage:ta5_pipe1A", { + description = S("TA5 Pipe"), + tiles = { + "techage_ta5_gaspipe_knee2.png^[colorize:#000080:160", + "techage_ta5_gaspipe_hole2.png^[transformR180^[colorize:#000080:160", + "techage_ta5_gaspipe_knee.png^[transformR270^[colorize:#000080:160", + "techage_ta5_gaspipe_knee.png^[colorize:#000080:160", + "techage_ta5_gaspipe_knee2.png^[colorize:#000080:160", + "techage_ta5_gaspipe_hole2.png^[colorize:#000080:160", + }, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Pipe:after_dig_tube(pos, oldnode, oldmetadata) + end, + + paramtype2 = "facedir", -- important! + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-1/16, -8/16, -1/16, 1/16, 1/16, 1/16}, + {-2/16, -0.5, -2/16, 2/16, -13/32, 2/16}, + {-1/16, -1/16, -8/16, 1/16, 1/16, -1/16}, + {-2/16, -2/16, -0.5, 2/16, 2/16, -13/32}, + }, + }, + on_rotate = screwdriver.disallow, -- important! + paramtype = "light", + use_texture_alpha = techage.CLIP, + sunlight_propagates = true, + is_ground_content = false, + groups = {crumbly = 2, cracky = 2, snappy = 2, + not_in_creative_inventory=1, techage_trowel = 1}, + sounds = default.node_sound_metal_defaults(), + drop = "techage:ta5_pipe1S", +}) + +minetest.register_node("techage:ta5_pipe2S", { + description = S("TA5 Pipe"), + tiles = { + "techage_ta5_gaspipe.png^[transformR90^[colorize:#008000:160", + "techage_ta5_gaspipe.png^[transformR90^[colorize:#008000:160", + "techage_ta5_gaspipe.png^[colorize:#008000:160", + "techage_ta5_gaspipe.png^[colorize:#008000:160", + "techage_ta5_gaspipe_hole2.png^[colorize:#008000:160", + "techage_ta5_gaspipe_hole2.png^[colorize:#008000:160", + }, + + after_place_node = function(pos, placer, itemstack, pointed_thing) + if not Pipe:after_place_tube(pos, placer, pointed_thing) then + minetest.remove_node(pos) + return true + end + return false + end, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Pipe:after_dig_tube(pos, oldnode, oldmetadata) + end, + + paramtype2 = "facedir", -- important! + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-1/16, -1/16, -8/16, 1/16, 1/16, 8/16}, + }, + }, + on_rotate = screwdriver.disallow, -- important! + paramtype = "light", + use_texture_alpha = techage.CLIP, + sunlight_propagates = true, + is_ground_content = false, + groups = {crumbly = 2, cracky = 2, snappy = 2, techage_trowel = 1}, + sounds = default.node_sound_metal_defaults(), +}) + +minetest.register_node("techage:ta5_pipe2A", { + description = S("TA5 Pipe"), + tiles = { + "techage_ta5_gaspipe_knee2.png^[colorize:#008000:160", + "techage_ta5_gaspipe_hole2.png^[transformR180^[colorize:#008000:160", + "techage_ta5_gaspipe_knee.png^[transformR270^[colorize:#008000:160", + "techage_ta5_gaspipe_knee.png^[colorize:#008000:160", + "techage_ta5_gaspipe_knee2.png^[colorize:#008000:160", + "techage_ta5_gaspipe_hole2.png^[colorize:#008000:160", + }, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Pipe:after_dig_tube(pos, oldnode, oldmetadata) + end, + + paramtype2 = "facedir", -- important! + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-1/16, -8/16, -1/16, 1/16, 1/16, 1/16}, + {-2/16, -0.5, -2/16, 2/16, -13/32, 2/16}, + {-1/16, -1/16, -8/16, 1/16, 1/16, -1/16}, + {-2/16, -2/16, -0.5, 2/16, 2/16, -13/32}, + }, + }, + on_rotate = screwdriver.disallow, -- important! + paramtype = "light", + use_texture_alpha = techage.CLIP, + sunlight_propagates = true, + is_ground_content = false, + groups = {crumbly = 2, cracky = 2, snappy = 2, + not_in_creative_inventory=1, techage_trowel = 1}, + sounds = default.node_sound_metal_defaults(), + drop = "techage:ta5_pipe2S", +}) + +local size1 = 1/16 +local size2 = 2/16 +local size3 = 13/32 +local Boxes = { + { + {-size1, -size1, size1, size1, size1, 0.5 }, -- z+ + {-size2, -size2, size3, size2, size2, 0.5 }, -- z+ + }, + { + {-size1, -size1, -size1, 0.5, size1, size1}, -- x+ + { size3, -size2, -size2, 0.5, size2, size2}, -- x+ + }, + { + {-size1, -size1, -0.5, size1, size1, size1}, -- z- + {-size2, -size2, -0.5, size2, size2, -size3}, -- z- + }, + { + {-0.5, -size1, -size1, size1, size1, size1}, -- x- + {-0.5, -size2, -size2, -size3, size2, size2}, -- x- + }, + { + {-size1, -0.5, -size1, size1, size1, size1}, -- y- + {-size2, -0.5, -size2, size2, -size3, size2}, -- y- + }, + { + {-size1, -size1, -size1, size1, 0.5, size1}, -- y+ + {-size2, size3, -size2, size2, 0.5, size2}, -- y+ + } +} + +local names1 = networks.register_junction("techage:ta5_junctionpipe1", 1/8, Boxes, Pipe, { + description = S("TA5 Junction Pipe"), + tiles = {"techage_ta5_gaspipe_junction.png^[colorize:#000080:160"}, + use_texture_alpha = techage.CLIP, + is_ground_content = false, + groups = {crumbly = 2, cracky = 2, snappy = 2, techage_trowel = 1}, + sounds = default.node_sound_metal_defaults(), + + after_place_node = function(pos, placer, itemstack, pointed_thing) + local name = "techage:ta5_junctionpipe1" .. networks.junction_type(pos, Pipe) + minetest.swap_node(pos, {name = name, param2 = 0}) + Pipe:after_place_node(pos) + end, + tubelib2_on_update2 = function(pos, dir1, tlib2, node) + if not networks.hidden_name(pos) then + local name = "techage:ta5_junctionpipe1" .. networks.junction_type(pos, Pipe) + minetest.swap_node(pos, {name = name, param2 = 0}) + end + liquid.update_network(pos, 0, tlib2, node) + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Pipe:after_dig_node(pos) + end, +}, 25) + +local names2 = networks.register_junction("techage:ta5_junctionpipe2", 1/8, Boxes, Pipe, { + description = S("TA5 Junction Pipe"), + tiles = {"techage_ta5_gaspipe_junction.png^[colorize:#008000:160"}, + use_texture_alpha = techage.CLIP, + is_ground_content = false, + groups = {crumbly = 2, cracky = 2, snappy = 2, techage_trowel = 1}, + sounds = default.node_sound_metal_defaults(), + + after_place_node = function(pos, placer, itemstack, pointed_thing) + local name = "techage:ta5_junctionpipe2" .. networks.junction_type(pos, Pipe) + minetest.swap_node(pos, {name = name, param2 = 0}) + Pipe:after_place_node(pos) + end, + tubelib2_on_update2 = function(pos, dir1, tlib2, node) + if not networks.hidden_name(pos) then + local name = "techage:ta5_junctionpipe2" .. networks.junction_type(pos, Pipe) + minetest.swap_node(pos, {name = name, param2 = 0}) + end + liquid.update_network(pos, 0, tlib2, node) + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Pipe:after_dig_node(pos) + end, +}, 25) + +liquid.register_nodes(names1, Pipe, "junc") +liquid.register_nodes(names2, Pipe, "junc") + +minetest.register_craft({ + output = "techage:ta5_pipe1S 6", + recipe = { + {'', '', "default:steel_ingot"}, + {'', 'dye:blue', 'techage:ta4_carbon_fiber'}, + {"", '', 'techage:aluminum'}, + }, +}) + +minetest.register_craft({ + output = "techage:ta5_pipe2S 6", + recipe = { + {'', '', "default:steel_ingot"}, + {'', 'dye:green', 'techage:ta4_carbon_fiber'}, + {"", '', 'techage:aluminum'}, + }, +}) + +minetest.register_craft({ + output = "techage:ta5_junctionpipe125 2", + recipe = { + {"", "techage:ta5_pipe1S", ""}, + {"techage:ta5_pipe1S", "", "techage:ta5_pipe1S"}, + {"", "techage:ta5_pipe1S", ""}, + }, +}) + +minetest.register_craft({ + output = "techage:ta5_junctionpipe225 2", + recipe = { + {"", "techage:ta5_pipe2S", ""}, + {"techage:ta5_pipe2S", "", "techage:ta5_pipe2S"}, + {"", "techage:ta5_pipe2S", ""}, + }, +}) + +techage.GasPipe = Pipe diff --git a/techage/fusion_reactor/generator.lua b/techage/fusion_reactor/generator.lua new file mode 100644 index 0000000..cd78b5c --- /dev/null +++ b/techage/fusion_reactor/generator.lua @@ -0,0 +1,204 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2022 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA5 Fusion Reactor Generator +]]-- + +-- for lazy programmers +local M = minetest.get_meta +local S = techage.S + +local Cable = techage.ElectricCable +local power = networks.power +local control = networks.control + +local CYCLE_TIME = 2 +local PWR_PERF = 800 + +local function swap_node(pos, name) + local node = techage.get_node_lvm(pos) + if node.name == name then + return + end + node.name = name + minetest.swap_node(pos, node) +end + +local function start_node(pos, nvm) + local meta = M(pos) + nvm.provided = 0 + nvm.alive_cnt = 5 + techage.evaluate_charge_termination(nvm, meta) + local outdir = meta:get_int("outdir") + power.start_storage_calc(pos, Cable, outdir) + swap_node(pos, "techage:ta5_generator_on") + minetest.get_node_timer(pos):start(CYCLE_TIME) +end + +local function stop_node(pos, nvm) + nvm.provided = 0 + nvm.alive_cnt = 0 + local outdir = M(pos):get_int("outdir") + power.start_storage_calc(pos, Cable, outdir) + swap_node(pos, "techage:ta5_generator") +end + +local function get_generator_data(pos, outdir, tlib2) + local nvm = techage.get_nvm(pos) + if (nvm.alive_cnt or 0) > 0 then + return {level = (nvm.load or 0) / PWR_PERF, perf = PWR_PERF, capa = PWR_PERF * 2} + end +end + +local function node_timer(pos, elapsed) + local nvm = techage.get_nvm(pos) + nvm.alive_cnt = (nvm.alive_cnt or 0) - 1 + if nvm.alive_cnt > 0 then + local meta = M(pos) + local outdir = meta:get_int("outdir") + local tp1 = tonumber(meta:get_string("termpoint1")) + local tp2 = tonumber(meta:get_string("termpoint2")) + nvm.provided = power.provide_power(pos, Cable, outdir, PWR_PERF, tp1, tp2) + local val = power.get_storage_load(pos, Cable, outdir, PWR_PERF) + if val > 0 then + nvm.load = val + end + return true + else + swap_node(pos, "techage:ta5_generator") + stop_node(pos, nvm) + return false + end +end + +minetest.register_node("techage:ta5_generator", { + description = S("TA5 Generator"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta5_top.png", + "techage_filling_ta4.png^techage_frame_ta4_bottom.png", + "techage_filling_ta4.png^techage_appl_hole_electric.png^techage_frame_ta5.png", + "techage_filling_ta4.png^techage_appl_open.png^techage_frame_ta5.png", + "techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_generator.png", + "techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_generator.png^[transformFX]", + }, + + after_place_node = function(pos, placer) + M(pos):set_int("outdir", networks.side_to_outdir(pos, "R")) + Cable:after_place_node(pos) + end, + after_dig_node = function(pos, oldnode) + Cable:after_dig_node(pos) + techage.del_mem(pos) + end, + + get_generator_data = get_generator_data, + ta4_formspec = techage.generator_settings("ta4", PWR_PERF), + paramtype2 = "facedir", + groups = {cracky=2, crumbly=2, choppy=2}, + on_rotate = screwdriver.disallow, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("techage:ta5_generator_on", { + description = S("TA5 Generator"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta5_top.png", + "techage_filling_ta4.png^techage_frame_ta4_bottom.png", + "techage_filling_ta4.png^techage_appl_hole_electric.png^techage_frame_ta5.png", + "techage_filling_ta4.png^techage_appl_open.png^techage_frame_ta5.png", + { + image = "techage_filling4_ta4.png^techage_appl_generator4.png^techage_frame4_ta5.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.3, + }, + }, + { + image = "techage_filling4_ta4.png^techage_appl_generator4.png^[transformFX]^techage_frame4_ta5.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.3, + }, + }, + }, + + get_generator_data = get_generator_data, + ta4_formspec = techage.generator_settings("ta4", PWR_PERF), + on_timer = node_timer, + paramtype2 = "facedir", + drop = "", + groups = {not_in_creative_inventory=1}, + diggable = false, + on_rotate = screwdriver.disallow, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), +}) + +power.register_nodes({"techage:ta5_generator", "techage:ta5_generator_on"}, Cable, "gen", {"R"}) + +-- controlled by the turbine +techage.register_node({"techage:ta5_generator", "techage:ta5_generator_on"}, { + on_transfer = function(pos, in_dir, topic, payload) + local nvm = techage.get_nvm(pos) + if topic == "trigger" then + nvm.alive_cnt = 5 + elseif topic == "start" then + start_node(pos, nvm) + elseif topic == "stop" then + stop_node(pos, nvm) + end + end, + on_recv_message = function(pos, src, topic, payload) + return "unsupported" + end, + on_node_load = function(pos) + -- remove legacy formspec + M(pos):set_string("formspec", "") + end, +}) + +control.register_nodes({"techage:ta5_generator", "techage:ta5_generator_on"}, { + on_receive = function(pos, tlib2, topic, payload) + end, + on_request = function(pos, tlib2, topic) + if topic == "info" then + local nvm = techage.get_nvm(pos) + local meta = M(pos) + return { + type = S("TA5 Generator"), + number = "-", + running = (nvm.alive_cnt or 0) > 0, + available = PWR_PERF, + provided = nvm.provided or 0, + termpoint = meta:get_string("termpoint"), + } + end + return false + end, + } +) + +minetest.register_craft({ + output = "techage:ta5_generator", + recipe = { + {"", "dye:red", ""}, + {"", "techage:ta4_generator", ""}, + {"", "techage:baborium_ingot", ""}, + }, +}) diff --git a/techage/fusion_reactor/heatexchanger1.lua b/techage/fusion_reactor/heatexchanger1.lua new file mode 100644 index 0000000..0a2cb8a --- /dev/null +++ b/techage/fusion_reactor/heatexchanger1.lua @@ -0,0 +1,109 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2022 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA5 Heat Exchanger1 (bottom part) + - has a connection to storage and turbine (via pipes) + - acts as a cable junction for Exchanger2 +]]-- + +-- for lazy programmers +local S2P = minetest.string_to_pos +local P2S = minetest.pos_to_string +local M = minetest.get_meta +local S = techage.S + +local Cable = techage.ElectricCable +local Pipe2 = techage.LiquidPipe +local Pipe3 = techage.GasPipe +local power = networks.power +local liquid = networks.liquid +local control = networks.control + +local function turbine_cmnd(pos, topic, payload) + return techage.transfer(pos, "R", topic, payload, Pipe2, + {"techage:ta5_turbine", "techage:ta5_turbine_on"}) +end + +-- Send to the magnets +local function control_cmnd(pos, topic) + local outdir = networks.side_to_outdir(pos, "L") + return control.request(pos, Pipe3, outdir, "tank", topic) +end + +minetest.register_node("techage:ta5_heatexchanger1", { + description = S("TA5 Heat Exchanger 1"), + tiles = { + -- up, down, right, left, back, front + "techage_hole_ta4.png^techage_appl_arrow_white.png", + "techage_filling_ta4.png^techage_frame_ta4.png", + "techage_filling_ta4.png^techage_frameB_ta4.png^techage_appl_hole_pipe.png", + "techage_filling_ta4.png^techage_frameB_ta4.png^techage_appl_hole_ta5_pipe2.png", + "techage_filling_ta4.png^techage_frameB_ta4.png^techage_appl_hole_electric.png", + "techage_filling_ta4.png^techage_frameB_ta4.png^techage_appl_hole_electric.png", + }, + + after_place_node = function(pos, placer, itemstack, pointed_thing) + Cable:after_place_node(pos) + Pipe2:after_place_node(pos) + Pipe3:after_place_node(pos) + end, + tubelib2_on_update2 = function(pos, outdir, tlib2, node) + if tlib2 == Cable then + power.update_network(pos, 0, Cable, node) -- junction!!! + elseif tlib2 == Pipe2 then + power.update_network(pos, outdir, Pipe2, node) + else + power.update_network(pos, outdir, Pipe3, node) + end + end, + can_dig = function(pos, player) + if minetest.is_protected(pos, player:get_player_name()) then + return false + end + pos.y = pos.y + 1 + return minetest.get_node(pos).name ~= "techage:ta5_heatexchanger2" + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Cable:after_dig_node(pos) + Pipe2:after_dig_node(pos) + Pipe3:after_dig_node(pos) + end, + paramtype2 = "facedir", + groups = {crumbly = 2, cracky = 2, snappy = 2}, + on_rotate = screwdriver.disallow, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +liquid.register_nodes({"techage:ta5_heatexchanger1"}, Pipe2, "tank", {"R"}, {}) +liquid.register_nodes({"techage:ta5_heatexchanger1"}, Pipe3, "tank", {"L"}, {}) +power.register_nodes({"techage:ta5_heatexchanger1"}, Cable, "junc", {"F", "B", "U"}) + +-- command interface +techage.register_node({"techage:ta5_heatexchanger1"}, { + on_transfer = function(pos, indir, topic, payload) + local nvm = techage.get_nvm(pos) + -- used by heatexchanger2 + if topic == "test_gas_blue" then + return control_cmnd(pos, topic) + else + return turbine_cmnd(pos, topic, payload) + end + end, +}) + +minetest.register_craft({ + output = "techage:ta5_heatexchanger1", + recipe = { + {"default:tin_ingot", "techage:electric_cableS", "default:steel_ingot"}, + {"techage:ta5_pipe1S", "basic_materials:gear_steel", "techage:ta4_pipeS"}, + {"", "techage:baborium_ingot", ""}, + }, +}) diff --git a/techage/fusion_reactor/heatexchanger2.lua b/techage/fusion_reactor/heatexchanger2.lua new file mode 100644 index 0000000..7ea1df2 --- /dev/null +++ b/techage/fusion_reactor/heatexchanger2.lua @@ -0,0 +1,378 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2022 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA5 Heat Exchanger2 (middle part) + +]]-- + +-- for lazy programmers +local S2P = minetest.string_to_pos +local P2S = minetest.pos_to_string +local M = minetest.get_meta +local S = techage.S + +local Cable = techage.ElectricCable +local power = networks.power +local control = networks.control +local sched = techage.scheduler + +local CYCLE_TIME = 2 +local PWR_NEEDED = 5 +local COUNTDOWN_TICKS = 1 +local DOWN = 5 -- dir +local DESCRIPTION = S("TA5 Heat Exchanger 2") +local EXPECT_BLUE = 56 +local EXPECT_GREEN = 52 +local CALL_RATE1 = 16 -- 2s * 16 = 32s +local CALL_RATE2 = 8 -- 2s * 8 = 16s +local EX_POINTS = 60 + +local function heatexchanger1_cmnd(pos, topic, payload) + return techage.transfer({x = pos.x, y = pos.y - 1, z = pos.z}, + nil, topic, payload, nil, + {"techage:ta5_heatexchanger1"}) +end + +local function heatexchanger3_cmnd(pos, topic, payload) + return techage.transfer({x = pos.x, y = pos.y + 1, z = pos.z}, + nil, topic, payload, nil, + {"techage:ta5_heatexchanger3"}) +end + +local function play_sound(pos) + local mem = techage.get_mem(pos) + if not mem.handle or mem.handle == -1 then + mem.handle = minetest.sound_play("techage_booster", { + pos = pos, + gain = 0.3, + max_hear_distance = 10, + loop = true}) + if mem.handle == -1 then + minetest.after(1, play_sound, pos) + end + end +end + +local function stop_sound(pos) + local mem = techage.get_mem(pos) + if mem.handle then + minetest.sound_stop(mem.handle) + mem.handle = nil + end +end + +local function count_trues(t) + local cnt = 0 + for _,v in ipairs(t) do + if v then + cnt = cnt + 1 + end + end + return cnt +end + +local tSched = {} + +sched.register(tSched, CALL_RATE1, 0, function(pos) + if not heatexchanger1_cmnd(pos, "turbine") then + return S("Turbine error") + end + return true + end) +sched.register(tSched, CALL_RATE1, 1, function(pos) + if not heatexchanger3_cmnd(pos, "turbine") then + return S("Cooler error") + end + return true + end) +sched.register(tSched, CALL_RATE1, 2, function(pos) + local resp = heatexchanger1_cmnd(pos, "test_gas_blue") + local cnt = count_trues(resp) + if cnt ~= EXPECT_BLUE then + return S("Blue pipe connection error\n(@1 found / @2 expected)", cnt, EXPECT_BLUE) + end + return true + end) +sched.register(tSched, CALL_RATE1, 3, function(pos) + local resp = heatexchanger3_cmnd(pos, "test_gas_green") + local cnt = count_trues(resp) + if cnt ~= EXPECT_GREEN then + return S("Green pipe connection error\n(@1 found / @2 expected)", cnt, EXPECT_GREEN) + end + return true + end) +sched.register(tSched, CALL_RATE2, 4, function(pos) + local resp = heatexchanger3_cmnd(pos, "dec_power") + local cnt = count_trues(resp) + --print("dec_power", cnt) + if cnt < 52 then + return 0 + end + return 1 + end) + +local function can_start(pos, nvm) + if not power.power_available(pos, Cable, DOWN) then + return S("No power") + end + heatexchanger3_cmnd(pos, "rst_power") + for i = 0,4 do + local res = tSched[i](pos) + if res ~= true and res ~= 1 then return res end + end + return true +end + +local function start_node(pos, nvm) + play_sound(pos) + sched.init(pos) + nvm.temperature = nvm.temperature or 0 + local mem = techage.get_mem(pos) + local t = minetest.get_gametime() - (mem.stopped_at or 0) + nvm.temperature = math.max(nvm.temperature - math.floor(t/2), 0) + nvm.temperature = math.min(nvm.temperature, 70) +end + +local function stop_node(pos, nvm) + stop_sound(pos) + heatexchanger1_cmnd(pos, "stop") + local mem = techage.get_mem(pos) + mem.stopped_at = minetest.get_gametime() +end + +local function temp_indicator (nvm, x, y) + local temp = techage.is_running(nvm) and nvm.temperature or 0 + return "image[" .. x .. "," .. y .. ";1,2;techage_form_temp_bg.png^[lowpart:" .. + temp .. ":techage_form_temp_fg.png]" .. + "tooltip[" .. x .. "," .. y .. ";1,2;" .. S("water temperature") .. ";#0C3D32;#FFFFFF]" +end + +local function formspec(self, pos, nvm) + return "size[5,3]".. + "box[0,-0.1;4.8,0.5;#c6e8ff]" .. + "label[0.2,-0.1;" .. minetest.colorize( "#000000", DESCRIPTION) .. "]" .. + temp_indicator (nvm, 1, 1) .. + "image_button[3.2,1.5;1,1;".. self:get_state_button_image(nvm) ..";state_button;]".. + "tooltip[3.2,1.5;1,1;"..self:get_state_tooltip(nvm).."]" +end + +local State = techage.NodeStates:new({ + node_name_passive = "techage:ta5_heatexchanger2", + cycle_time = CYCLE_TIME, + infotext_name = DESCRIPTION, + standby_ticks = 0, + can_start = can_start, + start_node = start_node, + stop_node = stop_node, + formspec_func = formspec, +}) + +local function steam_management(pos, nvm) + local resp = sched.get(pos, tSched, function() return true end)(pos) + + if resp == 0 then -- has no power + nvm.temperature = math.max(nvm.temperature - 10, 0) + elseif resp == 1 then -- has power + nvm.temperature = math.min(nvm.temperature + 10, 100) + elseif resp ~= true then + State:fault(pos, nvm, resp) + stop_node(pos, nvm) + return false + end + + if resp == 0 and nvm.temperature == 70 then + heatexchanger1_cmnd(pos, "stop") + elseif nvm.temperature == 80 then + if resp == 1 then + heatexchanger1_cmnd(pos, "start") + local owner = M(pos):get_string("owner") + minetest.log("action", "[techage] " .. owner .. " starts the TA5 Fusion Reactor at " .. P2S(pos)) + else + heatexchanger1_cmnd(pos, "trigger") + end + elseif nvm.temperature > 80 then + heatexchanger1_cmnd(pos, "trigger") + end + return true +end + +local function consume_power(pos, nvm) + if techage.needs_power(nvm) then + local taken = power.consume_power(pos, Cable, DOWN, PWR_NEEDED) + if techage.is_running(nvm) then + if taken < PWR_NEEDED then + State:nopower(pos, nvm, S("No power")) + stop_sound(pos) + heatexchanger1_cmnd(pos, "stop") + else + return true -- keep running + end + end + end +end + +local function node_timer(pos, elapsed) + local nvm = techage.get_nvm(pos) + nvm.temperature = nvm.temperature or 0 + --print("node_timer", nvm.temperature) + if consume_power(pos, nvm) then + if steam_management(pos, nvm) then + State:keep_running(pos, nvm, COUNTDOWN_TICKS) + end + end + if techage.is_activeformspec(pos) then + M(pos):set_string("formspec", formspec(State, pos, nvm)) + end + return State:is_active(nvm) or nvm.temperature > 0 +end + +local function can_dig(pos, player) + if minetest.is_protected(pos, player:get_player_name()) then + return false + end + local nvm = techage.get_nvm(pos) + return not techage.is_running(nvm) +end + +local function on_rightclick(pos, node, clicker) + techage.set_activeformspec(pos, clicker) + local nvm = techage.get_nvm(pos) + M(pos):set_string("formspec", formspec(State, pos, nvm)) +end + +local function after_place_node(pos, placer) + if techage.orientate_node(pos, "techage:ta5_heatexchanger1") then + return true + end + local meta = M(pos) + local nvm = techage.get_nvm(pos) + local own_num = techage.add_node(pos, "techage:ta5_heatexchanger2") + meta:set_string("owner", placer:get_player_name()) + meta:set_string("infotext", DESCRIPTION..": "..own_num) + meta:set_string("formspec", formspec(State, pos, nvm)) + Cable:after_place_node(pos, {DOWN}) + State:node_init(pos, nvm, own_num) +end + +local function after_dig_node(pos, oldnode, oldmetadata, digger) + Cable:after_dig_node(pos) + techage.del_mem(pos) +end + +local function on_receive_fields(pos, formname, fields, player) + if minetest.is_protected(pos, player:get_player_name()) then + return + end + + if techage.get_expoints(player) >= EX_POINTS then + local nvm = techage.get_nvm(pos) + State:state_button_event(pos, nvm, fields) + --M(pos):set_string("formspec", formspec(State, pos, nvm)) + end +end + +-- Middle node with the formspec from the bottom node +minetest.register_node("techage:ta5_heatexchanger2", { + description = DESCRIPTION, + tiles = { + -- up, down, right, left, back, front + "techage_hole_ta4.png", + "techage_hole_ta4.png", + "techage_filling_ta4.png^techage_frameM_ta4.png^techage_appl_tes_turb.png", + "techage_filling_ta4.png^techage_frameM_ta4.png", + "techage_filling_ta4.png^techage_frameM_ta4.png^techage_appl_ribsB.png", + "techage_filling_ta4.png^techage_frameM_ta4.png^techage_appl_ribsB.png", + }, + + selection_box = { + type = "fixed", + fixed = {-1/2, -1.5/2, -1/2, 1/2, 1/2, 1/2}, + }, + + on_receive_fields = on_receive_fields, + on_rightclick = on_rightclick, + on_timer = node_timer, + after_place_node = after_place_node, + can_dig = can_dig, + after_dig_node = after_dig_node, + + paramtype2 = "facedir", + groups = {crumbly = 2, cracky = 2, snappy = 2}, + on_rotate = screwdriver.disallow, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +power.register_nodes({"techage:ta5_heatexchanger2"}, Cable, "con", {"D"}) + +techage.register_node({"techage:ta5_heatexchanger2"}, { + on_recv_message = function(pos, src, topic, payload) + local nvm = techage.get_nvm(pos) + if topic == "state" then + if techage.is_running(nvm) then + return "running" + else + return "stopped" + end + elseif topic == "delivered" then + local data = power.get_network_data(pos, Cable, DOWN) + return data.consumed - data.provided + elseif topic == "on" then + start_node(pos, techage.get_nvm(pos)) + return true + elseif topic == "off" then + stop_node(pos, techage.get_nvm(pos)) + return true + else + return "unsupported" + end + end, + on_node_load = function(pos, node) + local nvm = techage.get_nvm(pos) + if techage.is_running(nvm) then + play_sound(pos) + else + stop_sound(pos) + end + -- Attempt to restart the system as the heat exchanger goes into error state + -- when parts of the storage block are unloaded. + if nvm.techage_state == techage.FAULT then + start_node(pos, nvm) + end + end, +}) + +control.register_nodes({"techage:ta5_heatexchanger2"}, { + on_receive = function(pos, tlib2, topic, payload) + end, + on_request = function(pos, tlib2, topic) + if topic == "info" then + local nvm = techage.get_nvm(pos) + return { + type = DESCRIPTION, + number = M(pos):get_string("node_number") or "", + running = techage.is_running(nvm) or false, + capa = nvm.capa_max or 1, + load = nvm.capa or 0, + } + end + return false + end, + } +) + +minetest.register_craft({ + output = "techage:ta5_heatexchanger2", + recipe = { + {"default:tin_ingot", "", "default:steel_ingot"}, + {"", "techage:ta5_aichip2", ""}, + {"", "techage:baborium_ingot", ""}, + }, +}) diff --git a/techage/fusion_reactor/heatexchanger3.lua b/techage/fusion_reactor/heatexchanger3.lua new file mode 100644 index 0000000..dd8ee47 --- /dev/null +++ b/techage/fusion_reactor/heatexchanger3.lua @@ -0,0 +1,106 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2022 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA5 Heat Exchanger3 (top part) + +]]-- + +-- for lazy programmers +local M = minetest.get_meta +local S = techage.S + +local Pipe2 = techage.LiquidPipe +local Pipe3 = techage.GasPipe +local liquid = networks.liquid +local control = networks.control + +local function orientate_node(pos, name) + local node = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}) + if node.name == name then + local param2 = node.param2 + node = minetest.get_node(pos) + node.param2 = param2 + minetest.swap_node(pos, node) + else + minetest.remove_node(pos) + return true + end +end + +local function after_place_node(pos) + if orientate_node(pos, "techage:ta5_heatexchanger2") then + return true + end + Pipe2:after_place_node(pos) + Pipe3:after_place_node(pos) +end + +local function after_dig_node(pos, oldnode) + Pipe2:after_dig_node(pos) + Pipe3:after_dig_node(pos) +end + +local function turbine_cmnd(pos, topic, payload) + return techage.transfer(pos, "R", topic, payload, Pipe2, + {"techage:ta5_turbine", "techage:ta5_turbine_on"}) +end + +-- Send to the magnets +local function control_cmnd(pos, topic) + local outdir = networks.side_to_outdir(pos, "L") + return control.request(pos, Pipe3, outdir, "tank", topic) +end + +minetest.register_node("techage:ta5_heatexchanger3", { + description = S("TA5 Heat Exchanger 3"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta5_top.png", + "techage_hole_ta4.png", + "techage_filling_ta4.png^techage_frameT_ta5.png^techage_appl_hole_pipe.png", + "techage_filling_ta4.png^techage_frameT_ta5.png^techage_appl_hole_ta5_pipe1.png", + "techage_filling_ta4.png^techage_frameT_ta5.png^techage_appl_ribsT.png", + "techage_filling_ta4.png^techage_frameT_ta5.png^techage_appl_ribsT.png", + }, + + after_place_node = after_place_node, + after_dig_node = after_dig_node, + + paramtype2 = "facedir", + groups = {crumbly = 2, cracky = 2, snappy = 2}, + on_rotate = screwdriver.disallow, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +liquid.register_nodes({"techage:ta5_heatexchanger3"}, Pipe2, "tank", {"R"}, {}) +liquid.register_nodes({"techage:ta5_heatexchanger3"}, Pipe3, "tank", {"L"}, {}) + +-- command interface, used by heatexchanger2 +techage.register_node({"techage:ta5_heatexchanger3"}, { + on_transfer = function(pos, indir, topic, payload) + if topic == "turbine" then + return turbine_cmnd(pos, topic, payload) + else + return control_cmnd(pos, topic) + end + end, +}) + +minetest.register_craft({ + output = "techage:ta5_heatexchanger3", + recipe = { + {"default:tin_ingot", "dye:red", "default:steel_ingot"}, + {"techage:ta5_pipe2S", "basic_materials:gear_steel", "techage:ta4_pipeS"}, + {"", "techage:baborium_ingot", ""}, + }, +}) + +techage.orientate_node = orientate_node diff --git a/techage/fusion_reactor/magnet.lua b/techage/fusion_reactor/magnet.lua new file mode 100644 index 0000000..66889cf --- /dev/null +++ b/techage/fusion_reactor/magnet.lua @@ -0,0 +1,266 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2022 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA5 Fusion Reactor Magnet + +]]-- + +-- for lazy programmers +local S2P = minetest.string_to_pos +local P2S = minetest.pos_to_string +local M = minetest.get_meta +local S = techage.S + +local Cable = techage.ElectricCable +local Pipe = techage.GasPipe +local power = networks.power +local liquid = networks.liquid +local control = networks.control + +local CAPACITY = 6 +local SHELLBLOCKS = {"techage:ta5_fr_shell", "techage:ta5_fr_nucleus", "techage:ta5_magnet1", "techage:ta5_magnet2"} + +minetest.register_node("techage:ta5_magnet1", { + description = S("TA5 Fusion Reactor Magnet 1"), + tiles = { + -- up, down, right, left, back, front + "techage_collider_magnet.png^techage_appl_hole_ta5_pipe1.png^techage_steel_tiles_top.png^[transformR180]", + "techage_collider_magnet.png^techage_appl_hole_ta5_pipe2.png^techage_steel_tiles_top.png", + "techage_collider_magnet.png^techage_steel_tiles_side.png", + "techage_collider_magnet.png^techage_steel_tiles_side.png^[transformR180]", + "techage_collider_magnet.png^techage_appl_hole_electric.png", + "techage_steel_tiles.png", + }, + after_place_node = function(pos, placer, itemstack) + Pipe:after_place_node(pos) + Cable:after_place_node(pos) + end, + ta_rotate_node = function(pos, node, new_param2) + Pipe:after_dig_node(pos) + Cable:after_dig_node(pos) + minetest.swap_node(pos, {name = node.name, param2 = new_param2}) + Pipe:after_place_node(pos) + Cable:after_place_node(pos) + end, + after_dig_node = function(pos, oldnode) + Pipe:after_dig_node(pos) + Cable:after_dig_node(pos) + techage.del_mem(pos) + end, + drawtype = "nodebox", + paramtype2 = "facedir", + groups = {choppy=2, cracky=2, crumbly=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +minetest.register_node("techage:ta5_magnet2", { + description = S("TA5 Fusion Reactor Magnet 2"), + tiles = { + -- up, down, right, left, back, front + "techage_collider_magnet.png^techage_appl_hole_ta5_pipe1.png^techage_steel_tiles_top2.png^[transformR180]", + "techage_collider_magnet.png^techage_appl_hole_ta5_pipe2.png^techage_steel_tiles_top2.png^[transformR270]", + "techage_steel_tiles.png", + "techage_collider_magnet.png^techage_steel_tiles_side.png^[transformR180]", + "techage_collider_magnet.png^techage_steel_tiles_side.png", + "techage_steel_tiles.png", + }, + after_place_node = function(pos, placer, itemstack) + Pipe:after_place_node(pos) + Cable:after_place_node(pos) + end, + ta_rotate_node = function(pos, node, new_param2) + Pipe:after_dig_node(pos) + Cable:after_dig_node(pos) + minetest.swap_node(pos, {name = node.name, param2 = new_param2}) + Pipe:after_place_node(pos) + Cable:after_place_node(pos) + end, + after_dig_node = function(pos, oldnode) + Pipe:after_dig_node(pos) + Cable:after_dig_node(pos) + techage.del_mem(pos) + end, + drawtype = "nodebox", + paramtype2 = "facedir", + groups = {choppy=2, cracky=2, crumbly=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +power.register_nodes({"techage:ta5_magnet1"}, Cable, "con", {"B"}) +liquid.register_nodes({"techage:ta5_magnet1", "techage:ta5_magnet2"}, Pipe, "tank", {"U", "D"}, { + capa = CAPACITY, + peek = function(pos, indir) + local nvm = techage.get_nvm(pos) + return liquid.srv_peek(nvm) + end, + put = function(pos, indir, name, amount) + local nvm = techage.get_nvm(pos) + return liquid.srv_put(nvm, name, amount, CAPACITY) + end, + take = function(pos, indir, name, amount) + local nvm = techage.get_nvm(pos) + return liquid.srv_take(nvm, name, amount) + end, + untake = function(pos, indir, name, amount) + local nvm = techage.get_nvm(pos) + liquid.srv_put(nvm, name, amount, CAPACITY) + end, +}) + +local function check_plasma(pos, param2) + local pos1 = networks.get_relpos(pos, "F", param2) + local node = minetest.get_node(pos1) or {} + return node.name == "air" +end + +local function swap_plasma(pos, name, param2) + local pos1 = networks.get_relpos(pos, "F", param2) + minetest.swap_node(pos1, {name = name, param2 = param2}) +end + +local function check_shell(pos, param2) + local pos1 = networks.get_relpos(pos, "D", param2) + local pos2 = networks.get_relpos(pos, "BU", param2) + local _,t = minetest.find_nodes_in_area(pos1, pos2, SHELLBLOCKS) + local cnt = 0 + for k,v in pairs(t) do + cnt = cnt + v + end + return cnt == 6 +end + +local function check_nucleus(pos, param2) + local pos1 = networks.get_relpos(pos, "B", param2) + local node = minetest.get_node(pos1) or {} + if node.name == "techage:ta5_fr_nucleus" then + return pos1 + end +end + +local function on_receive(pos, tlib2, topic, payload) + --print("on_receive", topic) + local nvm = techage.get_nvm(pos) + if topic == "on" then + nvm.running = true + elseif topic == "off" then + nvm.running = false + end +end + +local function rst_power(nvm) + nvm.power = 0 + return true +end + +local function inc_power(nvm) + nvm.power = nvm.power or 0 + if nvm.power < 0 then nvm.power = 0 end + nvm.power = nvm.power + 1 + return nvm.power <= 2 +end + +local function dec_power(nvm) + nvm.power = nvm.power or 0 + if nvm.power > 0 then nvm.power = 0 end + nvm.power = nvm.power - 1 + return nvm.power >= -2 +end + +local function on_request(pos, tlib2, topic) + local nvm = techage.get_nvm(pos) + nvm.liquid = nvm.liquid or {} + nvm.liquid.amount = nvm.liquid.amount or 0 + if tlib2 == Cable then + if topic == "connect" then + return true + elseif topic == "inc_power" then + return inc_power(nvm) + elseif topic == "test_plasma" then + local node = minetest.get_node(pos) or {} + return check_plasma(pos, node.param2) + elseif topic == "test_shell" then + local node = minetest.get_node(pos) or {} + return check_shell(pos, node.param2) + elseif topic == "test_nucleus" then + local node = minetest.get_node(pos) or {} + return check_nucleus(pos, node.param2) + elseif topic == "no_gas" then + nvm.liquid.amount = 0 + return true + end + else -- Pipe + if topic == "dec_power" then + return dec_power(nvm) + elseif topic == "test_gas_blue" then + nvm.has_gas = true + return nvm.liquid.amount == CAPACITY + elseif topic == "test_gas_green" then + local res = nvm.has_gas + nvm.has_gas = false + return res + end + end + if topic == "rst_power" then + return rst_power(nvm) + end + return false +end + +control.register_nodes({"techage:ta5_magnet1", "techage:ta5_magnet2"}, { + on_receive = on_receive, + on_request = on_request, + } +) + +minetest.register_craftitem("techage:ta5_magnet_blank", { + description = S("TA5 Fusion Reactor Magnet Blank"), + inventory_image = "techage_collider_magnet.png^techage_appl_hole_electric.png", +}) + +minetest.register_craftitem("techage:ta5_magnet_shield", { + description = S("TA5 Fusion Reactor Magnet Shield"), + inventory_image = "techage_steel_tiles.png", +}) + +techage.furnace.register_recipe({ + output = "techage:ta5_magnet_shield 2", + recipe = {"default:steel_ingot", "techage:usmium_powder", "techage:graphite_powder"}, + time = 2, + +}) + +minetest.register_craft({ + output = "techage:ta5_magnet_blank 2", + recipe = { + {'default:steel_ingot', 'techage:electric_cableS', 'techage:aluminum'}, + {'techage:ta5_pipe1S', 'basic_materials:gold_wire', 'techage:ta5_pipe2S'}, + {'techage:aluminum', 'dye:brown', 'default:steel_ingot'}, + }, +}) + +minetest.register_craft({ + output = "techage:ta5_magnet1", + recipe = { + {'', 'techage:ta5_magnet_shield', 'techage:ta5_magnet_blank'}, + {'', '', ''}, + {'', '', ''}, + }, +}) + +minetest.register_craft({ + output = "techage:ta5_magnet2", + recipe = { + {'', 'techage:ta5_magnet_shield', 'techage:ta5_magnet_blank'}, + {'', '', 'techage:ta5_magnet_shield'}, + {'', '', ''}, + }, +}) diff --git a/techage/fusion_reactor/shell.lua b/techage/fusion_reactor/shell.lua new file mode 100644 index 0000000..b2f1fcc --- /dev/null +++ b/techage/fusion_reactor/shell.lua @@ -0,0 +1,63 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2022 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA5 Fusion Reactor Shell + +]]-- + +-- for lazy programmers +local S2P = minetest.string_to_pos +local P2S = minetest.pos_to_string +local M = minetest.get_meta +local S = techage.S + +minetest.register_node("techage:ta5_fr_shell", { + description = S("TA5 Fusion Reactor Shell"), + tiles = { + "techage_reactor_shell.png", + }, + drawtype = "nodebox", + paramtype2 = "facedir", + paramtype = "light", + use_texture_alpha = "blend", + groups = {choppy=2, cracky=2, crumbly=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +minetest.register_node("techage:ta5_fr_nucleus", { + description = S("TA5 Fusion Reactor Nucleus"), + tiles = { + "techage_reactor_shell.png^techage_collider_detector_core.png", + }, + drawtype = "nodebox", + paramtype2 = "facedir", + paramtype = "light", + use_texture_alpha = "blend", + groups = {choppy=2, cracky=2, crumbly=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +techage.furnace.register_recipe({ + output = "techage:ta5_fr_shell 3", + recipe = {'techage:ta4_colliderblock', 'techage:ta4_colliderblock', "techage:graphite_powder"}, + time = 24, +}) + +minetest.register_craft({ + output = "techage:ta5_fr_nucleus", + recipe = { + {"", "techage:ta5_aichip2", ""}, + {"techage:electric_cableS", "techage:cylinder_large_hydrogen", "techage:ta3_valve_open"}, + {"", "techage:ta5_fr_shell", ""}, + }, +}) + diff --git a/techage/fusion_reactor/ta5_pump.lua b/techage/fusion_reactor/ta5_pump.lua new file mode 100644 index 0000000..fab96a0 --- /dev/null +++ b/techage/fusion_reactor/ta5_pump.lua @@ -0,0 +1,191 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2022 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA5 Pump + +]]-- + +local S2P = minetest.string_to_pos +local P2S = minetest.pos_to_string +local M = minetest.get_meta +local S = techage.S +local Pipe2 = techage.LiquidPipe +local Pipe3 = techage.GasPipe +local liquid = networks.liquid +local Flip = networks.Flip + +local STANDBY_TICKS = 16 +local COUNTDOWN_TICKS = 4 +local CYCLE_TIME = 2 +local CAPA = 4 + +local WRENCH_MENU = {{ + type = "output", + name = "flowrate", + label = S("Total flow rate"), + tooltip = S("Total flow rate in liquid units"), +}} + +local State = techage.NodeStates:new({ + node_name_passive = "techage:ta5_pump", + node_name_active = "techage:ta5_pump_on", + infotext_name = S("TA5 Pump"), + cycle_time = CYCLE_TIME, + standby_ticks = STANDBY_TICKS, +}) + +local function pumping(pos, nvm) + local outdir = M(pos):get_int("outdir") + local taken, name = liquid.take(pos, Pipe2, Flip[outdir], nil, CAPA) + if taken > 0 then + local leftover = liquid.put(pos, Pipe3, outdir, name, taken) + if leftover and leftover > 0 then + liquid.untake(pos, Pipe2, Flip[outdir], name, leftover) + if leftover == taken then + State:blocked(pos, nvm) + return 0 + end + State:keep_running(pos, nvm, COUNTDOWN_TICKS) + return taken - leftover + end + State:keep_running(pos, nvm, COUNTDOWN_TICKS) + return taken + end + State:idle(pos, nvm) + return 0 +end + +local function after_place_node(pos, placer) + local nvm = techage.get_nvm(pos) + local number = techage.add_node(pos, "techage:ta5_pump") + State:node_init(pos, nvm, number) + M(pos):set_int("outdir", networks.side_to_outdir(pos, "R")) + Pipe2:after_place_node(pos) + Pipe3:after_place_node(pos) +end + +local function node_timer(pos, elapsed) + local nvm = techage.get_nvm(pos) + nvm.flowrate = (nvm.flowrate or 0) + pumping(pos, nvm) + return State:is_active(nvm) +end + +local function on_rightclick(pos, node, clicker) + if minetest.is_protected(pos, clicker:get_player_name()) then + return + end + + local nvm = techage.get_nvm(pos) + if node.name == "techage:ta5_pump" then + State:start(pos, nvm) + elseif node.name == "techage:ta5_pump_on" then + State:stop(pos, nvm) + end +end + +local function after_dig_node(pos, oldnode, oldmetadata, digger) + Pipe2:after_dig_node(pos) + Pipe3:after_dig_node(pos) + techage.del_mem(pos) +end + +local tiles_pas = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta5_top.png^techage_appl_arrow.png", + "techage_filling_ta4.png^techage_frame_ta4_bottom.png", + "techage_filling_ta4.png^techage_appl_hole_ta5_pipe2.png^techage_frame_ta5.png", + "techage_filling_ta4.png^techage_appl_hole_pipe.png^techage_frame_ta5.png", + "techage_filling_ta4.png^techage_appl_pump.png^techage_frame_ta5.png^[transformFX", + "techage_filling_ta4.png^techage_appl_pump.png^techage_frame_ta5.png", +} + +local tiles_act = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta5_top.png^techage_appl_arrow.png", + "techage_filling_ta4.png^techage_frame_ta4_bottom.png", + "techage_filling_ta4.png^techage_appl_hole_ta5_pipe2.png^techage_frame_ta5.png", + "techage_filling_ta4.png^techage_appl_hole_pipe.png^techage_frame_ta5.png", + { + image = "techage_filling8_ta4.png^techage_appl_pump8.png^techage_frame8_ta5.png^[transformFX", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 2.0, + }, + }, + { + image = "techage_filling8_ta4.png^techage_appl_pump8.png^techage_frame8_ta5.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 2.0, + }, + }, +} + +minetest.register_node("techage:ta5_pump", { + description = S("TA5 Pump"), + tiles = tiles_pas, + after_place_node = after_place_node, + on_rightclick = on_rightclick, + on_timer = node_timer, + after_dig_node = after_dig_node, + on_rotate = screwdriver.disallow, + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + groups = {cracky=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), + ta4_formspec = WRENCH_MENU, +}) + +minetest.register_node("techage:ta5_pump_on", { + description = S("TA5 Pump"), + tiles = tiles_act, + --after_place_node = after_place_node4, + on_rightclick = on_rightclick, + on_timer = node_timer, + after_dig_node = after_dig_node, + on_rotate = screwdriver.disallow, + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + diggable = false, + groups = {not_in_creative_inventory=1}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +techage.register_node({"techage:ta5_pump", "techage:ta5_pump_on"}, { + on_recv_message = function(pos, src, topic, payload) + return State:on_receive_message(pos, topic, payload) + end, +}) + +-- Pumps have to provide one output and one input side +liquid.register_nodes({ + "techage:ta5_pump", "techage:ta5_pump_on", +}, Pipe2, "pump", {"L"}, {}) + +liquid.register_nodes({ + "techage:ta5_pump", "techage:ta5_pump_on", +}, Pipe3, "pump", {"R"}, {}) + +minetest.register_craft({ + output = "techage:ta5_pump", + recipe = { + {"techage:aluminum", "dye:red", "default:steel_ingot"}, + {"techage:ta4_pipeS", "techage:ta5_ceramic_turbine", "techage:ta5_pipe1S"}, + {"default:steel_ingot", "basic_materials:motor", "techage:aluminum"}, + }, +}) diff --git a/techage/fusion_reactor/turbine.lua b/techage/fusion_reactor/turbine.lua new file mode 100644 index 0000000..4703304 --- /dev/null +++ b/techage/fusion_reactor/turbine.lua @@ -0,0 +1,170 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2022 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA5 Gas Turbine + +]]-- + +-- for lazy programmers +local M = minetest.get_meta +local S = techage.S + +local Pipe = techage.LiquidPipe + +local function generator_cmnd(pos, topic, payload) + return techage.transfer(pos, "R", topic, payload, nil, + {"techage:ta5_generator", "techage:ta5_generator_on"}) +end + +local function swap_node(pos, name) + local node = techage.get_node_lvm(pos) + if node.name == name then + return + end + node.name = name + minetest.swap_node(pos, node) +end + +local function play_sound(pos) + local mem = techage.get_mem(pos) + if not mem.handle or mem.handle == -1 then + mem.handle = minetest.sound_play("techage_turbine", { + pos = pos, + gain = 0.4, + max_hear_distance = 10, + loop = true}) + if mem.handle == -1 then + minetest.after(1, play_sound, pos) + end + end +end + +local function stop_sound(pos) + local mem = techage.get_mem(pos) + if mem.handle then + minetest.sound_stop(mem.handle) + mem.handle = nil + end +end + +minetest.register_node("techage:ta5_turbine", { + description = S("TA5 Turbine"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta5_top.png^techage_appl_hole_pipe.png", + "techage_filling_ta4.png^techage_frame_ta4_bottom.png", + "techage_filling_ta4.png^techage_appl_open.png^techage_frame_ta5.png", + "techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_hole_pipe.png", + "techage_filling_ta4.png^techage_appl_turbine.png^techage_frame_ta5.png", + "techage_filling_ta4.png^techage_appl_turbine.png^techage_frame_ta5.png", + }, + + after_place_node = function(pos) + Pipe:after_place_node(pos) + end, + after_dig_node = function(pos, oldnode) + stop_sound(pos) + Pipe:after_dig_node(pos) + techage.del_mem(pos) + end, + networks = { + pipe2 = {}, + }, + paramtype2 = "facedir", + groups = {cracky=2, crumbly=2, choppy=2}, + on_rotate = screwdriver.disallow, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("techage:ta5_turbine_on", { + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta5_top.png^techage_appl_hole_pipe.png", + "techage_filling_ta4.png^techage_frame_ta4_bottom.png", + "techage_filling_ta4.png^techage_appl_open.png^techage_frame_ta5.png", + "techage_filling_ta4.png^techage_frame_ta5.png^techage_appl_hole_pipe.png", + { + image = "techage_filling4_ta4.png^techage_appl_turbine4.png^techage_frame4_ta5.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.4, + }, + }, + { + image = "techage_filling4_ta4.png^techage_appl_turbine4.png^techage_frame4_ta5.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.4, + }, + }, + }, + + tubelib2_on_update2 = function(pos, outdir, tlib2, node) + swap_node(pos, "techage:ta5_turbine") + stop_sound(pos) + generator_cmnd(pos, "stop") + end, + networks = { + pipe2 = {}, + }, + paramtype2 = "facedir", + groups = {not_in_creative_inventory=1}, + diggable = false, + on_rotate = screwdriver.disallow, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), +}) + +Pipe:add_secondary_node_names({"techage:ta5_turbine", "techage:ta5_turbine_on"}) +Pipe:set_valid_sides("techage:ta5_turbine", {"L", "U"}) +Pipe:set_valid_sides("techage:ta5_turbine_on", {"L", "U"}) + +techage.register_node({"techage:ta5_turbine", "techage:ta5_turbine_on"}, { + -- used by heatexchanger1 + on_transfer = function(pos, in_dir, topic, payload) + local nvm = techage.get_nvm(pos) + if topic == "trigger" then + return generator_cmnd(pos, topic, payload) + elseif topic == "start" then + swap_node(pos, "techage:ta5_turbine_on") + play_sound(pos) + return generator_cmnd(pos, topic, payload) + elseif topic == "stop" then + swap_node(pos, "techage:ta5_turbine") + stop_sound(pos) + return generator_cmnd(pos, topic, payload) + elseif topic == "turbine" then + return true + else + return generator_cmnd(pos, topic, payload) + end + end, + on_node_load = function(pos, node) + if node.name == "techage:ta5_turbine_on" then + play_sound(pos) + end + end, +}) + +minetest.register_craft({ + output = "techage:ta5_turbine", + recipe = { + {"", "dye:red", ""}, + {"", "techage:turbine", ""}, + {"", "techage:ta5_ceramic_turbine", ""}, + }, +}) diff --git a/techage/images/chemical_reactor.png b/techage/images/chemical_reactor.png index 78c56c5..6fbc83e 100644 Binary files a/techage/images/chemical_reactor.png and b/techage/images/chemical_reactor.png differ diff --git a/techage/images/distillation_tower.png b/techage/images/distillation_tower.png index 7e3826b..aa8e1db 100644 Binary files a/techage/images/distillation_tower.png and b/techage/images/distillation_tower.png differ diff --git a/techage/images/drilling_tower.png b/techage/images/drilling_tower.png index 6e098d1..06945dc 100644 Binary files a/techage/images/drilling_tower.png and b/techage/images/drilling_tower.png differ diff --git a/techage/images/fusion_reactor.png b/techage/images/fusion_reactor.png new file mode 100644 index 0000000..5b0f353 Binary files /dev/null and b/techage/images/fusion_reactor.png differ diff --git a/techage/images/melting_furnace.png b/techage/images/melting_furnace.png index 5341921..2c5f614 100644 Binary files a/techage/images/melting_furnace.png and b/techage/images/melting_furnace.png differ diff --git a/techage/images/solar_plant.png b/techage/images/solar_plant.png index 53dc02f..e17ef73 100644 Binary files a/techage/images/solar_plant.png and b/techage/images/solar_plant.png differ diff --git a/techage/images/steam_engine.png b/techage/images/steam_engine.png index f6b5637..8faaa33 100644 Binary files a/techage/images/steam_engine.png and b/techage/images/steam_engine.png differ diff --git a/techage/images/tank_cart.png b/techage/images/tank_cart.png index d641589..c1273a9 100644 Binary files a/techage/images/tank_cart.png and b/techage/images/tank_cart.png differ diff --git a/techage/images/thermal_energy_storage.png b/techage/images/thermal_energy_storage.png index 4fe067f..23527fb 100644 Binary files a/techage/images/thermal_energy_storage.png and b/techage/images/thermal_energy_storage.png differ diff --git a/techage/images/watermill.png b/techage/images/watermill.png index 8c3a8e2..69ac560 100644 Binary files a/techage/images/watermill.png and b/techage/images/watermill.png differ diff --git a/techage/images/wind_plant.png b/techage/images/wind_plant.png index 55210b0..1507582 100644 Binary files a/techage/images/wind_plant.png and b/techage/images/wind_plant.png differ diff --git a/techage/init.lua b/techage/init.lua index 50810a8..7674ca0 100644 --- a/techage/init.lua +++ b/techage/init.lua @@ -13,7 +13,7 @@ techage = {} -- Version for compatibility checks, see readme.md/history -techage.version = 1.06 +techage.version = 1.07 if minetest.global_exists("tubelib") then minetest.log("error", "[techage] Techage can't be used together with the mod tubelib!") @@ -24,8 +24,8 @@ elseif minetest.global_exists("ironage") then elseif minetest.global_exists("techpack") then minetest.log("error", "[techage] Techage can't be used together with the modpack techpack!") return -elseif minetest.global_exists("tubelib2") and tubelib2.version < 1.9 then - minetest.log("error", "[techage] Techage requires tubelib2 version 1.9 or newer!") +elseif minetest.global_exists("tubelib2") and tubelib2.version < 2.2 then + minetest.log("error", "[techage] Techage requires tubelib2 version 2.2 or newer!") return elseif minetest.global_exists("minecart") and minecart.version < 1.08 then minetest.log("error", "[techage] Techage requires minecart version 1.08 or newer!") @@ -172,6 +172,8 @@ dofile(MP.."/ta2_energy_storage/ta2_weight_chest.lua") dofile(MP.."/liquids/liquid_pipe.lua") dofile(MP.."/liquids/valve.lua") dofile(MP.."/liquids/pipe_wall_entry.lua") +dofile(MP.."/fusion_reactor/gas_pipe.lua") + -- Basic Machines dofile(MP.."/basic_machines/consumer.lua") -- consumer base model @@ -228,6 +230,7 @@ dofile(MP.."/tools/repairkit.lua") dofile(MP.."/tools/pipe_wrench.lua") dofile(MP.."/basic_machines/blackhole.lua") dofile(MP.."/basic_machines/forceload.lua") +dofile(MP.."/tools/screwdriver.lua") -- Lamps dofile(MP.."/lamps/lib.lua") @@ -386,7 +389,7 @@ dofile(MP.."/items/moreblocks.lua") dofile(MP.."/carts/tank_cart.lua") dofile(MP.."/carts/chest_cart.lua") --- Collider +-- TA4 Collider dofile(MP.."/collider/vacuumtube.lua") dofile(MP.."/collider/magnet.lua") dofile(MP.."/collider/inlets.lua") @@ -394,9 +397,20 @@ dofile(MP.."/collider/cooler.lua") dofile(MP.."/collider/detector.lua") dofile(MP.."/collider/worker.lua") +-- TA5 Teleport dofile(MP.."/teleport/teleport_tube.lua") dofile(MP.."/teleport/teleport_pipe.lua") +-- TA5 Fusion Reactor +dofile(MP.."/fusion_reactor/shell.lua") +dofile(MP.."/fusion_reactor/magnet.lua") +dofile(MP.."/fusion_reactor/controller.lua") +dofile(MP.."/fusion_reactor/heatexchanger3.lua") +dofile(MP.."/fusion_reactor/heatexchanger2.lua") +dofile(MP.."/fusion_reactor/heatexchanger1.lua") +dofile(MP.."/fusion_reactor/generator.lua") +dofile(MP.."/fusion_reactor/turbine.lua") +dofile(MP.."/fusion_reactor/ta5_pump.lua") -- Prevent other mods from using IE techage.IE = nil diff --git a/techage/items/ceramic.lua b/techage/items/ceramic.lua index f2d1dcf..5bdcad6 100644 --- a/techage/items/ceramic.lua +++ b/techage/items/ceramic.lua @@ -59,6 +59,11 @@ minetest.register_craftitem("techage:ta4_round_ceramic", { inventory_image = "techage_round_ceramic.png", }) +minetest.register_craftitem("techage:ta5_ceramic_turbine", { + description = S("TA5 Ceramic Turbine"), + inventory_image = "techage_ceramic_turbine.png", +}) + techage.furnace.register_recipe({ output = "techage:ta4_round_ceramic 2", recipe = { @@ -67,3 +72,13 @@ techage.furnace.register_recipe({ }, time = 16, }) + +techage.furnace.register_recipe({ + output = "techage:ta5_ceramic_turbine", + recipe = { + "techage:ta4_ceramic_material", + "techage:ta4_ceramic_material", + "techage:graphite_powder", + }, + time = 16, +}) diff --git a/techage/items/electronic.lua b/techage/items/electronic.lua index ad180ce..1f54551 100644 --- a/techage/items/electronic.lua +++ b/techage/items/electronic.lua @@ -41,7 +41,12 @@ minetest.register_craftitem("techage:ta4_leds", { minetest.register_craftitem("techage:ta5_aichip", { description = S("TA5 AI Chip"), - inventory_image = "techage_aichip.png", + inventory_image = "techage_aichip.png^[colorize:#48b9de:40", +}) + +minetest.register_craftitem("techage:ta5_aichip2", { + description = S("TA5 AI Chip II"), + inventory_image = "techage_aichip.png^[colorize:#de486c:40", }) techage.recipes.add("ta2_electronic_fab", { @@ -84,3 +89,9 @@ techage.recipes.add("ta4_electronic_fab", { input = {"techage:ta4_leds 8", "basic_materials:copper_wire 1", "basic_materials:gold_wire 1", "techage:ta4_silicon_wafer 1"}, ex_points = 10, }) + +techage.recipes.add("ta4_electronic_fab", { + output = "techage:ta5_aichip2 2", + input = {"techage:ta4_leds 8", "basic_materials:copper_wire 1", "basic_materials:gold_wire 1", "techage:ta4_silicon_wafer 1"}, + ex_points = 50, +}) diff --git a/techage/items/powder.lua b/techage/items/powder.lua index 1ca6484..a75ab61 100644 --- a/techage/items/powder.lua +++ b/techage/items/powder.lua @@ -50,6 +50,12 @@ minetest.register_craftitem("techage:silver_sandstone_powder", { groups = {powder = 1}, }) +minetest.register_craftitem("techage:graphite_powder", { + description = S("Graphite Powder"), + inventory_image = "techage_powder_inv.png^[colorize:#000000:160", + groups = {powder = 1}, +}) + techage.add_grinder_recipe({input="default:acacia_bush_leaves", output="techage:leave_powder"}) techage.add_grinder_recipe({input="default:acacia_leaves", output="techage:leave_powder"}) techage.add_grinder_recipe({input="default:aspen_leaves", output="techage:leave_powder"}) @@ -62,4 +68,5 @@ techage.add_grinder_recipe({input="default:iron_lump", output="techage:iron_powd techage.add_grinder_recipe({input="default:clay", output="techage:clay_powder"}) techage.add_grinder_recipe({input="techage:aluminum", output="techage:aluminum_powder"}) techage.add_grinder_recipe({input="default:silver_sandstone", output="techage:silver_sandstone_powder"}) +techage.add_grinder_recipe({input="default:coal_lump", output="techage:graphite_powder"}) diff --git a/techage/items/registered_nodes.lua b/techage/items/registered_nodes.lua index 36cf710..a6a6bae 100644 --- a/techage/items/registered_nodes.lua +++ b/techage/items/registered_nodes.lua @@ -38,3 +38,30 @@ minetest.register_on_mods_loaded(function() end) minetest.override_item("default:gravel", {groups = {crumbly = 2, gravel = 1, falling_node = 1}}) + +-- Register all known mobs mods for the move/fly controllers +techage.register_mobs_mods("ts_skins_dummies") +techage.register_mobs_mods("mobs") +techage.register_mobs_mods("draconis") +techage.register_mobs_mods("mobkit") +techage.register_mobs_mods("animalia") +techage.register_mobs_mods("mobs_animal") +techage.register_mobs_mods("mobs_monster") +techage.register_mobs_mods("dmobs") +techage.register_mobs_mods("mob_horse") +techage.register_mobs_mods("petz") +techage.register_mobs_mods("mobs_npc") +techage.register_mobs_mods("livingnether") +techage.register_mobs_mods("extra_mobs") +techage.register_mobs_mods("nssm") +techage.register_mobs_mods("goblins") +techage.register_mobs_mods("animalworld") +techage.register_mobs_mods("aliveai") +techage.register_mobs_mods("people") +techage.register_mobs_mods("paleotest") +techage.register_mobs_mods("mobs_balrog") +techage.register_mobs_mods("wildlife") +techage.register_mobs_mods("mobs_skeletons") +techage.register_mobs_mods("mobs_dwarves") +techage.register_mobs_mods("mobf_trader") +techage.register_mobs_mods("ts_vehicles") diff --git a/techage/liquids/liquid_pipe.lua b/techage/liquids/liquid_pipe.lua index 40a366f..2e94efa 100644 --- a/techage/liquids/liquid_pipe.lua +++ b/techage/liquids/liquid_pipe.lua @@ -20,7 +20,7 @@ local S = techage.S local MAX_PIPE_LENGHT = 100 -local power = networks.power +local liquid = networks.liquid local Pipe = tubelib2.Tube:new({ dirs_to_check = {1,2,3,4,5,6}, @@ -47,7 +47,7 @@ local Pipe = tubelib2.Tube:new({ -- Use global callback instead of node related functions Pipe:register_on_tube_update2(function(pos, outdir, tlib2, node) - power.update_network(pos, outdir, tlib2, node) + liquid.update_network(pos, outdir, tlib2, node) end) minetest.register_node("techage:ta3_pipeS", { @@ -172,14 +172,14 @@ local names = networks.register_junction("techage:ta3_junctionpipe", 1/8, Boxes, tubelib2_on_update2 = function(pos, dir1, tlib2, node) local name = "techage:ta3_junctionpipe" .. networks.junction_type(pos, Pipe) minetest.swap_node(pos, {name = name, param2 = 0}) - power.update_network(pos, 0, tlib2, node) + liquid.update_network(pos, 0, tlib2, node) end, after_dig_node = function(pos, oldnode, oldmetadata, digger) Pipe:after_dig_node(pos) end, }, 25) -power.register_nodes(names, Pipe, "junc") +liquid.register_nodes(names, Pipe, "junc") minetest.register_craft({ output = "techage:ta3_junctionpipe25 2", diff --git a/techage/liquids/pump.lua b/techage/liquids/pump.lua index 0a49247..868d81a 100644 --- a/techage/liquids/pump.lua +++ b/techage/liquids/pump.lua @@ -3,7 +3,7 @@ TechAge ======= - Copyright (C) 2019-2021 Joachim Stolberg + Copyright (C) 2019-2022 Joachim Stolberg AGPL v3 See LICENSE.txt for more information @@ -66,7 +66,7 @@ local function pumping(pos, nvm, state, capa) state:blocked(pos, nvm) return 0 end - state:keep_running(pos, nvm, COUNTDOWN_TICKS) + state:keep_running(pos, nvm, COUNTDOWN_TICKS) return taken - leftover end state:keep_running(pos, nvm, COUNTDOWN_TICKS) @@ -133,7 +133,7 @@ end local ta3_tiles_pas = { -- up, down, right, left, back, front "techage_filling_ta3.png^techage_frame_ta3_top.png^techage_appl_arrow.png", - "techage_filling_ta3.png^techage_frame_ta3.png", + "techage_filling_ta3.png^techage_frame_ta3_bottom.png", "techage_filling_ta3.png^techage_appl_hole_pipe.png^techage_frame_ta3.png", "techage_filling_ta3.png^techage_appl_hole_pipe.png^techage_frame_ta3.png", "techage_filling_ta3.png^techage_appl_pump.png^techage_frame_ta3.png^[transformFX", @@ -143,7 +143,7 @@ local ta3_tiles_pas = { local ta4_tiles_pas = { -- up, down, right, left, back, front "techage_filling_ta4.png^techage_frame_ta4_top.png^techage_appl_arrow.png", - "techage_filling_ta4.png^techage_frame_ta4.png", + "techage_filling_ta4.png^techage_frame_ta4_bottom.png", "techage_filling_ta4.png^techage_appl_hole_pipe.png^techage_frame_ta4.png", "techage_filling_ta4.png^techage_appl_hole_pipe.png^techage_frame_ta4.png", "techage_filling_ta4.png^techage_appl_pump.png^techage_frame_ta4.png^[transformFX", @@ -153,7 +153,7 @@ local ta4_tiles_pas = { local ta3_tiles_act = { -- up, down, right, left, back, front "techage_filling_ta3.png^techage_frame_ta3_top.png^techage_appl_arrow.png", - "techage_filling_ta3.png^techage_frame_ta3.png", + "techage_filling_ta3.png^techage_frame_ta3_bottom.png", "techage_filling_ta3.png^techage_appl_hole_pipe.png^techage_frame_ta3.png", "techage_filling_ta3.png^techage_appl_hole_pipe.png^techage_frame_ta3.png", { @@ -181,7 +181,7 @@ local ta3_tiles_act = { local ta4_tiles_act = { -- up, down, right, left, back, front "techage_filling_ta4.png^techage_frame_ta4_top.png^techage_appl_arrow.png", - "techage_filling_ta4.png^techage_frame_ta4.png", + "techage_filling_ta4.png^techage_frame_ta4_bottom.png", "techage_filling_ta4.png^techage_appl_hole_pipe.png^techage_frame_ta4.png", "techage_filling_ta4.png^techage_appl_hole_pipe.png^techage_frame_ta4.png", { diff --git a/techage/liquids/tank.lua b/techage/liquids/tank.lua index b970c50..9b87f51 100644 --- a/techage/liquids/tank.lua +++ b/techage/liquids/tank.lua @@ -91,7 +91,7 @@ minetest.register_node("techage:ta3_tank", { tiles = { -- up, down, right, left, back, front "techage_filling_ta3.png^techage_frame_ta3_top.png", - "techage_filling_ta3.png^techage_frame_ta3.png", + "techage_filling_ta3.png^techage_frame_ta3_bottom.png", "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_tank.png", "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_tank.png", "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_tank.png", @@ -197,7 +197,7 @@ minetest.register_node("techage:ta4_tank", { tiles = { -- up, down, right, left, back, front "techage_filling_ta4.png^techage_frame_ta4_top.png", - "techage_filling_ta4.png^techage_frame_ta4.png", + "techage_filling_ta4.png^techage_frame_ta4_bottom.png", "techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_tank.png", "techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_tank.png", "techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_tank.png", diff --git a/techage/locale/techage.de.tr b/techage/locale/techage.de.tr index fda454e..b59c664 100644 --- a/techage/locale/techage.de.tr +++ b/techage/locale/techage.de.tr @@ -97,6 +97,10 @@ TA3 Boiler Base=TA3 Boiler unten To add water punch@nthe boiler@nwith a water bucket=Um Wasser nachzufüllen,@nschlage mit einem Wassereimer@nauf den Block Water Boiler=Wasserboiler + +### boiler_lib.lua ### +### heatexchanger2.lua ### + water temperature=Wassertemperatur ### boiler_top.lua ### @@ -197,6 +201,7 @@ Cement Powder=Zement Pulver TA4 Ceramic Material=TA4 Keramik Material TA4 Furnace Ceramic=TA4 Ofen Keramik TA4 Round Ceramic=TA4 Rund-Keramik +TA5 Ceramic Turbine=TA5 Keramikturbine ### charcoalpile.lua ### @@ -232,6 +237,20 @@ TA4 State Collector=TA4 Zuständesammler TA4 Tube Concentrator=TA4 Röhren Konzentrator Tube Concentrator=Röhren Konzentrator +### controller.lua ### + +Cooling failed=Kühlung ausgefallen +Magnet detection error@n(@1% found / 100% expected)=Magneterkennungsfehler@n(@1% erkannt / 100% erwartet) +Nucleus detection error=Kern nicht erkannt +Plasma ring shape error=Formfehler des Plasmarings +Shell shape error@n(@1% found / 100% expected)=Hüllenformfehler@n(@1% erkannt / 100% erwartet) +TA5 Fusion Reactor Controller=TA5 Fusionsreaktor Controller + +### controller.lua ### +### heatexchanger2.lua ### + +No power=Kein Strom + ### cooking.lua ### TA3 Melting=TA3 Schmelzen @@ -383,6 +402,7 @@ TA4 LEDs=TA4 LEDs TA4 RAM Chip=RAM Chip TA4 WLAN Chip=TA4 WLAN Chip TA5 AI Chip=TA5 KI Chip +TA5 AI Chip II=TA5 KI Chip II WLAN Chip=WLAN Chip ### electronic_fab.lua ### @@ -523,6 +543,11 @@ Furnace Top=Ofenoberteil Outp=Ergeb. no fuel or no power=kein Strom oder Brennstoff +### gas_pipe.lua ### + +TA5 Junction Pipe=TA5 Leitungskupplung +TA5 Pipe=TA5 Leitung + ### gateblock.lua ### TechAge Gate Block=TechAge Torblock @@ -535,6 +560,7 @@ TA2 Gearbox=TA2 Getriebeblock TA3 Generator=TA3 Generator TA4 Generator=TA4 Generator +TA5 Generator=TA5 Generator ### generator.lua ### ### power_terminal2.lua ### @@ -571,6 +597,7 @@ TA4 LED Grow Light=TA4 LED Pflanzenlampe No plan available=Kein Plan verfügar Plan=Plan +Sectional view=Schnittbild Side view=Seitenansicht Top view=Draufsicht @@ -590,13 +617,18 @@ TA4 Furnace Heater=TA4 Ofenheizung ### heatexchanger1.lua ### TA4 Heat Exchanger 1=TA4 Wärmetauscher 1 +TA5 Heat Exchanger 1=TA5 Wärmetauscher 1 ### heatexchanger2.lua ### -No power=Kein Strom +Blue pipe connection error@n(@1 found / @2 expected)=Verbindungsfehler blaue Leitung@n(@1 erkannt / @2 erwartet) +Cooler error=Kühlungsfehler +Green pipe connection error@n(@1 found / @2 expected)=Verbindungsfehler grüne Leitung@n(@1 erkannt / @2 erwartet) Power network connection error=Stromnetz Verbindungsfehler TA4 Heat Exchanger=TA4 Wärmetauscher TA4 Heat Exchanger 2=TA4 Wärmetauscher 2 +TA5 Heat Exchanger 2=TA5 Wärmetauscher 2 +Turbine error= did you check the plan?=hast du den Plan geprüft? inlet/pipe error=Einlass/Leitungsfehler wrong storage diameter=Falscher Wärmespeicher-Durchmesser @@ -604,6 +636,7 @@ wrong storage diameter=Falscher Wärmespeicher-Durchmesser ### heatexchanger3.lua ### TA4 Heat Exchanger 3=TA4 Wärmetauscher 3 +TA5 Heat Exchanger 3=TA5 Wärmetauscher 3 ### hydrogen.lua ### @@ -770,6 +803,10 @@ TA4 Collider Detector Magnet=TA4 Collider Detektormagnet TA4 Collider Magnet=TA4 Collider Magnet TA4 Collider Magnet Base=TA4 Collider Magnetfuß TA4 Collider Steel Block=TA4 Collider Stahlblock +TA5 Fusion Reactor Magnet 1=TA5 Fusionsreaktor Magnet 1 +TA5 Fusion Reactor Magnet 2=TA5 Fusionsreaktor Magnet 2 +TA5 Fusion Reactor Magnet Blank=TA5 Fusionsreaktor Magnetrohling +TA5 Fusion Reactor Magnet Shield=TA5 Fusionsreaktor Magnetschild ### mba_detector.lua ### @@ -906,6 +943,7 @@ TA4 Player Detector=TA4 Spieler Detektor Aluminum Powder=Aluminium Pulver Clay Powder=Ton Pulver +Graphite Powder=Graphitpulver Iron Powder=Eisen Pulver Leave Powder=Laub Pulver Needle Powder=Nadel Pulver @@ -967,6 +1005,10 @@ Allow to dig/place Techage power lines nearby power poles=Erlaubt TODO TA3 Pump=TA3 Pumpe TA4 Pump=TA4 Pumpe + +### pump.lua ### +### ta5_pump.lua ### + Total flow rate=Gesamtdurchfluss Total flow rate in liquid units=Gesamtdurchfluss in Flüssigkeitseinheiten @@ -1049,6 +1091,11 @@ TA4 Rotor Blade=TA4 Rotorblatt TA4 Wind Turbine=TA4 Windkraftanlage TA4 Wind Turbine Nacelle=TA4 Windkraftanlagengondel +### screwdriver.lua ### + +Block alignment stored!=Blockausrichtung gespeichert! +Techage Screwdriver@n(See: TA3 > Tools)=Techage Schraubendreher@n(Siehe: TA3 > Werkzeuge) + ### sensorchest.lua ### Allow public chest access=Erlaube öffentlichen Zugriff @@ -1089,6 +1136,11 @@ the timeslot when the command is executed.@n=der Zeitpunkt, wenn der Befehl ausg Cancel=Abbruch +### shell.lua ### + +TA5 Fusion Reactor Nucleus=TA5 Fusionsreaktor Kern +TA5 Fusion Reactor Shell=TA5 Fusionsreaktor Hülle + ### signallamp.lua ### TA4 Wind Turbine Signal Lamp=TA4 Windkraftanlagenlampe @@ -1257,6 +1309,10 @@ no power=kein Strom TA5 Hyperloop Chest=TA5 Hyperloop Kiste +### ta5_pump.lua ### + +TA5 Pump=TA5 Pumpe + ### ta5_tank.lua ### TA5 Hyperloop Tank=TA5 Hyperloop Tank @@ -1343,6 +1399,7 @@ TA4 Tube=TA4 Röhre TA3 Turbine=TA3 Turbine TA4 Turbine=TA4 Turbine +TA5 Turbine=TA5 Turbine ### turncontroller.lua ### diff --git a/techage/locale/template.txt b/techage/locale/template.txt index 6a51b06..63384bd 100644 --- a/techage/locale/template.txt +++ b/techage/locale/template.txt @@ -97,6 +97,10 @@ TA3 Boiler Base= To add water punch@nthe boiler@nwith a water bucket= Water Boiler= + +### boiler_lib.lua ### +### heatexchanger2.lua ### + water temperature= ### boiler_top.lua ### @@ -197,6 +201,7 @@ Cement Powder= TA4 Ceramic Material= TA4 Furnace Ceramic= TA4 Round Ceramic= +TA5 Ceramic Turbine= ### charcoalpile.lua ### @@ -232,6 +237,20 @@ TA4 State Collector= TA4 Tube Concentrator= Tube Concentrator= +### controller.lua ### + +Cooling failed= +Magnet detection error@n(@1% found / 100% expected)= +Nucleus detection error= +Plasma ring shape error= +Shell shape error@n(@1% found / 100% expected)= +TA5 Fusion Reactor Controller= + +### controller.lua ### +### heatexchanger2.lua ### + +No power= + ### cooking.lua ### TA3 Melting= @@ -383,6 +402,7 @@ TA4 LEDs= TA4 RAM Chip= TA4 WLAN Chip= TA5 AI Chip= +TA5 AI Chip II= WLAN Chip= ### electronic_fab.lua ### @@ -523,6 +543,11 @@ Furnace Top= Outp= no fuel or no power= +### gas_pipe.lua ### + +TA5 Junction Pipe= +TA5 Pipe= + ### gateblock.lua ### TechAge Gate Block= @@ -535,6 +560,7 @@ TA2 Gearbox= TA3 Generator= TA4 Generator= +TA5 Generator= ### generator.lua ### ### power_terminal2.lua ### @@ -571,6 +597,7 @@ TA4 LED Grow Light= No plan available= Plan= +Sectional view= Side view= Top view= @@ -590,13 +617,18 @@ TA4 Furnace Heater= ### heatexchanger1.lua ### TA4 Heat Exchanger 1= +TA5 Heat Exchanger 1= ### heatexchanger2.lua ### -No power= +Blue pipe connection error@n(@1 found / @2 expected)= +Cooler error= +Green pipe connection error@n(@1 found / @2 expected)= Power network connection error= TA4 Heat Exchanger= TA4 Heat Exchanger 2= +TA5 Heat Exchanger 2= +Turbine error= did you check the plan?= inlet/pipe error= wrong storage diameter= @@ -604,6 +636,7 @@ wrong storage diameter= ### heatexchanger3.lua ### TA4 Heat Exchanger 3= +TA5 Heat Exchanger 3= ### hydrogen.lua ### @@ -770,6 +803,10 @@ TA4 Collider Detector Magnet= TA4 Collider Magnet= TA4 Collider Magnet Base= TA4 Collider Steel Block= +TA5 Fusion Reactor Magnet 1= +TA5 Fusion Reactor Magnet 2= +TA5 Fusion Reactor Magnet Blank= +TA5 Fusion Reactor Magnet Shield= ### mba_detector.lua ### @@ -906,6 +943,7 @@ TA4 Player Detector= Aluminum Powder= Clay Powder= +Graphite Powder= Iron Powder= Leave Powder= Needle Powder= @@ -967,6 +1005,10 @@ Allow to dig/place Techage power lines nearby power poles= TA3 Pump= TA4 Pump= + +### pump.lua ### +### ta5_pump.lua ### + Total flow rate= Total flow rate in liquid units= @@ -1049,6 +1091,11 @@ TA4 Rotor Blade= TA4 Wind Turbine= TA4 Wind Turbine Nacelle= +### screwdriver.lua ### + +Block alignment stored!= +Techage Screwdriver@n(See: TA3 > Tools)= + ### sensorchest.lua ### Allow public chest access= @@ -1089,6 +1136,11 @@ the timeslot when the command is executed.@n= Cancel= +### shell.lua ### + +TA5 Fusion Reactor Nucleus= +TA5 Fusion Reactor Shell= + ### signallamp.lua ### TA4 Wind Turbine Signal Lamp= @@ -1257,6 +1309,10 @@ no power= TA5 Hyperloop Chest= +### ta5_pump.lua ### + +TA5 Pump= + ### ta5_tank.lua ### TA5 Hyperloop Tank= @@ -1343,6 +1399,7 @@ TA4 Tube= TA3 Turbine= TA4 Turbine= +TA5 Turbine= ### turncontroller.lua ### diff --git a/techage/manuals/manual_ta3_DE.md b/techage/manuals/manual_ta3_DE.md index 6916f56..e44f9f7 100644 --- a/techage/manuals/manual_ta3_DE.md +++ b/techage/manuals/manual_ta3_DE.md @@ -836,8 +836,6 @@ Mit Shift+Rechtsklick kann bei einigen Blöcken ein erweitertes Menü geöffnet [ta3_end_wrench|image] - - ### TechAge Programmer Mit dem Programmer können Blocknummern mit einem Rechtsklick von mehreren Blöcken eingesammelt und mit einem Linksklick in einen Block wie Taster/Schalter geschrieben werden. @@ -845,8 +843,6 @@ Wird in die Luft geklickt, wird der interne Speicher gelöscht. [ta3_programmer|image] - - ### TechAge Kelle / Trowel Die Kelle dient zum Verputzen von Stromkabel. Siehe dazu "TA Stromkabel". @@ -859,3 +855,14 @@ Die Kelle dient zum Verputzen von Stromkabel. Siehe dazu "TA Stromkabel". Mit diesem Werkzeug lassen sich die Bohrgestängezange Blöcke wieder entfernen, wenn dort bspw. ein Tunnel durch soll. [ta3_drill_pipe_wrench|image] + +### Techage Schraubendreher + +Der Techage Schraubendreher dient als Ersatz für den normalen Schraubendreher. Es besitzt folgende Funktionen: + +- Linksklick: Den Block nach links drehen +- Rechtsklick: Die sichtbare Seite des Blockes nach oben drehen +- Shift+Linksklick: Ausrichtung des angeklickten Blockes speichern +- Shift+Rechtsklick: Die gespeicherte Ausrichtung auf den angeklickten Block anwenden + +[ta3_screwdriver|image] \ No newline at end of file diff --git a/techage/manuals/manual_ta3_EN.md b/techage/manuals/manual_ta3_EN.md index 82b6f81..b24434c 100644 --- a/techage/manuals/manual_ta3_EN.md +++ b/techage/manuals/manual_ta3_EN.md @@ -829,7 +829,6 @@ With Shift + right click an extended menu can be opened for some blocks. Dependi [ta3_end_wrench|image] - ### TechAge Programmer With the programmer, block numbers can be collected from several blocks with a right click and written into a block like a button / switch with a left click. @@ -837,17 +836,25 @@ If you click in the air, the internal memory is deleted. [ta3_programmer|image] - - ### TechAge Trowel / Trowel The trowel is used for plastering power cables. See also "TA power cable". [ta3_trowel|image] - ### TA3 drill pipe wrench This tool can be used to remove the drill pipe blocks if, for example, a tunnel is to pass through there. [ta3_drill_pipe_wrench|image] + +### Techage Screwdriver + +The Techage Screwdriver serves as a replacement for the normal screwdriver. It has the following functions: + +- Left click: turn the block to the left +- Right click: turn the visible side of the block upwards +- Shift + left click: save the alignment of the clicked block +- Shift + right click: apply the saved alignment to the clicked block + +[ta3_screwdriver|image] diff --git a/techage/manuals/manual_ta5_DE.md b/techage/manuals/manual_ta5_DE.md index 599594b..29f1124 100644 --- a/techage/manuals/manual_ta5_DE.md +++ b/techage/manuals/manual_ta5_DE.md @@ -8,7 +8,61 @@ Für die Herstellung und Nutzung von TA5 Maschinen und Blöcken sind Erfahrungsp ## Energiequellen -### TA5 Fusionsreaktor (geplant) +### TA5 Fusionsreaktor + +Kernfusion bedeutet das Verschmelzen zweier Atomkerne. Dabei können, je nach Reaktion, große Mengen von Energie freigesetzt werden. Kernfusionen, bei denen Energie frei wird, laufen in Form von Kettenreaktionen ab. Sie sind die Quelle der Energie der Sterne, zum Beispiel auch unserer Sonne. Ein Fusionsreaktor wandelt die Energie, die bei einer kontrollierten Kernfusion frei wird, in elektrischen Strom um. + +**Wie funktionieren ein Fusionsreaktor?** + +Ein Fusionsreaktor funktioniert nach dem klassischen Prinzip eines Wärmekraftwerks: Wasser wird erhitzt und treibt eine Dampfturbine an, deren Bewegungsenergie von einem Generator in Strom gewandelt wird. + +Ein Fusionskraftwerk benötigt zunächst eine hohe Menge an Energie, da ein Plasma erzeugt werden muss. „Plasma“ nennt man den vierten Zustand von Stoffen, nach fest, flüssig und gasförmig. Dafür wird viel Strom benötigt. Erst durch diese extreme Energiekonzentration zündet die Fusionsreaktion und mit der abgegebenen Wärme wird über den Wärmetauscher Strom erzeugt. Der Generator liefert dann 800 ku an Strom. + +Der Plan rechts zeigt einen Schnitt durch den Fusionsreaktor. + +Für den Betrieb des Fusionsreaktors werden 60 Erfahrungspunkte benötigt. Der Fusionsreaktur muss komplett in einem Forceload Block Bereich aufgebaut werden. + +[ta5_fusion_reactor|plan] + +#### TA5 Fusionreaktor Magnet + +Für den Aufbau des Fusionsreaktor werden insgesamt 60 TA5 Fusionreaktor Magnete benötigt. Diese bilden den Ring, in dem sich das Plasma bildet. Der TA5 Fusionsreaktor Magnete benötigt Strom und hat zwei Anschlüsse für die Kühlung. + +Es gibt zwei Typen von Magneten, so dass auch alle Seiten des Magnets, die zum Plasmaring zeigen, mit einem Hitzeschild geschützt werden können. + +Bei den Eckmagneten auf der Innenseite des Rings ist jeweils eine Anschlussseite verdeckt (Strom oder Kühlung) und kann daher nicht angeschlossen werden. Dies ist technisch nicht machbar und hat daher keinen Einfluß auf die Funktion des Fusionsreaktor. + +[ta5_magnet|image] + +#### TA5 Pumpe + +Die Pumpe wird benötigt, um den Kühlkreislauf mit Isobutan zu füllen. Es werden ca. 350 Einheiten Isobutan benötigt. + +[ta5_pump|image] + +#### TA5 Wärmetauscher + +Der TA5 Wärmetauscher wird benötigt, um die im Fusionsreaktor erzeugte Hitze zuerst in Dampf und dann in Strom umzuwandeln. Der Wärmetauscher selbst benötigt dazu 5 ku Strom. Der Aufbau gleicht dem Wärmetauscher des Energiespeichers aus TA4. + +[ta5_heatexchanger|plan] + +#### TA5 Fusionreaktor Controller + +Über den TA5 Fusionreaktor Controller wird der Fusionreaktors eingeschaltet. Dabei muss zuerst die Kühlung/Wärmetauscher und dann der Controller eingeschaltet werden. Es dauert ca. 2 min, bis der Reaktor in Gang kommt und Strom liefert. Der Fusionreaktor und damit der Controller benötigt 400 ku an Strom, um das Plasma aufrecht zu erhalten. + +[ta5_fr_controller|image] + +#### TA5 Fusionreaktor Hülle + +Der komplette Reaktor muss mit einer Hülle umgeben werden, die den enormen Druck, den die Magnete auf das Plasma ausüben, abfängt und die Umgebung vor Strahlung schützt. Ohne diese Hülle kann der Reaktor nicht gestartet werden. Mit der TechAge Kelle können auch Stromkabel und Kühlleitungen des Fusionreaktors in die Hülle integriert werden. + +[ta5_fr_shell|image] + +#### TA5 Fusionreaktor Kern + +Der Kern muss in der Mitte des Reaktors sitzen. Siehe Abbildung unter "TA5 Fusionsreaktor". Auch hierfür wird die TechAge Kelle benötigt. + +[ta5_fr_nucleus|image] ## Energiespeicher diff --git a/techage/manuals/manual_ta5_EN.md b/techage/manuals/manual_ta5_EN.md index f61e370..fea4a84 100644 --- a/techage/manuals/manual_ta5_EN.md +++ b/techage/manuals/manual_ta5_EN.md @@ -8,7 +8,61 @@ Experience points are required for the manufacture and use of TA5 machines and b ## Energy Sources -### TA5 Fusion Reactor (planned) +### TA5 Fusion Reactor + +Nuclear fusion means the fusing of two atomic nuclei. Depending on the reaction, large amounts of energy can be released. Nuclear fusions, in which energy is released, take place in the form of chain reactions. They are the source of the energy of the stars, including our sun, for example. A fusion reactor converts the energy released during controlled nuclear fusion into electricity. + +**How ​​do fusion reactors work?** + +A fusion reactor works according to the classic principle of a thermal power plant: water is heated and drives a steam turbine, whose kinetic energy is converted into electricity by a generator. + +A fusion power plant initially requires a large amount of energy, since a plasma has to be generated. "Plasma" is the name given to the fourth state of matter, after solid, liquid and gaseous. This requires a lot of electricity. Only through this extreme concentration of energy does the fusion reaction ignite and the heat given off is used to generate electricity via the heat exchanger. The generator then delivers 800 ku of electricity. + +The plan on the right shows a section through the fusion reactor. + +60 experience points are required to operate the fusion reactor. The fusion reactor must be built entirely in a forceload block area. + +[ta5_fusion_reactor|plan] + +#### TA5 Fusion Reactor Magnet + +A total of 60 TA5 Fusion Reactor Magnets are required to set up the fusion reactor. These form the ring in which the plasma forms. The TA5 Fusion Reactor Magnets requires power and has two ports for cooling. + +There are two types of magnets, so all sides of the magnet that face the plasma ring can also be protected with a heat shield. + +With the corner magnets on the inside of the ring, one connection side is covered (power or cooling) and can therefore not be connected. This is technically not feasible and therefore has no influence on the function of the fusion reactor. + +[ta5_magnet|image] + +#### TA5 Pump + +The pump is required to fill the cooling circuit with isobutane. About 350 units of isobutane are required. + +[ta5_pump|image] + +#### TA5 Heat Exchanger + +The TA5 Heat Exchanger is required to convert the heat generated in the fusion reactor first to steam and then to electricity. The Heat Exchanger itself requires 5 ku electricity. The structure is similar to the Heat Exchanger of the energy store from TA4. + +[ta5_heatexchanger|plan] + +#### TA5 Fusion Reactor Controller + +The fusion reactor is switched on via the TA5 Fusion Reactor Controller. The cooling/Heat Exchanger must be switched on first and then the controller. It takes about 2 minutes for the reactor to start up and supply electricity. The fusion reactor and thus the controller requires 400 ku of electricity to maintain the plasma. + +[ta5_fr_controller|image] + +#### TA5 Fusion Reactor Shell + +The entire reactor must be surrounded by a shell that absorbs the enormous pressure that the magnets exert on the plasma and protects the environment from radiation. Without this shell, the reactor cannot be started. With the TechAge Trowel, power cables and cooling pipes of the fusion reactor can also be integrated into the shell. + +[ta5_fr_shell|image] + +#### TA5 Fusion Reactor Core + +The core must sit in the center of the reactor. See illustration under "TA5 Fusion Reactor". The TechAge Trowel is also required for this. + +[ta5_fr_nucleus|image] ## Energy Storage diff --git a/techage/manuals/toc_DE.md b/techage/manuals/toc_DE.md index b55e835..36fc807 100644 --- a/techage/manuals/toc_DE.md +++ b/techage/manuals/toc_DE.md @@ -138,6 +138,7 @@ - [TechAge Programmer](./manual_ta3_DE.md#techage-programmer) - [TechAge Kelle / Trowel](./manual_ta3_DE.md#techage-kelle--trowel) - [TA3 Bohrgestängezange / TA3 Drill Pipe Wrench](./manual_ta3_DE.md#ta3-bohrgestängezange--ta3-drill-pipe-wrench) + - [Techage Schraubendreher](./manual_ta3_DE.md#techage-schraubendreher) - [TA4: Gegenwart](./manual_ta4_DE.md#ta4:-gegenwart) - [Windkraftanlage](./manual_ta4_DE.md#windkraftanlage) - [TA4 Windkraftanlage / Wind Turbine](./manual_ta4_DE.md#ta4-windkraftanlage--wind-turbine) @@ -228,7 +229,13 @@ - [TA4 Recycler](./manual_ta4_DE.md#ta4-recycler) - [TA5: Zukunft](./manual_ta5_DE.md#ta5:-zukunft) - [Energiequellen](./manual_ta5_DE.md#energiequellen) - - [TA5 Fusionsreaktor (geplant)](./manual_ta5_DE.md#ta5-fusionsreaktor-(geplant)) + - [TA5 Fusionsreaktor](./manual_ta5_DE.md#ta5-fusionsreaktor) + - [TA5 Fusionreaktor Magnet](./manual_ta5_DE.md#ta5-fusionreaktor-magnet) + - [TA5 Pumpe](./manual_ta5_DE.md#ta5-pumpe) + - [TA5 Wärmetauscher](./manual_ta5_DE.md#ta5-wärmetauscher) + - [TA5 Fusionreaktor Controller](./manual_ta5_DE.md#ta5-fusionreaktor-controller) + - [TA5 Fusionreaktor Hülle](./manual_ta5_DE.md#ta5-fusionreaktor-hülle) + - [TA5 Fusionreaktor Kern](./manual_ta5_DE.md#ta5-fusionreaktor-kern) - [Energiespeicher](./manual_ta5_DE.md#energiespeicher) - [TA5 Hybrid-Speicher (geplant)](./manual_ta5_DE.md#ta5-hybrid-speicher-(geplant)) - [Logik Blöcke](./manual_ta5_DE.md#logik-blöcke) diff --git a/techage/manuals/toc_EN.md b/techage/manuals/toc_EN.md index 359853c..705a0a2 100644 --- a/techage/manuals/toc_EN.md +++ b/techage/manuals/toc_EN.md @@ -138,6 +138,7 @@ - [TechAge Programmer](./manual_ta3_EN.md#techage-programmer) - [TechAge Trowel / Trowel](./manual_ta3_EN.md#techage-trowel--trowel) - [TA3 drill pipe wrench](./manual_ta3_EN.md#ta3-drill-pipe-wrench) + - [Techage Screwdriver](./manual_ta3_EN.md#techage-screwdriver) - [TA4: Present](./manual_ta4_EN.md#ta4:-present) - [Wind Turbine](./manual_ta4_EN.md#wind-turbine) - [TA4 Wind Turbine](./manual_ta4_EN.md#ta4-wind-turbine) @@ -228,7 +229,13 @@ - [TA4 Recycler](./manual_ta4_EN.md#ta4-recycler) - [TA5: Future](./manual_ta5_EN.md#ta5:-future) - [Energy Sources](./manual_ta5_EN.md#energy-sources) - - [TA5 Fusion Reactor (planned)](./manual_ta5_EN.md#ta5-fusion-reactor-(planned)) + - [TA5 Fusion Reactor](./manual_ta5_EN.md#ta5-fusion-reactor) + - [TA5 Fusion Reactor Magnet](./manual_ta5_EN.md#ta5-fusion-reactor-magnet) + - [TA5 Pump](./manual_ta5_EN.md#ta5-pump) + - [TA5 Heat Exchanger](./manual_ta5_EN.md#ta5-heat-exchanger) + - [TA5 Fusion Reactor Controller](./manual_ta5_EN.md#ta5-fusion-reactor-controller) + - [TA5 Fusion Reactor Shell](./manual_ta5_EN.md#ta5-fusion-reactor-shell) + - [TA5 Fusion Reactor Core](./manual_ta5_EN.md#ta5-fusion-reactor-core) - [Energy Storage](./manual_ta5_EN.md#energy-storage) - [TA5 Hybrid Storage (planned)](./manual_ta5_EN.md#ta5-hybrid-storage-(planned)) - [Logic blocks](./manual_ta5_EN.md#logic-blocks) diff --git a/techage/move_controller/flycontroller.lua b/techage/move_controller/flycontroller.lua index ca12aa1..7bdf96c 100644 --- a/techage/move_controller/flycontroller.lua +++ b/techage/move_controller/flycontroller.lua @@ -96,7 +96,7 @@ minetest.register_node("techage:ta5_flycontroller", { nvm.lpos1 = {} nvm.lpos2 = {} nvm.moveBA = false - nvm.running = true + nvm.running = nil meta:set_string("status", S("Recording...")) local name = player:get_player_name() minetest.chat_send_player(name, S("Click on all blocks that shall be moved")) @@ -109,7 +109,7 @@ minetest.register_node("techage:ta5_flycontroller", { if not err then meta:set_string("path", fields.path) end - nvm.running = false + nvm.running = nil local text = #pos_list.." "..S("block positions are stored.") meta:set_string("status", text) nvm.lpos1 = pos_list @@ -128,12 +128,12 @@ minetest.register_node("techage:ta5_flycontroller", { local name = player:get_player_name() mark.stop(name) nvm.moveBA = false - nvm.running = true + nvm.running = nil elseif fields.test then local path, err = fly.to_path(fields.path, MAX_DIST) if err then meta:set_string("status", err) - elseif path and nvm.lpos1 then + elseif path and nvm.lpos1 and nvm.lpos1[1] then local pos = table.copy(nvm.lpos1[1]) if pos then for _, offs in ipairs(path) do @@ -179,8 +179,7 @@ minetest.register_node("techage:ta5_flycontroller", { meta:set_string("formspec", formspec(nvm, meta)) elseif fields.move then meta:set_string("status", "") - nvm.moveBA = nvm.moveBA == false - if fly.move_to_other_pos(pos, nvm.moveBA == false) then + if fly.move_to_other_pos(pos, nvm.moveBA) then nvm.moveBA = nvm.moveBA == false nvm.running = true meta:set_string("formspec", formspec(nvm, meta)) diff --git a/techage/move_controller/movecontroller.lua b/techage/move_controller/movecontroller.lua index 92e2348..ab000ec 100644 --- a/techage/move_controller/movecontroller.lua +++ b/techage/move_controller/movecontroller.lua @@ -112,7 +112,7 @@ minetest.register_node("techage:ta4_movecontroller", { nvm.lpos1 = {} nvm.lpos2 = {} nvm.moveBA = false - nvm.running = true + nvm.running = nil meta:set_string("status", S("Recording...")) local name = player:get_player_name() minetest.chat_send_player(name, S("Click on all blocks that shall be moved")) @@ -125,7 +125,7 @@ minetest.register_node("techage:ta4_movecontroller", { meta:set_string("path", fields.path) end local text = #pos_list.." "..S("block positions are stored.") - nvm.running = false + nvm.running = nil meta:set_string("status", text) nvm.lpos1 = pos_list mark.unmark_all(name) @@ -142,7 +142,7 @@ minetest.register_node("techage:ta4_movecontroller", { local name = player:get_player_name() mark.stop(name) nvm.moveBA = false - nvm.running = true + nvm.running = nil elseif fields.moveAB then meta:set_string("status", "") if fly.move_to_other_pos(pos, false) then diff --git a/techage/ta3_power/tiny_generator.lua b/techage/ta3_power/tiny_generator.lua index 3b172bd..db82c46 100644 --- a/techage/ta3_power/tiny_generator.lua +++ b/techage/ta3_power/tiny_generator.lua @@ -127,10 +127,10 @@ local function node_timer(pos, elapsed) local fuel = has_fuel(pos, nvm) if running and not fuel then State:standby(pos, nvm, S("no fuel")) - stop_node(pos, nvm, State) + stop_node(pos, nvm, State) elseif not running and fuel then State:start(pos, nvm) - -- start_node() is called implicit + -- start_node() is called implicit elseif running then local meta = M(pos) local outdir = meta:get_int("outdir") @@ -166,7 +166,7 @@ end local function get_generator_data(pos, outdir, tlib2) local nvm = techage.get_nvm(pos) - if nvm.running and techage.is_running(nvm) then + if techage.is_running(nvm) then return {level = (nvm.load or 0) / PWR_PERF, perf = PWR_PERF, capa = PWR_PERF * 2} end end @@ -190,7 +190,6 @@ minetest.register_node("techage:tiny_generator", { after_place_node = function(pos, placer, itemstack) local nvm = techage.get_nvm(pos) local number = techage.add_node(pos, "techage:tiny_generator") - nvm.running = false nvm.burn_cycles = 0 if itemstack then local stack_meta = itemstack:get_meta() diff --git a/techage/teleport/teleport_tube.lua b/techage/teleport/teleport_tube.lua index 747a018..11517d3 100644 --- a/techage/teleport/teleport_tube.lua +++ b/techage/teleport/teleport_tube.lua @@ -154,16 +154,18 @@ techage.register_node({"techage:ta5_tele_tube"}, { local nvm = techage.get_nvm(pos) if techage.is_operational(nvm) then local rmt_pos = teleport.get_remote_pos(pos) - local rmt_nvm = techage.get_nvm(rmt_pos) - if techage.is_operational(rmt_nvm) then - local tube_dir = M(rmt_pos):get_int("tube_dir") - if techage.push_items(rmt_pos, tube_dir, stack) then - State:keep_running(pos, nvm, COUNTDOWN_TICKS) - State:keep_running(rmt_pos, rmt_nvm, COUNTDOWN_TICKS) - return true + if rmt_pos then + local rmt_nvm = techage.get_nvm(rmt_pos) + if techage.is_operational(rmt_nvm) then + local tube_dir = M(rmt_pos):get_int("tube_dir") + if techage.push_items(rmt_pos, tube_dir, stack) then + State:keep_running(pos, nvm, COUNTDOWN_TICKS) + State:keep_running(rmt_pos, rmt_nvm, COUNTDOWN_TICKS) + return true + end + else + State:blocked(pos, nvm, S("Remote block error")) end - else - State:blocked(pos, nvm, S("Remote block error")) end end return false diff --git a/techage/textures/shrink.sh b/techage/textures/shrink.sh deleted file mode 100755 index 36036c5..0000000 --- a/techage/textures/shrink.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -pngquant --skip-if-larger --quality=80 --strip *.png --ext .png --force \ No newline at end of file diff --git a/techage/textures/techage_aichip.png b/techage/textures/techage_aichip.png index 58dfd32..85403ae 100644 Binary files a/techage/textures/techage_aichip.png and b/techage/textures/techage_aichip.png differ diff --git a/techage/textures/techage_appl_hole_ta5_pipe1.png b/techage/textures/techage_appl_hole_ta5_pipe1.png new file mode 100644 index 0000000..fa8de79 Binary files /dev/null and b/techage/textures/techage_appl_hole_ta5_pipe1.png differ diff --git a/techage/textures/techage_appl_hole_ta5_pipe2.png b/techage/textures/techage_appl_hole_ta5_pipe2.png new file mode 100644 index 0000000..ab2e41e Binary files /dev/null and b/techage/textures/techage_appl_hole_ta5_pipe2.png differ diff --git a/techage/textures/techage_appl_plasma.png b/techage/textures/techage_appl_plasma.png new file mode 100644 index 0000000..2cea306 Binary files /dev/null and b/techage/textures/techage_appl_plasma.png differ diff --git a/techage/textures/techage_appl_plasma4.png b/techage/textures/techage_appl_plasma4.png new file mode 100644 index 0000000..eb3cd70 Binary files /dev/null and b/techage/textures/techage_appl_plasma4.png differ diff --git a/techage/textures/techage_ceramic_turbine.png b/techage/textures/techage_ceramic_turbine.png new file mode 100644 index 0000000..d2f55e5 Binary files /dev/null and b/techage/textures/techage_ceramic_turbine.png differ diff --git a/techage/textures/techage_filling4_ta3.png b/techage/textures/techage_filling4_ta3.png index 74c33a6..4576f68 100644 Binary files a/techage/textures/techage_filling4_ta3.png and b/techage/textures/techage_filling4_ta3.png differ diff --git a/techage/textures/techage_filling8_ta3.png b/techage/textures/techage_filling8_ta3.png index 3802a64..74739a3 100644 Binary files a/techage/textures/techage_filling8_ta3.png and b/techage/textures/techage_filling8_ta3.png differ diff --git a/techage/textures/techage_filling_ta3.png b/techage/textures/techage_filling_ta3.png index 0cd5219..fe5a214 100644 Binary files a/techage/textures/techage_filling_ta3.png and b/techage/textures/techage_filling_ta3.png differ diff --git a/techage/textures/techage_filling_ta4.png b/techage/textures/techage_filling_ta4.png index 8612391..8d0a03d 100644 Binary files a/techage/textures/techage_filling_ta4.png and b/techage/textures/techage_filling_ta4.png differ diff --git a/techage/textures/techage_frame4_ta5.png b/techage/textures/techage_frame4_ta5.png new file mode 100644 index 0000000..15c168d Binary files /dev/null and b/techage/textures/techage_frame4_ta5.png differ diff --git a/techage/textures/techage_frame8_ta5.png b/techage/textures/techage_frame8_ta5.png new file mode 100644 index 0000000..bd643e1 Binary files /dev/null and b/techage/textures/techage_frame8_ta5.png differ diff --git a/techage/textures/techage_frameT_ta5.png b/techage/textures/techage_frameT_ta5.png new file mode 100644 index 0000000..d6af881 Binary files /dev/null and b/techage/textures/techage_frameT_ta5.png differ diff --git a/techage/textures/techage_frame_ta2_bottom.png b/techage/textures/techage_frame_ta2_bottom.png new file mode 100644 index 0000000..f7ac529 Binary files /dev/null and b/techage/textures/techage_frame_ta2_bottom.png differ diff --git a/techage/textures/techage_frame_ta3_bottom.png b/techage/textures/techage_frame_ta3_bottom.png new file mode 100644 index 0000000..4e23692 Binary files /dev/null and b/techage/textures/techage_frame_ta3_bottom.png differ diff --git a/techage/textures/techage_frame_ta4_bottom.png b/techage/textures/techage_frame_ta4_bottom.png new file mode 100644 index 0000000..af32e7a Binary files /dev/null and b/techage/textures/techage_frame_ta4_bottom.png differ diff --git a/techage/textures/techage_fusion_reactor.png b/techage/textures/techage_fusion_reactor.png new file mode 100644 index 0000000..2516d4e Binary files /dev/null and b/techage/textures/techage_fusion_reactor.png differ diff --git a/techage/textures/techage_gas_inv.png b/techage/textures/techage_gas_inv.png index 7565178..ea6868d 100644 Binary files a/techage/textures/techage_gas_inv.png and b/techage/textures/techage_gas_inv.png differ diff --git a/techage/textures/techage_isobutane_inv.png b/techage/textures/techage_isobutane_inv.png index 2189b67..432c96d 100644 Binary files a/techage/textures/techage_isobutane_inv.png and b/techage/textures/techage_isobutane_inv.png differ diff --git a/techage/textures/techage_magnet_hole.png b/techage/textures/techage_magnet_hole.png new file mode 100644 index 0000000..5e00e1e Binary files /dev/null and b/techage/textures/techage_magnet_hole.png differ diff --git a/techage/textures/techage_plasma.png b/techage/textures/techage_plasma.png new file mode 100644 index 0000000..1e7cf86 Binary files /dev/null and b/techage/textures/techage_plasma.png differ diff --git a/techage/textures/techage_reactor_shell.png b/techage/textures/techage_reactor_shell.png new file mode 100644 index 0000000..52165c9 Binary files /dev/null and b/techage/textures/techage_reactor_shell.png differ diff --git a/techage/textures/techage_screwdriver.png b/techage/textures/techage_screwdriver.png new file mode 100644 index 0000000..e80ac2a Binary files /dev/null and b/techage/textures/techage_screwdriver.png differ diff --git a/techage/textures/techage_steel_tiles.png b/techage/textures/techage_steel_tiles.png new file mode 100644 index 0000000..21a25cd Binary files /dev/null and b/techage/textures/techage_steel_tiles.png differ diff --git a/techage/textures/techage_steel_tiles_side.png b/techage/textures/techage_steel_tiles_side.png new file mode 100644 index 0000000..59fb186 Binary files /dev/null and b/techage/textures/techage_steel_tiles_side.png differ diff --git a/techage/textures/techage_steel_tiles_top.png b/techage/textures/techage_steel_tiles_top.png new file mode 100644 index 0000000..95f1cf5 Binary files /dev/null and b/techage/textures/techage_steel_tiles_top.png differ diff --git a/techage/textures/techage_steel_tiles_top2.png b/techage/textures/techage_steel_tiles_top2.png new file mode 100644 index 0000000..f5e2e7e Binary files /dev/null and b/techage/textures/techage_steel_tiles_top2.png differ diff --git a/techage/textures/techage_steel_tiles_top3.png b/techage/textures/techage_steel_tiles_top3.png new file mode 100644 index 0000000..3eb4c8a Binary files /dev/null and b/techage/textures/techage_steel_tiles_top3.png differ diff --git a/techage/textures/techage_ta5_gaspipe.png b/techage/textures/techage_ta5_gaspipe.png new file mode 100644 index 0000000..7f9106d Binary files /dev/null and b/techage/textures/techage_ta5_gaspipe.png differ diff --git a/techage/textures/techage_ta5_gaspipeB.png b/techage/textures/techage_ta5_gaspipeB.png new file mode 100644 index 0000000..17659c4 Binary files /dev/null and b/techage/textures/techage_ta5_gaspipeB.png differ diff --git a/techage/textures/techage_ta5_gaspipe_hole.png b/techage/textures/techage_ta5_gaspipe_hole.png new file mode 100644 index 0000000..821059d Binary files /dev/null and b/techage/textures/techage_ta5_gaspipe_hole.png differ diff --git a/techage/textures/techage_ta5_gaspipe_hole2.png b/techage/textures/techage_ta5_gaspipe_hole2.png new file mode 100644 index 0000000..9097b83 Binary files /dev/null and b/techage/textures/techage_ta5_gaspipe_hole2.png differ diff --git a/techage/textures/techage_ta5_gaspipe_junction.png b/techage/textures/techage_ta5_gaspipe_junction.png new file mode 100644 index 0000000..f5c44ad Binary files /dev/null and b/techage/textures/techage_ta5_gaspipe_junction.png differ diff --git a/techage/textures/techage_ta5_gaspipe_knee.png b/techage/textures/techage_ta5_gaspipe_knee.png new file mode 100644 index 0000000..bafe337 Binary files /dev/null and b/techage/textures/techage_ta5_gaspipe_knee.png differ diff --git a/techage/textures/techage_ta5_gaspipe_knee2.png b/techage/textures/techage_ta5_gaspipe_knee2.png new file mode 100644 index 0000000..d0ea469 Binary files /dev/null and b/techage/textures/techage_ta5_gaspipe_knee2.png differ diff --git a/techage/tools/repairkit.lua b/techage/tools/repairkit.lua index eef67cd..2622a47 100644 --- a/techage/tools/repairkit.lua +++ b/techage/tools/repairkit.lua @@ -19,6 +19,9 @@ local Cable2 = techage.TA4_Cable local Pipe2 = techage.LiquidPipe local menu = techage.menu +local N = techage.get_node_lvm +local CTL = function(pos) return (minetest.registered_nodes[N(pos).name] or {}).control end + local function network_check(start_pos, Cable, player_name) -- local ndef = techage.networks.net_def(start_pos, Cable.tube_type) -- local outdir = nil @@ -61,17 +64,6 @@ local function read_state(itemstack, user, pointed_thing) minetest.chat_send_player(user:get_player_name(), S("Biome")..": "..name..", "..S("Position temperature")..": "..math.floor(data.heat).." ") end - if ndef and ndef.networks then - local player_name = user:get_player_name() - if ndef.networks.ele1 then - network_check(pos, Cable1, player_name) - elseif ndef.networks.ele2 then - network_check(pos, Cable2, player_name) - elseif ndef.networks.pipe2 then - network_check(pos, Pipe2, player_name) - end - end - if number then if ndef and ndef.description then local info = techage.send_single("0", number, "info", nil) diff --git a/techage/tools/screwdriver.lua b/techage/tools/screwdriver.lua new file mode 100644 index 0000000..26f0929 --- /dev/null +++ b/techage/tools/screwdriver.lua @@ -0,0 +1,155 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2020-2022 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + Screwdriver + +]]-- +if minetest.global_exists("screwdriver") then + +local S = techage.S +local M = minetest.get_meta + +local USES = 2000 + +local function base_checks(user, pointed_thing) + if pointed_thing.type ~= "node" then + return false + end + + if not user then + return false + end + + local pos = pointed_thing.under + local player_name = user:get_player_name() + + if minetest.is_protected(pos, player_name) then + return false + end + + local node = minetest.get_node(pos) + local ndef = minetest.registered_nodes[node.name] + + if not ndef then + return false + end + + if ndef.on_rotate == screwdriver.disallow and not ndef.ta_rotate_node then + return false + end + + local yaw = user:get_look_horizontal() + local dir = minetest.yaw_to_dir(yaw) + local facedir = minetest.dir_to_facedir(dir) + + return true, pos, player_name, facedir, node, ndef +end + + +local function store_node_param2(user, node) + user:get_meta():set_int("techage_screwdriver_param2", node.param2) + minetest.chat_send_player(user:get_player_name(), S("Block alignment stored!")) +end + +local function turn_node_param2(pos, node, ndef, user) + local param2 = user:get_meta():get_int("techage_screwdriver_param2") or 0 + if ndef.ta_rotate_node then + ndef.ta_rotate_node(pos, node, param2) + else + minetest.swap_node(pos, {name = node.name, param2 = param2}) + minetest.check_for_falling(pos) + end +end + +local function turn_left(pos, node, ndef) + local param2 = techage.param2_turn_left(node.param2) + if ndef.ta_rotate_node then + ndef.ta_rotate_node(pos, node, param2) + else + minetest.swap_node(pos, {name = node.name, param2 = param2}) + minetest.check_for_falling(pos) + end +end + +local function turn_up(pos, node, ndef, facedir) + local param2 = techage.param2_turn_up(facedir, node.param2) + if ndef.ta_rotate_node then + ndef.ta_rotate_node(pos, node, param2) + else + minetest.swap_node(pos, {name = node.name, param2 = param2}) + minetest.check_for_falling(pos) + end +end + +-- on_use == on_left_click == turn left +local function on_use(itemstack, user, pointed_thing) + local res, pos, player_name, facedir, node, ndef = base_checks(user, pointed_thing) + if res then + if ndef.paramtype2 == "facedir" then + if user:get_player_control().sneak then + store_node_param2(user, node) + else + turn_left(pos, node, ndef) + end + else + return screwdriver.handler(itemstack, user, pointed_thing, screwdriver.ROTATE_FACE, USES) + end + + if not minetest.is_creative_enabled(player_name) then + itemstack:add_wear(65535 / (USES - 1)) + end + end + return itemstack +end + +-- on_place == on_right_click == turn up +local function on_place(itemstack, user, pointed_thing) + local res, pos, player_name, facedir, node, ndef = base_checks(user, pointed_thing) + if res then + if ndef.paramtype2 == "facedir" then + if ndef.on_rotate ~= screwdriver.rotate_simple then + if user:get_player_control().sneak then + turn_node_param2(pos, node, ndef, user) + else + turn_up(pos, node, ndef, facedir) + end + else + return itemstack + end + else + return screwdriver.handler(itemstack, user, pointed_thing, screwdriver.ROTATE_AXIS, USES) + end + + if not minetest.is_creative_enabled(player_name) then + itemstack:add_wear(65535 / (USES - 1)) + end + end + return itemstack +end + +minetest.register_tool("techage:screwdriver", { + description = S("Techage Screwdriver\n(See: TA3 > Tools)"), + inventory_image = "techage_screwdriver.png", + on_use = on_use, + on_place = on_place, + node_placement_prediction = "", + stack_max = 1, +}) + +minetest.register_craft({ + output = "techage:screwdriver", + recipe = { + {"", "default:diamond", ""}, + {"", "basic_materials:steel_bar", ""}, + {"", "techage:baborium_ingot", ""}, + }, +}) + +end diff --git a/techage/wind_turbine/pillar.lua b/techage/wind_turbine/pillar.lua index 11551d2..31c83b9 100644 --- a/techage/wind_turbine/pillar.lua +++ b/techage/wind_turbine/pillar.lua @@ -21,10 +21,14 @@ minetest.register_node("techage:pillar", { mesh = "techage_cylinder_07.obj", selection_box = { type = "fixed", - fixed = {-8/32, -16/32, -8/32, 8/32, 16/32, 8/32}, + fixed = {-10/32, -16/32, -10/32, 10/32, 16/32, 10/32}, + }, + collision_box = { + type = "fixed", + fixed = {-4/32, -16/32, -4/32, 4/32, 16/32, 4/32}, }, climbable = true, - walkable = false, + walkable = true, paramtype = "light", backface_culling = true, groups = {cracky=1}, diff --git a/tubelib2/README.md b/tubelib2/README.md index 8403a59..acb8c22 100644 --- a/tubelib2/README.md +++ b/tubelib2/README.md @@ -55,7 +55,7 @@ optional: intllib ## License -Copyright (C) 2017-2021 Joachim Stolberg +Copyright (C) 2017-2022 Joachim Stolberg Code: Licensed under the GNU LGPL version 2.1 or later. See LICENSE.txt and http://www.gnu.org/licenses/lgpl-2.1.txt Textures: CC0 @@ -89,5 +89,6 @@ Textures: CC0 - 2020-05-31 v1.9 * Generator function 'get_tube_line' added, storage improvements - 2021-01-23 v2.0 * Add functions for easy & fast 'valid side' checking (PR #8) - 2021-05-24 v2.1 * Add API functions 'register_on_tube_update2' +- 2022-01-05 v2.2 * Extend the 'node.param2' support for all 24 possible values diff --git a/tubelib2/internal1.lua b/tubelib2/internal1.lua index 9902053..1ee3246 100644 --- a/tubelib2/internal1.lua +++ b/tubelib2/internal1.lua @@ -9,7 +9,7 @@ See LICENSE.txt for more information internal1.lua - + First level functions behind the API ]]-- @@ -133,7 +133,7 @@ end -------------------------------------------------------------------------------------- -- Pairing helper function. NOT USED (see internal2.lua)!!! -function Tube:store_teleport_data(pos, peer_pos) +function Tube:store_teleport_data(pos, peer_pos) local meta = M(pos) meta:set_string("tele_pos", S(peer_pos)) meta:set_string("channel", nil) @@ -183,14 +183,14 @@ function Tube:update_after_place_tube(pos, placer, pointed_thing) if self.valid_dirs[dir1] and self.valid_dirs[dir2] and tValidNum[num_tubes] then self.clbk_after_place_tube(self:get_tube_data(pos, dir1, dir2, num_tubes)) end - + if num_tubes >= 1 then local npos, d1, d2, num = self:add_tube_dir(pos, dir1) if npos and self.valid_dirs[d1] and self.valid_dirs[d2] and num < 2 then self.clbk_after_place_tube(self:get_tube_data(npos, d1, d2, num+1)) end end - + if num_tubes >= 2 then local npos, d1, d2, num = self:add_tube_dir(pos, dir2) if npos and self.valid_dirs[d1] and self.valid_dirs[d2] and num < 2 then @@ -198,25 +198,25 @@ function Tube:update_after_place_tube(pos, placer, pointed_thing) end end return true, dir1, dir2, num_tubes -end - +end + function Tube:update_after_dig_tube(pos, param2) local dir1, dir2 = self:decode_param2(pos, param2) - + local npos, d1, d2, num = self:del_tube_dir(pos, dir1) if npos and self.valid_dirs[d1] and self.valid_dirs[d2] and tValidNum[num] then self.clbk_after_place_tube(self:get_tube_data(npos, d1, d2, num)) else dir1 = nil end - + npos, d1, d2, num = self:del_tube_dir(pos, dir2) if npos and self.valid_dirs[d1] and self.valid_dirs[d2] and tValidNum[num] then self.clbk_after_place_tube(self:get_tube_data(npos, d1, d2, num)) else dir2 = nil end - + return dir1, dir2 end @@ -229,7 +229,7 @@ function Tube:replace_nodes(pos1, pos2, dir1, dir2) pos = get_pos(pos, dir1) end self.clbk_after_place_tube(self:get_tube_data(pos2, dir1, dir2, 1)) -end +end function Tube:switch_nodes(pos, dir, state) pos = get_pos(pos, dir) diff --git a/tubelib2/internal2.lua b/tubelib2/internal2.lua index 3367a21..6c9d0dd 100644 --- a/tubelib2/internal2.lua +++ b/tubelib2/internal2.lua @@ -93,7 +93,7 @@ function Tube:get_node_lvm(pos) end -- Read param2 from a primary node at the given position. --- If dir == nil then node_pos = pos +-- If dir == nil then node_pos = pos -- Function returns param2, new_pos or nil function Tube:get_primary_node_param2(pos, dir) local npos = vector.add(pos, Dir6dToVector[dir or 0]) @@ -104,7 +104,7 @@ function Tube:get_primary_node_param2(pos, dir) end -- Check if node at given position is a tube node --- If dir == nil then node_pos = pos +-- If dir == nil then node_pos = pos -- Function returns true/false function Tube:is_primary_node(pos, dir) local npos = vector.add(pos, Dir6dToVector[dir or 0]) @@ -113,7 +113,7 @@ function Tube:is_primary_node(pos, dir) end -- Get secondary node at given position --- If dir == nil then node_pos = pos +-- If dir == nil then node_pos = pos -- Function returns node and new_pos or nil function Tube:get_secondary_node(pos, dir) local npos = vector.add(pos, Dir6dToVector[dir or 0]) @@ -124,7 +124,7 @@ function Tube:get_secondary_node(pos, dir) end -- Get special registered nodes at given position --- If dir == nil then node_pos = pos +-- If dir == nil then node_pos = pos -- Function returns node and new_pos or nil function Tube:get_special_node(pos, dir) local npos = vector.add(pos, Dir6dToVector[dir or 0]) @@ -135,7 +135,7 @@ function Tube:get_special_node(pos, dir) end -- Check if node at given position is a secondary node --- If dir == nil then node_pos = pos +-- If dir == nil then node_pos = pos -- Function returns true/false function Tube:is_secondary_node(pos, dir) local npos = vector.add(pos, Dir6dToVector[dir or 0]) @@ -144,7 +144,7 @@ function Tube:is_secondary_node(pos, dir) end -- Check if node at given position is a special node --- If dir == nil then node_pos = pos +-- If dir == nil then node_pos = pos -- Function returns true/false function Tube:is_special_node(pos, dir) local npos = vector.add(pos, Dir6dToVector[dir or 0]) @@ -216,7 +216,7 @@ end function Tube:get_tube_data(pos, dir1, dir2, num_tubes, state) local param2, tube_type = self:encode_param2(dir1, dir2, num_tubes) return pos, param2, tube_type, num_tubes, state -end +end -- Return pos for a primary_node and true if num_conn < 2, else false function Tube:friendly_primary_node(pos, dir) @@ -238,12 +238,12 @@ function Tube:vector_to_dir(v) end end --- Check all 6 possible positions for known nodes considering preferred_pos +-- Check all 6 possible positions for known nodes considering preferred_pos -- and the players fdir and return dir1, dir2 and the number of tubes to connect to (0..2). function Tube:determine_tube_dirs(pos, preferred_pos, fdir) local tbl = {} local allowed = table.copy(self.valid_dirs) - + -- If the node at players "prefered position" is a tube, -- then the other side of the new tube shall point to the player. if preferred_pos then @@ -282,7 +282,7 @@ function Tube:determine_tube_dirs(pos, preferred_pos, fdir) elseif #tbl >= 2 then return tbl[1], tbl[2], 2 end - + -- Check for secondary nodes (chests and so on) for dir = 1,6 do if allowed[dir] then @@ -301,8 +301,8 @@ function Tube:determine_tube_dirs(pos, preferred_pos, fdir) end end end - - -- player pointed to an unknown node to force the tube orientation? + + -- player pointed to an unknown node to force the tube orientation? if preferred_pos and fdir then if tbl[1] == Turn180Deg[fdir] and allowed[fdir] then tbl[2] = fdir @@ -310,7 +310,7 @@ function Tube:determine_tube_dirs(pos, preferred_pos, fdir) tbl[2] = Turn180Deg[fdir] end end - + -- dir1, dir2 still unknown? if fdir then if #tbl == 0 and allowed[Turn180Deg[fdir]] then @@ -324,14 +324,14 @@ function Tube:determine_tube_dirs(pos, preferred_pos, fdir) end if #tbl >= 2 and tbl[1] ~= tbl[2] then - local num_tubes = (self:connected(pos, tbl[1]) and 1 or 0) + + local num_tubes = (self:connected(pos, tbl[1]) and 1 or 0) + (self:connected(pos, tbl[2]) and 1 or 0) return tbl[1], tbl[2], math.min(2, num_tubes) end end -- Determine a tube side without connection, increment the number of connections --- and return the new data to be able to update the node: +-- and return the new data to be able to update the node: -- new_pos, dir1, dir2, num_connections (1, 2) function Tube:add_tube_dir(pos, dir) local param2, npos = self:get_primary_node_param2(pos, dir) @@ -359,7 +359,7 @@ function Tube:add_tube_dir(pos, dir) end -- Decrement the number of tube connections --- and return the new data to be able to update the node: +-- and return the new data to be able to update the node: -- new_pos, dir1, dir2, num_connections (0, 1) function Tube:del_tube_dir(pos, dir) local param2, npos = self:get_primary_node_param2(pos, dir) @@ -372,9 +372,9 @@ function Tube:del_tube_dir(pos, dir) end end end - + -- Pairing helper function -function Tube:store_teleport_data(pos, peer_pos) +function Tube:store_teleport_data(pos, peer_pos) local meta = M(pos) meta:set_string("tele_pos", S(peer_pos)) meta:set_string("channel", nil) @@ -409,7 +409,7 @@ function Tube:dbg_out() end end end - + -- Walk to the end of the tube line and return pos and outdir of both head tube nodes. -- If no tube is available, return nil function Tube:walk_tube_line(pos, dir) @@ -429,4 +429,4 @@ function Tube:walk_tube_line(pos, dir) end end return table.copy(pos), dir, 0 -end +end diff --git a/tubelib2/storage.lua b/tubelib2/storage.lua index 883840c..b41657c 100644 --- a/tubelib2/storage.lua +++ b/tubelib2/storage.lua @@ -29,7 +29,7 @@ local function update_mod_storage() storage:set_string(k, minetest.serialize(v)) MemStore[k] = nil -- remove from memory end - end + end -- run every 10 minutes minetest.after(600, update_mod_storage) end @@ -37,7 +37,7 @@ end minetest.register_on_shutdown(function() for k,v in pairs(MemStore) do storage:set_string(k, minetest.serialize(v)) - end + end end) minetest.after(600, update_mod_storage) @@ -52,14 +52,14 @@ local function empty_block(block) end return empty end - + minetest.after(1, function() local tbl = storage:to_table() for k,v in pairs(tbl.fields) do if empty_block(v) then storage:set_string(k, "") end - end + end end) -- @@ -81,7 +81,7 @@ local function new_node(block, node_key) end local function unlock(pos) - local block_key = math.floor((pos.z+32768)/16)*4096*4096 + + local block_key = math.floor((pos.z+32768)/16)*4096*4096 + math.floor((pos.y+32768)/16)*4096 + math.floor((pos.x+32768)/16) local node_key = (pos.z%16)*16*16 + (pos.y%16)*16 + (pos.x%16) local block = MemStore[block_key] or new_block(block_key) diff --git a/tubelib2/tube_api.lua b/tubelib2/tube_api.lua index b7789b4..48293cd 100644 --- a/tubelib2/tube_api.lua +++ b/tubelib2/tube_api.lua @@ -13,7 +13,7 @@ ]]-- -- Version for compatibility checks, see readme.md/history -tubelib2.version = 2.1 +tubelib2.version = 2.2 -- for lazy programmers local S = function(pos) if pos then return minetest.pos_to_string(pos) end end @@ -31,23 +31,31 @@ function tubelib2.dir_to_string(dir) end -- Relative directions, dependant on orientation (param2) -local DirToSide = {"B", "R", "F", "L", "D", "U"} +local DirToSide = { + -- param2 (0 to 23) + {[0]="B","L","F","R", "U","U","U","U", "D","D","D","D", "B","L","F","R", "B","L","F","R", "B","L","F","R",}, -- dir = 1 + {[0]="R","B","L","F", "R","B","L","F", "R","B","L","F", "U","U","U","U", "D","D","D","D", "L","F","R","B",}, -- dir = 2 + {[0]="F","R","B","L", "D","D","D","D", "U","U","U","U", "F","R","B","L", "F","R","B","L", "F","R","B","L",}, -- dir = 3 + {[0]="L","F","R","B", "L","F","R","B", "L","F","R","B", "D","D","D","D", "U","U","U","U", "R","B","L","F",}, -- dir = 4 + {[0]="D","D","D","D", "B","L","F","R", "F","R","B","L", "R","B","L","F", "L","F","R","B", "U","U","U","U",}, -- dir = 5 + {[0]="U","U","U","U", "F","R","B","L", "B","L","F","R", "L","F","R","B", "R","B","L","F", "D","D","D","D",}, -- dir = 6 +} -function tubelib2.dir_to_side(dir, param2) - if dir < 5 then - dir = (((dir - 1) - (param2 % 4)) % 4) + 1 +local SideToDir = {B={}, R={}, F={}, L={}, D={}, U={}} + +for param2 = 0,23 do + for dir = 1,6 do + local side = DirToSide[dir][param2] + SideToDir[side][param2] = dir end - return DirToSide[dir] end -local SideToDir = {B=1, R=2, F=3, L=4, D=5, U=6} +function tubelib2.dir_to_side(dir, param2) + return DirToSide[dir][param2] +end function tubelib2.side_to_dir(side, param2) - local dir = SideToDir[side] - if dir < 5 then - dir = (((dir - 1) + (param2 % 4)) % 4) + 1 - end - return dir + return SideToDir[side][param2] end @@ -92,7 +100,7 @@ local function update1(self, pos, dir) local fpos,fdir = self:walk_tube_line(pos, dir) self:infotext(get_pos(pos, dir), fpos) self:infotext(fpos, get_pos(pos, dir)) - -- Translate pos/dir pointing to the secondary node into + -- Translate pos/dir pointing to the secondary node into -- spos/sdir of the secondary node pointing to the tube. if fpos and fdir then local spos, sdir = get_pos(fpos,fdir), Turn180Deg[fdir] @@ -113,11 +121,11 @@ local function update2(self, pos1, dir1, pos2, dir2) self:update_after_dig_tube(pos1, param2) M(get_pos(pos1, dir1)):set_string("infotext", I("Maximum length reached!")) M(get_pos(pos1, dir2)):set_string("infotext", I("Maximum length reached!")) - return false + return false end self:infotext(fpos1, fpos2) self:infotext(fpos2, fpos1) - -- Translate fpos/fdir pointing to the secondary node into + -- Translate fpos/fdir pointing to the secondary node into -- spos/sdir of the secondary node pointing to the tube. local spos1, sdir1 = get_pos(fpos1,fdir1), Turn180Deg[fdir1] local spos2, sdir2 = get_pos(fpos2,fdir2), Turn180Deg[fdir2] @@ -136,7 +144,7 @@ local function update3(self, pos, dir1, dir2) local fpos2,fdir2,cnt2 = self:walk_tube_line(pos, dir2) self:infotext(fpos1, fpos2) self:infotext(fpos2, fpos1) - -- Translate fpos/fdir pointing to the secondary node into + -- Translate fpos/fdir pointing to the secondary node into -- spos/sdir of the secondary node pointing to the tube. if fpos1 and fpos2 and fdir1 and fdir2 then local spos1, sdir1 = get_pos(fpos1,fdir1), Turn180Deg[fdir1] @@ -161,7 +169,7 @@ local function update_secondary_nodes_after_node_placed(self, pos, dirs) if self.force_to_use_tubes then tmp, npos = self:get_special_node(pos, dir) else - tmp, npos = self:get_secondary_node(pos, dir) + tmp, npos = self:get_secondary_node(pos, dir) end if npos then self:update_secondary_node(npos, Turn180Deg[dir], pos, dir) @@ -178,7 +186,7 @@ local function update_secondary_nodes_after_node_dug(self, pos, dirs) if self.force_to_use_tubes then tmp, npos = self:get_special_node(pos, dir) else - tmp, npos = self:get_secondary_node(pos, dir) + tmp, npos = self:get_secondary_node(pos, dir) end if npos then self:del_from_cache(npos, Turn180Deg[dir]) @@ -196,18 +204,18 @@ end function Tube:new(attr) local o = { dirs_to_check = attr.dirs_to_check or {1,2,3,4,5,6}, - max_tube_length = attr.max_tube_length or 1000, - primary_node_names = Tbl(attr.primary_node_names or {}), + max_tube_length = attr.max_tube_length or 1000, + primary_node_names = Tbl(attr.primary_node_names or {}), secondary_node_names = Tbl(attr.secondary_node_names or {}), valid_node_contact_sides = {}, show_infotext = attr.show_infotext or false, - force_to_use_tubes = attr.force_to_use_tubes or false, + force_to_use_tubes = attr.force_to_use_tubes or false, clbk_after_place_tube = attr.after_place_tube, tube_type = attr.tube_type or "unknown", pairingList = {}, -- teleporting nodes connCache = {}, -- connection cache {pos1 = {dir1 = {pos2 = pos2, dir2 = dir2},...} special_node_names = {}, -- use add_special_node_names() to register nodes - debug_info = attr.debug_info, -- debug_info(pos, text) + debug_info = attr.debug_info, -- debug_info(pos, text) } o.valid_dirs = Tbl(o.dirs_to_check) setmetatable(o, self) @@ -234,7 +242,7 @@ local function invert_booleans(tab) end return inversion end -local valid_sides_default_true = Tbl(DirToSide) +local valid_sides_default_true = Tbl({"B", "R", "F", "L", "D", "U"}) local valid_sides_default_false = invert_booleans(valid_sides_default_true) local function complete_valid_sides(valid_sides, existing_defaults) local valid_sides_complete = {} @@ -368,13 +376,13 @@ end function Tube:after_dig_tube(pos, oldnode) -- [s1][f1]----[n1] x [n2]-----[f2][s2] -- s..secondary, f..far, n..near, x..node to be removed - + -- update tubes if oldnode and oldnode.param2 then local dir1, dir2 = self:update_after_dig_tube(pos, oldnode.param2) if dir1 then update1(self, pos, dir1) end if dir2 then update1(self, pos, dir2) end - + -- Update secondary nodes, if right beside dir1, dir2 = self:decode_param2(pos, oldnode.param2) local npos1,ndir1 = get_pos(pos, dir1),Turn180Deg[dir1] @@ -395,7 +403,7 @@ function Tube:get_connected_node_pos(pos, dir) if self.connCache[key] and self.connCache[key][dir] then local item = self.connCache[key][dir] return item.pos2, Turn180Deg[item.dir2] - end + end local fpos,fdir = self:walk_tube_line(pos, dir) local spos = get_pos(fpos,fdir) self:add_to_cache(pos, dir, spos, Turn180Deg[fdir]) @@ -405,7 +413,7 @@ end -- Check if node at given position is a tubelib2 compatible node, -- able to receive and/or deliver items. --- If dir == nil then node_pos = pos +-- If dir == nil then node_pos = pos -- Function returns the result (true/false), new pos, and the node function Tube:compatible_node(pos, dir) local npos = vector.add(pos, Dir6dToVector[dir or 0]) @@ -497,14 +505,14 @@ end -- Used by chat commands, when tubes are placed e.g. via WorldEdit function Tube:replace_tube_line(pos1, pos2) if pos1 and pos2 and not vector.equals(pos1, pos2) then - local check = (((pos1.x == pos2.x) and 1) or 0) + - (((pos1.y == pos2.y) and 1) or 0) + + local check = (((pos1.x == pos2.x) and 1) or 0) + + (((pos1.y == pos2.y) and 1) or 0) + (((pos1.z == pos2.z) and 1) or 0) if check == 2 then local v = vector.direction(pos1, pos2) local dir1 = self:vector_to_dir(v) local dir2 = Turn180Deg[dir1] - + self:replace_nodes(pos1, pos2, dir1, dir2) update3(self, pos1, dir1, dir2) end @@ -532,4 +540,4 @@ function Tube:get_tube_line(pos, dir) end end, self, 0 end -end +end diff --git a/tubelib2/tube_test.lua b/tubelib2/tube_test.lua index 0b40140..b925ae7 100644 --- a/tubelib2/tube_test.lua +++ b/tubelib2/tube_test.lua @@ -9,7 +9,7 @@ See LICENSE.txt for more information tube_test.lua - + THIS FILE IS ONLY FOR TESTING PURPOSES ]]-- @@ -62,10 +62,10 @@ local Tube = tubelib2.Tube:new({ -- dirs_to_check = {1,2,3,4}, -- horizontal only -- dirs_to_check = {5,6}, -- vertical only dirs_to_check = {1,2,3,4,5,6}, - max_tube_length = 10, + max_tube_length = 10, show_infotext = true, - primary_node_names = {"tubelib2:tubeS", "tubelib2:tubeA"}, - secondary_node_names = {"default:chest", "default:chest_open", + primary_node_names = {"tubelib2:tubeS", "tubelib2:tubeA"}, + secondary_node_names = {"default:chest", "default:chest_open", "tubelib2:source", "tubelib2:junction", "tubelib2:teleporter"}, after_place_tube = function(pos, param2, tube_type, num_tubes, tbl) minetest.swap_node(pos, {name = "tubelib2:tube"..tube_type, param2 = param2}) @@ -102,7 +102,7 @@ minetest.register_node("tubelib2:tubeS", { "tubelib2_hole.png", "tubelib2_hole.png", }, - + after_place_node = function(pos, placer, itemstack, pointed_thing) --local t = minetest.get_us_time() if not Tube:after_place_tube(pos, placer, pointed_thing) then @@ -112,11 +112,11 @@ minetest.register_node("tubelib2:tubeS", { --print("place time", minetest.get_us_time() - t) return false end, - + after_dig_node = function(pos, oldnode, oldmetadata, digger) Tube:after_dig_tube(pos, oldnode, oldmetadata) end, - + paramtype2 = "facedir", -- important! drawtype = "nodebox", node_box = { @@ -143,11 +143,11 @@ minetest.register_node("tubelib2:tubeA", { "tubelib2_tube.png", "tubelib2_hole.png", }, - + after_dig_node = function(pos, oldnode, oldmetadata, digger) Tube:after_dig_tube(pos, oldnode, oldmetadata) end, - + paramtype2 = "facedir", -- important! drawtype = "nodebox", node_box = { @@ -174,7 +174,7 @@ local function push_item(pos) --print("on_timer: dest_pos="..S(dest_pos).." dest_dir="..dest_dir) local inv = minetest.get_inventory({type="node", pos=dest_pos}) local stack = ItemStack("default:dirt") - + if on_push_item then return on_push_item(dest_pos, dest_dir, stack) elseif inv then @@ -204,7 +204,7 @@ minetest.register_node("tubelib2:source", { after_place_node = function(pos, placer) local tube_dir = ((minetest.dir_to_facedir(placer:get_look_dir()) + 2) % 4) + 1 M(pos):set_int("tube_dir", tube_dir) - Tube:after_place_node(pos, {tube_dir}) + Tube:after_place_node(pos, {tube_dir}) minetest.get_node_timer(pos):start(2) end, @@ -212,14 +212,14 @@ minetest.register_node("tubelib2:source", { local tube_dir = tonumber(oldmetadata.fields.tube_dir or 0) Tube:after_dig_node(pos, {tube_dir}) end, - + on_timer = function(pos, elapsed) if not push_item(pos) then print("push_item error") end return true end, - + paramtype2 = "facedir", -- important! on_rotate = screwdriver.disallow, -- important! paramtype = "light", @@ -245,7 +245,7 @@ minetest.register_node("tubelib2:junction", { after_dig_node = function(pos, oldnode, oldmetadata, digger) Tube:after_dig_node(pos) end, - + paramtype2 = "facedir", -- important! on_rotate = screwdriver.disallow, -- important! paramtype = "light", @@ -264,7 +264,7 @@ local sFormspec = "size[7.5,3]".. "field[0.5,1;7,1;channel;Enter channel string;]" .. "button_exit[2,2;3,1;exit;Save]" -local function store_connection(pos, peer_pos) +local function store_connection(pos, peer_pos) local meta = M(pos) meta:set_string("peer_pos", P2S(peer_pos)) meta:set_string("channel", "") @@ -332,7 +332,7 @@ minetest.register_node("tubelib2:teleporter", { pairing(pos, fields.channel) end end, - + on_push_item = function(pos, dir, item) local tube_dir = M(pos):get_int("tube_dir") if dir == tubelib2.Turn180Deg[tube_dir] then @@ -343,13 +343,13 @@ minetest.register_node("tubelib2:teleporter", { end end end, - + after_dig_node = function(pos, oldnode, oldmetadata, digger) stop_pairing(pos, oldmetadata) local tube_dir = tonumber(oldmetadata.fields.tube_dir or 0) Tube:after_dig_node(pos, {tube_dir}) end, - + paramtype2 = "facedir", -- important! on_rotate = screwdriver.disallow, -- important! paramtype = "light", @@ -363,7 +363,7 @@ minetest.register_node("tubelib2:teleporter", { -- Tool ------------------------------------------------------------------------------- local function read_param2(pos, player) - local node = minetest.get_node(pos) + local node = minetest.get_node(pos) local dir1, dir2, num_tubes = Tube:decode_param2(pos, node.param2) minetest.chat_send_player(player:get_player_name(), "[Tubelib2] pos="..P2S(pos)..", dir1="..dir1..", dir2="..dir2..", num_tubes="..num_tubes) end @@ -378,7 +378,7 @@ local function remove_tube(itemstack, placer, pointed_thing) end else local dir = (minetest.dir_to_facedir(placer:get_look_dir()) % 4) + 1 - minetest.chat_send_player(placer:get_player_name(), + minetest.chat_send_player(placer:get_player_name(), "[Tool Help] dir="..dir.."\n".. " left: remove node\n".. " right: repair tube line\n") @@ -399,7 +399,7 @@ end -- end -- else -- local dir = (minetest.dir_to_facedir(placer:get_look_dir()) % 4) + 1 --- minetest.chat_send_player(placer:get_player_name(), +-- minetest.chat_send_player(placer:get_player_name(), -- "[Tool Help] dir="..dir.."\n".. -- " left: remove node\n".. -- " right: repair tube line\n") @@ -411,22 +411,22 @@ local function repair_tube(itemstack, placer, pointed_thing) local pos = pointed_thing.under local _, _, fpos1, fpos2, _, _, cnt1, cnt2 = Tube:tool_repair_tube(pos) local length = cnt1 + cnt2 - + local s = "Tube from " .. P2S(fpos1) .. " to " .. P2S(fpos2) .. ". Lenght = " .. length minetest.chat_send_player(placer:get_player_name(), s) - + if length > Tube.max_tube_length then local s = string.char(0x1b) .. "(c@#ff0000)" .. "Tube length error!" minetest.chat_send_player(placer:get_player_name(), s) end - + minetest.sound_play("carts_cart_new", { - pos = pos, + pos = pos, gain = 1, max_hear_distance = 5}) else local dir = (minetest.dir_to_facedir(placer:get_look_dir()) % 4) + 1 - minetest.chat_send_player(placer:get_player_name(), + minetest.chat_send_player(placer:get_player_name(), "[Tool Help] dir="..dir.."\n".. " left: remove node\n".. " right: repair tube line\n") diff --git a/unified_inventory/callbacks.lua b/unified_inventory/callbacks.lua index 5874a0f..af2c127 100644 --- a/unified_inventory/callbacks.lua +++ b/unified_inventory/callbacks.lua @@ -1,3 +1,5 @@ +local ui = unified_inventory + local function default_refill(stack) stack:set_count(stack:get_stack_max()) local itemdef = minetest.registered_items[stack:get_name()] @@ -48,11 +50,11 @@ end) local function apply_new_filter(player, search_text, new_dir) local player_name = player:get_player_name() + minetest.sound_play("click", {to_player=player_name, gain = 0.1}) - unified_inventory.apply_filter(player, search_text, new_dir) - unified_inventory.current_searchbox[player_name] = search_text - unified_inventory.set_inventory_formspec(player, - unified_inventory.current_page[player_name]) + ui.apply_filter(player, search_text, new_dir) + ui.current_searchbox[player_name] = search_text + ui.set_inventory_formspec(player, ui.current_page[player_name]) end minetest.register_on_player_receive_fields(function(player, formname, fields) @@ -65,9 +67,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end -- always take new search text, even if not searching on it yet + local dirty_search_filter = false + if fields.searchbox and fields.searchbox ~= unified_inventory.current_searchbox[player_name] then unified_inventory.current_searchbox[player_name] = fields.searchbox + dirty_search_filter = true end @@ -88,19 +93,14 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) unified_inventory.current_page[player_name]) end - if fields.next_category then - local scroll = math.min(#unified_inventory.category_list-ui_peruser.pagecols, unified_inventory.current_category_scroll[player_name] + 1) - if scroll ~= unified_inventory.current_category_scroll[player_name] then - unified_inventory.current_category_scroll[player_name] = scroll - unified_inventory.set_inventory_formspec(player, - unified_inventory.current_page[player_name]) - end - end - if fields.prev_category then - local scroll = math.max(0, unified_inventory.current_category_scroll[player_name] - 1) - if scroll ~= unified_inventory.current_category_scroll[player_name] then - unified_inventory.current_category_scroll[player_name] = scroll - unified_inventory.set_inventory_formspec(player, + if fields.next_category or fields.prev_category then + local step = fields.next_category and 1 or -1 + local scroll_old = ui.current_category_scroll[player_name] + local scroll_new = math.max(0, math.min(#ui.category_list - ui_peruser.pagecols, scroll_old + step)) + + if scroll_old ~= scroll_new then + ui.current_category_scroll[player_name] = scroll_new + ui.set_inventory_formspec(player, unified_inventory.current_page[player_name]) end end @@ -197,13 +197,16 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if fields.searchbutton or fields.key_enter_field == "searchbox" then - unified_inventory.apply_filter(player, unified_inventory.current_searchbox[player_name], "nochange") - unified_inventory.set_inventory_formspec(player, - unified_inventory.current_page[player_name]) - minetest.sound_play("paperflip2", - {to_player=player_name, gain = 1.0}) + if dirty_search_filter then + ui.apply_filter(player, ui.current_searchbox[player_name], "nochange") + ui.set_inventory_formspec(player, ui.current_page[player_name]) + minetest.sound_play("paperflip2", + {to_player=player_name, gain = 1.0}) + end elseif fields.searchresetbutton then - apply_new_filter(player, "", "nochange") + if ui.activefilter[player_name] ~= "" then + apply_new_filter(player, "", "nochange") + end end -- alternate buttons