mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-24 03:47:58 +02:00
17486c4053
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.
197 lines
4.7 KiB
Lua
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
|