mirror of
https://github.com/veden/Rampant.git
synced 2025-01-05 22:53:24 +02:00
231 lines
7.0 KiB
Lua
231 lines
7.0 KiB
Lua
if (chunkProcessorG) then
|
|
return chunkProcessorG
|
|
end
|
|
local chunkProcessor = {}
|
|
|
|
-- imports
|
|
|
|
local chunkUtils = require("ChunkUtils")
|
|
local constants = require("Constants")
|
|
local baseUtils = require("BaseUtils")
|
|
local mapUtils = require("MapUtils")
|
|
|
|
-- constants
|
|
|
|
local CHUNK_SIZE = constants.CHUNK_SIZE
|
|
|
|
-- imported functions
|
|
|
|
local queueGeneratedChunk = mapUtils.queueGeneratedChunk
|
|
local getChunkByPosition = mapUtils.getChunkByPosition
|
|
|
|
local findNearbyBase = baseUtils.findNearbyBase
|
|
local createBase = baseUtils.createBase
|
|
|
|
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 next = next
|
|
local table_size = table_size
|
|
|
|
local tRemove = table.remove
|
|
local tInsert = table.insert
|
|
local mCeil = math.ceil
|
|
|
|
-- module code
|
|
|
|
local function findInsertionPoint(processQueue, chunk)
|
|
local low = 1
|
|
local high = #processQueue
|
|
local pivot
|
|
while (low <= high) do
|
|
pivot = mCeil((low + high) * 0.5)
|
|
local pivotChunk = processQueue[pivot]
|
|
if (pivotChunk.dOrigin > chunk.dOrigin) then
|
|
high = pivot - 1
|
|
elseif (pivotChunk.dOrigin <= chunk.dOrigin) then
|
|
low = pivot + 1
|
|
end
|
|
end
|
|
return low
|
|
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 = map.chunkProcessorIterator
|
|
if not event then
|
|
event = next(pendingChunks, nil)
|
|
end
|
|
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
|
|
if (event.tick > tick) then
|
|
map.chunkProcessorIterator = event
|
|
return
|
|
end
|
|
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 not map[x] then
|
|
map[x] = {}
|
|
end
|
|
|
|
local chunk = createChunk(x, y)
|
|
|
|
chunk = initialScan(chunk, map, tick)
|
|
|
|
if (chunk ~= -1) then
|
|
map[x][y] = chunk
|
|
tInsert(
|
|
processQueue,
|
|
findInsertionPoint(processQueue, chunk),
|
|
chunk
|
|
)
|
|
end
|
|
end
|
|
local newEvent = next(pendingChunks, event)
|
|
pendingChunks[event] = nil
|
|
event = newEvent
|
|
end
|
|
end
|
|
map.chunkProcessorIterator = event
|
|
end
|
|
|
|
function chunkProcessor.processPendingUpgrades(map, tick)
|
|
local pendingUpgrades = map.pendingUpgrades
|
|
local entity = map.pendingUpgradeIterator
|
|
local entityData
|
|
if not entity then
|
|
entity, entityData = next(pendingUpgrades, nil)
|
|
else
|
|
entityData = pendingUpgrades[entity]
|
|
end
|
|
if entity then
|
|
if entity.valid then
|
|
map.pendingUpgradeIterator = next(pendingUpgrades, entity)
|
|
pendingUpgrades[entity] = nil
|
|
local universe = map.universe
|
|
local query = universe.upgradeEntityQuery
|
|
query.position = entityData.position or entity.position
|
|
query.name = entityData.name
|
|
local surface = entity.surface
|
|
entity.destroy()
|
|
if remote.interfaces["kr-creep"] then
|
|
remote.call("kr-creep", "spawn_creep_at_position", surface, query.position)
|
|
end
|
|
local createdEntity = surface.create_entity(query)
|
|
if createdEntity and createdEntity.valid and entityData.register then
|
|
local chunk = getChunkByPosition(map, createdEntity.position)
|
|
if (chunk ~= -1) then
|
|
local base = findNearbyBase(map, chunk)
|
|
if not base then
|
|
base = createBase(map,
|
|
chunk,
|
|
tick)
|
|
end
|
|
if base then
|
|
chunkUtils.registerEnemyBaseStructure(map, createdEntity, base)
|
|
end
|
|
else
|
|
queueGeneratedChunk(
|
|
universe,
|
|
{
|
|
surface = createdEntity.surface,
|
|
area = {
|
|
left_top = {
|
|
x = createdEntity.position.x,
|
|
y = createdEntity.position.y
|
|
}
|
|
}
|
|
}
|
|
)
|
|
end
|
|
end
|
|
else
|
|
map.pendingUpgradeIterator = next(pendingUpgrades, entity)
|
|
pendingUpgrades[entity] = nil
|
|
end
|
|
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 preScanChunk in pairs(chunkToPassScan) do
|
|
local x = preScanChunk.x
|
|
local y = preScanChunk.y
|
|
|
|
topOffset[1] = x
|
|
topOffset[2] = y
|
|
bottomOffset[1] = x + CHUNK_SIZE
|
|
bottomOffset[2] = y + CHUNK_SIZE
|
|
|
|
if (chunkPassScan(preScanChunk, map) == -1) then
|
|
map[x][y] = nil
|
|
|
|
chunkCount = chunkCount + 1
|
|
removals[chunkCount] = preScanChunk
|
|
end
|
|
|
|
chunkToPassScan[preScanChunk] = 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)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
chunkProcessorG = chunkProcessor
|
|
return chunkProcessor
|