power distribution changed
This commit is contained in:
parent
857def71e8
commit
c088867c00
@ -8,8 +8,7 @@ local PWR_PERF = 10
|
||||
local PWR_CAPA = 300
|
||||
|
||||
local Cable = techage.ElectricCable
|
||||
local secondary_power = techage.power.secondary_power
|
||||
local power_switched = techage.power.power_switched
|
||||
local power = techage.power
|
||||
|
||||
local function in_range(val, min, max)
|
||||
if val < min then return min end
|
||||
@ -32,52 +31,36 @@ end
|
||||
local function node_timer(pos, elapsed)
|
||||
--print("node_timer akku "..S(pos))
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.capa = mem.capa or 0
|
||||
if mem.generating then
|
||||
local delivered
|
||||
if mem.capa >= PWR_CAPA then
|
||||
delivered = secondary_power(pos, PWR_PERF, 0)
|
||||
elseif mem.capa <= 0 then
|
||||
delivered = secondary_power(pos, 0, PWR_PERF)
|
||||
else
|
||||
delivered = secondary_power(pos, PWR_PERF, PWR_PERF)
|
||||
end
|
||||
if delivered ~= mem.delivered then
|
||||
mem.delivered = delivered
|
||||
--techage.power2.power_switched(pos)
|
||||
end
|
||||
if mem.running then
|
||||
mem.delivered = power.secondary_alive(pos, mem, mem.capa, PWR_CAPA)
|
||||
--print("provided", mem.delivered)
|
||||
mem.capa = mem.capa - mem.delivered
|
||||
mem.capa = in_range(mem.capa, 0, PWR_CAPA)
|
||||
--print("delivered = "..mem.delivered)
|
||||
return true
|
||||
end
|
||||
mem.delivered = 0
|
||||
return false
|
||||
return mem.running
|
||||
end
|
||||
|
||||
|
||||
local function on_receive_fields(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
if fields.update then
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
M(pos):set_string("formspec", formspec(pos, mem))
|
||||
end
|
||||
end
|
||||
techage.power.network_changed(pos, mem)
|
||||
|
||||
local function on_rightclick(pos)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if fields.update then
|
||||
M(pos):set_string("formspec", formspec(pos, mem))
|
||||
end
|
||||
end
|
||||
|
||||
local function after_place_node(pos, placer)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.generating = true
|
||||
mem.running = true
|
||||
mem.capa = 0
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
techage.power.power_switched(pos)
|
||||
on_rightclick(pos)
|
||||
power.secondary_start(pos, mem, PWR_PERF, PWR_PERF)
|
||||
M(pos):set_string("formspec", formspec(pos, mem))
|
||||
end
|
||||
|
||||
|
||||
@ -97,7 +80,6 @@ minetest.register_node("techage:akku", {
|
||||
is_ground_content = false,
|
||||
after_place_node = after_place_node,
|
||||
on_receive_fields = on_receive_fields,
|
||||
on_rightclick = on_rightclick,
|
||||
on_timer = node_timer,
|
||||
})
|
||||
|
||||
|
@ -7,7 +7,7 @@ local PWR_NEEDED = 5
|
||||
local CYCLE_TIME = 4
|
||||
|
||||
local Cable = techage.ElectricCable
|
||||
local consume_power = techage.power.consume_power
|
||||
local power = techage.power
|
||||
|
||||
local function swap_node(pos, name)
|
||||
local node = minetest.get_node(pos)
|
||||
@ -18,45 +18,42 @@ local function swap_node(pos, name)
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
|
||||
|
||||
local function on_power(pos)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
--print("sink on_power", mem.running)
|
||||
mem.timer_running = (mem.timer_running or 1) - 1
|
||||
if mem.running and mem.timer_running >= 0 then
|
||||
local got = consume_power(pos, PWR_NEEDED)
|
||||
if got < PWR_NEEDED then
|
||||
swap_node(pos, "techage:sink")
|
||||
else
|
||||
local function on_power(pos, mem)
|
||||
print("on_power")
|
||||
if mem.running then
|
||||
swap_node(pos, "techage:sink_on")
|
||||
mem.power_available = true
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
M(pos):set_string("infotext", "on")
|
||||
end
|
||||
end
|
||||
|
||||
local function on_nopower(pos, mem)
|
||||
print("on_nopower")
|
||||
swap_node(pos, "techage:sink")
|
||||
M(pos):set_string("infotext", "nopower")
|
||||
end
|
||||
|
||||
local function node_timer(pos, elapsed)
|
||||
--print("node_timer sink "..S(pos))
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if mem.running and not mem.power_available then
|
||||
--print("sink not triggered")
|
||||
swap_node(pos, "techage:sink")
|
||||
power.consumer_alive(pos, mem)
|
||||
return mem.running
|
||||
end
|
||||
mem.power_available = false
|
||||
mem.timer_running = CYCLE_TIME/2 + 1
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
local function on_rightclick(pos, node, clicker)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if not mem.running then
|
||||
if not mem.running and power.power_available(pos, mem, PWR_NEEDED) then
|
||||
mem.running = true
|
||||
node_timer(pos, 2)
|
||||
swap_node(pos, "techage:sink_on")
|
||||
power.consumer_start(pos, mem, CYCLE_TIME, PWR_NEEDED)
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
M(pos):set_string("infotext", "on")
|
||||
else
|
||||
swap_node(pos, "techage:sink")
|
||||
minetest.get_node_timer(pos):stop()
|
||||
mem.running = false
|
||||
swap_node(pos, "techage:sink")
|
||||
power.consumer_stop(pos, mem)
|
||||
minetest.get_node_timer(pos):stop()
|
||||
M(pos):set_string("infotext", "off")
|
||||
end
|
||||
end
|
||||
|
||||
@ -64,6 +61,11 @@ end
|
||||
minetest.register_node("techage:sink", {
|
||||
description = "Sink",
|
||||
tiles = {'techage_electric_button.png'},
|
||||
|
||||
after_place_node = function(pos)
|
||||
M(pos):set_string("infotext", "off")
|
||||
end,
|
||||
|
||||
on_timer = node_timer,
|
||||
on_rightclick = on_rightclick,
|
||||
|
||||
@ -96,4 +98,5 @@ minetest.register_node("techage:sink_on", {
|
||||
techage.power.register_node({"techage:sink", "techage:sink_on"}, {
|
||||
power_network = Cable,
|
||||
on_power = on_power,
|
||||
on_nopower = on_nopower,
|
||||
})
|
||||
|
@ -7,32 +7,33 @@ local CYCLE_TIME = 2
|
||||
local PWR_CAPA = 15
|
||||
|
||||
local Cable = techage.ElectricCable
|
||||
local provide_power = techage.power.provide_power
|
||||
local power = techage.power
|
||||
|
||||
local function node_timer(pos, elapsed)
|
||||
--print("node_timer source "..S(pos))
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if mem.generating then
|
||||
local provided = provide_power(pos, PWR_CAPA)
|
||||
return true
|
||||
local provided = power.generator_alive(pos, mem)
|
||||
--print("provided", provided)
|
||||
end
|
||||
return false
|
||||
return mem.generating
|
||||
end
|
||||
|
||||
local function on_rightclick(pos, node, clicker)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if not mem.generating then
|
||||
mem.generating = true
|
||||
node_timer(pos, 2)
|
||||
power.generator_start(pos, mem, PWR_CAPA)
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
M(pos):set_string("infotext", "on")
|
||||
else
|
||||
minetest.get_node_timer(pos):stop()
|
||||
mem.generating = false
|
||||
power.generator_stop(pos, mem)
|
||||
minetest.get_node_timer(pos):stop()
|
||||
M(pos):set_string("infotext", "off")
|
||||
end
|
||||
techage.power.power_switched(pos)
|
||||
end
|
||||
|
||||
|
||||
minetest.register_node("techage:source", {
|
||||
description = "Source",
|
||||
tiles = {
|
||||
@ -44,6 +45,10 @@ minetest.register_node("techage:source", {
|
||||
'techage_electric_button.png^techage_appl_electronic_fab.png',
|
||||
'techage_electric_button.png^techage_appl_electronic_fab.png',
|
||||
},
|
||||
after_place_node = function(pos)
|
||||
M(pos):set_string("infotext", "off")
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
|
@ -84,7 +84,7 @@ local function node_timer(pos, elapsed)
|
||||
State:keep_running(pos, mem, COUNTDOWN_TICKS)
|
||||
mem.power_available = (mem.power_available or 1) - 1
|
||||
mem.triggered = (mem.triggered or 1) - 1
|
||||
if mem.power_available <= 0 or mem.triggered <= 0 then
|
||||
if mem.power_available < 0 or mem.triggered < 0 then
|
||||
power_switched(pos)
|
||||
State:stop(pos, mem)
|
||||
mem.generating = false
|
||||
|
1
init.lua
1
init.lua
@ -43,6 +43,7 @@ else
|
||||
|
||||
-- Power networks
|
||||
dofile(MP.."/power/power.lua")
|
||||
dofile(MP.."/power/power2.lua")
|
||||
dofile(MP.."/power/junction.lua")
|
||||
dofile(MP.."/power/drive_axle.lua")
|
||||
dofile(MP.."/power/steam_pipe.lua")
|
||||
|
@ -171,6 +171,7 @@ minetest.register_node("techage:charcoal_burn", {
|
||||
return false
|
||||
end,
|
||||
drop = "",
|
||||
paramtype = "light",
|
||||
light_source = 10,
|
||||
is_ground_content = false,
|
||||
groups = {crumbly = 2, falling_node = 1, not_in_creative_inventory=1},
|
||||
|
@ -17,8 +17,7 @@ local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
local Cable = techage.ElectricCable
|
||||
local power_switched = techage.power.power_switched
|
||||
local power_available = techage.power.power_available
|
||||
local power = techage.power
|
||||
|
||||
local size = 3/32
|
||||
local Boxes = {
|
||||
@ -40,10 +39,10 @@ techage.register_junction("techage:electric_junction", 2/8, Boxes, Cable, {
|
||||
after_tube_update = function(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
local name = "techage:electric_junction"..techage.junction_type(pos, Cable)
|
||||
minetest.swap_node(pos, {name = name, param2 = 0})
|
||||
power_switched(pos)
|
||||
power.network_changed(pos, tubelib2.get_mem(pos))
|
||||
end,
|
||||
is_power_available = function(pos)
|
||||
return techage.power.power_accounting(pos)
|
||||
return techage.power.power_accounting(pos, tubelib2.get_mem(pos))
|
||||
end,
|
||||
})
|
||||
|
||||
|
604
power/power.lua
604
power/power.lua
@ -19,16 +19,17 @@ local P = minetest.string_to_pos
|
||||
local M = minetest.get_meta
|
||||
-- Techage Related Data
|
||||
local PWR = function(pos) return (minetest.registered_nodes[minetest.get_node(pos).name] or {}).power end
|
||||
local PWRN = function(node) return (minetest.registered_nodes[node.name] or {}).power end
|
||||
|
||||
-- Used to determine the already passed nodes while power distribution
|
||||
local Route = {}
|
||||
|
||||
local function in_range(val, min, max)
|
||||
if val < min then return min end
|
||||
if val > max then return max end
|
||||
return val
|
||||
end
|
||||
techage.power = {}
|
||||
|
||||
-- Consumer States
|
||||
local STOPPED = 1
|
||||
local NOPOWER = 2
|
||||
local RUNNING = 3
|
||||
|
||||
|
||||
local function pos_already_reached(pos)
|
||||
local key = minetest.hash_node_position(pos)
|
||||
@ -39,88 +40,21 @@ local function pos_already_reached(pos)
|
||||
return true
|
||||
end
|
||||
|
||||
local SideToDir = {B=1, R=2, F=3, L=4, D=5, U=6}
|
||||
|
||||
local function side_to_dir(param2, side)
|
||||
local dir = SideToDir[side]
|
||||
if dir < 5 then
|
||||
dir = (((dir - 1) + (param2 % 4)) % 4) + 1
|
||||
end
|
||||
return dir
|
||||
end
|
||||
|
||||
function techage.get_pos(pos, side)
|
||||
local node = minetest.get_node(pos)
|
||||
local dir = nil
|
||||
if node.name ~= "air" and node.name ~= "ignore" then
|
||||
dir = side_to_dir(node.param2, side)
|
||||
end
|
||||
return tubelib2.get_pos(pos, dir)
|
||||
end
|
||||
|
||||
local function set_conn_dirs(pos, sides)
|
||||
local tbl = {}
|
||||
local node = minetest.get_node(pos)
|
||||
if type(sides) == "function" then
|
||||
tbl = sides(pos, node)
|
||||
else
|
||||
for _,side in ipairs(sides) do
|
||||
tbl[#tbl+1] = tubelib2.Turn180Deg[side_to_dir(node.param2, side)]
|
||||
end
|
||||
end
|
||||
M(pos):set_string("power_dirs", minetest.serialize(tbl))
|
||||
end
|
||||
|
||||
local function valid_indir(pos, in_dir)
|
||||
local s = M(pos):get_string("power_dirs")
|
||||
if s == "" then
|
||||
local pwr = PWR(pos)
|
||||
if pwr then
|
||||
set_conn_dirs(pos, pwr.conn_sides)
|
||||
end
|
||||
end
|
||||
if s ~= "" then
|
||||
for _,dir in ipairs(minetest.deserialize(s)) do
|
||||
if dir == in_dir then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function valid_outdir(pos, out_dir)
|
||||
return valid_indir(pos, tubelib2.Turn180Deg[out_dir])
|
||||
end
|
||||
|
||||
-- Both nodes are from the same power network type?
|
||||
local function matching_nodes(pos, peer_pos)
|
||||
local tube_type1 = pos and PWR(pos) and PWR(pos).power_network.tube_type
|
||||
local tube_type2 = peer_pos and PWR(peer_pos) and PWR(peer_pos).power_network.tube_type
|
||||
return not tube_type1 or not tube_type2 or tube_type1 == tube_type2
|
||||
end
|
||||
|
||||
local function min(val, max)
|
||||
if val < 0 then return 0 end
|
||||
if val > max then return max end
|
||||
return val
|
||||
end
|
||||
|
||||
-- called from master every cycle (2 seconds)
|
||||
local function accounting(mem)
|
||||
-- defensive programming
|
||||
mem.needed1 = mem.needed1 or 0
|
||||
mem.needed2 = mem.needed2 or 0
|
||||
mem.available1 = mem.available1 or 0
|
||||
mem.available2 = mem.available2 or 0
|
||||
local function accounting(pos, mem)
|
||||
-- calculate the primary and secondary supply and demand
|
||||
mem.supply1 = min(mem.needed1 + mem.needed2, mem.available1)
|
||||
mem.demand1 = min(mem.needed1, mem.available1 + mem.available2)
|
||||
mem.supply2 = min(mem.demand1 - mem.supply1, mem.available2)
|
||||
mem.demand2 = min(mem.supply1 - mem.demand1, mem.available1)
|
||||
mem.reserve = (mem.available1 + mem.available2) > mem.needed1
|
||||
--print("needed = "..mem.needed1.."/"..mem.needed2..", available = "..mem.available1.."/"..mem.available2)
|
||||
--print("supply = "..mem.supply1.."/"..mem.supply2..", demand = "..mem.demand1.."/"..mem.demand2..", reserve = "..dump(mem.reserve))
|
||||
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
|
||||
--print("needed = "..mem.mst_needed1.."/"..mem.mst_needed2..", available = "..mem.mst_available1.."/"..mem.mst_available2)
|
||||
--print("supply = "..mem.mst_supply1.."/"..mem.mst_supply2..", demand = "..mem.mst_demand1.."/"..mem.mst_demand2..", reserve = "..mem.mst_reserve)
|
||||
end
|
||||
|
||||
local function connection_walk(pos, clbk)
|
||||
@ -137,6 +71,24 @@ local function connection_walk(pos, clbk)
|
||||
end
|
||||
end
|
||||
|
||||
local function consumer_turn_off(pos, mem)
|
||||
local pwr = PWR(pos)
|
||||
print("consumer_turn_off")
|
||||
if pwr and pwr.on_nopower then
|
||||
pwr.on_nopower(pos, mem)
|
||||
end
|
||||
mem.pwr_node_alive_cnt = 0
|
||||
mem.pwr_state = NOPOWER
|
||||
end
|
||||
|
||||
local function consumer_turn_on(pos, mem)
|
||||
local pwr = PWR(pos)
|
||||
print("consumer_turn_on")
|
||||
if pwr and pwr.on_power then
|
||||
pwr.on_power(pos, mem)
|
||||
end
|
||||
mem.pwr_state = RUNNING
|
||||
end
|
||||
|
||||
-- determine one "generating" node as master (largest hash number)
|
||||
local function determine_master(pos)
|
||||
@ -145,8 +97,10 @@ local function determine_master(pos)
|
||||
local hash = 0
|
||||
local master = nil
|
||||
connection_walk(pos, function(pos, mem)
|
||||
mem.generator_available = (mem.generator_available or 1) - 1
|
||||
if mem.generating and mem.generator_available > 0 then
|
||||
if (mem.pwr_node_alive_cnt or 0) >= 0 and
|
||||
(mem.pwr_available or 0) > 0 or
|
||||
(mem.pwr_available2 or 0) > 0 then -- active generator?
|
||||
|
||||
local new = minetest.hash_node_position(pos)
|
||||
if hash <= new then
|
||||
hash = new
|
||||
@ -162,302 +116,256 @@ local function store_master(pos, master_pos)
|
||||
Route = {}
|
||||
pos_already_reached(pos)
|
||||
connection_walk(pos, function(pos, mem)
|
||||
mem.master_pos = master_pos
|
||||
mem.is_master = false
|
||||
mem.pwr_master_pos = master_pos
|
||||
mem.pwr_is_master = false
|
||||
end)
|
||||
end
|
||||
|
||||
local function trigger_nodes(pos)
|
||||
Route = {}
|
||||
pos_already_reached(pos)
|
||||
connection_walk(pos, function(pos, mem)
|
||||
local pwr = PWR(pos)
|
||||
if pwr and pwr.on_power then
|
||||
pwr.on_power(pos)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Called from any generator on any power switching process
|
||||
-- and to determine a new master in case of a timeout
|
||||
local function on_power_switch(pos)
|
||||
--print("on_power_change"..S(pos))
|
||||
--local t = minetest.get_us_time()
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.master_pos = nil
|
||||
mem.is_master = nil
|
||||
-- used to check if generator is active
|
||||
mem.generator_available = 2
|
||||
|
||||
local mpos = determine_master(pos)
|
||||
store_master(pos, mpos)
|
||||
--print("store_master", S(pos), S(mpos))
|
||||
if mpos then
|
||||
local mem = tubelib2.get_mem(mpos)
|
||||
mem.is_master = true
|
||||
-- trigger all nodes so that we get a stable state again
|
||||
-- reset values for nect cycle
|
||||
mem.needed1 = 0
|
||||
mem.needed2 = 0
|
||||
mem.available1 = 0
|
||||
mem.available2 = 0
|
||||
trigger_nodes(mpos)
|
||||
accounting(tubelib2.get_mem(mpos))
|
||||
--t = minetest.get_us_time() - t
|
||||
--print("t = "..t)
|
||||
return mem
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Generic API functions
|
||||
--
|
||||
techage.power = {}
|
||||
|
||||
techage.power.power_switched = on_power_switch
|
||||
|
||||
-- Used to turn on/off the power by means of a power switch
|
||||
function techage.power.power_cut(pos, dir, cable, cut)
|
||||
local npos = vector.add(pos, tubelib2.Dir6dToVector[dir or 0])
|
||||
|
||||
local node = minetest.get_node(npos)
|
||||
if node.name ~= "techage:powerswitch_box" and
|
||||
M(npos):get_string("techage_hidden_nodename") ~= "techage:powerswitch_box" then
|
||||
return
|
||||
end
|
||||
|
||||
local mem = tubelib2.get_mem(npos)
|
||||
mem.interrupted_dirs = mem.interrupted_dirs or {}
|
||||
|
||||
if cut then
|
||||
mem.interrupted_dirs = {true, true, true, true, true, true}
|
||||
for dir,_ in pairs(mem.connections) do
|
||||
mem.interrupted_dirs[dir] = false
|
||||
on_power_switch(npos)
|
||||
trigger_nodes(npos)
|
||||
mem.interrupted_dirs[dir] = true
|
||||
end
|
||||
else
|
||||
mem.interrupted_dirs = {}
|
||||
on_power_switch(npos)
|
||||
end
|
||||
end
|
||||
|
||||
-- only for nodes with own 'conn_sides' and rotate function
|
||||
function techage.power.after_rotate_node(pos, cable)
|
||||
cable:after_dig_node(pos)
|
||||
set_conn_dirs(pos, PWR(pos).conn_sides)
|
||||
cable:after_place_node(pos)
|
||||
end
|
||||
|
||||
function techage.power.register_node(names, pwr_def)
|
||||
for _,name in ipairs(names) do
|
||||
local ndef = minetest.registered_nodes[name]
|
||||
if ndef then
|
||||
minetest.override_item(name, {
|
||||
power = {
|
||||
conn_sides = pwr_def.conn_sides or {"L", "R", "U", "D", "F", "B"},
|
||||
on_power = pwr_def.on_power,
|
||||
power_network = pwr_def.power_network,
|
||||
after_place_node = ndef.after_place_node,
|
||||
after_dig_node = ndef.after_dig_node,
|
||||
after_tube_update = ndef.after_tube_update,
|
||||
},
|
||||
-- after_place_node decorator
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
local pwr = PWR(pos)
|
||||
set_conn_dirs(pos, pwr.conn_sides)
|
||||
pwr.power_network:after_place_node(pos)
|
||||
if pwr.after_place_node then
|
||||
return pwr.after_place_node(pos, placer, itemstack, pointed_thing)
|
||||
end
|
||||
end,
|
||||
-- after_dig_node decorator
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
local pwr = PWRN(oldnode)
|
||||
pwr.power_network:after_dig_node(pos)
|
||||
minetest.after(0.1, tubelib2.del_mem, pos) -- At latest...
|
||||
if pwr.after_dig_node then
|
||||
return pwr.after_dig_node(pos, oldnode, oldmetadata, digger)
|
||||
end
|
||||
end,
|
||||
-- tubelib2 callback, called after any connection change
|
||||
after_tube_update = function(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
local pwr = PWR(pos)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.connections = mem.connections or {}
|
||||
if not peer_pos or not valid_indir(peer_pos, peer_in_dir)
|
||||
or not valid_outdir(pos, out_dir)
|
||||
or not matching_nodes(pos, peer_pos) then
|
||||
mem.connections[out_dir] = nil -- del connection
|
||||
else
|
||||
mem.connections[out_dir] = {pos = peer_pos, in_dir = peer_in_dir}
|
||||
end
|
||||
-- To be called delayed, so that all network connections have been established
|
||||
minetest.after(0.2, on_power_switch, pos)
|
||||
if pwr.after_tube_update then
|
||||
return pwr.after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
end
|
||||
end,
|
||||
})
|
||||
pwr_def.power_network:add_secondary_node_names({name})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function techage.power.after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir, power)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.connections = mem.connections or {}
|
||||
if not peer_pos or not valid_indir(peer_pos, peer_in_dir)
|
||||
or not valid_outdir(pos, out_dir)
|
||||
or not matching_nodes(pos, peer_pos) then
|
||||
mem.connections[out_dir] = nil -- del connection
|
||||
else
|
||||
mem.connections[out_dir] = {pos = peer_pos, in_dir = peer_in_dir}
|
||||
end
|
||||
-- To be called delayed, so that all network connections have been established
|
||||
minetest.after(0.2, on_power_switch, pos)
|
||||
if power.after_tube_update then
|
||||
return power.after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
end
|
||||
end
|
||||
|
||||
-- Called from every generator every 2 seconds
|
||||
function techage.power.power_distribution(pos)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
-- used to check if generator is active
|
||||
mem.generator_available = 2
|
||||
if mem.is_master then
|
||||
-- reset values for nect cycle
|
||||
mem.needed1 = 0
|
||||
mem.needed2 = 0
|
||||
mem.available1 = 0
|
||||
mem.available2 = 0
|
||||
trigger_nodes(pos, mem)
|
||||
accounting(mem)
|
||||
end
|
||||
end
|
||||
|
||||
function techage.power.consume_power(pos, needed)
|
||||
local master_pos = tubelib2.get_mem(pos).master_pos
|
||||
--print("consume_power", S(master_pos))
|
||||
if master_pos then
|
||||
local mem = tubelib2.get_mem(master_pos)
|
||||
local function handle_generator(mst_mem, mem, pos, power_available)
|
||||
-- for next cycle
|
||||
mem.needed1 = (mem.needed1 or 0) + needed
|
||||
mst_mem.mst_available1 = mst_mem.mst_available1 + power_available
|
||||
-- current cycle
|
||||
mem.demand1 = mem.demand1 or 0
|
||||
local val = math.min(needed, mem.demand1)
|
||||
mem.demand1 = mem.demand1 - val
|
||||
--return val
|
||||
if mem.reserve then -- TODO ????
|
||||
return needed
|
||||
mst_mem.mst_supply1 = mst_mem.mst_supply1 or 0
|
||||
if mst_mem.mst_supply1 < power_available then
|
||||
mem.pwr_provided = mst_mem.mst_supply1
|
||||
mst_mem.mst_supply1 = 0
|
||||
else
|
||||
mst_mem.mst_supply1 = mst_mem.mst_supply1 - power_available
|
||||
mem.pwr_provided = power_available
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function techage.power.provide_power(pos, provide)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if mem.is_master then
|
||||
-- nothing to do
|
||||
elseif mem.master_pos then
|
||||
mem = tubelib2.get_mem(mem.master_pos)
|
||||
else
|
||||
return 0
|
||||
end
|
||||
local function handle_consumer(mst_mem, mem, pos, power_needed)
|
||||
print("handle_consumer", mem.pwr_state)
|
||||
if mem.pwr_state == NOPOWER then
|
||||
--print("power_needed", power_needed,"mst_mem.demand1", mst_mem.mst_demand1)
|
||||
-- for next cycle
|
||||
mem.available1 = (mem.available1 or 0) + provide
|
||||
mst_mem.mst_needed1 = mst_mem.mst_needed1 + power_needed
|
||||
-- current cycle
|
||||
mem.supply1 = mem.supply1 or 0
|
||||
local val = math.min(provide, mem.supply1)
|
||||
mem.supply1 = mem.supply1 - val
|
||||
return val
|
||||
end
|
||||
|
||||
function techage.power.secondary_power(pos, provide, needed)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if mem.is_master then
|
||||
-- nothing to do
|
||||
elseif mem.master_pos then
|
||||
mem = tubelib2.get_mem(mem.master_pos)
|
||||
else
|
||||
return 0
|
||||
if (mst_mem.mst_demand1 or 0) - power_needed >= 0 then
|
||||
mst_mem.mst_demand1 = (mst_mem.mst_demand1 or 0) - power_needed
|
||||
consumer_turn_on(pos, mem)
|
||||
end
|
||||
elseif mem.pwr_state == RUNNING then
|
||||
-- for next cycle
|
||||
mem.available2 = (mem.available2 or 0) + provide
|
||||
mem.needed2 = (mem.needed2 or 0) + needed
|
||||
|
||||
-- defensive programming
|
||||
mem.supply2 = mem.supply2 or 0
|
||||
mem.demand2 = mem.demand2 or 0
|
||||
mst_mem.mst_needed1 = mst_mem.mst_needed1 + power_needed
|
||||
-- current cycle
|
||||
mst_mem.mst_demand1 = (mst_mem.mst_demand1 or 0) - power_needed
|
||||
if mst_mem.mst_demand1 < 0 then
|
||||
mst_mem.mst_demand1 = 0
|
||||
consumer_turn_off(pos, mem)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function handle_secondary(mst_mem, mem, pos, provides, needed)
|
||||
-- for next cycle
|
||||
mst_mem.mst_available2 = (mst_mem.mst_available2 or 0) + provides
|
||||
mst_mem.mst_needed2 = (mst_mem.mst_needed2 or 0) + needed
|
||||
-- check as generator
|
||||
if mem.supply2 > 0 then
|
||||
local val = math.min(provide, mem.supply2)
|
||||
mem.supply2 = mem.supply2 - val
|
||||
return val
|
||||
end
|
||||
mst_mem.mst_supply2 = mst_mem.mst_supply2 or 0
|
||||
mst_mem.mst_demand2 = mst_mem.mst_demand2 or 0
|
||||
if mst_mem.mst_supply2 > 0 then
|
||||
local val = math.min(provides, mst_mem.mst_supply2)
|
||||
mst_mem.mst_supply2 = mst_mem.mst_supply2 - val
|
||||
mem.pwr_provided = val
|
||||
-- check as consumer
|
||||
if mem.demand2 > 0 then
|
||||
local val = math.min(needed, mem.demand2)
|
||||
mem.demand2 = mem.demand2 - val
|
||||
return -val
|
||||
end
|
||||
return 0
|
||||
elseif mst_mem.mst_demand2 > 0 then
|
||||
local val = math.min(needed, mst_mem.mst_demand2)
|
||||
mst_mem.mst_demand2 = mst_mem.mst_demand2 - val
|
||||
mem.pwr_provided = -val
|
||||
else
|
||||
mem.pwr_provided = 0
|
||||
end
|
||||
|
||||
function techage.power.power_available(pos, needed)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if mem.master_pos then
|
||||
mem = tubelib2.get_mem(mem.master_pos)
|
||||
if needed then
|
||||
-- for next cycle
|
||||
mem.needed1 = (mem.needed1 or 0) + needed
|
||||
end
|
||||
return mem.reserve
|
||||
|
||||
local function trigger_nodes(mst_pos, mst_mem)
|
||||
Route = {}
|
||||
pos_already_reached(mst_pos)
|
||||
connection_walk(mst_pos, function(pos, mem)
|
||||
mem.pwr_node_alive_cnt = (mem.pwr_node_alive_cnt or 1) - 1
|
||||
mem.pwr_power_provided_cnt = 2
|
||||
--print("trigger_nodes", mem.pwr_node_alive_cnt, mem.pwr_available2 or mem.pwr_available or mem.pwr_needed)
|
||||
if mem.pwr_node_alive_cnt >= 0 then
|
||||
if mem.pwr_available then
|
||||
handle_generator(mst_mem, mem, pos, mem.pwr_available)
|
||||
elseif mem.pwr_needed then
|
||||
handle_consumer(mst_mem, mem, pos, mem.pwr_needed)
|
||||
elseif mem.pwr_available2 then
|
||||
handle_secondary(mst_mem, mem, pos, mem.pwr_available2, mem.pwr_needed2)
|
||||
end
|
||||
end
|
||||
end)
|
||||
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)
|
||||
--print("determine_new_master", S(mpos))
|
||||
store_master(pos, mpos)
|
||||
if mpos then
|
||||
tubelib2.get_mem(mpos).pwr_is_master = true
|
||||
elseif was_master then -- no master any more
|
||||
-- delete data
|
||||
local mmem = tubelib2.get_mem(mpos)
|
||||
mmem.mst_supply1 = 0
|
||||
mmem.mst_supply2 = 0
|
||||
mmem.mst_reserve = 0
|
||||
end
|
||||
return was_master or mem.pwr_is_master
|
||||
end
|
||||
|
||||
-- called from master position
|
||||
local function power_distribution(pos, mem)
|
||||
mem.mst_needed1 = 0
|
||||
mem.mst_needed2 = 0
|
||||
mem.mst_available1 = 0
|
||||
mem.mst_available2 = 0
|
||||
trigger_nodes(pos, mem)
|
||||
accounting(pos, mem)
|
||||
end
|
||||
|
||||
--
|
||||
-- Power API functions
|
||||
--
|
||||
|
||||
-- To be called for each network change from any node
|
||||
function techage.power.network_changed(pos, mem)
|
||||
print("network_changed")
|
||||
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 next(mem.connections) then -- isolated?
|
||||
if mem.pwr_needed then -- consumer?
|
||||
consumer_turn_off(pos, mem)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Generator related functions
|
||||
--
|
||||
function techage.power.generator_start(pos, mem, available)
|
||||
mem.pwr_node_alive_cnt = 2
|
||||
mem.pwr_cycle_time = 2
|
||||
mem.pwr_available = available
|
||||
if determine_new_master(pos, mem) then -- new master
|
||||
power_distribution(pos, mem)
|
||||
end
|
||||
end
|
||||
|
||||
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)
|
||||
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)
|
||||
end
|
||||
return mem.pwr_provided
|
||||
end
|
||||
|
||||
--
|
||||
-- Consumer related functions
|
||||
--
|
||||
function techage.power.consumer_alive(pos, mem)
|
||||
print("consumer_alive", mem.pwr_power_provided_cnt)
|
||||
mem.pwr_power_provided_cnt = (mem.pwr_power_provided_cnt or 0) - (mem.pwr_cycle_time or 2)/2
|
||||
if mem.pwr_power_provided_cnt >= 0 then
|
||||
mem.pwr_node_alive_cnt = (mem.pwr_cycle_time or 2)/2 + 1
|
||||
else
|
||||
consumer_turn_off(pos, mem)
|
||||
end
|
||||
end
|
||||
|
||||
function techage.power.consumer_start(pos, mem, cycle_time, needed)
|
||||
mem.pwr_cycle_time = cycle_time
|
||||
mem.pwr_power_provided_cnt = 0
|
||||
mem.pwr_node_alive_cnt = 2
|
||||
mem.pwr_needed = needed
|
||||
mem.pwr_state = NOPOWER
|
||||
end
|
||||
|
||||
function techage.power.consumer_stop(pos, mem)
|
||||
mem.pwr_power_provided_cnt = 0
|
||||
mem.pwr_node_alive_cnt = 0
|
||||
mem.pwr_needed = 0
|
||||
mem.pwr_state = STOPPED
|
||||
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 >= 0 then
|
||||
mem.mst_reserve = mem.mst_reserve - needed
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function techage.power.power_accounting(pos)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if mem.master_pos then
|
||||
mem = tubelib2.get_mem(mem.master_pos)
|
||||
return "\nGenerators = "..mem.available1.."\nAkkus = "..mem.available2.."\nMachines = "..mem.needed1.."\n"
|
||||
-- Power terminal function
|
||||
function techage.power.power_accounting(pos, mem)
|
||||
if mem.pwr_master_pos then
|
||||
mem = tubelib2.get_mem(mem.pwr_master_pos)
|
||||
return {
|
||||
prim_available = mem.mst_available1,
|
||||
sec_available = mem.mst_available2,
|
||||
prim_needed = mem.mst_needed1,
|
||||
sec_needed = mem.mst_needed2,
|
||||
}
|
||||
end
|
||||
return "no power"
|
||||
return {
|
||||
prim_available = 0,
|
||||
sec_available = 0,
|
||||
prim_needed = 0,
|
||||
sec_needed = 0,
|
||||
}
|
||||
end
|
||||
|
||||
function techage.power.percent(max_val, curr_val)
|
||||
return math.min(math.ceil(((curr_val or 0) * 100.0) / (max_val or 1.0)), 100)
|
||||
--
|
||||
-- Akku related functions
|
||||
--
|
||||
function techage.power.secondary_start(pos, mem, available, needed)
|
||||
mem.pwr_node_alive_cnt = 2
|
||||
mem.pwr_could_provide = available
|
||||
mem.pwr_could_need = needed
|
||||
if determine_new_master(pos, mem) then -- new master
|
||||
power_distribution(pos, mem)
|
||||
end
|
||||
end
|
||||
|
||||
function techage.power.formspec_load_bar(charging, max_val)
|
||||
local percent
|
||||
charging = charging or 0
|
||||
max_val = max_val or 1
|
||||
if charging ~= 0 then
|
||||
percent = 50 + math.ceil((charging * 50.0) / max_val)
|
||||
function techage.power.secondary_stop(pos, mem)
|
||||
mem.pwr_node_alive_cnt = 0
|
||||
mem.pwr_could_provide = 0
|
||||
mem.pwr_could_need = 0
|
||||
if determine_new_master(pos, mem) then -- last available master
|
||||
power_distribution(pos, mem)
|
||||
end
|
||||
end
|
||||
|
||||
if charging > 0 then
|
||||
return "techage_form_level_off.png^[lowpart:"..percent..":techage_form_level_charge.png"
|
||||
elseif charging < 0 then
|
||||
return "techage_form_level_unload.png^[lowpart:"..percent..":techage_form_level_off.png"
|
||||
function techage.power.secondary_alive(pos, mem, capa_curr, capa_max)
|
||||
--print("secondary_alive")
|
||||
if capa_curr >= capa_max then
|
||||
mem.pwr_available2, mem.pwr_needed2 = mem.pwr_could_provide, 0 -- can provide only
|
||||
elseif capa_curr <= 0 then
|
||||
mem.pwr_available2, mem.pwr_needed2 = 0, mem.pwr_could_need -- can deliver only
|
||||
else
|
||||
return "techage_form_level_off.png"
|
||||
end
|
||||
mem.pwr_available2, mem.pwr_needed2 = mem.pwr_could_provide, mem.pwr_could_need
|
||||
end
|
||||
|
||||
function techage.power.formspec_power_bar(max_power, current_power)
|
||||
local percent = techage.power.percent(max_power, current_power)
|
||||
percent = (percent + 5) / 1.22 -- texture correction
|
||||
return "techage_form_level_bg.png^[lowpart:"..percent..":techage_form_level_fg.png"
|
||||
mem.pwr_node_alive_cnt = 2
|
||||
if mem.pwr_is_master then
|
||||
--print("secondary_alive is master")
|
||||
power_distribution(pos, mem)
|
||||
end
|
||||
|
||||
|
||||
function techage.power.side_to_outdir(pos, side)
|
||||
local node = minetest.get_node(pos)
|
||||
return side_to_dir(node.param2, side)
|
||||
return mem.pwr_provided
|
||||
end
|
224
power/power2.lua
Normal file
224
power/power2.lua
Normal file
@ -0,0 +1,224 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Power helper functions
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||
local P = minetest.string_to_pos
|
||||
local M = minetest.get_meta
|
||||
-- Techage Related Data
|
||||
local PWR = function(pos) return (minetest.registered_nodes[minetest.get_node(pos).name] or {}).power end
|
||||
local PWRN = function(node) return (minetest.registered_nodes[node.name] or {}).power end
|
||||
|
||||
local network_changed = techage.power.network_changed
|
||||
|
||||
local SideToDir = {B=1, R=2, F=3, L=4, D=5, U=6}
|
||||
|
||||
local function side_to_dir(param2, side)
|
||||
local dir = SideToDir[side]
|
||||
if dir < 5 then
|
||||
dir = (((dir - 1) + (param2 % 4)) % 4) + 1
|
||||
end
|
||||
return dir
|
||||
end
|
||||
|
||||
local function set_conn_dirs(pos, sides)
|
||||
local tbl = {}
|
||||
local node = minetest.get_node(pos)
|
||||
if type(sides) == "function" then
|
||||
tbl = sides(pos, node)
|
||||
else
|
||||
for _,side in ipairs(sides) do
|
||||
tbl[#tbl+1] = tubelib2.Turn180Deg[side_to_dir(node.param2, side)]
|
||||
end
|
||||
end
|
||||
M(pos):set_string("power_dirs", minetest.serialize(tbl))
|
||||
end
|
||||
|
||||
local function valid_indir(pos, in_dir)
|
||||
local s = M(pos):get_string("power_dirs")
|
||||
if s == "" then
|
||||
local pwr = PWR(pos)
|
||||
if pwr then
|
||||
set_conn_dirs(pos, pwr.conn_sides)
|
||||
end
|
||||
end
|
||||
if s ~= "" then
|
||||
for _,dir in ipairs(minetest.deserialize(s)) do
|
||||
if dir == in_dir then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function valid_outdir(pos, out_dir)
|
||||
return valid_indir(pos, tubelib2.Turn180Deg[out_dir])
|
||||
end
|
||||
|
||||
-- Both nodes are from the same power network type?
|
||||
local function matching_nodes(pos, peer_pos)
|
||||
local tube_type1 = pos and PWR(pos) and PWR(pos).power_network.tube_type
|
||||
local tube_type2 = peer_pos and PWR(peer_pos) and PWR(peer_pos).power_network.tube_type
|
||||
return not tube_type1 or not tube_type2 or tube_type1 == tube_type2
|
||||
end
|
||||
|
||||
function techage.get_pos(pos, side)
|
||||
local node = minetest.get_node(pos)
|
||||
local dir = nil
|
||||
if node.name ~= "air" and node.name ~= "ignore" then
|
||||
dir = side_to_dir(node.param2, side)
|
||||
end
|
||||
return tubelib2.get_pos(pos, dir)
|
||||
end
|
||||
|
||||
-- only for nodes with own 'conn_sides' and rotate function
|
||||
function techage.power.after_rotate_node(pos, cable)
|
||||
cable:after_dig_node(pos)
|
||||
set_conn_dirs(pos, PWR(pos).conn_sides)
|
||||
cable:after_place_node(pos)
|
||||
end
|
||||
|
||||
function techage.power.register_node(names, pwr_def)
|
||||
for _,name in ipairs(names) do
|
||||
local ndef = minetest.registered_nodes[name]
|
||||
if ndef then
|
||||
minetest.override_item(name, {
|
||||
power = {
|
||||
conn_sides = pwr_def.conn_sides or {"L", "R", "U", "D", "F", "B"},
|
||||
on_power = pwr_def.on_power,
|
||||
on_nopower = pwr_def.on_nopower,
|
||||
power_network = pwr_def.power_network,
|
||||
after_place_node = ndef.after_place_node,
|
||||
after_dig_node = ndef.after_dig_node,
|
||||
after_tube_update = ndef.after_tube_update,
|
||||
},
|
||||
-- after_place_node decorator
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
local pwr = PWR(pos)
|
||||
set_conn_dirs(pos, pwr.conn_sides)
|
||||
pwr.power_network:after_place_node(pos)
|
||||
if pwr.after_place_node then
|
||||
return pwr.after_place_node(pos, placer, itemstack, pointed_thing)
|
||||
end
|
||||
end,
|
||||
-- after_dig_node decorator
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
local pwr = PWRN(oldnode)
|
||||
pwr.power_network:after_dig_node(pos)
|
||||
minetest.after(0.1, tubelib2.del_mem, pos) -- At latest...
|
||||
if pwr.after_dig_node then
|
||||
return pwr.after_dig_node(pos, oldnode, oldmetadata, digger)
|
||||
end
|
||||
end,
|
||||
-- tubelib2 callback, called after any connection change
|
||||
after_tube_update = function(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
local pwr = PWR(pos)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.connections = mem.connections or {}
|
||||
if not peer_pos or not valid_indir(peer_pos, peer_in_dir)
|
||||
or not valid_outdir(pos, out_dir)
|
||||
or not matching_nodes(pos, peer_pos) then
|
||||
mem.connections[out_dir] = nil -- del connection
|
||||
else
|
||||
mem.connections[out_dir] = {pos = peer_pos, in_dir = peer_in_dir}
|
||||
end
|
||||
-- To be called delayed, so that all network connections have been established
|
||||
minetest.after(0.2, network_changed, pos, mem)
|
||||
if pwr.after_tube_update then
|
||||
return pwr.after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
end
|
||||
end,
|
||||
})
|
||||
pwr_def.power_network:add_secondary_node_names({name})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function techage.power.after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir, power)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.connections = mem.connections or {}
|
||||
if not peer_pos or not valid_indir(peer_pos, peer_in_dir)
|
||||
or not valid_outdir(pos, out_dir)
|
||||
or not matching_nodes(pos, peer_pos) then
|
||||
mem.connections[out_dir] = nil -- del connection
|
||||
else
|
||||
mem.connections[out_dir] = {pos = peer_pos, in_dir = peer_in_dir}
|
||||
end
|
||||
-- To be called delayed, so that all network connections have been established
|
||||
minetest.after(0.2, network_changed, pos, mem)
|
||||
if power.after_tube_update then
|
||||
return power.after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function techage.power.percent(max_val, curr_val)
|
||||
return math.min(math.ceil(((curr_val or 0) * 100.0) / (max_val or 1.0)), 100)
|
||||
end
|
||||
|
||||
function techage.power.formspec_load_bar(charging, max_val)
|
||||
local percent
|
||||
charging = charging or 0
|
||||
max_val = max_val or 1
|
||||
if charging ~= 0 then
|
||||
percent = 50 + math.ceil((charging * 50.0) / max_val)
|
||||
end
|
||||
|
||||
if charging > 0 then
|
||||
return "techage_form_level_off.png^[lowpart:"..percent..":techage_form_level_charge.png"
|
||||
elseif charging < 0 then
|
||||
return "techage_form_level_unload.png^[lowpart:"..percent..":techage_form_level_off.png"
|
||||
else
|
||||
return "techage_form_level_off.png"
|
||||
end
|
||||
end
|
||||
|
||||
function techage.power.formspec_power_bar(max_power, current_power)
|
||||
local percent = techage.power.percent(max_power, current_power)
|
||||
percent = (percent + 5) / 1.22 -- texture correction
|
||||
return "techage_form_level_bg.png^[lowpart:"..percent..":techage_form_level_fg.png"
|
||||
end
|
||||
|
||||
|
||||
function techage.power.side_to_outdir(pos, side)
|
||||
local node = minetest.get_node(pos)
|
||||
return side_to_dir(node.param2, side)
|
||||
end
|
||||
|
||||
-- Used to turn on/off the power by means of a power switch
|
||||
function techage.power.power_cut(pos, dir, cable, cut)
|
||||
local npos = vector.add(pos, tubelib2.Dir6dToVector[dir or 0])
|
||||
|
||||
local node = minetest.get_node(npos)
|
||||
if node.name ~= "techage:powerswitch_box" and
|
||||
M(npos):get_string("techage_hidden_nodename") ~= "techage:powerswitch_box" then
|
||||
return
|
||||
end
|
||||
|
||||
local mem = tubelib2.get_mem(npos)
|
||||
mem.interrupted_dirs = mem.interrupted_dirs or {}
|
||||
|
||||
if cut then
|
||||
mem.interrupted_dirs = {true, true, true, true, true, true}
|
||||
for dir,_ in pairs(mem.connections) do
|
||||
mem.interrupted_dirs[dir] = false
|
||||
techage.power.network_changed(pos, mem)
|
||||
mem.interrupted_dirs[dir] = true
|
||||
end
|
||||
else
|
||||
mem.interrupted_dirs = {}
|
||||
techage.power.network_changed(pos, mem)
|
||||
end
|
||||
end
|
||||
|
@ -74,7 +74,8 @@ local function read_state(itemstack, user, pointed_thing)
|
||||
elseif ndef and ndef.description then
|
||||
if ndef.is_power_available then
|
||||
local power = ndef.is_power_available(pos)
|
||||
minetest.chat_send_player(user:get_player_name(), ndef.description..": power = "..power.." ")
|
||||
local text = "\nGenerators = "..power.prim_available.."\nAkkus = "..power.sec_available.."\nMachines = "..power.prim_needed.."\n"
|
||||
minetest.chat_send_player(user:get_player_name(), ndef.description..": power = "..text)
|
||||
end
|
||||
itemstack:add_wear(65636/200)
|
||||
return itemstack
|
||||
|
Loading…
Reference in New Issue
Block a user