From 41b5db5330c39c459d4bcd4ea6700f4f4ac8ee25 Mon Sep 17 00:00:00 2001 From: Joachim Stolberg Date: Sun, 1 Nov 2020 21:40:32 +0100 Subject: [PATCH] Add nodes TA2 Power Generator and TA3 Electric Motor --- ta3_power/axle2power.lua | 236 ++++++++++++++++++++++ ta3_power/power2axle.lua | 245 +++++++++++++++++++++++ textures/techage_appl_generator_red.png | Bin 0 -> 3035 bytes textures/techage_appl_generator_red4.png | Bin 0 -> 5430 bytes 4 files changed, 481 insertions(+) create mode 100644 ta3_power/axle2power.lua create mode 100644 ta3_power/power2axle.lua create mode 100644 textures/techage_appl_generator_red.png create mode 100644 textures/techage_appl_generator_red4.png diff --git a/ta3_power/axle2power.lua b/ta3_power/axle2power.lua new file mode 100644 index 0000000..cc06dfd --- /dev/null +++ b/ta3_power/axle2power.lua @@ -0,0 +1,236 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2020 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA2 Power Generator + +]]-- + +-- for lazy programmers +local M = minetest.get_meta +local S = techage.S +local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local S2P = minetest.string_to_pos + +local Cable = techage.ElectricCable +local Axle = techage.Axle +local power = techage.power +local networks = techage.networks + +local CYCLE_TIME = 2 +local PWR_PERF = 24 + +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 on_power(pos) + local nvm = techage.get_nvm(pos) + nvm.axle = nvm.axle or {} + nvm.consumer_powered = true + M(pos):set_string("infotext", S("TA2 Power Generator")) + swap_node(pos, "techage:ta2_generator_on") + nvm.ticks = 0 + local outdir = M(pos):get_int("outdir") + nvm.axle.curr_power = techage.power.needed_power(pos, Cable, outdir) +end + +local function on_nopower(pos) + local nvm = techage.get_nvm(pos) + nvm.consumer_powered = false + if (nvm.ticks or 0) < 4 then + M(pos):set_string("infotext", S("TA2 Power Generator: Overload fault?\n(restart with right-click)")) + end + nvm.ticks = 0 +end + +local function node_timer(pos, elapsed) + local nvm = techage.get_nvm(pos) + nvm.axle = nvm.axle or {} + + -- trigger network on consumer side + nvm.ticks = (nvm.ticks or 0) + 1 + if nvm.ticks % 2 then + power.consumer_alive(pos, Axle, CYCLE_TIME) + end + + -- handle generator side delayed + if nvm.ticks > 3 then + local outdir = M(pos):get_int("outdir") + + if nvm.consumer_powered and not nvm.running_as_generator then + nvm.running_as_generator = true + power.generator_start(pos, Cable, CYCLE_TIME, outdir, nvm.max_power) + elseif not nvm.consumer_powered and nvm.running_as_generator then + nvm.running_as_generator = false + power.generator_stop(pos, Cable, outdir) + end + + if nvm.running_as_generator then + nvm.axle.curr_power = power.generator_alive(pos, Cable, CYCLE_TIME, outdir, PWR_PERF) + 1 + else + swap_node(pos, "techage:ta2_generator_off") + end + end + return true +end + +local function tubelib2_on_update2(pos, outdir, tlib2, node) + local nvm = techage.get_nvm(pos) + nvm.axle = nvm.axle or {} + nvm.axle.curr_power = 1 + power.update_network(pos, outdir, tlib2) +end + +minetest.register_node("techage:ta2_generator_off", { + description = S("TA2 Power Generator"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta2.png^techage_frame_ta2_top.png^techage_appl_arrow.png", + "techage_filling_ta2.png^techage_frame_ta2.png", + "techage_filling_ta2.png^techage_frame_ta2.png^techage_appl_hole_electric.png", + "techage_filling_ta2.png^techage_axle_clutch.png^techage_frame_ta2.png", + "techage_filling_ta2.png^techage_frame_ta2.png^techage_appl_generator_red.png", + "techage_filling_ta2.png^techage_frame_ta2.png^techage_appl_generator_red.png^[transformFX]", + }, + paramtype2 = "facedir", + groups = {cracky=2, crumbly=2, choppy=2}, + on_rotate = screwdriver.disallow, + is_ground_content = false, + + after_place_node = function(pos) + local nvm = techage.get_nvm(pos) + nvm.axle = nvm.axle or {} + nvm.axle.curr_power = 1 + nvm.consumer_powered = false + nvm.running_as_generator = false + M(pos):set_int("outdir", networks.side_to_outdir(pos, "R")) + M(pos):set_int("leftdir", networks.side_to_outdir(pos, "L")) + Cable:after_place_node(pos) + Axle:after_place_node(pos) + minetest.get_node_timer(pos):start(CYCLE_TIME) + power.consumer_start(pos, Axle, CYCLE_TIME*2) + M(pos):set_string("infotext", S("TA2 Power Generator")) + end, + + on_rightclick = function(pos, node, clicker) + local nvm = techage.get_nvm(pos) + nvm.axle = nvm.axle or {} + nvm.axle.curr_power = 1 + M(pos):set_string("infotext", S("TA2 Power Generator")) + end, + + after_dig_node = function(pos, oldnode) + Cable:after_dig_node(pos) + Axle:after_dig_node(pos) + techage.del_mem(pos) + end, + + tubelib2_on_update2 = tubelib2_on_update2, + on_timer = node_timer, + networks = { + ele1 = { + sides = {R = 1}, + ntype = "gen1", + nominal = PWR_PERF, + }, + axle = { + sides = {L = 1}, + ntype = "con1", + on_power = on_power, + on_nopower = on_nopower, + }, + } +}) + +minetest.register_node("techage:ta2_generator_on", { + description = S("TA2 Power Generator"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta2.png^techage_frame_ta2_top.png^techage_appl_arrow.png", + "techage_filling_ta2.png^techage_frame_ta2.png", + "techage_filling_ta2.png^techage_frame_ta2.png^techage_appl_hole_electric.png", + { + image = "techage_filling4_ta2.png^techage_axle_clutch4.png^techage_frame4_ta2.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.6, + }, + }, + { + image = "techage_filling4_ta2.png^techage_appl_generator_red4.png^techage_frame4_ta2.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.3, + }, + }, + { + image = "techage_filling4_ta2.png^techage_appl_generator_red4.png^[transformFX]^techage_frame4_ta2.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.3, + }, + }, + }, + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + is_ground_content = false, + drop = "", + groups = {not_in_creative_inventory=1}, + diggable = false, + + tubelib2_on_update2 = tubelib2_on_update2, + on_timer = node_timer, + networks = { + ele1 = { + sides = {R = 1}, + ntype = "gen1", + nominal = PWR_PERF, + }, + axle = { + sides = {L = 1}, + ntype = "con1", + on_power = on_power, + on_nopower = on_nopower, + }, + } +}) + +techage.register_node({"techage:ta2_generator_off", "techage:ta2_generator_on"}, { + on_node_load = function(pos, node) + minetest.get_node_timer(pos):start(CYCLE_TIME) + end, +}) + +Cable:add_secondary_node_names({"techage:ta2_generator_off", "techage:ta2_generator_on"}) +Axle:add_secondary_node_names({"techage:ta2_generator_off", "techage:ta2_generator_on"}) + +minetest.register_craft({ + output = "techage:ta2_generator_off", + recipe = { + {"basic_materials:steel_bar", "dye:red", "default:wood"}, + {'techage:axle', 'basic_materials:gear_steel', 'techage:electric_cableS'}, + {"default:wood", "techage:iron_ingot", "basic_materials:steel_bar"}, + }, +}) + diff --git a/ta3_power/power2axle.lua b/ta3_power/power2axle.lua new file mode 100644 index 0000000..3e37294 --- /dev/null +++ b/ta3_power/power2axle.lua @@ -0,0 +1,245 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2020 Joachim Stolberg + + AGPL v3 + See LICENSE.txt for more information + + TA3 Electric Motor + +]]-- + +-- for lazy programmers +local M = minetest.get_meta +local S = techage.S +local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local S2P = minetest.string_to_pos + +local Cable = techage.ElectricCable +local Axle = techage.Axle +local power = techage.power +local networks = techage.networks + +local CYCLE_TIME = 2 +local PWR_PERF = 40 + +-- Axles texture animation +local function switch_axles(pos, on) + for _,outdir in ipairs(networks.get_node_connections(pos, "axle")) do + Axle:switch_tube_line(pos, outdir, on and "on" or "off") + end +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 on_power(pos) + local nvm = techage.get_nvm(pos) + nvm.ele1 = nvm.ele1 or {} + nvm.consumer_powered = true + M(pos):set_string("infotext", S("TA3 Electric Motor")) + swap_node(pos, "techage:ta3_motor_on") + nvm.ticks = 0 + local outdir = M(pos):get_int("outdir") + nvm.ele1.curr_power = techage.power.needed_power(pos, Axle, outdir) +end + +local function on_nopower(pos) + local nvm = techage.get_nvm(pos) + nvm.consumer_powered = false + if (nvm.ticks or 0) < 4 then + M(pos):set_string("infotext", S("TA3 Electric Motor: Overload fault?\n(restart with right-click)")) + end + nvm.ticks = 0 +end + +local function node_timer(pos, elapsed) + local nvm = techage.get_nvm(pos) + nvm.ele1 = nvm.ele1 or {} + + -- trigger network on consumer side + nvm.ticks = (nvm.ticks or 0) + 1 + if nvm.ticks % 2 then + power.consumer_alive(pos, Cable, CYCLE_TIME) + end + + -- handle generator side delayed + if nvm.ticks > 3 then + local outdir = M(pos):get_int("outdir") + + if nvm.consumer_powered and not nvm.running_as_generator then + nvm.running_as_generator = true + power.generator_start(pos, Axle, CYCLE_TIME, outdir, nvm.max_power) + switch_axles(pos, true) + elseif not nvm.consumer_powered and nvm.running_as_generator then + nvm.running_as_generator = false + power.generator_stop(pos, Axle, outdir) + switch_axles(pos, false) + end + + if nvm.running_as_generator then + nvm.ele1.curr_power = power.generator_alive(pos, Axle, CYCLE_TIME, outdir, PWR_PERF) + 1 + else + swap_node(pos, "techage:ta3_motor_off") + end + end + return true +end + +local function tubelib2_on_update2(pos, outdir, tlib2, node) + local nvm = techage.get_nvm(pos) + nvm.ele1 = nvm.ele1 or {} + nvm.ele1.curr_power = 1 + power.update_network(pos, outdir, tlib2) +end + +minetest.register_node("techage:ta3_motor_off", { + description = S("TA3 Electric Motor"), + tiles = { + -- 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_axle_clutch.png^techage_frame_ta3.png", + "techage_filling_ta3.png^techage_appl_hole_electric.png^techage_frame_ta3.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_generator_red.png^[transformFX]", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_generator_red.png", + }, + paramtype2 = "facedir", + groups = {cracky=2, crumbly=2, choppy=2}, + on_rotate = screwdriver.disallow, + is_ground_content = false, + + after_place_node = function(pos) + local nvm = techage.get_nvm(pos) + nvm.ele1 = nvm.ele1 or {} + nvm.ele1.curr_power = 1 + nvm.consumer_powered = false + nvm.running_as_generator = false + M(pos):set_int("outdir", networks.side_to_outdir(pos, "R")) + M(pos):set_int("leftdir", networks.side_to_outdir(pos, "L")) + Cable:after_place_node(pos) + Axle:after_place_node(pos) + minetest.get_node_timer(pos):start(CYCLE_TIME) + power.consumer_start(pos, Cable, CYCLE_TIME*2) + M(pos):set_string("infotext", S("TA3 Electric Motor")) + end, + + on_rightclick = function(pos, node, clicker) + local nvm = techage.get_nvm(pos) + nvm.ele1 = nvm.ele1 or {} + nvm.ele1.curr_power = 1 + M(pos):set_string("infotext", S("TA3 Electric Motor")) + end, + + after_dig_node = function(pos, oldnode) + Cable:after_dig_node(pos) + Axle:after_dig_node(pos) + techage.del_mem(pos) + end, + + tubelib2_on_update2 = tubelib2_on_update2, + on_timer = node_timer, + networks = { + axle = { + sides = {R = 1}, + ntype = "gen1", + nominal = PWR_PERF, + }, + ele1 = { + sides = {L = 1}, + ntype = "con1", + on_power = on_power, + on_nopower = on_nopower, + }, + } +}) + +minetest.register_node("techage:ta3_motor_on", { + description = S("TA3 Electric Motor"), + tiles = { + -- 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", + { + image = "techage_filling4_ta3.png^techage_axle_clutch4.png^techage_frame4_ta3.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.6, + }, + }, + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_hole_electric.png", + { + image = "techage_filling4_ta3.png^techage_appl_generator_red4.png^[transformFX]^techage_frame4_ta3.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.3, + }, + }, + { + image = "techage_filling4_ta3.png^techage_appl_generator_red4.png^techage_frame4_ta3.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 0.3, + }, + }, + }, + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + is_ground_content = false, + drop = "", + groups = {not_in_creative_inventory=1}, + diggable = false, + + tubelib2_on_update2 = tubelib2_on_update2, + on_timer = node_timer, + networks = { + axle = { + sides = {R = 1}, + ntype = "gen1", + nominal = PWR_PERF, + }, + ele1 = { + sides = {L = 1}, + ntype = "con1", + on_power = on_power, + on_nopower = on_nopower, + }, + } +}) + +techage.register_node({"techage:ta3_motor_off", "techage:ta3_motor_on"}, { + on_node_load = function(pos, node) + minetest.get_node_timer(pos):start(CYCLE_TIME) + end, +}) + +Cable:add_secondary_node_names({"techage:ta3_motor_off", "techage:ta3_motor_on"}) +Axle:add_secondary_node_names({"techage:ta3_motor_off", "techage:ta3_motor_on"}) + +minetest.register_craft({ + output = "techage:ta3_motor_off", + recipe = { + {"basic_materials:steel_bar", "dye:red", "default:wood"}, + {'techage:electric_cableS', 'basic_materials:gear_steel', 'techage:axle'}, + {"default:wood", "techage:iron_ingot", "basic_materials:steel_bar"}, + }, +}) + diff --git a/textures/techage_appl_generator_red.png b/textures/techage_appl_generator_red.png new file mode 100644 index 0000000000000000000000000000000000000000..751fc8582439524a5aacb72c3d327087327088d8 GIT binary patch literal 3035 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 literal 0 HcmV?d00001 diff --git a/textures/techage_appl_generator_red4.png b/textures/techage_appl_generator_red4.png new file mode 100644 index 0000000000000000000000000000000000000000..15c99d8db8ed2d90688c23ebb93aac7f8d010a88 GIT binary patch literal 5430 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 g{6Ojtr050z1u2>E@rr5c8vp