238 lines
6.2 KiB
Lua
238 lines
6.2 KiB
Lua
if (chunkProcessorG) then
|
|
return chunkProcessorG
|
|
end
|
|
local chunkProcessor = {}
|
|
|
|
-- imports
|
|
|
|
local chunkUtils = require("ChunkUtils")
|
|
local mathUtils = require("MathUtils")
|
|
local constants = require("Constants")
|
|
local baseUtils = require("BaseUtils")
|
|
|
|
-- constants
|
|
|
|
local CHUNK_SIZE = constants.CHUNK_SIZE
|
|
|
|
local MAX_TICKS_BEFORE_SORT_CHUNKS = constants.MAX_TICKS_BEFORE_SORT_CHUNKS
|
|
|
|
-- imported functions
|
|
|
|
local mapScanEnemyChunk = chunkUtils.mapScanEnemyChunk
|
|
local mapScanPlayerChunk = chunkUtils.mapScanPlayerChunk
|
|
local mapScanResourceChunk = chunkUtils.mapScanResourceChunk
|
|
|
|
local createChunk = chunkUtils.createChunk
|
|
local initialScan = chunkUtils.initialScan
|
|
local chunkPassScan = chunkUtils.chunkPassScan
|
|
|
|
local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
|
|
|
|
local changeEntityAndUpdateDynamicRates = baseUtils.changeEntityAndUpdateDynamicRates
|
|
local getDynamicRates = baseUtils.getDynamicRates
|
|
|
|
local tSort = table.sort
|
|
|
|
local abs = math.abs
|
|
local next = next
|
|
local table_size = table_size
|
|
|
|
local tRemove = table.remove
|
|
|
|
-- module code
|
|
|
|
local origin = {x=0,y=0}
|
|
|
|
local function sorter(a, b)
|
|
local aDistance = euclideanDistanceNamed(a, origin)
|
|
local bDistance = euclideanDistanceNamed(b, origin)
|
|
|
|
if (aDistance == bDistance) then
|
|
if (a.x == b.x) then
|
|
return (abs(a.y) < abs(b.y))
|
|
else
|
|
return (abs(a.x) < abs(b.x))
|
|
end
|
|
end
|
|
|
|
return (aDistance < bDistance)
|
|
end
|
|
|
|
function chunkProcessor.processPendingChunks(universe, tick, flush)
|
|
local pendingChunks = universe.pendingChunks
|
|
|
|
local area = universe.area
|
|
local topOffset = area[1]
|
|
local bottomOffset = area[2]
|
|
|
|
local endCount = 2
|
|
local chunkCount = 0
|
|
-- if flush then
|
|
-- endCount = table_size(pendingChunks)
|
|
-- end
|
|
for event, _ in pairs(pendingChunks) do
|
|
local map = event.surface.valid and universe.maps[event.surface.index]
|
|
if map then
|
|
chunkCount = chunkCount + 1
|
|
local topLeft = event.area.left_top
|
|
local x = topLeft.x
|
|
local y = topLeft.y
|
|
|
|
topOffset[1] = x
|
|
topOffset[2] = y
|
|
bottomOffset[1] = x + CHUNK_SIZE
|
|
bottomOffset[2] = y + CHUNK_SIZE
|
|
|
|
if map[x] and map[x][y] then
|
|
local chunk = map[x][y]
|
|
mapScanPlayerChunk(chunk, map)
|
|
mapScanEnemyChunk(chunk, map)
|
|
mapScanResourceChunk(chunk, map)
|
|
else
|
|
if map[x] == nil then
|
|
map[x] = {}
|
|
end
|
|
|
|
local chunk = createChunk(x, y)
|
|
|
|
chunk = initialScan(chunk, map, tick)
|
|
|
|
if (chunk ~= -1) then
|
|
map[x][y] = chunk
|
|
local processQueue = map.processQueue
|
|
processQueue[#processQueue+1] = chunk
|
|
end
|
|
end
|
|
end
|
|
pendingChunks[event] = nil
|
|
if (not flush) and (chunkCount >= endCount) then
|
|
break
|
|
end
|
|
end
|
|
-- if (#processQueue > map.nextChunkSort) or
|
|
-- (((tick - map.nextChunkSortTick) > MAX_TICKS_BEFORE_SORT_CHUNKS) and
|
|
-- ((map.nextChunkSort - 150) < #processQueue))
|
|
-- then
|
|
-- map.nextChunkSort = #processQueue + 150
|
|
-- map.nextChunkSortTick = tick
|
|
-- tSort(processQueue, sorter)
|
|
-- end
|
|
end
|
|
|
|
function chunkProcessor.processScanChunks(universe)
|
|
local area = universe.area
|
|
|
|
local topOffset = area[1]
|
|
local bottomOffset = area[2]
|
|
|
|
--local removals = map.chunkRemovals
|
|
|
|
local endCount = 2
|
|
local chunkCount = 0
|
|
|
|
local chunkToPassScan = universe.chunkToPassScan
|
|
|
|
for chunkIndex, chunkData in pairs(chunkToPassScan) do
|
|
local x = chunkData[1]
|
|
local y = chunkData[2]
|
|
local map = universe.maps[chunkData[3]]
|
|
if map then
|
|
|
|
topOffset[1] = x
|
|
topOffset[2] = y
|
|
bottomOffset[1] = x + CHUNK_SIZE
|
|
bottomOffset[2] = y + CHUNK_SIZE
|
|
|
|
local preScanChunk = map[x] and map[x][y]
|
|
if not preScanChunk or (chunkPassScan(preScanChunk, map) == -1) then
|
|
map[x][y] = nil
|
|
-- removals[chunkCount] = preScanChunk
|
|
end
|
|
|
|
chunkCount = chunkCount + 1
|
|
chunkToPassScan[chunkIndex] = nil
|
|
if chunkCount >= endCount then
|
|
break
|
|
end
|
|
else
|
|
chunkToPassScan[chunkIndex] = nil
|
|
end
|
|
end
|
|
|
|
-- if (chunkCount > 0) then
|
|
-- local processQueue = map.processQueue
|
|
-- for i=#processQueue,1,-1 do
|
|
-- for ri=chunkCount,1,-1 do
|
|
-- if (removals[ri] == processQueue[i]) then
|
|
-- tRemove(processQueue, i)
|
|
-- -- tRemove(removals, ri)
|
|
-- break
|
|
-- end
|
|
-- end
|
|
-- end
|
|
-- end
|
|
end
|
|
|
|
function chunkProcessor.processPendingMutations(universe)
|
|
local pendingChunks = universe.pendingMutations["chunks"]
|
|
local pendingEntities = universe.pendingMutations["entities"]
|
|
local entityId = universe.pendingMutationsIterator
|
|
local entityData
|
|
if not entityId then
|
|
entityId, entityData = next(pendingEntities, nil)
|
|
else
|
|
entityData = pendingEntities[entityId]
|
|
end
|
|
|
|
if not entityId then
|
|
universe.pendingMutationsIterator = nil
|
|
return
|
|
end
|
|
|
|
local dynamicRates
|
|
local base
|
|
local map
|
|
|
|
local processedCnt = 0
|
|
local mutatesCnt = 0
|
|
local maxMutations = 1
|
|
while entityId and (maxMutations > mutatesCnt) and (processedCnt < 100) do
|
|
local entityValid
|
|
local chunkIndex = entityData.chunkIndex
|
|
map = universe.maps[entityData.surfaceIndex]
|
|
entityValid = entityData.entity.valid and entityData.base and map
|
|
if entityValid then
|
|
if not base or (base ~= entityData.base) then
|
|
base = entityData.base
|
|
dynamicRates = getDynamicRates(base)
|
|
end
|
|
newBuilding = changeEntityAndUpdateDynamicRates(entityData.entity, dynamicRates, map, base)
|
|
if newBuilding then
|
|
mutatesCnt = mutatesCnt + 1
|
|
end
|
|
end
|
|
processedCnt = processedCnt + 1
|
|
|
|
pendingEntities[entityId] = nil
|
|
pendingChunks[chunkIndex] = pendingChunks[chunkIndex] - 1
|
|
|
|
entityId, entityData = next(pendingEntities, entityId)
|
|
end
|
|
|
|
local pendingEntities_left = table_size(pendingEntities)
|
|
if pendingEntities_left == 0 then
|
|
universe.pendingMutationsIterator = nil
|
|
|
|
universe.pendingMutations = {
|
|
["chunks"] = {},
|
|
["entities"] = {}
|
|
}
|
|
else
|
|
universe.pendingMutationsIterator = entityId
|
|
end
|
|
end
|
|
|
|
|
|
chunkProcessorG = chunkProcessor
|
|
return chunkProcessor
|