1
0
mirror of https://github.com/veden/Rampant.git synced 2024-12-30 21:19:46 +02:00
Rampant/libs/ChunkProcessor.lua
2021-02-19 23:31:36 -08:00

175 lines
4.6 KiB
Lua
Executable File

if (chunkProcessorG) then
return chunkProcessorG
end
local chunkProcessor = {}
-- imports
local chunkUtils = require("ChunkUtils")
local mathUtils = require("MathUtils")
local constants = require("Constants")
-- 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 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(map, tick, flush)
local processQueue = map.processQueue
local pendingChunks = map.pendingChunks
local area = map.universe.area
local topOffset = area[1]
local bottomOffset = area[2]
local event = next(pendingChunks, map.chunkProcessorIterator)
local endCount = 2
if flush then
endCount = table_size(pendingChunks)
end
for _=1,endCount do
if not event then
map.chunkProcessorIterator = nil
if (table_size(pendingChunks) == 0) then
-- this is needed as the next command remembers the max length a table has been
map.pendingChunks = {}
end
break
else
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
processQueue[#processQueue+1] = chunk
end
end
local newEvent,_ = next(pendingChunks, event)
pendingChunks[event] = nil
event = newEvent
end
end
map.chunkProcessorIterator = event
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(map)
local area = map.universe.area
local topOffset = area[1]
local bottomOffset = area[2]
local removals = map.chunkRemovals
local chunkCount = 0
local chunkToPassScan = map.chunkToPassScan
for chunk,_ in pairs(chunkToPassScan) do
local x = chunk.x
local y = chunk.y
topOffset[1] = x
topOffset[2] = y
bottomOffset[1] = x + CHUNK_SIZE
bottomOffset[2] = y + CHUNK_SIZE
chunk = chunkPassScan(chunk, map)
if (chunk == -1) then
map[x][y] = nil
chunkCount = chunkCount + 1
removals[chunkCount] = chunk
end
chunkToPassScan[chunk] = nil
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
chunkProcessorG = chunkProcessor
return chunkProcessor