UnrealisticReactors/scripts/heat/buffer.lua

118 lines
3.6 KiB
Lua

local rpath = (...):match("(.-)[^%.]+$")
local rroot = rpath:match("^([^%.]+%.)")
local bigunpack = require("__big-data-string__.unpack")
local util = require(rpath .. "util")
local moveposition = util.moveposition
local get2d = util.get2d
local set2d = util.set2d
local split = util.split
local memo = util.memo
local function decode(s)
return split(s or "",",",tonumber)
end
local function is_internal(prototype)
return prototype.type == "reactor"
and string.sub(prototype.name, 1,17) == "realistic-reactor"
and not (prototype.name == "realistic-reactor")
end
local function heat_buffer_prototype_connections(prototype)
local data = decode(bigunpack(prototype.name .. "-heat-buffer-connections"))
local connections = {}
for i = 1,#data,3 do
local d,x,y = unpack(data,i)
table.insert(connections, {direction=d, position={x=x,y=y}})
end
return connections
end
local function all_heat_buffer_prototype_connections()
local connections = {}
local filters = {
{mode="or", filter="type", type="reactor"},
{mode="or", filter="type", type="heat-pipe"},
}
for name,prototype in pairs(game.get_filtered_entity_prototypes(filters)) do
if not is_internal(prototype) then
connections[name] = heat_buffer_prototype_connections(prototype)
end
end
-- add connections for internals
connections["realistic-reactor-normal" ] = connections["realistic-reactor"]
connections["realistic-reactor-breeder"] = connections["realistic-reactor"]
return connections
end
local function get_heat_buffer_prototype_connections(name)
return memo(all_heat_buffer_prototype_connections)[name] or {}
end
local function get_heat_buffer_prototype_transitions(name)
local transitions = {}
for i,connection in ipairs(get_heat_buffer_prototype_connections(name)) do
transitions[i] = {
p = connection.position, -- inside entity
o = moveposition({x=0,y=0}, connection.direction, 1), -- outlet offset
}
end
return transitions
end
local function vecadd(a,b) return {x=a.x+b.x, y=a.y+b.y} end
local function vecfmut(f,v) v.x = f(v.x) v.y = f(v.y) return v end
local function iterate_heat_buffer_prototype_transitions(s, i)
i = i + 1 local t = s.t[i] -- transition
if not t then return end -- stop iteration
local p = vecfmut(math.floor, vecadd(s,t.p))
return i, p, vecadd(p,t.o)
end
local TRANSITIONS = setmetatable({}, { __index = function (T, name)
local transitions = get_heat_buffer_prototype_transitions(name)
T[name] = transitions -- memoize
return transitions
end})
local function heat_buffer_transitions(entity)
local index = 0
local iterator = iterate_heat_buffer_prototype_transitions
local state = {
t = TRANSITIONS[entity.name],
x = entity.position.x,
y = entity.position.y,
}
return iterator, state, index
end
local function get_heat_buffer_prototype_transition_lookup(name)
local lookup = {}
for _,transition in ipairs(TRANSITIONS[name]) do
local p = vecfmut(math.floor,vecadd({x=0.5,y=0.5},transition.p))
local v = vecadd(transition.o, p)
set2d(lookup, v.x,v.y, p)
end
return lookup
end
local TRANSITION_LOOKUP = setmetatable({}, {__index = function (T, name)
local lookup = get_heat_buffer_prototype_transition_lookup(name)
T[name] = lookup -- memoize
return lookup
end})
local function heat_buffer_transition_position(entity, o,p)
local t = get2d(TRANSITION_LOOKUP[entity.name], p.x-o.x, p.y-o.y)
if t then return vecadd(t,o) end
end
return { -- exports
get_heat_buffer_prototype_connections = get_heat_buffer_prototype_connections,
heat_buffer_transition_position = heat_buffer_transition_position,
heat_buffer_transitions = heat_buffer_transitions,
}