142 lines
3.9 KiB
Lua
142 lines
3.9 KiB
Lua
local _M = {}
|
|
|
|
|
|
_M.CONTAINER_TYPES = {
|
|
['container'] = true,
|
|
['logistic-container'] = true,
|
|
}
|
|
|
|
|
|
-- Coppied from __core__/lualib/util.lua
|
|
function _M.deepcopy(object)
|
|
local lookup_table = {}
|
|
local function _copy(object)
|
|
if type(object) ~= "table" then
|
|
return object
|
|
-- don't copy factorio rich objects
|
|
elseif object.__self then
|
|
return object
|
|
elseif lookup_table[object] then
|
|
return lookup_table[object]
|
|
end
|
|
local new_table = {}
|
|
lookup_table[object] = new_table
|
|
for index, value in pairs(object) do
|
|
new_table[_copy(index)] = _copy(value)
|
|
end
|
|
return setmetatable(new_table, getmetatable(object))
|
|
end
|
|
return _copy(object)
|
|
end
|
|
|
|
|
|
local _module_limitations
|
|
function _M.module_limitations()
|
|
if not _module_limitations then
|
|
_module_limitations = {}
|
|
for _, item in pairs(game.item_prototypes) do
|
|
if item.type == 'module' and next(item.limitations) then
|
|
_module_limitations[item.name] = {}
|
|
for _, limitation in pairs(item.limitations) do _module_limitations[item.name][limitation] = true; end
|
|
end
|
|
end
|
|
end
|
|
return _module_limitations
|
|
end
|
|
|
|
|
|
function _M.simulate_overflow(number) return (number + 2147483648) % 4294967296 - 2147483648; end
|
|
|
|
|
|
function _M.class(tab)
|
|
tab = tab or {}
|
|
tab.__mt = {__index = tab}
|
|
tab.__class = tab
|
|
function tab.__new() end
|
|
function tab.new(...)
|
|
local res = setmetatable({}, tab.__mt)
|
|
return res:__new(...) or res
|
|
end
|
|
return setmetatable(tab, {__call = function(class, ...) return class.new(...); end})
|
|
end
|
|
|
|
|
|
_M.direction = _M.class()
|
|
function _M.direction:__new(direction)
|
|
if type(direction) == 'table' then return direction; end
|
|
self.direction = (direction or 0) % 8
|
|
end
|
|
|
|
_M.direction.VECTOR_MAP = {
|
|
[defines.direction.north] = { 0, -1},
|
|
[defines.direction.northeast] = { 1, -1},
|
|
[defines.direction.east] = { 1, 0},
|
|
[defines.direction.southeast] = { 1, 1},
|
|
[defines.direction.south] = { 0, 1},
|
|
[defines.direction.southwest] = {-1, 1},
|
|
[defines.direction.west] = {-1, 0},
|
|
[defines.direction.northwest] = {-1, -1},
|
|
}
|
|
|
|
function _M.direction:get() return self.direction; end
|
|
|
|
function _M.direction:vector() return _M.position(table.unpack(_M.direction.VECTOR_MAP[self:get()])); end
|
|
|
|
function _M.direction:rotate(degrees)
|
|
local round = degrees > 0 and math.floor or math.ceil
|
|
local steps = round((degrees % 360) / 45)
|
|
return _M.direction(self.direction + steps)
|
|
end
|
|
|
|
|
|
_M.position = _M.class()
|
|
function _M.position:__new(x, y)
|
|
if x and not y then
|
|
self.x = x.x or x[1]
|
|
self.y = x.y or x[2]
|
|
else
|
|
self.x = x or 0
|
|
self.y = y or 0
|
|
end
|
|
end
|
|
|
|
function _M.position.__mt:__unm() return _M.position(-self.x, -self.y); end
|
|
function _M.position.__mt:__add(other) return _M.position(self.x + other.x, self.y + other.y); end
|
|
function _M.position.__mt:__sub(other) return _M.position(self.x - other.x, self.y - other.y); end
|
|
function _M.position.__mt:__mul(q)
|
|
if type(q) ~= 'number' then self, q = q, self; end
|
|
return _M.position(self.x * q, self.y * q)
|
|
end
|
|
|
|
function _M.position.direction_vector(direction) return _M.direction(direction):vector(); end
|
|
|
|
function _M.position:shift(direction, distance)
|
|
return self + (_M.direction(direction):vector() * distance)
|
|
end
|
|
|
|
function _M.position:expand(x, y) return _M.area(self):expand(x, y); end
|
|
|
|
|
|
_M.area = _M.class()
|
|
function _M.area:__new(left_top, right_bottom)
|
|
if left_top.left_top then left_top, right_bottom = left_top.left_top, left_top.right_bottom; end
|
|
self.left_top = _M.position(left_top)
|
|
self.right_bottom = _M.position(right_bottom or left_top)
|
|
end
|
|
|
|
function _M.area:expand(x, y)
|
|
y = y or x
|
|
return _M.area({self.left_top.x - x, self.left_top.y - y}, {self.right_bottom.x + x, self.right_bottom.y + y})
|
|
end
|
|
|
|
function _M.area.__mt:__add(other)
|
|
if self.__class ~= _M.area then return other + self; end
|
|
return _M.area(self.left_top + other, self.right_bottom + other)
|
|
end
|
|
function _M.area.__mt:__sub(other)
|
|
if self.__class ~= _M.area then return other - self; end
|
|
return self + (-other)
|
|
end
|
|
|
|
return _M
|