UnrealisticReactors/migrations/10-from-realistic-reactors.lua
numzero 1f97804bbb Migrate reactors
Or rather, recover them from the map
2024-07-17 23:24:10 +03:00

127 lines
5.8 KiB
Lua

local function get_subs(entities, matchers)
local subs = {}
for _, entity in pairs(entities) do
for name, matcher in pairs(matchers) do
local matches
if type(matcher) == "string" then
matches = entity.name == matcher
else
matches = matcher(entity.name)
end
if matches then
if subs[name] ~= nil then
error("Duplicate entity for "..name)
end
subs[name] = entity
end
end
end
for name, _ in pairs(matchers) do
if subs[name] == nil then
error("Missing entity for "..name)
end
end
return subs
end
local function Signals() return { parameters = { -- signals for interface
["core_temperature" ] = {signal=SIGNAL_CORE_TEMP, count=TEMPERATURE, index=1},
["state_stopped" ] = {signal=SIGNAL_STATE_STOPPED, count=1, index=2},
["state_starting" ] = {signal=SIGNAL_STATE_STARTING, count=0, index=3},
["state_running" ] = {signal=SIGNAL_STATE_RUNNING, count=0, index=4},
["state_scramed" ] = {signal=SIGNAL_STATE_SCRAMED, count=0, index=5},
["coolant-amount" ] = {signal=SIGNAL_COOLANT_AMOUNT, count=0, index=6},
["power-output" ] = {signal=SIGNAL_REACTOR_POWER_OUTPUT, count=0, index=7},
["uranium-fuel-cells"] = {signal=SIGNAL_URANIUM_FUEL_CELLS, count=0, index=8},
--["used-uranium-fuel-cells"] = {signal=SIGNAL_USED_URANIUM_FUEL_CELLS, count=0, index=9},
["efficiency" ] = {signal=SIGNAL_REACTOR_EFFICIENCY, count=0, index=10},
["cell-bonus" ] = {signal=SIGNAL_REACTOR_CELL_BONUS, count=0, index=11},
["electric-power" ] = {signal=SIGNAL_REACTOR_ELECTRIC_POWER, count=0, index=12},
["neighbour-bonus" ] = {signal=SIGNAL_NEIGHBOUR_BONUS, count=0, index=13},
} } end
local function find_reactors()
local reactor_max_power, reactor_max_efficiency
local formula = settings["global"]["realistic-reactors-calculate-stats-function"].value
if formula == "ingo" then
reactor_max_power = 123
reactor_max_efficiency = 200
elseif formula == "ownly" then
reactor_max_power = 250
reactor_max_efficiency = 210
else
error("formula missing")
end
local reactors = {}
for name, surface in pairs(game.surfaces) do
for _, reactor_entity in ipairs(surface.find_entities_filtered{name={REACTOR_ENTITY_NAME, BREEDER_ENTITY_NAME}}) do
local p = reactor_entity.position
local subs = get_subs(surface.find_entities({{p.x-1.5, p.y-1.5}, {p.x+1.5, p.y+1.5}}), {
entity = reactor_entity.name,
core = function(name) return string.match(name, "realistic%-reactor%-%d+") end,
interface = E2I_NAME[reactor_entity.name],
eccs = BOILER_ENTITY_NAME,
power = POWER_NAME[reactor_entity.name],
lamp = function(name) return string.match(name, "rr%-%w+%-lamp") end,
light = function(name) return string.match(name, "rr%-%w+%-light") end,
})
local reactor = {
id = subs.entity.unit_number, -- ID of the reactor (doesn't change)
core_id = subs.core.unit_number, -- ID of the core (changes when core is replaced)
core = subs.core, -- core entity
interface = subs.interface, -- interface entity
eccs = subs.eccs, -- eccs entity
power = subs.power, -- power entity
entity = subs.entity, -- displayer entity
position = subs.core.position, -- core position = reactor position
state = 0, -- reactor state
state_active_since = game.tick - TICKS_PER_UPDATE, -- state begin
neighbours = 1, -- number of connected reactors and itself
control = subs.interface.get_or_create_control_behavior(), -- control behaviour for interface signals
efficiency = 0, -- reactor efficiency
bonus_cells = {}, -- list of bonus cell amount for breeder
cooling_history = 0, -- average power loss through cooling in the last TICKS_PER_UPDATE*8 ticks
lamp = subs.lamp, --reactor lamp dummy
light = subs.light, --light dummy for the lamp
interface_warning_tick = 0, --last tick an electricity warning was displayed on the interface (for imitating the game's behaviour)
interface_warning = nil, --electricity warning dummy (interface)
cooling_warning_tick = 0, --last tick an electricity warning was displayed on the cooling
cooling_warning = nil, --electricity warning dummy (cooling)
power_usage = {starting = 0,cooling = 0, interface = 0}, --portions of the power consumption
last_states_update = game.tick - TICKS_PER_UPDATE,
fuel_last_tick = 0, -- fuel value in the core on last tick
--fluid_amount_last_tick = 0, -- fluid amount in eccs on last tick
power_output_last_tick = 0, --power output in MW on last tick (only updated in start or running phase)
last_temp_update = game.tick - TICKS_PER_UPDATE,
max_power = reactor_max_power, --dynamic maximum value for gui
max_efficiency = reactor_max_efficiency, --dynamic maximum value for gui
signals = Signals(),
}
for _, saved_signal in pairs(reactor.signals.parameters) do
local real_signal = reactor.control.parameters[saved_signal.index]
if (real_signal.signal.type ~= saved_signal.signal.type) or
(real_signal.signal.name ~= saved_signal.signal.name and saved_signal.index ~= 8) then -- 8 is fuel, it may differ
error(string.format("Can't migrate signal %d (expected %q:%q, got %q:%q)",
saved_signal.index, saved_signal.signal.type, saved_signal.signal.name, real_signal.signal.type, real_signal.signal.name))
end
saved_signal.count = real_signal.count
end
reactor.control.parameters = reactor.signals.parameters
if reactor.signals.parameters["state_stopped"].count == 1 then
reactor.state = 0
elseif reactor.signals.parameters["state_starting"].count == 1 then
reactor.state = 1
elseif reactor.signals.parameters["state_running"].count == 1 then
reactor.state = 2
elseif reactor.signals.parameters["state_scramed"].count == 1 then
reactor.state = 3
end
reactors[reactor.id] = reactor
end
end
return reactors
end
global.reactors = find_reactors()