From 38d115fdf35c2346ee7bbde2ae2f29d808722e01 Mon Sep 17 00:00:00 2001 From: Joachim Stolberg Date: Wed, 1 May 2019 23:01:14 +0200 Subject: [PATCH] Electronic Fab and Vacuum Tubes added --- basic_machines/autocrafter.lua | 9 +- basic_machines/distributor.lua | 11 +- basic_machines/electronic_fab.lua | 288 ++++++++++++++++++++++ basic_machines/gravelsieve.lua | 5 +- basic_machines/grinder.lua | 6 +- basis/consumer.lua | 1 + basis/guide.lua | 10 +- basis/node_states.lua | 11 +- init.lua | 6 +- iron_age/charcoalpile.lua | 10 +- iron_age/coalburner.lua | 14 +- iron_age/gravelsieve.lua | 2 +- iron_age/main.lua | 8 +- steam_engine/boiler.lua | 13 +- steam_engine/cylinder.lua | 6 + steam_engine/firebox.lua | 17 +- steam_engine/flywheel.lua | 10 +- steam_engine/help.lua | 49 ++++ textures/techage_appl_electronic_fab.png | Bin 0 -> 252 bytes textures/techage_appl_electronic_fab4.png | Bin 0 -> 352 bytes textures/techage_boiler_bottom_ta2.png | Bin 0 -> 3788 bytes textures/techage_boiler_top_ta2.png | Bin 0 -> 3813 bytes textures/techage_form_mask.png | Bin 185 -> 185 bytes textures/techage_vacuum_tube.png | Bin 0 -> 1029 bytes 24 files changed, 428 insertions(+), 48 deletions(-) create mode 100644 basic_machines/electronic_fab.lua create mode 100644 steam_engine/help.lua create mode 100644 textures/techage_appl_electronic_fab.png create mode 100644 textures/techage_appl_electronic_fab4.png create mode 100644 textures/techage_boiler_bottom_ta2.png create mode 100644 textures/techage_boiler_top_ta2.png create mode 100644 textures/techage_vacuum_tube.png diff --git a/basic_machines/autocrafter.lua b/basic_machines/autocrafter.lua index e357030..b275547 100644 --- a/basic_machines/autocrafter.lua +++ b/basic_machines/autocrafter.lua @@ -200,8 +200,7 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) if minetest.is_protected(pos, player:get_player_name()) then return 0 end - local inv = minetest.get_meta(pos):get_inventory() - local trd = TRD(pos) + local inv = M(pos):get_inventory() if listname == "recipe" then stack:set_count(1) inv:set_stack(listname, index, stack) @@ -210,8 +209,8 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) elseif listname == "output" then on_output_change(pos, inv, stack) return 0 - elseif listname == "src" and trd.State:get_state(M(pos)) == techage.STANDBY then - trd.State:start(pos, M(pos)) + elseif listname == "src" then + TRD(pos).State:start_if_standby(pos) end return stack:get_count() end @@ -402,7 +401,7 @@ local node_name_ta2, node_name_ta3, node_name_ta4 = groups = {choppy=2, cracky=2, crumbly=2}, sounds = default.node_sound_wood_defaults(), num_items = {0,1,2,4}, - power_consumption = {0,2,3,4}, + power_consumption = {0,4,6,9}, }) minetest.register_craft({ diff --git a/basic_machines/distributor.lua b/basic_machines/distributor.lua index 58133fc..1c57980 100644 --- a/basic_machines/distributor.lua +++ b/basic_machines/distributor.lua @@ -117,18 +117,14 @@ end local function allow_metadata_inventory_put(pos, listname, index, stack, player) - local meta = M(pos) - local trd = TRD(pos) - local inv = meta:get_inventory() + local inv = M(pos):get_inventory() local list = inv:get_list(listname) if minetest.is_protected(pos, player:get_player_name()) then return 0 end if listname == "src" then - if trd.State:get_state(M(pos)) == techage.STANDBY then - trd.State:start(pos, meta) - end + TRD(pos).State:start_if_standby(pos) return stack:get_count() elseif stack:get_count() == 1 and (list[index]:get_count() == 0 or stack:get_name() ~= list[index]:get_name()) then @@ -273,7 +269,8 @@ local function change_filter_settings(pos, slot, val) filter_settings(pos) - meta:set_string("formspec", formspec(TRD(pos).State, pos, meta)) + local mem = tubelib2.get_mem(pos) + meta:set_string("formspec", formspec(TRD(pos).State, pos, mem)) return true end diff --git a/basic_machines/electronic_fab.lua b/basic_machines/electronic_fab.lua new file mode 100644 index 0000000..48e41a8 --- /dev/null +++ b/basic_machines/electronic_fab.lua @@ -0,0 +1,288 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + TA2/TA3/TA4 Electronic Fab + +]]-- + +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta +-- Techage Related Data +local TRD = function(pos) return (minetest.registered_nodes[minetest.get_node(pos).name] or {}).techage end + +-- Load support for intllib. +local MP = minetest.get_modpath("techage") +local I,_ = dofile(MP.."/intllib.lua") + +local STANDBY_TICKS = 10 +local COUNTDOWN_TICKS = 6 +local CYCLE_TIME = 6 + + +local ValidInput = { + {}, -- 1 + { -- 2 + ["default:glass"] = true, + ["basic_materials:copper_wire"] = true, + ["basic_materials:plastic_sheet"] = true, + }, + {}, -- 3 + {}, -- 4 +} + +local Input = { + {}, -- 1 + {"default:glass", "basic_materials:copper_wire", "basic_materials:plastic_sheet"}, --2 + {}, -- 3 + {}, -- 4 +} + +local Output = { + "", -- 1 + "techage:vacuum_tube", -- 2 + "", -- 3 + "", -- 4 +} + +local function formspec(self, pos, mem) + return "size[8,8]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "list[context;src;0,0;3,3;]".. + "item_image[0,0;1,1;default:glass]".. + "item_image[0,1;1,1;basic_materials:copper_wire]".. + "item_image[0,2;1,1;basic_materials:plastic_sheet]".. + "image[3.5,0;1,1;"..techage.get_power_image(pos, mem).."]".. + "image[3.5,1;1,1;techage_form_arrow.png]".. + "image_button[3.5,2;1,1;".. self:get_state_button_image(mem) ..";state_button;]".. + "list[context;dst;5,0;3,3;]".. + "item_image[5,0;1,1;techage:vacuum_tube]".. + "list[current_player;main;0,4;8,4;]".. + "listring[context;dst]".. + "listring[current_player;main]".. + "listring[context;src]".. + "listring[current_player;main]".. + default.get_hotbar_bg(0, 4) +end + +local function allow_metadata_inventory_put(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + --local meta = minetest.get_meta(pos) + --local inv = meta:get_inventory() + local trd = TRD(pos) + if listname == "src" and ValidInput[trd.stage][stack:get_name()] then + trd.State:start_if_standby(pos) + return stack:get_count() + end + return 0 +end + +local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(from_list, from_index) + return allow_metadata_inventory_put(pos, to_list, to_index, stack, player) +end + +local function allow_metadata_inventory_take(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + return stack:get_count() +end + +local function making(pos, trd, mem, inv) + if inv:room_for_item("dst", ItemStack(Output[trd.stage])) then + for _,name in ipairs(Input[trd.stage]) do + if not inv:contains_item("src", ItemStack(name)) then + trd.State:idle(pos, mem) + return + end + end + for _,name in ipairs(Input[trd.stage]) do + inv:remove_item("src", ItemStack(name)) + end + inv:add_item("dst", ItemStack(Output[trd.stage])) + trd.State:keep_running(pos, mem, COUNTDOWN_TICKS) + return + end + trd.State:idle(pos, mem) +end + +local function keep_running(pos, elapsed) + local mem = tubelib2.get_mem(pos) + local trd = TRD(pos) + local inv = M(pos):get_inventory() + if inv then + making(pos, trd, mem, inv) + end + return trd.State:is_active(mem) +end + +local function on_receive_fields(pos, formname, fields, player) + if minetest.is_protected(pos, player:get_player_name()) then + return + end + local mem = tubelib2.get_mem(pos) + TRD(pos).State:state_button_event(pos, mem, fields) +end + +local function can_dig(pos, player) + if minetest.is_protected(pos, player:get_player_name()) then + return false + end + local inv = M(pos):get_inventory() + return inv:is_empty("dst") and inv:is_empty("src") +end + +local tiles = {} +-- '#' will be replaced by the stage number +tiles.pas = { + -- up, down, right, left, back, front + "techage_filling_ta#.png^techage_frame_ta#_top.png", + "techage_filling_ta#.png^techage_frame_ta#.png", + "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_outp.png", + "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_inp.png", + "techage_filling_ta#.png^techage_appl_electronic_fab.png^techage_frame_ta#.png", + "techage_filling_ta#.png^techage_appl_electronic_fab.png^techage_frame_ta#.png", +} +tiles.act = { + -- up, down, right, left, back, front + "techage_filling_ta#.png^techage_frame_ta#_top.png", + "techage_filling_ta#.png^techage_frame_ta#.png", + "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_outp.png", + "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_inp.png", + { + image = "techage_filling4_ta#.png^techage_appl_electronic_fab4.png^techage_frame4_ta#.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.5, + }, + }, + { + image = "techage_filling4_ta#.png^techage_appl_electronic_fab4.png^techage_frame4_ta#.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.5, + }, + }, +} +tiles.def = { + -- up, down, right, left, back, front + "techage_filling_ta#.png^techage_frame_ta#_top.png", + "techage_filling_ta#.png^techage_frame_ta#.png", + "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_outp.png^techage_appl_defect.png", + "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_inp.png^techage_appl_defect.png", + "techage_filling_ta#.png^techage_appl_electronic_fab.png^techage_frame_ta#.png^techage_appl_defect.png", + "techage_filling_ta#.png^techage_appl_electronic_fab.png^techage_frame_ta#.png^techage_appl_defect.png", +} + +local tubing = { + on_pull_item = function(pos, in_dir, num) + local meta = minetest.get_meta(pos) + if meta:get_int("pull_dir") == in_dir then + local inv = M(pos):get_inventory() + return techage.get_items(inv, "dst", num) + end + end, + on_push_item = function(pos, in_dir, stack) + local meta = minetest.get_meta(pos) + if meta:get_int("push_dir") == in_dir or in_dir == 5 then + local inv = M(pos):get_inventory() + return techage.put_items(inv, "src", stack) + end + end, + on_unpull_item = function(pos, in_dir, stack) + local meta = minetest.get_meta(pos) + if meta:get_int("pull_dir") == in_dir then + local inv = M(pos):get_inventory() + return techage.put_items(inv, "dst", stack) + end + end, + on_recv_message = function(pos, topic, payload) + local resp = TRD(pos).State:on_receive_message(pos, topic, payload) + if resp then + return resp + else + return "unsupported" + end + end, + on_node_load = function(pos) + TRD(pos).State:on_node_load(pos) + end, + on_node_repair = function(pos) + return TRD(pos).State:on_node_repair(pos) + end, +} + +local node_name_ta2, node_name_ta3, node_name_ta4 = + techage.register_consumer("electronic_fab", I("Electronic Fab"), tiles, { + drawtype = "normal", + cycle_time = CYCLE_TIME, + standby_ticks = STANDBY_TICKS, + has_item_meter = true, + aging_factor = 10, + formspec = formspec, + tubing = tubing, + after_place_node = function(pos, placer) + local inv = M(pos):get_inventory() + inv:set_size("src", 3*3) + inv:set_size("dst", 3*3) + end, + can_dig = can_dig, + node_timer = keep_running, + on_receive_fields = on_receive_fields, + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, + groups = {choppy=2, cracky=2, crumbly=2}, + sounds = default.node_sound_wood_defaults(), + num_items = {0,1,1,1}, + power_consumption = {0,8,12,18}, + }) + +minetest.register_craft({ + output = node_name_ta2, + recipe = { + {"group:wood", "default:diamond", "group:wood"}, + {"techage:tubeS", "basic_materials:gear_steel", "techage:tubeS"}, + {"group:wood", "techage:steel_ingot", "group:wood"}, + }, +}) + +minetest.register_craftitem("techage:vacuum_tube", { + description = I("TA3 Vacuum Tubes"), + inventory_image = "techage_vacuum_tube.png", +}) + +if minetest.global_exists("unified_inventory") then + unified_inventory.register_craft_type("electronic_fab", { + description = I("Electronic Fab"), + icon = 'techage_filling_ta2.png^techage_appl_electronic_fab.png^techage_frame_ta2.png', + width = 2, + height = 2, + }) + unified_inventory.register_craft({ + output = "techage:vacuum_tube", + items = {"default:glass", "basic_materials:copper_wire", "basic_materials:plastic_sheet"}, + type = "electronic_fab", + }) +end diff --git a/basic_machines/gravelsieve.lua b/basic_machines/gravelsieve.lua index 9e0b5bc..9a87b34 100644 --- a/basic_machines/gravelsieve.lua +++ b/basic_machines/gravelsieve.lua @@ -55,9 +55,8 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) if minetest.is_protected(pos, player:get_player_name()) then return 0 end - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() if listname == "src" then + TRD(pos).State:start_if_standby(pos) return stack:get_count() elseif listname == "dst" then return 0 @@ -237,7 +236,7 @@ local node_name_ta2, node_name_ta3, node_name_ta4 = groups = {choppy=2, cracky=2, crumbly=2}, sounds = default.node_sound_wood_defaults(), num_items = {0,1,2,4}, - power_consumption = {0,2,3,4}, + power_consumption = {0,3,4,5}, }) minetest.register_craft({ diff --git a/basic_machines/grinder.lua b/basic_machines/grinder.lua index 7854256..0f7d006 100644 --- a/basic_machines/grinder.lua +++ b/basic_machines/grinder.lua @@ -57,8 +57,8 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) if minetest.is_protected(pos, player:get_player_name()) then return 0 end - if listname == "src" and TRD(pos).State:get_state(M(pos)) == techage.STANDBY then - TRD(pos).State:start(pos, M(pos)) + if listname == "src" then + TRD(pos).State:start_if_standby(pos) end return stack:get_count() end @@ -248,7 +248,7 @@ local node_name_ta2, node_name_ta3, node_name_ta4 = groups = {choppy=2, cracky=2, crumbly=2}, sounds = default.node_sound_wood_defaults(), num_items = {0,1,2,4}, - power_consumption = {0,2,3,4}, + power_consumption = {0,4,6,9}, }) minetest.register_craft({ diff --git a/basis/consumer.lua b/basis/consumer.lua index d7888ab..0c3a67b 100644 --- a/basis/consumer.lua +++ b/basis/consumer.lua @@ -108,6 +108,7 @@ function techage.register_consumer(base_name, inv_name, tiles, tNode) stop_node = power_used and stop_node or nil, }) local tTechage = { + stage = stage, State = tState, num_items = tNode.num_items[stage], turn_on = power_used and turn_on_clbk or nil, diff --git a/basis/guide.lua b/basis/guide.lua index d89ed03..d86d3f8 100644 --- a/basis/guide.lua +++ b/basis/guide.lua @@ -33,7 +33,7 @@ local function plan(images) local img = images[y][x] or false if img ~= false then local x_offs, y_offs = (x-1) * 1, (y-1) * 1 + 0.8 - tbl[#tbl+1] = "image["..x_offs..","..y_offs..";1,1;"..img..".png]" + tbl[#tbl+1] = "image["..x_offs..","..y_offs..";1,1;"..img.."]" end end end @@ -130,16 +130,16 @@ minetest.register_craft({ function techage.register_help_page(name, text, item_name, images) - RecipeList[#RecipeList+1] = name + RecipeList[#RecipeList+1] = " "..name ItemNames[#ItemNames+1] = item_name or "plan" - NamesAsStr = table.concat(RecipeList, ", ") or "" + NamesAsStr = table.concat(RecipeList, ",") or "" Recipes[#Recipes+1] = text PlanImages[#PlanImages+1] = images or "none" end -function techage.register_chap_page(name, text) +function techage.register_chap_page(name, text, item_name) RecipeList[#RecipeList+1] = name - ItemNames[#ItemNames+1] = "-" + ItemNames[#ItemNames+1] = item_name or "-" NamesAsStr = table.concat(RecipeList, ",") or "" Recipes[#Recipes+1] = text PlanImages[#PlanImages+1] = "none" diff --git a/basis/node_states.lua b/basis/node_states.lua index b370681..7376d0b 100644 --- a/basis/node_states.lua +++ b/basis/node_states.lua @@ -208,7 +208,7 @@ function NodeStates:start(pos, mem, called_from_on_timer) self.start_node(pos, mem, state) end mem.techage_state = RUNNING - mem.techage_countdown = 4 + mem.techage_countdown = 1 if called_from_on_timer then -- timer has to be stopped once to be able to be restarted self.stop_timer = true @@ -333,12 +333,19 @@ function NodeStates:is_active(mem) return state == RUNNING or state == STANDBY or state == BLOCKED end +function NodeStates:start_if_standby(pos) + local mem = tubelib2.get_mem(pos) + if mem.techage_state == STANDBY then + self:start(pos, mem) + end +end + -- To be called if node is idle. -- If countdown reaches zero, the node is set to STANDBY. function NodeStates:idle(pos, mem) local countdown = mem.techage_countdown - 1 mem.techage_countdown = countdown - if countdown < 0 then + if countdown <= 0 then self:standby(pos, mem) end end diff --git a/init.lua b/init.lua index aa6c72e..39e5f31 100644 --- a/init.lua +++ b/init.lua @@ -60,13 +60,13 @@ else end -- Steam Engine + dofile(MP.."/steam_engine/help.lua") dofile(MP.."/steam_engine/firebox.lua") dofile(MP.."/steam_engine/boiler.lua") dofile(MP.."/steam_engine/cylinder.lua") dofile(MP.."/steam_engine/flywheel.lua") dofile(MP.."/steam_engine/gearbox.lua") - dofile(MP.."/steam_engine/consumer.lua") - + -- Basic Machines dofile(MP.."/basic_machines/pusher.lua") dofile(MP.."/basic_machines/blackhole.lua") @@ -78,6 +78,7 @@ else dofile(MP.."/basic_machines/autocrafter.lua") dofile(MP.."/basic_machines/mark.lua") dofile(MP.."/basic_machines/forceload.lua") + dofile(MP.."/basic_machines/electronic_fab.lua") if techage.basalt_stone_enabled then dofile(MP.."/basic_machines/basalt.lua") end @@ -96,6 +97,7 @@ else --dofile(MP.."/test/test.lua") dofile(MP.."/test/generator.lua") --dofile(MP.."/test/consumer.lua") + --dofile(MP.."/test/consumer2.lua") --dofile(MP.."/fermenter/gasflare.lua") diff --git a/iron_age/charcoalpile.lua b/iron_age/charcoalpile.lua index ccf1c65..7565d2e 100644 --- a/iron_age/charcoalpile.lua +++ b/iron_age/charcoalpile.lua @@ -224,11 +224,11 @@ local PileHelp = S([[Coal Pile to produce charcoal: (see plan)]]) local PileImages = { - {"default_dirt", "default_dirt", "default_dirt", "default_dirt", "default_dirt"}, - {"default_dirt", "default_wood", "default_wood", "default_wood", "default_dirt"}, - {"default_dirt", "default_wood", "default_wood", "default_wood", "default_dirt"}, - {"default_dirt", "default_wood", "techage_lighter", "default_wood", "default_dirt"}, - {"default_dirt", "default_dirt", "default_dirt", "default_dirt", "default_dirt"}, + {"default_dirt.png", "default_dirt.png", "default_dirt.png", "default_dirt.png", "default_dirt.png"}, + {"default_dirt.png", "default_wood.png", "default_wood.png", "default_wood.png", "default_dirt.png"}, + {"default_dirt.png", "default_wood.png", "default_wood.png", "default_wood.png", "default_dirt.png"}, + {"default_dirt.png", "default_wood.png", "techage_lighter.png", "default_wood.png", "default_dirt.png"}, + {"default_dirt.png", "default_dirt.png", "default_dirt.png", "default_dirt.png", "default_dirt.png"}, } techage.register_help_page("Coal Pile", PileHelp, nil, PileImages) diff --git a/iron_age/coalburner.lua b/iron_age/coalburner.lua index 1a33e84..e40e72a 100644 --- a/iron_age/coalburner.lua +++ b/iron_age/coalburner.lua @@ -203,14 +203,14 @@ local BurnerHelp = S([[Coal Burner to heat the melting pot: local BurnerImages = { - {false, false, false, "default_cobble.png^techage_meltingpot", false}, + {false, false, false, "default_cobble.png^techage_meltingpot.png", false}, {false, false, false, false, false}, - {false, false, "default_cobble", "techage_charcoal", "default_cobble"}, - {false, false, "default_cobble", "techage_charcoal", "default_cobble"}, - {false, false, "default_cobble", "techage_charcoal", "default_cobble"}, - {false, false, "default_cobble", "techage_charcoal", "default_cobble"}, - {false, false, false, "techage_lighter", "default_cobble"}, - {false, false, "default_cobble", "default_cobble", "default_cobble"}, + {false, false, "default_cobble.png", "techage_charcoal.png", "default_cobble.png"}, + {false, false, "default_cobble.png", "techage_charcoal.png", "default_cobble.png"}, + {false, false, "default_cobble.png", "techage_charcoal.png", "default_cobble.png"}, + {false, false, "default_cobble.png", "techage_charcoal.png", "default_cobble.png"}, + {false, false, false, "techage_lighter.png", "default_cobble.png"}, + {false, false, "default_cobble.png", "default_cobble.png", "default_cobble.png"}, } techage.register_help_page("Coal Burner", BurnerHelp, nil, BurnerImages) diff --git a/iron_age/gravelsieve.lua b/iron_age/gravelsieve.lua index 8eeda68..148df32 100644 --- a/iron_age/gravelsieve.lua +++ b/iron_age/gravelsieve.lua @@ -134,7 +134,7 @@ for idx = 0,3 do paramtype2 = "facedir", sunlight_propagates = true, is_ground_content = false, - groups = {choppy = 2, cracky = 1}, + groups = {choppy = 2, cracky = 1, not_in_creative_inventory = (idx == 3) and 0 or 1}, drop = "techage:sieve3", }) end diff --git a/iron_age/main.lua b/iron_age/main.lua index 85e89dd..15a8608 100644 --- a/iron_age/main.lua +++ b/iron_age/main.lua @@ -32,13 +32,13 @@ function techage.ironage_swap_nodes(pos1, pos2, name1, name2) end techage.register_chap_page("Iron Age (TA1)", S([[Iron Age is the first level of the available technic stages. -The goal of TA1 is to collect and craft enough XYZ Ingots +The goal of TA1 is to collect and craft enough Iron Ingots to be able to build machines for stage 2 (TA2). 1. You have to collect dirt and wood to build a Coal Pile. (The Coal Pile is needed to produce charcoal) -2. Build a Coal Burner to melt iron to steel ingots. +2. Build a Coal Burner to melt iron to iron ingots. 3. Craft a Gravel Sieve and collect gravel. (A Hammer can be used to smash cobble to gravel) -4. Sieve the gravel to get the necessary ores -]])) +4. Sieve the gravel to get the necessary ores or go mining. +]]), "techage:iron_ingot") diff --git a/steam_engine/boiler.lua b/steam_engine/boiler.lua index 13dca88..6de5504 100644 --- a/steam_engine/boiler.lua +++ b/steam_engine/boiler.lua @@ -255,7 +255,7 @@ minetest.register_node("techage:boiler2", { turn_on = turn_power_on, read_power_consumption = generator.read_power_consumption, power_network = Pipe, - trigger_boiler = function(pos) + signal_heat = function(pos) local mem = tubelib2.get_mem(pos) mem.fire_trigger = true if not minetest.get_node_timer(pos):is_started() then @@ -315,3 +315,14 @@ minetest.register_craft({ {"techage:iron_ingot", "", "techage:iron_ingot"}, }, }) + +techage.register_help_page(I("TA2 Boiler Base"), +I([[Part of the steam engine. +Has to be placed on top of the Firebox +and filled with water. +(see TA2 Steam Engine)]]), "techage:boiler1") + +techage.register_help_page(I("TA2 Boiler Top"), +I([[Part of the steam engine. +Has to be placed on top of TA2 Boiler Base. +(see TA2 Steam Engine)]]), "techage:boiler2") \ No newline at end of file diff --git a/steam_engine/cylinder.lua b/steam_engine/cylinder.lua index 6cec750..e43e594 100644 --- a/steam_engine/cylinder.lua +++ b/steam_engine/cylinder.lua @@ -155,3 +155,9 @@ minetest.register_craft({ {"default:wood", "techage:iron_ingot", "basic_materials:steel_bar"}, }, }) + +techage.register_help_page(I("TA2 Cylinder"), +I([[Part of the steam engine. +Has to be placed side by side +with the TA2 Flywheel. +(see TA2 Steam Engine)]]), "techage:cylinder") \ No newline at end of file diff --git a/steam_engine/firebox.lua b/steam_engine/firebox.lua index 6962ab4..dabf9d2 100644 --- a/steam_engine/firebox.lua +++ b/steam_engine/firebox.lua @@ -32,8 +32,8 @@ local function node_timer(pos, elapsed) local mem = tubelib2.get_mem(pos) if mem.running then local trd = TRD({x=pos.x, y=pos.y+2, z=pos.z}) - if trd and trd.trigger_boiler then - trd.trigger_boiler({x=pos.x, y=pos.y+2, z=pos.z}) + if trd and trd.signal_heat then + trd.signal_heat({x=pos.x, y=pos.y+2, z=pos.z}) end mem.burn_cycles = (mem.burn_cycles or 0) - 1 if mem.burn_cycles <= 0 then @@ -143,3 +143,16 @@ minetest.register_craft({ {'group:stone', 'group:stone', 'group:stone'}, }, }) + +techage.register_node("techage:firebox", {"techage:firebox_on"}, { + on_push_item = function(pos, in_dir, stack) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if inv:room_for_item("fuel", stack) then + inv:add_item("fuel", stack) + minetest.get_node_timer(pos):start(CYCLE_TIME) + return true + end + return false + end, +}) diff --git a/steam_engine/flywheel.lua b/steam_engine/flywheel.lua index f4f1d7e..700d6fc 100644 --- a/steam_engine/flywheel.lua +++ b/steam_engine/flywheel.lua @@ -26,7 +26,7 @@ local I,_ = dofile(MP.."/intllib.lua") local STANDBY_TICKS = 4 local COUNTDOWN_TICKS = 4 local CYCLE_TIME = 8 -local POWER_CAPACITY = 12 +local POWER_CAPACITY = 20 local Axle = techage.Axle local generator = techage.generator @@ -274,3 +274,11 @@ minetest.register_lbm({ end }) +techage.register_help_page(I("TA2 Flywheel"), +I([[Part of the steam engine. +Has to be placed side by side +with the TA2 Cylinder. +Used to turn on/off the steam engine. +Connect the Flywheel with your TA2 machines +by means of Axles and Gearboxes +(see TA2 Steam Engine)]]), "techage:flywheel") \ No newline at end of file diff --git a/steam_engine/help.lua b/steam_engine/help.lua new file mode 100644 index 0000000..f595ab5 --- /dev/null +++ b/steam_engine/help.lua @@ -0,0 +1,49 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + TA2 Steam Engine Help + +]]-- + +-- Load support for intllib. +local MP = minetest.get_modpath("techage") +local S, NS = dofile(MP.."/intllib.lua") + +techage.register_chap_page(S("Steam Age (TA2)"), S([[Steam Age is the second level of the available technic stages. +The goal of TA2 is build a steam engine and machines +to produce ores and vacuum tubes for the first +electronic devices and machines in TA3.]]), "techage:vacuum_tube") + +local HelpText = S([[1. Build a steam machine according +to the plan with TA2 Firebox, TA2 Boiler, +Steam Pipes, TA2 Cyclinder and TA2 Flywheel. +2. Heat the Firebox with coal/charcoal +3. Fill the boiler with water (more than on bucket is needed) +4. Wait until the water is heated +5. Open the steam ventil +6. Start the Flywheel +7. Connect the Flywheel with your machines by means of Axles and Gearboxes]]) + +local Images = { + + {false, false, false, false, false, false, false}, + {false, false, false, false, false, false, false}, + {false, false, "techage_steam_knee.png", 'techage_steam_pipe.png', "techage_steam_knee.png^[transformR270"}, + {false, false, "techage_boiler_top_ta2.png", false, 'techage_steam_pipe.png^[transformR90'}, + {false, false, "techage_boiler_bottom_ta2.png", false, 'techage_steam_pipe.png^[transformR90'}, + {false, false, "techage_firebox.png^techage_appl_firehole.png^techage_frame_ta2.png", false, + "techage_steam_knee.png^[transformR90", + "techage_filling_ta2.png^techage_cylinder.png^techage_frame_ta2.png", + "techage_filling_ta2.png^techage_frame_ta2.png^techage_flywheel.png^[transformFX]"}, +} + +techage.register_help_page("Steam Machine", HelpText, nil, Images) + + diff --git a/textures/techage_appl_electronic_fab.png b/textures/techage_appl_electronic_fab.png new file mode 100644 index 0000000000000000000000000000000000000000..4be44d65f10f8a96f8a1349bec9e00f3fdd64bd1 GIT binary patch literal 252 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&pI^l~IVDlQq5Q2~eoh)5S3);&8G}^*5cv4oqrojBJbf zBuWo7SU0fFPl-#sSDzJOw6b1EIg&2{2nEFYYoZ|@@QGCAkOp+iO%ixNx(`6855jxKl@Dc+-Y=%R~-#-fIR oT0hMMnYS}~tP-v;GQVYD5VlbI*_8iL5a=idPgg&ebxsLQ00S^lCjbBd literal 0 HcmV?d00001 diff --git a/textures/techage_appl_electronic_fab4.png b/textures/techage_appl_electronic_fab4.png new file mode 100644 index 0000000000000000000000000000000000000000..c7b9d28e2440c134a33836917903906c85df8cec GIT binary patch literal 352 zcmeAS@N?(olHy`uVBq!ia0vp^3P9Yz!3HF=(z2z16kC$Fy9>jA5L~c#`DCC7XMsm# zF#`j)FbFd;%$g$s6l5>)^mS!_%*rUlqq5lNdlXRUt*47)NX4zUv-WZwG7xcFeaDbr z;h&A$vL=50l2gnY>#ja}5yNC9sy=zf3iB71*|%m-s$TH&x(P3XhA}tqw%gyn^?B}! z{azy1c{gXR?yNhO;xf~xD9wIqmHnyC!gc-3Z0iYIn0`N2T)o3^*&D_^-%qv{ac*;P zd6mH^w94~`*TQ~}2w(0A0-T}I0@d@Gf$sSUg+iY)+gdz4?0`ZHPne%D$KMoPFLwQm zs76hLru>Wcz;xDSH4kbeOQRcFvV`ooG_4z2Jbv64n#2!OKY@P&f5=AdXMY;1xF<}A j-|o@TGDn`FVg55dzu-=-qp|I)K&E=S`njxgN@xNA95R4X literal 0 HcmV?d00001 diff --git a/textures/techage_boiler_bottom_ta2.png b/textures/techage_boiler_bottom_ta2.png new file mode 100644 index 0000000000000000000000000000000000000000..a270b023b794d6ded2997a917ddc20f1692e12e7 GIT binary patch literal 3788 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 OAnVqlmn%~0B~FmyQs O5O})!xvXWFU8GbZ8()Nlj2>E@cM*00U`BL_t(o!`+r$XcSiz zfWJGtvy;tso2*hzQxq)NYO7!+7;Os{o20QZA{vNI>w_2{1gW%*umm9ldQSiWJ?$5dReD~aQ z&mDn_4E7(Vsbv?#*RNrw5}1ZX%1pXV!HQ24C@p2p`uFi7irZjQ%Ps)^9v>r~jN8Vg zTTy}`3@I2q)epeXm7iPzL_WeFPJhqhmlxWG0a*7=EtX|Ir2E^|pL5o(+OR3F2V4Qh zMn|~)@3>=p$M&7*Q+nFf2qvc!C;~K9r94uOJ~czRrf}x`8P5=|M{qm#mt*{c`mK)f zp09cc1bhg;y1E8WLFjiIoRy|fGp976$5{{#0?_tZo1-(K#{u}J_uDkF5J)K<-GTrD0ZmGo z;-lsr%$K+V;8Vd!vHJCPLZvUFC(cq`{TlzolDxWNNsj8D!(%L}&=?vTAzZSJ>6!aL ztgt*#Sy{<^i>n8ciJ6=z?l|1;Y0)naZz~SKWG2A=U-*Vo|NPJ!PCL6^R1fI){FG?q z7|oXKc6R-7U|eIsOobonYuwn1q6TQ(*h-0}5-dsA?XkxdSAazo;du{2SAZ3(BhMB< zh`HY?(=xoK`T`TtBOeGQ1E`^hrwnlZ^0A!nqxy;jAc0?;R&(tUOs+F{v5&pY9mHa{ z0H~;Vh2DWqnre6BV^#5D;KBcu$-7(gF6c$4pd%Q(*atxGK-p=Tsz_zh#u(1XPP-B zdZ61eZtI>q;S>3DiU;XAG{AceFF9%N^mjvyUfY+Wv;3{2Z2zR%Y5)GKCH8z;!`EF$ z*&p5aWB^AxF7QR?=JfTtq;m64Eplm_YyQ=T`^4HMCn>AZfGJu(yvwm4BTw#uuIK>K zu4X1LsYnzAmYg+%LiNSvbRs1DeihAsPbQ79(EPfzq+ck)psZ$=?v8#AcD59L1hxmV z(xb@w&e>O1Gy5D}Lwom`U5Poo=k$5qxh?+zJrg$+m((vD00000NkvXXu0mjfI3C#l literal 0 HcmV?d00001