mirror of
https://github.com/Refactorio/RedMew.git
synced 2024-12-14 10:13:13 +02:00
156 lines
4.5 KiB
Lua
156 lines
4.5 KiB
Lua
-- dependencies
|
|
local Event = require 'utils.event'
|
|
|
|
-- this
|
|
local StressMap = {}
|
|
local stress_offset_causing_collapse = 0.1
|
|
|
|
-- main block
|
|
global.stress_map_storage = {}
|
|
|
|
local defaultValue = 0
|
|
local _mt_y = { __index=function(tbl,key) tbl[key] = defaultValue return tbl[key] end}
|
|
local _mt_x = {__index=function(tbl,key) tbl[key] = setmetatable({},_mt_y) return rawget(tbl,key) end}
|
|
|
|
local function set_metatables()
|
|
for _,map in ipairs(global.stress_map_storage) do
|
|
for _,quad in pairs(map) do
|
|
setmetatable(quad,_mt_x)
|
|
for _,stbl in pairs(quad) do
|
|
setmetatable(stbl,_mt_y)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
Event.on_init(set_metatables)
|
|
Event.on_load(set_metatables)
|
|
|
|
StressMap.events = {
|
|
--[[--
|
|
When stress at certain position changes
|
|
- position LuaPosition
|
|
- value Number
|
|
- old_value Number
|
|
- surface LuaSurface
|
|
]]
|
|
on_stress_changed = script.generate_event_name()
|
|
}
|
|
|
|
--[[--
|
|
Adds a fraction to a given location on the stress_map. Returns the new
|
|
fraction value of that position.
|
|
|
|
@param stress_map Table of {@see get_stress_map}
|
|
@param position Table with x and y
|
|
@param number fraction
|
|
|
|
@return number sum of old fraction + new fraction
|
|
]]
|
|
local function add_fraction(stress_map, position, fraction)
|
|
local x = position.x
|
|
local y = position.y
|
|
local quadrant = 1
|
|
if x < 0 then
|
|
quadrant = quadrant + 1
|
|
x = - x
|
|
end
|
|
if y < 0 then
|
|
quadrant = quadrant + 2
|
|
y = - y
|
|
end
|
|
|
|
--magic meta tables!
|
|
local value = stress_map[quadrant][x][y] + fraction
|
|
|
|
stress_map[quadrant][x][y] = value
|
|
|
|
local surface = game.surfaces[stress_map.surface_index]
|
|
|
|
script.raise_event(StressMap.events.on_stress_changed, {old_value = value - fraction, value = value, position = position, surface = surface})
|
|
return value
|
|
end
|
|
|
|
|
|
--[[--
|
|
Creates a new stress map if it doesn't exist yet and returns it.
|
|
|
|
@param surface LuaSurface
|
|
@return Table [1,2,3,4] containing the quadrants
|
|
]]
|
|
local function get_stress_map(surface)
|
|
if not global.stress_map_storage[surface.index] then
|
|
|
|
global.stress_map_storage[surface.index] = {}
|
|
|
|
local map = global.stress_map_storage[surface.index]
|
|
|
|
map[1] = setmetatable({},_mt_x)
|
|
map[2] = setmetatable({},_mt_x)
|
|
map[3] = setmetatable({},_mt_x)
|
|
map[4] = setmetatable({},_mt_x)
|
|
|
|
map["surface_index"] = surface.index
|
|
end
|
|
|
|
return global.stress_map_storage[surface.index]
|
|
end
|
|
|
|
|
|
--[[--
|
|
@param surface LuaSurface
|
|
@param position Position with x and y
|
|
@param number fraction to add to the given position on the surface increase or decreasing stress
|
|
@return boolean
|
|
]]
|
|
function StressMap.add(surface, position, fraction)
|
|
if ('table' ~= type(surface) or nil == surface.name) then
|
|
error('StressMap.add argument #1 expects a LuaSurface, ' .. type(surface) .. ' given.')
|
|
end
|
|
|
|
if ('table' ~= type(position) or nil == position.x or nil == position.y) then
|
|
error('StressMap.add argument #2 expects a position with x and y, ' .. type(position) .. ' given.')
|
|
end
|
|
|
|
local stress_map = get_stress_map(surface)
|
|
|
|
local new = add_fraction(stress_map, position, fraction)
|
|
|
|
if (new >= 1 - stress_offset_causing_collapse) then
|
|
return true
|
|
end
|
|
end
|
|
|
|
--[[--
|
|
Checks whether a tile's pressure is within a given threshold and calls the handler if not.
|
|
@param surface LuaSurface
|
|
@param position Position with x and y
|
|
@param number threshold
|
|
@param callback
|
|
|
|
]]
|
|
function StressMap.check_stress_in_threshold(surface, position, threshold, callback)
|
|
if ('table' ~= type(surface) or nil == surface.name) then
|
|
error('StressMap.check_stress_in_threshold argument #1 expects a LuaSurface, ' .. type(surface) .. ' given.')
|
|
end
|
|
|
|
if ('table' ~= type(position) or nil == position.x or nil == position.y) then
|
|
error('StressMap.check_stress_in_threshold argument #2 expects a position with x and y, ' .. type(position) .. ' given.')
|
|
end
|
|
|
|
if ('number' ~= type(threshold)) then
|
|
error('StressMap.check_stress_in_threshold argument #3 expects a number, ' .. type(threshold) .. ' given.')
|
|
end
|
|
|
|
local stress_map = get_stress_map(surface)
|
|
local value = add_fraction(stress_map, position, 0)
|
|
|
|
if (value >= 1 - stress_offset_causing_collapse - threshold) then
|
|
callback(surface, position)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
return StressMap
|