1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-24 03:47:58 +02:00
cogito 17486c4053 planet_prison: optimize map gen
Optimizes map generation. Currently, 16kb were used per chunk for
internal processing geared towards update time and not save time.
Map generation was optimized in a such was that only 8 bytes are
used per chunk, but since we no longer have granular data as before,
occasional lag spikes may occur as much more data needs to get
processed right as we get it.
2020-01-10 17:39:44 +01:00

197 lines
4.7 KiB
Lua

local public = {}
global.this = {}
local _global = require("utils.global")
local _common = require(".common")
local _simplex = require(".simplex_noise")
_global.register(global.this, function(t) global.this = t end)
global.this._grid = {}
global.this._exclusions = {}
global.this._layers = {}
global.this._collision_mask = {}
public.init = function()
_simplex.init()
end
--[[
push_chunk - Pushes chunk position into a grid for later processing.
@param chunk - ChunkPosition
--]]
public.push_chunk = function(chunk)
table.insert(global.this._grid, chunk)
end
--[[
add_excluding_bounding_box - Pushes bounding box into exclusion list.
@param bb - BoundindBox.
--]]
public.push_excluding_bounding_box = function(bb)
table.insert(global.this._exclusions, bb)
end
--[[
remove_ecluding_bounding_box - Removes bounding box from exclusion list.
@param bb - BoundingBox to get rid of.
--]]
public.remove_excluding_bounding_box = function(bb)
for i = 1, #global.this._exclusions do
local box = global.this._exclusions[i]
if box == bb then
table.remove(global.this._exclusions, i)
break
end
end
end
--[[
add_noise_layer - Add noise layer that will be applied onto the grid.
@param type - Type of an object that will be placed onto layer.
@param name - Name of the layer
@param objects - Names of the objects that will be placed.
@param resolution - Resolution of a layer [0f - 1f]
@param elevation - Layer visibility [0f - 1f)
--]]
public.add_noise_layer = function(type, name, objects, elevation, resolution)
local layer = {
type = type,
name = name,
objects = objects,
elevation = elevation,
resolution = resolution,
cache = {},
hook = nil,
}
table.insert(global.this._layers, layer)
end
--[[
add_noise_layer_hook - Execute callback on created object.
@param name - Name of the layer.
@param hook - Callback that will be called with an object argument.
--]]
public.add_noise_layer_hook = function(name, hook)
for _, layer in pairs(global.this._layers) do
if layer.name == name then
layer.hook = hook
break
end
end
end
--[[
set_collision_mask - Set which tiles should be ignored.
@param mask - Table of collision masks.
--]]
public.set_collision_mask = function(mask)
global.this._collision_mask = mask
end
local function _do_job_tile(surf, layer)
surf.set_tiles(layer.cache)
end
local function _do_job_entity(surf, layer)
local hook = layer.hook
for _, object in pairs(layer.cache) do
if object.name == "character" or object.name == "gun-turret" then
if not surf.can_place_entity(object) then
goto continue
end
end
local ent = surf.create_entity(object)
if not ent or not ent.valid then
goto continue
end
if hook then
hook(ent)
end
::continue::
end
end
local function _do_job(surf, x, y)
local point = {
x = x,
y = y,
}
for _, exclusion in pairs(global.this._exclusions) do
if _common.point_in_bounding_box(point, exclusion) then
return
end
end
for _, layer in pairs(global.this._layers) do
local ret = _simplex.get(point, layer.resolution)
if ret >= layer.elevation then
local tile = surf.get_tile(point)
for _, mask in pairs(global.this._collision_mask) do
if tile.collides_with(mask) then
goto continue
end
end
local object_name = layer.objects[1]
if #layer.objects > 1 then
local index = _common.rand_range(1, #layer.objects)
object_name = layer.objects[index]
end
local object = {
name = object_name,
position = point,
}
table.insert(layer.cache, object)
break
::continue::
end
end
end
--[[
do_job - Do a single step propagation of a layers.
@param surf - LuaSurface, onto which action is taken.
--]]
public.do_job = function(surf)
if #global.this._grid <= 0 then
return
end
local chunk = table.remove(global.this._grid)
local x = _common.get_axis(chunk, "x")
local y = _common.get_axis(chunk, "y")
chunk = {
left_top = {
x = x * 32,
y = y * 32
},
right_bottom = {
x = (x * 32) + 32,
y = (y * 32) + 32,
}
}
_common.for_bounding_box(surf, chunk, _do_job)
for _, layer in pairs(global.this._layers) do
local cache = layer.cache
if #cache >= 1 then
if layer.type == "LuaTile" then
_do_job_tile(surf, layer)
elseif layer.type == "LuaEntity" then
_do_job_entity(surf, layer)
end
layer.cache = {}
end
end
end
return public