diff --git a/basic_machines/forceload.lua b/basic_machines/forceload.lua index e73e950..fb2bdc8 100644 --- a/basic_machines/forceload.lua +++ b/basic_machines/forceload.lua @@ -79,6 +79,16 @@ local function set_pos_list(player, lPos) player:set_attribute("techage_forceload_blocks", minetest.serialize(lPos)) end +local function shoe_flbs(pos, name, range) + local pos1 = {x=pos.x-range, y=pos.y-range, z=pos.z-range} + local pos2 = {x=pos.x+range, y=pos.y+range, z=pos.z+range} + for _,npos in ipairs(minetest.find_nodes_in_area(pos1, pos2, {"techage:forceload"})) do + local _pos1, _pos2 = calc_area(npos) + local owner = M(npos):get_string("owner") + techage.mark_region(name, _pos1, _pos2, owner) + end +end + local function get_data(pos, player) local pos1, pos2 = calc_area(pos) local num = #minetest.deserialize(player:get_attribute("techage_forceload_blocks")) or 0 @@ -86,24 +96,27 @@ local function get_data(pos, player) return pos1, pos2, num, max end -local function formspec(player) - local lPos = get_pos_list(player) - local tRes = {} - for idx,pos in ipairs(lPos) do - local pos1, pos2 = calc_area(pos) - local ypos = 0.2 + idx * 0.4 - tRes[#tRes+1] = idx - tRes[#tRes+1] = minetest.formspec_escape(P2S(pos1)) - tRes[#tRes+1] = "to" - tRes[#tRes+1] = minetest.formspec_escape(P2S(pos2)) +local function formspec(name) + local player = minetest.get_player_by_name(name) + if player then + local lPos = get_pos_list(player) + local tRes = {} + for idx,pos in ipairs(lPos) do + local pos1, pos2 = calc_area(pos) + local ypos = 0.2 + idx * 0.4 + tRes[#tRes+1] = idx + tRes[#tRes+1] = minetest.formspec_escape(P2S(pos1)) + tRes[#tRes+1] = "to" + tRes[#tRes+1] = minetest.formspec_escape(P2S(pos2)) + end + return "size[7,9]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "label[0,0;List of your Forceload Blocks:]".. + "tablecolumns[text,width=1.2;text,width=12;text,width=1.6;text,width=12]".. + "table[0,0.6;6.8,8.4;output;"..table.concat(tRes, ",")..";1]" end - return "size[7,9]".. - default.gui_bg.. - default.gui_bg_img.. - default.gui_slots.. - "label[0,0;List of your Forceload Blocks:]".. - "tablecolumns[text,width=1.2;text,width=12;text,width=1.6;text,width=12]".. - "table[0,0.6;6.8,8.4;output;"..table.concat(tRes, ",")..";1]" end @@ -151,10 +164,13 @@ minetest.register_node("techage:forceload", { end, on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - if M(pos):get_string("owner") == clicker:get_player_name() or - minetest.check_player_privs(clicker:get_player_name(), "server") then - local s = formspec(clicker) - minetest.show_formspec(clicker:get_player_name(), "techage:forceload", s) + local owner = M(pos):get_string("owner") + local name = clicker:get_player_name() + if name == owner or minetest.check_player_privs(name, "server") then + local s = formspec(owner) + if s then + minetest.show_formspec(owner, "techage:forceload", s) + end end end, @@ -201,3 +217,20 @@ minetest.register_on_leaveplayer(function(player) end end) + +minetest.register_chatcommand("forceload", { + params = "", + description = "Forceloadblöcke der Umgebung 64x64x64 anzeigen", + func = function(name, param) + if minetest.check_player_privs(name, "superminer") then + local player = minetest.get_player_by_name(name) + if player then + local pos = player:get_pos() + pos = vector.round(pos) + shoe_flbs(pos, name, 64) + end + else + return false, "Priv missing" + end + end, +}) diff --git a/basic_machines/grinder.lua b/basic_machines/grinder.lua index 8e68021..4e8461b 100644 --- a/basic_machines/grinder.lua +++ b/basic_machines/grinder.lua @@ -293,4 +293,5 @@ techage.add_grinder_recipe({input="default:pine_tree", output="default:pine_need techage.add_grinder_recipe({input="default:acacia_tree", output="default:acacia_leaves 8"}) techage.add_grinder_recipe({input="default:aspen_tree", output="default:aspen_leaves 8"}) +techage.add_grinder_recipe({input="techage:bauxite_cobble", output="techage:bauxite_gravel"}) diff --git a/basis/mark.lua b/basis/mark.lua index 9878e4a..5432617 100644 --- a/basis/mark.lua +++ b/basis/mark.lua @@ -24,7 +24,7 @@ function techage.unmark_region(name) end end -function techage.mark_region(name, pos1, pos2) +function techage.mark_region(name, pos1, pos2, owner) techage.unmark_region(name) @@ -41,6 +41,9 @@ function techage.mark_region(name, pos1, pos2) --collisionbox = {-sizex, -sizey, -thickness, sizex, sizey, thickness}, collisionbox = {0,0,0, 0,0,0}, }) + if owner then + marker:set_nametag_attributes({text = owner}) + end marker:get_luaentity().player_name = name table.insert(markers, marker) end diff --git a/chemistry/reactor.lua b/chemistry/reactor.lua new file mode 100644 index 0000000..71bc990 --- /dev/null +++ b/chemistry/reactor.lua @@ -0,0 +1,32 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + TA4 Reactor + +]]-- + +local S = techage.S + +minetest.register_node("techage:ta4_reactor", { + description = S("TA4 Reactor"), + tiles = {"techage_reactor_side.png"}, + drawtype = "mesh", + mesh = "techage_boiler_large.obj", + selection_box = { + type = "fixed", + fixed = {-13/32, -16/32, -13/32, 13/32, 16/32, 13/32}, + }, + + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + groups = {cracky=2}, + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), +}) diff --git a/coal_power_station/power_terminal.lua b/coal_power_station/power_terminal.lua index 4008f61..421fa59 100644 --- a/coal_power_station/power_terminal.lua +++ b/coal_power_station/power_terminal.lua @@ -13,20 +13,18 @@ ]]-- -- for lazy programmers -local P = minetest.string_to_pos +local P2P = minetest.string_to_pos +local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end local M = minetest.get_meta +local N = function(pos) return minetest.get_node(pos).name end local S = techage.S -local BLOCKING_TIME = 2 +local CYCLE_TIME = 2 +local PWR_CAPA = 0.1 +local COUNTDOWN = 5 -local Param2ToDir = { - [0] = 6, - [1] = 5, - [2] = 2, - [3] = 4, - [4] = 1, - [5] = 3, -} +local Cable = techage.ElectricCable +local power = techage.power local function collect_network_data(pos, mem) local data = { @@ -39,74 +37,57 @@ local function collect_network_data(pos, mem) fcel = {}, other = {}, } - local add = function(kind, attr, val) - data[kind][attr] = (data[kind][attr] or 0) + (val or 0) - end - local max = function(kind, attr, val) - data[kind][attr] = math.max((data[kind][attr] or 0), (val or 0)) - end + local add = function(tbl, mem, nomi, real) + tbl.num = (tbl.num or 0) + 1 + tbl.load = (tbl.load or 0) + (((mem.pwr_node_alive_cnt or 0) > 0) and 1 or 0) + tbl.nomi = (tbl.nomi or 0) + (nomi or 0) + tbl.real = (tbl.real or 0) + (((mem.pwr_node_alive_cnt or 0) > 0) and (real or 0) or 0) + end local nnodes = techage.power.limited_connection_walk(pos, function(pos, node, mem, num_hops, num_nodes) if node.name == "techage:generator" or node.name == "techage:generator_on" then - add("fuel", "num", 1) - add("fuel", "nomi", mem.pwr_available) - add("fuel", "curr", mem.provided) + add(data.fuel, mem, mem.pwr_available, mem.provided) elseif node.name == "techage:ta3_akku" then - add("akku", "num", 1) - add("akku", "nomi", mem.pwr_could_provide) - add("akku", "curr", mem.delivered) + add(data.akku, mem, mem.pwr_could_provide, mem.delivered) elseif node.name == "techage:heatexchanger1" then - add("stor", "num", 1) - add("stor", "nomi", mem.pwr_could_provide) - add("stor", "curr", mem.delivered) + add(data.stor, mem, mem.pwr_could_provide, mem.delivered) elseif node.name == "techage:tiny_generator" or node.name == "techage:tiny_generator_on" then - add("fuel", "num", 1) - add("fuel", "nomi", mem.pwr_available) - add("fuel", "curr", mem.provided) + add(data.fuel, mem, mem.pwr_available, mem.provided) elseif node.name == "techage:ta4_solar_inverter" then - add("solar", "num", 1) - add("solar", "nomi", mem.pwr_available) - add("solar", "curr", mem.delivered) + add(data.solar, mem, mem.pwr_available, mem.delivered) elseif node.name == "techage:ta4_wind_turbine" then - add("wind", "num", 1) - add("wind", "nomi", mem.pwr_available) - add("wind", "curr", mem.delivered) + add(data.wind, mem, mem.pwr_available, mem.delivered) elseif node.name == "techage:ta4_fuelcell" or node.name == "techage:ta4_fuelcell_on" then - add("fcel", "num", 1) - add("fcel", "nomi", mem.pwr_available) - add("fcel", "curr", mem.provided) + add(data.fcel, mem, mem.pwr_available, mem.provided) elseif node.name == "techage:ta4_electrolyzer" or node.name == "techage:ta4_electrolyzer_on" then - add("elec", "num", 1) - add("elec", "nomi", -(mem.pwr_could_need or 0)) - add("elec", "curr", -(mem.consumed or 0)) + add(data.elec, mem, -(mem.pwr_could_need or 0), -(mem.consumed or 0)) elseif mem.pwr_needed and mem.pwr_needed > 0 and (mem.pwr_node_alive_cnt or 0) > 0 then - add("other", "num", 1) - add("other", "nomi", -mem.pwr_needed) - add("other", "curr", mem.pwr_state == 3 and -mem.pwr_needed) + add(data.other, mem, -(mem.pwr_needed or 0), (-mem.pwr_needed or 0)) end end ) return data, nnodes end -local function formspec(pos) - local jpos = minetest.deserialize(M(pos):get_string("junction_pos")) - local data, nnodes = collect_network_data(jpos, tubelib2.get_mem(jpos)) +local function formspec(pos, mem) + local data, nnodes = collect_network_data(pos, mem) local get = function(kind) - return (data[kind].num or 0).." / "..(data[kind].curr or 0).." ku / "..(data[kind].nomi or 0).. " ku" + return (data[kind].load or 0).." / "..(data[kind].num or 0).." : ".. + (data[kind].curr or 0).." / "..(data[kind].nomi or 0).. " ku" end local alarm = "" if nnodes > (techage.MAX_NUM_NODES - 50) then alarm = " (max. "..(techage.MAX_NUM_NODES).." !!!)" end + local update = mem.countdown > 0 and mem.countdown or S("Update") return "size[9.5,8.2]".. default.gui_bg.. default.gui_bg_img.. default.gui_slots.. "label[2,0.0;"..S("Network Data").."]".. - "label[3,0.7;"..S("(number / current / max.)").."]".. + "label[1,0.7;"..S("(Num. nodes loaded / max. : Power current / max.)").."]".. "label[0,1.4;"..S("TA3 Coal/oil")..":]".. "label[5,1.4;"..get("fuel").."]".. "label[0,2.1;"..S("TA3 Akku")..":]".. "label[5,2.1;"..get("akku").."]".. "label[0,2.8;"..S("TA4 Solar Inverter")..":]".. "label[5,2.8;"..get("solar").."]".. @@ -116,11 +97,20 @@ local function formspec(pos) "label[0,5.6;"..S("TA4 Fuel Cell")..":]".. "label[5,5.6;"..get("fcel").."]".. "label[0,6.3;"..S("Other consumers")..":]".. "label[5,6.3;"..get("other").."]".. "label[0,7;"..S("Number of nodes").." : "..nnodes..alarm.."]".. - "button[2.5,7.5;2,1;update;"..S("Update").."]" + "button[3.5,7.5;2,1;update;"..update.."]" end -local function update_formspec(pos) - M(pos):set_string("formspec", formspec(pos)) +local function node_timer(pos, elapsed) + local mem = tubelib2.get_mem(pos) + power.generator_alive(pos, mem) + + mem.countdown = mem.countdown or 0 + if mem.countdown > 0 then + mem.countdown = mem.countdown - 1 + M(pos):set_string("formspec", formspec(pos, mem)) + end + + return true end minetest.register_node("techage:ta3_power_terminal", { @@ -142,31 +132,19 @@ minetest.register_node("techage:ta3_power_terminal", { }, }, - after_place_node = function(pos, placer, itemstack) - local node = minetest.get_node(pos) - local outdir = techage.side_to_outdir("B", node.param2) - local jpos = tubelib2.get_pos(pos, outdir) - local mem = tubelib2.init_mem(pos) - mem.blocked_until = 0 - local meta = M(pos) - meta:set_string("junction_pos", minetest.serialize(jpos)) - meta:set_string("formspec", formspec(pos)) - end, - on_receive_fields = function(pos, formname, fields, player) local mem = tubelib2.get_mem(pos) - mem.blocked_until = mem.blocked_until or minetest.get_gametime() - if fields.update and mem.blocked_until < minetest.get_gametime() then - M(pos):set_string("formspec", formspec(pos)) - mem.blocked_until = minetest.get_gametime() + BLOCKING_TIME - minetest.after(BLOCKING_TIME + 1, update_formspec, pos) - end + mem.countdown = COUNTDOWN end, on_rightclick = function(pos, node, clicker) - M(pos):set_string("formspec", formspec(pos)) + local mem = tubelib2.get_mem(pos) + minetest.get_node_timer(pos):start(CYCLE_TIME) + power.generator_start(pos, mem, PWR_CAPA) + mem.countdown = COUNTDOWN end, + on_timer = node_timer, paramtype2 = "facedir", paramtype = "light", on_rotate = screwdriver.disallow, @@ -176,6 +154,19 @@ minetest.register_node("techage:ta3_power_terminal", { sounds = default.node_sound_metal_defaults(), }) +techage.power.register_node({"techage:ta3_power_terminal"}, { + power_network = Cable, + conn_sides = {"B"}, + after_place_node = function(pos) + local mem = tubelib2.init_mem(pos) + minetest.get_node_timer(pos):start(CYCLE_TIME) + power.generator_start(pos, mem, PWR_CAPA) + local meta = M(pos) + mem.countdown = 0 + meta:set_string("formspec", formspec(pos, mem)) + end, +}) + minetest.register_craft({ output = "techage:ta3_power_terminal", recipe = { diff --git a/hydrogen/hydrogen.lua b/hydrogen/hydrogen.lua index 868407e..2b7a456 100644 --- a/hydrogen/hydrogen.lua +++ b/hydrogen/hydrogen.lua @@ -20,7 +20,7 @@ minetest.register_craftitem("techage:hydrogen", { }) minetest.register_craftitem("techage:ta4_fuelcellstack", { - description = S("TA4 Fuell Cell Stack"), + description = S("TA4 Fuel Cell Stack"), inventory_image = "techage_fc_stack_inv.png", }) diff --git a/init.lua b/init.lua index 8561001..40f6ced 100644 --- a/init.lua +++ b/init.lua @@ -59,8 +59,12 @@ else -- Nodes1 dofile(MP.."/nodes/baborium.lua") dofile(MP.."/nodes/usmium.lua") + --dofile(MP.."/nodes/bauxit.lua") -- Power networks + dofile(MP.."/power/schedule.lua") + --dofile(MP.."/power/distribute.lua") + --dofile(MP.."/power/test.lua") dofile(MP.."/power/power.lua") dofile(MP.."/power/power2.lua") dofile(MP.."/power/junction.lua") @@ -202,7 +206,7 @@ else dofile(MP.."/energy_storage/nodes.lua") -- Chemistry - --dofile(MP.."/chemistry/reaktor.lua") + --dofile(MP.."/chemistry/reactor.lua") -- Hydrogen dofile(MP.."/hydrogen/hydrogen.lua") diff --git a/locale/techage.de.tr b/locale/techage.de.tr index 96d6751..0b2243f 100644 --- a/locale/techage.de.tr +++ b/locale/techage.de.tr @@ -1,7 +1,7 @@ # textdomain: techage #### TA3 Terminal ####@n@nSend commands to your machines@nand output text messages from your@nmachines to the Terminal.@n@nCommand syntax:@n cmd @n@nexample: cmd 181 on@n is the number of the node to which the command is sent@n'on' is the command to turn machines/nodes on@nFurther commands can be retrieved by clicking on@nmachines/nodes with the Techage Info Tool.@n@nLocal commands:@n- clear @= clear screen@n- help @= this message@n- pub @= switch to public use@n- priv @= switch to private use@nTo program a user button with a command:@n set @ne.g. 'set 1 ON cmd 123 on'@n= -(number / current / max.)=(Anzahl / aktuell / max.) +(Num. nodes loaded / max. : Power current / max.)=(Anz. Blöcke geladen / max. : Strom aktuell / max.) Allow to dig/place Techage power lines nearby power poles=Erlaubt TODO Ash=Asche Autocrafter=Autocrafter @@ -20,6 +20,9 @@ Basalt Gravel=Basaltkies Basalt Stone=Basaltgestein Basalt Stone Block=Basaltsteinblock Basalt Stone Brick=Basaltsteinziegel +Bauxite Cobblestone=Bauxit Kopfsteinpflaster +Bauxite Gravel=Bauxit Kies +Bauxite Stone=Bauxit Biome=Biom Block configured items for open ports=Blockiere konfigurierte Gegenstände für offene Ausgänge Build derrick=Errichte Ölturm @@ -62,6 +65,7 @@ Oil Drill Box=Ölbohrkiste Oil Pumpjack=Ölpumpe Oil Source=Erdöl Oil amount:=Ölmenge: +Other consumers=Weitere Verbraucher Outp=Ergeb. Plan=Plan Position=Position @@ -163,6 +167,7 @@ TA4 Electrolyzer=TA4 Elektrolyseur TA4 Energy Storage=TA4 Energiespeicher TA4 Epoxide Resin=TA4 Epoxidharz TA4 Fuel Cell=TA4 Brennstoffzelle +TA4 Fuel Cell Stack=Brennstoffzellenstapel TA4 Generator=TA4 Generator TA4 Heat Exchanger=TA4 Wärmetauscher TA4 Heat Exchanger 1=TA4 Wärmetauscher 1 @@ -176,6 +181,7 @@ TA4 Pillar=TA4 Säule TA4 Pipe=TA4 Röhre TA4 Pipe Inlet=TA4 Rohrzulauf TA4 Protected Chest=TA4 Gesicherte Kiste +TA4 Reactor=Reaktor TA4 Rotor Blade=TA4 Rotorblatt TA4 Silicon Wafer=TA4 Silizium-Wafer TA4 Solar Carrier Module=TA4 Solar Trägermodul @@ -227,6 +233,8 @@ added=hinzugefügt wird added or removed=hinzugefügt oder entfernt wird commands like: help=Kommandos wie: help connected with=verbunden mit +light=Licht +power=Strom removed=entfernt stopped=gestoppt ##### not used anymore ##### \ No newline at end of file diff --git a/locale/template.txt b/locale/template.txt index f8cfb8c..9aa9631 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -1,5 +1,5 @@ #### TA3 Terminal ####@n@nSend commands to your machines@nand output text messages from your@nmachines to the Terminal.@n@nCommand syntax:@n cmd @n@nexample: cmd 181 on@n is the number of the node to which the command is sent@n'on' is the command to turn machines/nodes on@nFurther commands can be retrieved by clicking on@nmachines/nodes with the Techage Info Tool.@n@nLocal commands:@n- clear @= clear screen@n- help @= this message@n- pub @= switch to public use@n- priv @= switch to private use@nTo program a user button with a command:@n set @ne.g. 'set 1 ON cmd 123 on'@n= -(number / current / max.)= +(Num. nodes loaded / max. : Power current / max.)= Allow to dig/place Techage power lines nearby power poles= Ash= Autocrafter= @@ -18,6 +18,9 @@ Basalt Gravel= Basalt Stone= Basalt Stone Block= Basalt Stone Brick= +Bauxite Cobblestone= +Bauxite Gravel= +Bauxite Stone= Biome= Block configured items for open ports= Build derrick= @@ -60,6 +63,7 @@ Oil Drill Box= Oil Pumpjack= Oil Source= Oil amount:= +Other consumers= Outp= Plan= Position= @@ -161,6 +165,7 @@ TA4 Electrolyzer= TA4 Energy Storage= TA4 Epoxide Resin= TA4 Fuel Cell= +TA4 Fuel Cell Stack= TA4 Generator= TA4 Heat Exchanger= TA4 Heat Exchanger 1= @@ -174,6 +179,7 @@ TA4 Pillar= TA4 Pipe= TA4 Pipe Inlet= TA4 Protected Chest= +TA4 Reactor= TA4 Rotor Blade= TA4 Silicon Wafer= TA4 Solar Carrier Module= @@ -225,5 +231,7 @@ added= added or removed= commands like: help= connected with= +light= +power= removed= stopped= \ No newline at end of file diff --git a/nodes/bauxit.lua b/nodes/bauxit.lua new file mode 100644 index 0000000..f9b6ba2 --- /dev/null +++ b/nodes/bauxit.lua @@ -0,0 +1,61 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + Bauxite + +]]-- + +local S = techage.S + +minetest.register_node("techage:bauxite_stone", { + description = S("Bauxite Stone"), + tiles = {"default_desert_stone.png^techage_bauxit_overlay.png^[colorize:#800000:80"}, + groups = {cracky = 3, stone = 1}, + drop = 'techage:bauxite_cobble', + sounds = default.node_sound_stone_defaults(), + --paramtype = "light", + --light_source = minetest.LIGHT_MAX +}) + +minetest.register_node("techage:bauxite_cobble", { + description = S("Bauxite Cobblestone"), + tiles = {"default_desert_cobble.png^[colorize:#800000:80"}, + is_ground_content = false, + groups = {cracky = 3, stone = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("techage:bauxite_gravel", { + description = S("Bauxite Gravel"), + tiles = {"default_gravel.png^[colorize:#9b1f06:180"}, + is_ground_content = false, + groups = {crumbly = 2, falling_node = 1}, + sounds = default.node_sound_gravel_defaults(), +}) + +minetest.register_ore({ + ore_type = "blob", + ore = "techage:bauxite_stone", + wherein = {"default:stone"}, + clust_scarcity = 12 * 12 * 12, + clust_size = 5, + y_max = -100, + y_min = -200, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 8, y = 8, z = 8}, + seed = 1234, --2316, + octaves = 1, + persist = 0.0 + }, + biomes = {"underground"} +}) diff --git a/power/power.lua b/power/power.lua index 5b10f42..697bf9d 100644 --- a/power/power.lua +++ b/power/power.lua @@ -220,16 +220,14 @@ local function min(val, max) end local function accounting(pos, mem) - if mem.pwr_is_master then - -- calculate the primary and secondary supply and demand - mem.mst_supply1 = min(mem.mst_needed1 + mem.mst_needed2, mem.mst_available1) - mem.mst_demand1 = min(mem.mst_needed1, mem.mst_available1 + mem.mst_available2) - mem.mst_supply2 = min(mem.mst_demand1 - mem.mst_supply1, mem.mst_available2) - mem.mst_demand2 = min(mem.mst_supply1 - mem.mst_demand1, mem.mst_available1) - mem.mst_reserve = (mem.mst_available1 + mem.mst_available2) - mem.mst_needed1 - if D.sts then D.dbg("needed = "..mem.mst_needed1.."/"..mem.mst_needed2..", available = "..mem.mst_available1.."/"..mem.mst_available2) end - if D.sts then D.dbg("supply = "..mem.mst_supply1.."/"..mem.mst_supply2..", demand = "..mem.mst_demand1.."/"..mem.mst_demand2..", reserve = "..mem.mst_reserve) end - end + -- calculate the primary and secondary supply and demand + mem.mst_supply1 = min(mem.mst_needed1 + mem.mst_needed2, mem.mst_available1) + mem.mst_demand1 = min(mem.mst_needed1, mem.mst_available1 + mem.mst_available2) + mem.mst_supply2 = min(mem.mst_demand1 - mem.mst_supply1, mem.mst_available2) + mem.mst_demand2 = min(mem.mst_supply1 - mem.mst_demand1, mem.mst_available1) + mem.mst_reserve = (mem.mst_available1 + mem.mst_available2) - mem.mst_needed1 + if D.sts then D.dbg("needed = "..mem.mst_needed1.."/"..mem.mst_needed2..", available = "..mem.mst_available1.."/"..mem.mst_available2) end + if D.sts then D.dbg("supply = "..mem.mst_supply1.."/"..mem.mst_supply2..", demand = "..mem.mst_demand1.."/"..mem.mst_demand2..", reserve = "..mem.mst_reserve) end end local function connection_walk(pos, clbk) @@ -318,10 +316,16 @@ local function store_master(pos, master_pos) pos_already_reached(pos) connection_walk(pos, function(pos, mem) mem.pwr_master_pos = master_pos - mem.pwr_is_master = false end) end +local function master_mem(mem) + if mem.pwr_master_pos then + local netkey = minetest.hash_node_position(mem.pwr_master_pos) + return techage.schedule.get_network(netkey) + end +end + local function handle_generator(mst_mem, mem, pos, power_available) -- for next cycle mst_mem.mst_available1 = (mst_mem.mst_available1 or 0) + power_available @@ -420,33 +424,32 @@ local function turn_off_nodes(mst_pos) end local function determine_new_master(pos, mem) - local was_master = mem.pwr_is_master - mem.pwr_is_master = false local mpos = determine_master(pos) store_master(pos, mpos) - if mpos then - local mmem = tubelib2.get_mem(mpos) - mmem.pwr_is_master = true - mmem.mst_num_nodes = NumNodes - elseif was_master then -- no master any more - -- delete data - mem.mst_supply1 = 0 - mem.mst_supply2 = 0 - mem.mst_reserve = 0 - end - return was_master or mem.pwr_is_master + mem.pwr_master_pos = mpos + return true end --- called from master position -local function power_distribution(pos, mem, dec) - if D.pwr then D.dbg("power_distribution") end - if mem.pwr_is_master then - mem.mst_needed1 = 0 - mem.mst_needed2 = 0 - mem.mst_available1 = 0 - mem.mst_available2 = 0 +-- called from all nodes +local function trigger_network(pos, mem) + if mem.pwr_master_pos then + local netkey = minetest.hash_node_position(mem.pwr_master_pos) + local network = techage.schedule.get_network(netkey) or + techage.schedule.add_network(netkey, {mst_pos = mem.pwr_master_pos}) + network.alive = 10 + else + print("node without master_pos "..N(pos).." at "..S(pos)) end - trigger_nodes(pos, mem, dec or 0) +end + +-- called from global timer +function techage.power.power_distribution(time, pos, mem) + if D.pwr then D.dbg("power_distribution"..math.floor(time).." "..N(pos)) end + mem.mst_needed1 = 0 + mem.mst_needed2 = 0 + mem.mst_available1 = 0 + mem.mst_available2 = 0 + trigger_nodes(pos, mem, 1) accounting(pos, mem) end @@ -458,14 +461,8 @@ end function techage.power.network_changed(pos, mem) if D.pwr then D.dbg("network_changed") end mem.pwr_node_alive_cnt = (mem.pwr_cycle_time or 2)/2 + 1 - if determine_new_master(pos, mem) then -- new master? - power_distribution(pos, mem) - elseif not mem.pwr_master_pos then -- no master? - turn_off_nodes(pos) - elseif not next(mem.connections) then -- isolated? - if mem.pwr_needed then -- consumer? - consumer_turn_off(pos, mem) - end + if determine_new_master(pos, mem) then -- new master + trigger_network(pos, mem) end end @@ -477,7 +474,7 @@ function techage.power.generator_start(pos, mem, available) mem.pwr_cycle_time = 2 mem.pwr_available = available if determine_new_master(pos, mem) then -- new master - power_distribution(pos, mem) + trigger_network(pos, mem) end end @@ -489,15 +486,13 @@ function techage.power.generator_stop(pos, mem) mem.pwr_node_alive_cnt = 0 mem.pwr_available = 0 if determine_new_master(pos, mem) then -- last available master - power_distribution(pos, mem) + trigger_network(pos, mem) end end function techage.power.generator_alive(pos, mem) mem.pwr_node_alive_cnt = 2 - if mem.pwr_is_master then - power_distribution(pos, mem, 1) - end + trigger_network(pos, mem) return mem.pwr_provided or 0 end @@ -531,8 +526,8 @@ end -- Lamp related function to speed up the turn on function techage.power.power_available(pos, mem, needed) if mem.pwr_master_pos and (mem.pwr_power_provided_cnt or 0) > 0 then - mem = tubelib2.get_mem(mem.pwr_master_pos) - if (mem.mst_reserve or 0) >= needed then + mem = master_mem(mem) + if mem and (mem.mst_reserve or 0) >= needed then mem.mst_reserve = (mem.mst_reserve or 0) - needed return true end @@ -544,14 +539,16 @@ end function techage.power.power_accounting(pos, mem) if mem.pwr_master_pos and (mem.pwr_power_provided_cnt or 0) > 0 then mem.pwr_power_provided_cnt = (mem.pwr_power_provided_cnt or 0) - 1 - mem = tubelib2.get_mem(mem.pwr_master_pos) - return { - prim_available = mem.mst_available1 or 0, - sec_available = mem.mst_available2 or 0, - prim_needed = mem.mst_needed1 or 0, - sec_needed = mem.mst_needed2 or 0, - num_nodes = mem.mst_num_nodes or 0, - } + mem = master_mem(mem) + if mem then + return { + prim_available = mem.mst_available1 or 0, + sec_available = mem.mst_available2 or 0, + prim_needed = mem.mst_needed1 or 0, + sec_needed = mem.mst_needed2 or 0, + num_nodes = mem.mst_num_nodes or 0, + } + end end return { prim_available = 0, @@ -570,7 +567,7 @@ function techage.power.secondary_start(pos, mem, available, needed) mem.pwr_could_provide = available mem.pwr_could_need = needed if determine_new_master(pos, mem) then -- new master - power_distribution(pos, mem) + trigger_network(pos, mem) end end @@ -580,7 +577,7 @@ function techage.power.secondary_stop(pos, mem) mem.pwr_could_need = 0 mem.pwr_needed2 = 0 if determine_new_master(pos, mem) then -- last available master - power_distribution(pos, mem) + trigger_network(pos, mem) end end @@ -597,7 +594,7 @@ function techage.power.secondary_alive(pos, mem, capa_curr, capa_max) mem.pwr_node_alive_cnt = 2 if mem.pwr_is_master then if D.pwr then D.dbg("secondary_alive is master") end - power_distribution(pos, mem, 1) + trigger_network(pos, mem) end if mem.pwr_master_pos then return mem.pwr_provided or 0 diff --git a/power/power2.lua b/power/power2.lua index eafcb91..347e2cc 100644 --- a/power/power2.lua +++ b/power/power2.lua @@ -102,6 +102,8 @@ local function add_connection(mem, pos, out_dir, peer_pos, peer_in_dir, power) else mem.connections[out_dir] = {pos = peer_pos, in_dir = peer_in_dir} end + -- update network for power scheduling + techage.power.network_changed(pos, mem) end function techage.power.register_node(names, pwr_def) diff --git a/power/schedule.lua b/power/schedule.lua new file mode 100644 index 0000000..b399264 --- /dev/null +++ b/power/schedule.lua @@ -0,0 +1,87 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + Global power Job Scheduler + +]]-- + +-- for lazy programmers +local P2P = minetest.string_to_pos +local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local M = minetest.get_meta +local N = function(pos) return minetest.get_node(pos).name end + +local CYCLE_TIME = 2.0 + +techage.schedule = {} + +local NetList = {} +local JobQueue = {} +local first = 0 +local last = -1 +local LocalTime = 0 + +local function push(item) + last = last + 1 + item.time = LocalTime + CYCLE_TIME + JobQueue[last] = item +end + +local function pop() + if first > last then return end + local item = JobQueue[first] + if item.time <= LocalTime then + JobQueue[first] = nil -- to allow garbage collection + first = first + 1 + return item + end +end + +-- Scheduler +minetest.register_globalstep(function(dtime) + LocalTime = LocalTime + dtime + local item = pop() + while item do + local network = NetList[item.netkey] + if network and network.alive and network.alive >= 0 then + --techage.distribute.power_distribution(LocalTime, network) + techage.power.power_distribution(LocalTime, network.mst_pos, network) + network.alive = network.alive - 1 + push(item) + else + NetList[item.netkey] = nil + end + item = pop() + end +end) + +function techage.schedule.add_network(netkey, network) + if netkey then + if NetList[netkey] then -- already scheduled + NetList[netkey] = network + else + NetList[netkey] = network + push({netkey = netkey}) + end + return NetList[netkey] + end +end + +function techage.schedule.has_network(netkey) + if netkey then + return NetList[netkey] ~= nil + end +end + +function techage.schedule.get_network(netkey) + if netkey then + return NetList[netkey] + end +end diff --git a/textures/techage_bauxit_overlay.png b/textures/techage_bauxit_overlay.png new file mode 100644 index 0000000..2a57f9b Binary files /dev/null and b/textures/techage_bauxit_overlay.png differ diff --git a/textures/techage_reactor_side.png b/textures/techage_reactor_side.png new file mode 100644 index 0000000..d91bc0a Binary files /dev/null and b/textures/techage_reactor_side.png differ