power distribution reworked, bugs fixed

master
Joachim Stolberg 2019-08-01 22:31:43 +02:00
parent 7db45b187c
commit 567bd040b7
20 changed files with 884 additions and 575 deletions

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ Techage, go through 4 tech ages in search of wealth and power.
### License
Copyright (C) 2019 Joachim Stolberg
Code: Licensed under the GNU LGPL version 2.1 or later. See LICENSE.txt
Code: Licensed under the GNU GPL version 3 or later. See LICENSE.txt
Textures: CC BY-SA 3.0

View File

@ -22,6 +22,7 @@ local TA3_Power = techage.SteamPipe
local TA4_Power = techage.ElectricCable
local provide_power = techage.power.provide_power
local power_switched = techage.power.power_switched
local power_distribution = techage.power.power_distribution
local STANDBY_TICKS = 4
local COUNTDOWN_TICKS = 4
@ -80,15 +81,28 @@ local State4 = techage.NodeStates:new({
stop_node = stop_node,
})
local function node_timer(pos, elapsed)
local function on_power(pos)
local mem = tubelib2.get_mem(pos)
if mem.generating then
mem.provided = provide_power(pos, PWR_CAPA)
return true
else
mem.provided = 0
end
return false
mem.trigger = 2
end
local function node_timer(pos, elapsed)
local mem = tubelib2.get_mem(pos)
if mem.generating then
power_distribution(pos)
mem.trigger = (mem.trigger or 1) - 1
if mem.trigger <= 0 then
-- power distribution timeout
--print("source not triggered")
power_switched(pos)
end
end
return mem.generating
end
local tStates = {0, State2, State3, State4}
@ -202,14 +216,17 @@ minetest.register_node("techage:t4_source", {
techage.power.register_node({"techage:t2_source"}, {
conn_sides = {"R"},
power_network = TA2_Power,
on_power = on_power,
})
techage.power.register_node({"techage:t3_source"}, {
conn_sides = {"R"},
power_network = TA3_Power,
on_power = on_power,
})
techage.power.register_node({"techage:t4_source"}, {
conn_sides = {"R"},
power_network = TA4_Power,
on_power = on_power,
})

View File

@ -26,7 +26,7 @@ local M = minetest.get_meta
local CRD = function(pos) return (minetest.registered_nodes[minetest.get_node(pos).name] or {}).consumer end
local CRDN = function(node) return (minetest.registered_nodes[node.name] or {}).consumer end
local CYCLE_TIME = 2 -- required from power
--local CYCLE_TIME = 2 -- required from power
local consume_power = techage.power.consume_power
local power_available = techage.power.power_available
@ -43,31 +43,39 @@ end
local function stop_node(pos, mem, state)
end
local function on_power(pos)
local crd = CRD(pos)
local mem = tubelib2.get_mem(pos)
local state = mem.techage_state
mem.node_loaded = (mem.node_loaded or 1) - 1
if mem.node_loaded >= 0 then
if techage.needs_power(mem)then
local got = consume_power(pos, crd.power_consumption)
if got < crd.power_consumption then
crd.State:nopower(pos, mem)
end
elseif state == techage.STANDBY and not power_available(pos) then
crd.State:nopower(pos, mem)
elseif state == techage.NOPOWER and power_available(pos) then
crd.State:start(pos, mem)
end
mem.power_available = true
end
end
local function node_timer(pos, elapsed)
local crd = CRD(pos)
local mem = tubelib2.get_mem(pos)
local state = mem.techage_state
if techage.needs_power(mem) then
local got = consume_power(pos, crd.power_consumption)
if got < crd.power_consumption then
crd.State:nopower(pos, mem)
end
elseif state == techage.STANDBY then
if crd.power_consumption > 0 and not power_available(pos) then
crd.State:nopower(pos, mem)
end
elseif state == techage.NOPOWER and power_available(pos) then
crd.State.start_from_timer(crd.State, pos, mem)
if crd.power_consumption > 0 and not mem.power_available then
crd.State:nopower(pos, mem)
end
-- call the secondary timer routine with the requested frequency
mem.power_available = false
-- node cycle time / power cycle time + security surcharge
mem.node_loaded = crd.cycle_time/2 + 1
-- call the node timer routine
if techage.is_operational(mem) then
mem.conn_next_call = mem.conn_next_call or 0
mem.conn_cycle_timer = (mem.conn_cycle_timer or 0) + CYCLE_TIME
--print(mem.conn_next_call, mem.conn_cycle_timer)
if mem.conn_cycle_timer >= mem.conn_next_call then
crd.node_timer(pos, crd.cycle_time)
mem.conn_next_call = mem.conn_next_call + crd.cycle_time
end
crd.node_timer(pos, crd.cycle_time)
end
return crd.State:is_active(mem)
end
@ -124,7 +132,7 @@ function techage.register_consumer(base_name, inv_name, tiles, tNode, validState
node_name_passive = name_pas,
node_name_active = name_act,
infotext_name = name_inv,
cycle_time = CYCLE_TIME,
cycle_time = tNode.cycle_time,
standby_ticks = tNode.standby_ticks,
formspec_func = tNode.formspec,
on_state_change = tNode.on_state_change,
@ -230,6 +238,7 @@ function techage.register_consumer(base_name, inv_name, tiles, tNode, validState
techage.power.register_node({name_pas, name_act}, {
conn_sides = {"F", "B"},
power_network = power_network,
on_power = on_power,
})
end
techage.register_node({name_pas, name_act}, tNode.tubing)

View File

@ -200,7 +200,7 @@ function NodeStates:stop(pos, mem)
return true
end
function NodeStates:start(pos, mem, called_from_on_timer)
function NodeStates:start(pos, mem)
local state = mem.techage_state or STOPPED
if state ~= RUNNING and state ~= FAULT then
if not self.can_start(pos, mem, state) then
@ -212,10 +212,6 @@ function NodeStates:start(pos, mem, called_from_on_timer)
self.start_node(pos, mem, state)
end
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
end
if self.node_name_active then
swap_node(pos, self.node_name_active)
end
@ -239,16 +235,17 @@ function NodeStates:start(pos, mem, called_from_on_timer)
end
-- to be used from node timer functions
function NodeStates:start_from_timer(pos, mem, called_from_on_timer)
minetest.after(0.1, self.start, self, pos, mem)
function NodeStates:start_from_timer(pos, mem)
local state = mem.techage_state or STOPPED
if state ~= RUNNING and state ~= FAULT then
minetest.after(0.1, self.start, self, pos, mem)
end
end
function NodeStates:standby(pos, mem)
local state = mem.techage_state or STOPPED
if state == RUNNING then
mem.techage_state = STANDBY
-- timer has to be stopped once to be able to be restarted
self.stop_timer = true
if self.node_name_passive then
swap_node(pos, self.node_name_passive)
end
@ -276,8 +273,6 @@ function NodeStates:blocked(pos, mem)
local state = mem.techage_state or STOPPED
if state == RUNNING then
mem.techage_state = BLOCKED
-- timer has to be stopped once to be able to be restarted
self.stop_timer = true
if self.node_name_passive then
swap_node(pos, self.node_name_passive)
end
@ -304,8 +299,6 @@ function NodeStates:nopower(pos, mem)
local state = mem.techage_state or RUNNING
if state ~= STOPPED then
mem.techage_state = NOPOWER
-- timer has to be stopped once to be able to be restarted
self.stop_timer = true
if self.node_name_passive then
swap_node(pos, self.node_name_passive)
end
@ -359,10 +352,6 @@ end
-- keep the timer running?
function NodeStates:is_active(mem)
local state = mem.techage_state or STOPPED
if self.stop_timer == true then
self.stop_timer = false
return false
end
return state < FAULT
end
@ -387,7 +376,7 @@ end
-- and keep the node in state RUNNING
function NodeStates:keep_running(pos, mem, val, num_items)
-- set to RUNNING if not already done
self:start(pos, mem, true)
self:start_from_timer(pos, mem)
mem.techage_countdown = val or 4
mem.techage_item_meter = (mem.techage_item_meter or 0) + (num_items or 1)
end

View File

@ -23,6 +23,7 @@ local PWR_CAPA = 3000
local Power = techage.ElectricCable
local secondary_power = techage.power.secondary_power
local power_switched = techage.power.power_switched
local power_distribution = techage.power.power_distribution
local function in_range(val, min, max)
if val < min then return min end
@ -65,7 +66,7 @@ local State = techage.NodeStates:new({
stop_node = stop_node,
})
local function node_timer(pos, elapsed)
local function on_power(pos)
local mem = tubelib2.get_mem(pos)
mem.capa = mem.capa or 0
if mem.generating then
@ -79,12 +80,27 @@ local function node_timer(pos, elapsed)
end
mem.capa = mem.capa - mem.delivered
mem.capa = in_range(mem.capa, 0, PWR_CAPA)
mem.trigger = 2
return true
end
mem.delivered = 0
return false
end
local function node_timer(pos, elapsed)
local mem = tubelib2.get_mem(pos)
if mem.generating then
power_distribution(pos)
mem.trigger = (mem.trigger or 1) - 1
if mem.trigger <= 0 then
power_switched(pos)
end
return true
else
mem.provided = 0
end
return false
end
local function on_receive_fields(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
@ -168,6 +184,7 @@ minetest.register_node("techage:ta3_akku", {
techage.power.register_node({"techage:ta3_akku"}, {
conn_sides = {"R"},
power_network = Power,
on_power = on_power,
})
techage.register_entry_page("ta3ps", "akku",

View File

@ -52,7 +52,7 @@ local function node_timer(pos, elapsed)
if mem.burn_cycles <= 0 then
local taken = firebox.get_fuel(pos)
if taken then
mem.burn_cycles = firebox.Burntime[taken:get_name()] / CYCLE_TIME * BURN_CYCLE_FACTOR
mem.burn_cycles = (firebox.Burntime[taken:get_name()] or 1) / CYCLE_TIME * BURN_CYCLE_FACTOR
mem.burn_cycles_total = mem.burn_cycles
else
mem.running = false

View File

@ -24,6 +24,7 @@ local PWR_CAPA = 80
local Cable = techage.ElectricCable
local provide_power = techage.power.provide_power
local power_switched = techage.power.power_switched
local power_distribution = techage.power.power_distribution
local function formspec(self, pos, mem)
return "size[8,7]"..
@ -66,22 +67,33 @@ local State = techage.NodeStates:new({
stop_node = stop_node,
})
local function node_timer(pos, elapsed)
local function on_power(pos)
local mem = tubelib2.get_mem(pos)
--print("generator", mem.triggered, mem.generating, PWR_CAPA * (mem.power_level or 0))
mem.triggered = mem.triggered or 0
if mem.triggered > 0 and mem.generating then
mem.provided = provide_power(pos, PWR_CAPA * (mem.power_level or 0))
mem.triggered = mem.triggered - 1
State:keep_running(pos, mem, COUNTDOWN_TICKS)
elseif mem.generating then -- trigger missing
State:stop(pos, mem)
mem.generating = 0
mem.provided = 0
if mem.generating then
mem.provided = provide_power(pos, PWR_CAPA)
else
mem.provided = 0
end
return State:is_active(mem)
mem.power_available = 2
end
local function node_timer(pos, elapsed)
local mem = tubelib2.get_mem(pos)
if mem.generating then
power_distribution(pos)
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
power_switched(pos)
State:stop(pos, mem)
mem.generating = 0
mem.provided = 0
end
else
mem.provided = 0
end
return mem.generating
end
local function on_receive_fields(pos, formname, fields, player)
@ -191,6 +203,7 @@ minetest.register_craft({
techage.power.register_node({"techage:generator", "techage:generator_on"}, {
conn_sides = {"R"},
power_network = Cable,
on_power = on_power,
})
-- for logical communication

View File

@ -36,23 +36,47 @@ local function swap_node(pos, name)
minetest.swap_node(pos, node)
end
local function node_timer(pos, elapsed)
local function on_power(pos)
local mem = tubelib2.get_mem(pos)
if mem.running then
mem.timer_running = (mem.timer_running or 1) - 1
if mem.timer_running >= 0 then
local got = consume_power(pos, PWR_NEEDED)
if got < PWR_NEEDED then
swap_node(pos, "techage:ta3_booster")
infotext(pos, "no power")
mem.running = false
else
swap_node(pos, "techage:ta3_booster_on")
infotext(pos, "running")
mem.power_available = 2
minetest.sound_play("techage_booster", {
pos = pos,
gain = 1,
max_hear_distance = 7})
end
return true
else
swap_node(pos, "techage:ta3_booster")
infotext(pos, "stopped")
mem.running = false
end
end
local function node_timer(pos, elapsed)
local mem = tubelib2.get_mem(pos)
mem.power_available = (mem.power_available or 1) - 1
if mem.running and mem.power_available < 0 then
swap_node(pos, "techage:ta3_booster")
mem.running = false
return false
end
mem.timer_running = CYCLE_TIME/2 + 1
return true
end
local function on_rightclick(pos, node, clicker)
if mem.running then
minetest.get_node_timer(pos):start(CYCLE_TIME)
end
swap_node(pos, "techage:ta3_booster")
return false
end
minetest.register_node("techage:ta3_booster", {
@ -125,6 +149,7 @@ minetest.register_node("techage:ta3_booster_on", {
techage.power.register_node({"techage:ta3_booster", "techage:ta3_booster_on"}, {
power_network = Power,
conn_sides = {"F", "B", "U", "D", "L"},
on_power = on_power,
})
-- for intra machine communication
@ -135,7 +160,7 @@ techage.register_node({"techage:ta3_booster", "techage:ta3_booster_on"}, {
if topic == "power" then
return mem.running
elseif topic == "start" then
if power_available(pos, PWR_NEEDED) then
if power_available(pos, 0) then
mem.running = true
node_timer(pos, 2)
infotext(pos, "running")
@ -147,7 +172,7 @@ techage.register_node({"techage:ta3_booster", "techage:ta3_booster_on"}, {
mem.running = false
swap_node(pos, "techage:ta3_booster")
minetest.get_node_timer(pos):stop()
if mem.has_power then
if mem.power_available then
infotext(pos, "stopped")
else
infotext(pos, "no power")

View File

@ -38,7 +38,7 @@ local function node_timer(pos, elapsed)
if mem.burn_cycles <= 0 then
local taken = firebox.get_fuel(pos)
if taken then
mem.burn_cycles = firebox.Burntime[taken:get_name()] / CYCLE_TIME
mem.burn_cycles = (firebox.Burntime[taken:get_name()] or 1) / CYCLE_TIME
mem.burn_cycles_total = mem.burn_cycles
else
stop_firebox(pos, mem)

View File

@ -137,8 +137,8 @@ else
-- Test
dofile(MP.."/recipe_checker.lua")
--dofile(MP.."/.test/sink.lua")
--dofile(MP.."/.test/source.lua")
--dofile(MP.."/.test/akku.lua")
dofile(MP.."/.test/sink.lua")
dofile(MP.."/.test/source.lua")
dofile(MP.."/.test/akku.lua")
--dofile(MP.."/.test/switch.lua")
end

View File

@ -26,9 +26,7 @@ local function handler(player_name, node, itemstack, digparams)
if minetest.get_item_group(node.name, "stone") > 0 then
-- Remove item from players inventory or from the world
local ndef = minetest.registered_nodes[node.name]
print(1)
if ndef then
print(2)
local item = ItemStack(ndef.drop or node.name)
local inv = minetest.get_inventory({type="player", name=player_name})
if inv:room_for_item("main", item) then

View File

@ -22,7 +22,8 @@ end
local function on_power(pos)
local mem = tubelib2.get_mem(pos)
if mem.turned_on then
mem.node_loaded = (mem.node_loaded or 1) - 1
if mem.turned_on and mem.node_loaded >= 0 then
local got = consume_power(pos, PWR_NEEDED)
if got < PWR_NEEDED and mem.node_on then
swap_node(pos, "off")
@ -31,17 +32,18 @@ local function on_power(pos)
swap_node(pos, "on")
mem.node_on = true
end
mem.trigger = true
mem.power_available = true
end
end
local function node_timer(pos, elapsed)
local mem = tubelib2.get_mem(pos)
if mem.node_on and not mem.trigger then
if mem.node_on and not mem.power_available then
mem.node_on = false
swap_node(pos, "off")
end
mem.trigger = false
mem.power_available = false
mem.node_loaded = CYCLE_TIME/2 + 1
return mem.turned_on
end

View File

@ -136,6 +136,11 @@ local function drilling(pos, crd, mem, inv)
elseif node.name == "techage:oil_drillbit2" then
mem.drill_pos.y = mem.drill_pos.y-1
crd.State:keep_running(pos, mem, COUNTDOWN_TICKS)
elseif minetest.get_item_group(node.name, "lava") >= 1 then
minetest.swap_node(mem.drill_pos, {name = "techage:oil_drillbit2"})
inv:remove_item("src", ItemStack("techage:oil_drillbit"))
mem.drill_pos.y = mem.drill_pos.y-1
crd.State:keep_running(pos, mem, COUNTDOWN_TICKS)
elseif techage.can_node_dig(node, ndef) then
local drop_name = techage.dropped_node(node, ndef)
if drop_name then

View File

@ -17,9 +17,10 @@ local M = minetest.get_meta
local S = techage.S
local Power = techage.ElectricCable
local firebox = techage.firebox
local provide_power = techage.power.provide_power
local power_switched = techage.power.power_switched
local firebox = techage.firebox
local power_distribution = techage.power.power_distribution
local CYCLE_TIME = 2
local PWR_CAPA = 12
@ -84,7 +85,8 @@ local function burning(pos, mem)
if mem.burn_cycles <= 0 then
local taken = firebox.get_fuel(pos)
if taken then
mem.burn_cycles = firebox.Burntime[taken:get_name()] / CYCLE_TIME * BURN_CYCLE_FACTOR
mem.burn_cycles = (firebox.Burntime[taken:get_name()] or 1) / CYCLE_TIME * BURN_CYCLE_FACTOR
mem.burn_cycles_total = mem.burn_cycles
return true
else
@ -96,15 +98,29 @@ local function burning(pos, mem)
end
end
local function on_power(pos)
local mem = tubelib2.get_mem(pos)
if mem.generating then
mem.provided = provide_power(pos, PWR_CAPA)
else
mem.provided = 0
end
mem.trigger = 2
end
local function node_timer(pos, elapsed)
local mem = tubelib2.get_mem(pos)
if mem.generating and burning(pos, mem) then
mem.provided = provide_power(pos, PWR_CAPA)
power_distribution(pos)
minetest.sound_play("techage_generator", {
pos = pos,
gain = 1,
max_hear_distance = 10})
State:keep_running(pos, mem, CYCLE_TIME)
--State:keep_running(pos, mem, CYCLE_TIME)
mem.trigger = (mem.trigger or 1) - 1
if mem.trigger <= 0 then
power_switched(pos)
end
return true
else
mem.provided = 0
@ -223,6 +239,7 @@ minetest.register_node("techage:tiny_generator_on", {
techage.power.register_node({"techage:tiny_generator", "techage:tiny_generator_on"}, {
conn_sides = {"R"},
power_network = Power,
on_power = on_power,
})
techage.register_node({"techage:tiny_generator", "techage:tiny_generator_on"}, {

View File

@ -100,6 +100,34 @@ local function matching_nodes(pos, peer_pos)
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
-- 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))
-- reset values for nect cycle
mem.needed1 = 0
mem.needed2 = 0
mem.available1 = 0
mem.available2 = 0
end
local function connection_walk(pos, clbk)
local mem = tubelib2.get_mem(pos)
mem.interrupted_dirs = mem.interrupted_dirs or {}
@ -122,7 +150,8 @@ local function determine_master(pos)
local hash = 0
local master = nil
connection_walk(pos, function(pos, mem)
if mem.generating then
if mem.generating and mem.could_be_master then
mem.could_be_master = false
local new = minetest.hash_node_position(pos)
if hash <= new then
hash = new
@ -143,7 +172,7 @@ local function store_master(pos, master_pos)
end)
end
local function trigger_lamps(pos)
local function trigger_nodes(pos)
Route = {}
pos_already_reached(pos)
connection_walk(pos, function(pos, mem)
@ -154,50 +183,30 @@ local function trigger_lamps(pos)
end)
end
-- called from any generator
-- 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
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
trigger_nodes(mpos)
accounting(tubelib2.get_mem(mpos))
--t = minetest.get_us_time() - t
--print("t = "..t)
return mem
end
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 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
-- 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))
-- reset values for nect cycle
mem.needed1 = 0
mem.needed2 = 0
mem.available1 = 0
mem.available2 = 0
end
--
-- Generic API functions
--
@ -223,7 +232,7 @@ function techage.power.power_cut(pos, dir, cable, cut)
for dir,_ in pairs(mem.connections) do
mem.interrupted_dirs[dir] = false
on_power_switch(npos)
trigger_lamps(npos)
trigger_nodes(npos)
mem.interrupted_dirs[dir] = true
end
else
@ -311,8 +320,21 @@ function techage.power.after_tube_update(node, pos, out_dir, peer_pos, peer_in_d
end
end
-- Called from every generator every 2 seconds
function techage.power.power_distribution(pos)
local mem = tubelib2.get_mem(pos)
--print("power_distribution", S(pos), mem.is_master)
-- timer is running, which is needed to be master
mem.could_be_master = true
if mem.is_master then
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)
-- for next cycle
@ -332,19 +354,12 @@ end
function techage.power.provide_power(pos, provide)
local mem = tubelib2.get_mem(pos)
if mem.is_master then
--nothing todo
-- nothing to do
elseif mem.master_pos then
mem = tubelib2.get_mem(mem.master_pos)
else
return 0
end
if (mem.next_cycle or 0) < minetest.get_us_time() then
accounting(mem)
trigger_lamps(pos, mem)
mem.next_cycle = minetest.get_us_time() + 2000000 -- 2s
elseif (mem.next_cycle or 0) > minetest.get_us_time() + 2000000 then
mem.next_cycle = minetest.get_us_time()
end
-- for next cycle
mem.available1 = (mem.available1 or 0) + provide
-- current cycle
@ -357,19 +372,12 @@ end
function techage.power.secondary_power(pos, provide, needed)
local mem = tubelib2.get_mem(pos)
if mem.is_master then
--nothing todo
-- nothing to do
elseif mem.master_pos then
mem = tubelib2.get_mem(mem.master_pos)
else
return 0
end
if (mem.next_cycle or 0) < minetest.get_us_time() then
accounting(mem)
trigger_lamps(pos, mem)
mem.next_cycle = minetest.get_us_time() + 2000000 -- 2s
elseif (mem.next_cycle or 0) > minetest.get_us_time() + 2000000 then
mem.next_cycle = minetest.get_us_time()
end
-- for next cycle
mem.available2 = (mem.available2 or 0) + provide
mem.needed2 = (mem.needed2 or 0) + needed

View File

@ -38,7 +38,7 @@ local function node_timer(pos, elapsed)
if mem.burn_cycles <= 0 then
local taken = firebox.get_fuel(pos)
if taken then
mem.burn_cycles = firebox.Burntime[taken:get_name()] / CYCLE_TIME * BURN_CYCLE_FACTOR
mem.burn_cycles = (firebox.Burntime[taken:get_name()] or 1) / CYCLE_TIME * BURN_CYCLE_FACTOR
mem.burn_cycles_total = mem.burn_cycles
else
mem.running = false

View File

@ -25,6 +25,7 @@ local PWR_CAPA = 25
local Axle = techage.Axle
local provide_power = techage.power.provide_power
local power_switched = techage.power.power_switched
local power_distribution = techage.power.power_distribution
local function formspec(self, pos, mem)
return "size[8,7]"..
@ -39,7 +40,7 @@ local function formspec(self, pos, mem)
end
local function can_start(pos, mem, state)
return (mem.triggered or 0) > 0 -- by means of firebox
return (mem.firebox_trigger or 0) > 0 -- by means of firebox
end
local function start_node(pos, mem, state)
@ -76,26 +77,41 @@ local State = techage.NodeStates:new({
stop_node = stop_node,
})
local function node_timer(pos, elapsed)
local function on_power(pos)
local mem = tubelib2.get_mem(pos)
mem.triggered = mem.triggered or 0
if mem.triggered > 0 and mem.generating then
if mem.generating then
mem.provided = provide_power(pos, PWR_CAPA)
mem.triggered = mem.triggered - 1
State:keep_running(pos, mem, COUNTDOWN_TICKS)
mem.handle = minetest.sound_play("techage_steamengine", {
pos = pos,
gain = 0.5,
max_hear_distance = 10})
elseif mem.generating then -- trigger missing
State:stop(pos, mem)
mem.generating = 0
mem.provided = 0
techage.transfer(pos, "L", "stop", nil, nil, {
"techage:cylinder_on"})
else
mem.provided = 0
end
mem.master_trigger = 2
end
local function node_timer(pos, elapsed)
local mem = tubelib2.get_mem(pos)
if mem.generating then
mem.firebox_trigger = (mem.firebox_trigger or 0) - 1
mem.master_trigger = (mem.master_trigger or 0) - 1
if mem.firebox_trigger <= 0 then
power_switched(pos)
State:nopower(pos, mem)
mem.generating = 0
mem.provided = 0
techage.transfer(pos, "L", "stop", nil, nil, {"techage:cylinder_on"})
else
power_distribution(pos)
State:keep_running(pos, mem, COUNTDOWN_TICKS)
mem.handle = minetest.sound_play("techage_steamengine", {
pos = pos,
gain = 0.5,
max_hear_distance = 10})
if mem.master_trigger <= 0 then
power_switched(pos)
end
end
end
return State:is_active(mem)
end
@ -205,13 +221,14 @@ minetest.register_node("techage:flywheel_on", {
techage.power.register_node({"techage:flywheel", "techage:flywheel_on"}, {
conn_sides = {"R"},
power_network = Axle,
on_power = on_power,
})
techage.register_node({"techage:flywheel", "techage:flywheel_on"}, {
on_transfer = function(pos, in_dir, topic, payload)
local mem = tubelib2.get_mem(pos)
if topic == "trigger" then
mem.triggered = 2
mem.firebox_trigger = 3
if mem.generating then
return math.max((mem.provided or PWR_CAPA) / PWR_CAPA, 0.1)
else

View File

@ -18,7 +18,7 @@ local M = minetest.get_meta
local S = techage.S
local PWR_NEEDED = 1
local CYCLE_TIME = 2
local CYCLE_TIME = 4
local Axle = techage.Axle
local consume_power = techage.power.consume_power
@ -32,18 +32,34 @@ local function swap_node(pos, name)
minetest.swap_node(pos, node)
end
local function on_power(pos)
local mem = tubelib2.get_mem(pos)
mem.node_loaded = (mem.node_loaded or 1) - 1
if mem.node_loaded >= 0 then
local got = consume_power(pos, PWR_NEEDED)
if got < PWR_NEEDED and mem.node_on then
swap_node(pos, "techage:gearbox")
techage.switch_axles(pos, false)
mem.node_on = false
elseif not mem.node_on then
swap_node(pos, "techage:gearbox_on")
techage.switch_axles(pos, true)
mem.node_on = true
end
mem.power_available = true
end
end
local function node_timer(pos, elapsed)
local mem = tubelib2.get_mem(pos)
local got = consume_power(pos, PWR_NEEDED)
if mem.running and got < PWR_NEEDED then
if mem.node_on and not mem.power_available then
swap_node(pos, "techage:gearbox")
techage.switch_axles(pos, false)
mem.running = false
elseif not mem.running and got == PWR_NEEDED then
swap_node(pos, "techage:gearbox_on")
techage.switch_axles(pos, true)
mem.running = true
mem.node_on = false
end
mem.power_available = false
mem.node_loaded = CYCLE_TIME/2 + 1
return true
end
@ -100,6 +116,7 @@ minetest.register_node("techage:gearbox_on", {
techage.power.register_node({"techage:gearbox", "techage:gearbox_on"}, {
power_network = Axle,
on_power = on_power,
})
minetest.register_craft({

View File

@ -37,7 +37,8 @@ local function hide_node(pos, node, meta, placer)
local taken = stack:take_item(1)
local ndef = minetest.registered_nodes[taken:get_name()]
-- test if it is a simple node without logic
if taken:get_count() == 1
if taken:get_count() == 1
and ndef
and not ndef.groups.soil
and not ndef.after_place_node
and not ndef.on_construct then
@ -97,6 +98,8 @@ minetest.register_on_dignode(function(pos, oldnode, digger)
-- test both hidden networks
techage.ElectricCable:after_dig_node(pos, oldnode, digger)
techage.BiogasPipe:after_dig_node(pos, oldnode, digger)
-- probably a hidden node with mem data
tubelib2.del_mem(pos)
else
-- store pos for other tools without own 'register_on_dignode'
techage.dug_node[digger:get_player_name()] = pos