1
0
mirror of https://github.com/veden/Rampant.git synced 2025-09-16 09:16:43 +02:00

potential desync fix and warding pheromone on attack path

This commit is contained in:
Aaron Veden
2021-12-05 10:19:04 -08:00
parent c7850c3649
commit e814a9c648
15 changed files with 469 additions and 524 deletions

View File

@@ -3,11 +3,8 @@ local upgrade = {}
-- imports -- imports
local constants = require("libs/Constants") local constants = require("libs/Constants")
local mathUtils = require("libs/MathUtils")
local chunkPropertyUtils = require("libs/ChunkPropertyUtils")
local mapUtils = require("libs/MapUtils")
local baseUtils = require("libs/BaseUtils")
local chunkProcessor = require("libs/ChunkProcessor") local chunkProcessor = require("libs/ChunkProcessor")
local mapUtils = require("libs/MapUtils")
-- constants -- constants
@@ -31,37 +28,11 @@ local TRIPLE_CHUNK_SIZE = constants.TRIPLE_CHUNK_SIZE
-- imported functions -- imported functions
local queueGeneratedChunk = mapUtils.queueGeneratedChunk
local processPendingChunks = chunkProcessor.processPendingChunks local processPendingChunks = chunkProcessor.processPendingChunks
local queueGeneratedChunk = mapUtils.queueGeneratedChunk
local getEnemyStructureCount = chunkPropertyUtils.getEnemyStructureCount
local getChunkBase = chunkPropertyUtils.getChunkBase
local removeChunkBase = chunkPropertyUtils.removeChunkBase
local findNearbyBase = baseUtils.findNearbyBase
local createBase = baseUtils.createBase
local setChunkBase = chunkPropertyUtils.setChunkBase
local euclideanDistancePoints = mathUtils.euclideanDistancePoints
local mAbs = math.abs
local tSort = table.sort
-- module code -- module code
local function sorter(a, b)
if (a.dOrigin == b.dOrigin) then
if (a.x == b.x) then
return (mAbs(a.y) < mAbs(b.y))
else
return (mAbs(a.x) < mAbs(b.x))
end
end
return (a.dOrigin < b.dOrigin)
end
local function addCommandSet(queriesAndCommands) local function addCommandSet(queriesAndCommands)
-- preallocating memory to be used in code, making it fast by reducing garbage generated. -- preallocating memory to be used in code, making it fast by reducing garbage generated.
queriesAndCommands.neighbors = { queriesAndCommands.neighbors = {
@@ -445,105 +416,165 @@ function upgrade.attempt(universe)
universe.maxPoints = 0 universe.maxPoints = 0
end end
if global.version < 122 then if global.version < 200 then
global.version = 122 global.version = 200
addCommandSet(universe) addCommandSet(universe)
universe.eventId = 0
universe.randomGenerator = nil universe.randomGenerator = nil
universe.random = game.create_random_generator(settings.startup["rampant--enemySeed"].value+game.map_gen_settings.seed) universe.random = game.create_random_generator(settings.startup["rampant--enemySeed"].value+game.default_map_gen_settings.seed)
if (universe.maps) then game.forces.enemy.kill_all_units()
local tick = game.tick universe.maps = {}
for _,map in pairs(universe.maps) do for _,surface in pairs(game.surfaces) do
map.random = universe.random upgrade.prepMap(universe, surface)
map.pendingUpgrades = {}
map.sentAggressiveGroups = 0
map.maxAggressiveGroups = 1
local basesToRemove = {}
for i=1,#map.processQueue do
local chunk = map.processQueue[i]
chunk.dOrigin = euclideanDistancePoints(chunk.x, chunk.y, 0, 0)
if universe.NEW_ENEMIES then
local base = getChunkBase(map, chunk)
if base then
if not map.bases[base.id] then
map.bases[base.id] = base
end
if not base.damagedBy then
base.damagedBy = {}
end
if not base.deathEvents then
base.deathEvents = 0
end
if not base.chunkCount then
base.chunkCount = 0
end
if not base.mutations then
base.mutations = 0
end
if not base.alignment[1] then
basesToRemove[base.id] = true
end
end
end
end
tSort(map.processQueue, sorter)
map.pendingChunks = {}
map.chunkToNests = {}
map.chunkToNestIds = {}
map.chunkToHives = {}
map.chunkToHiveIds = {}
map.chunkToTraps = {}
map.chunkToTrapIds = {}
map.chunkToTurrets = {}
map.chunkToTurretIds = {}
map.chunkToUtilities = {}
map.chunkToUtilityIds = {}
for chunkXY in map.surface.get_chunks() do
if map.surface.is_chunk_generated(chunkXY) then
local x = chunkXY.x * 32
local y = chunkXY.y * 32
queueGeneratedChunk(universe,
{
surface = map.surface,
area = {
left_top = {
x = x,
y = y
}
}
}
)
end
end
processPendingChunks(map, tick, true)
if universe.NEW_ENEMIES then
for baseId in pairs(basesToRemove) do
map.bases[baseId] = nil
end
map.chunkToBases = {}
for i=1,#map.processQueue do
local chunk = map.processQueue[i]
if (getEnemyStructureCount(map, chunk) > 0) then
local newBase = findNearbyBase(map, chunk)
if not newBase then
createBase(map, chunk, tick)
end
setChunkBase(map, chunk, newBase)
end
end
end
for _,squad in pairs(map.groupNumberToSquad) do
squad.commandTick = tick
end
end
end end
universe.activeMap = nil
universe.mapIterator = nil
game.print("Rampant - Version 1.2.0") game.print("Rampant - Version 2.0.0")
end end
return (starting ~= global.version) and global.version return (starting ~= global.version) and global.version
end end
function upgrade.prepMap(universe, surface)
game.print("Rampant - Indexing surface:" .. tostring(surface.index) .. ", please wait.")
local surfaceIndex = surface.index
if not universe.maps then
universe.maps = {}
end
local map = {}
universe.maps[surfaceIndex] = map
map.eventId = 1
map.chunkId = 1
map.maxAggressiveGroups = 1
map.sentAggressiveGroups = 0
map.processedChunks = 0
map.processQueue = {}
map.processIndex = 1
map.cleanupIndex = 1
map.scanPlayerIndex = 1
map.scanResourceIndex = 1
map.scanEnemyIndex = 1
map.processStaticIndex = 1
map.outgoingScanWave = true
map.outgoingStaticScanWave = true
map.pendingUpgrades = {}
map.pendingChunks = {}
map.chunkToBase = {}
map.chunkToNests = {}
map.chunkToTurrets = {}
map.chunkToTraps = {}
map.chunkToUtilities = {}
map.chunkToHives = {}
map.chunkToNestIds = {}
map.chunkToHiveIds = {}
map.chunkToTrapIds = {}
map.chunkToTurretIds = {}
map.chunkToUtilityIds = {}
map.chunkToPlayerBase = {}
map.chunkToResource = {}
map.chunkToPlayerCount = {}
map.playerToChunk = {}
map.pendingChunks = {}
map.chunkToPassScan = {}
map.chunkToSquad = {}
map.chunkToRetreats = {}
map.chunkToRallys = {}
map.chunkIdToChunk = {}
map.chunkToPassable = {}
map.chunkToPathRating = {}
map.chunkToDeathGenerator = {}
map.chunkToDrained = {}
map.chunkToVictory = {}
map.chunkToActiveNest = {}
map.chunkToActiveRaidNest = {}
map.chunkToPassScanIterator = nil
map.pendingUpgradeIterator = nil
map.squadIterator = nil
map.regroupIterator = nil
map.deployVengenceIterator = nil
map.recycleBaseIterator = nil
map.processActiveSpawnerIterator = nil
map.processActiveRaidSpawnerIterator = nil
map.processMigrationIterator = nil
map.processNestIterator = nil
map.victoryScentIterator = nil
map.chunkScanCounts = {}
map.chunkRemovals = {}
map.processActiveNest = {}
map.tickActiveNest = {}
map.emptySquadsOnChunk = {}
map.surface = surface
map.universe = universe
map.vengenceQueue = {}
map.bases = {}
map.baseIndex = 1
map.baseIncrement = 0
map.points = 0
map.state = constants.AI_STATE_AGGRESSIVE
map.baseId = 0
map.squads = nil
map.pendingAttack = nil
map.building = nil
map.evolutionLevel = game.forces.enemy.evolution_factor
map.canAttackTick = 0
map.drainPylons = {}
map.groupNumberToSquad = {}
map.activeRaidNests = 0
map.activeNests = 0
map.destroyPlayerBuildings = 0
map.lostEnemyUnits = 0
map.lostEnemyBuilding = 0
map.rocketLaunched = 0
map.builtEnemyBuilding = 0
map.ionCannonBlasts = 0
map.artilleryBlasts = 0
map.temperament = 0.5
map.temperamentScore = 0
map.stateTick = 0
map.random = universe.random
-- queue all current chunks that wont be generated during play
local tick = game.tick
for chunk in surface.get_chunks() do
if surface.is_chunk_generated(chunk) then
queueGeneratedChunk(universe,
{
surface = surface,
tick = tick,
area = {
left_top = {
x = chunk.x * 32,
y = chunk.y * 32
}
}
}
)
end
end
processPendingChunks(map, tick, true)
end
function upgrade.compareTable(entities, option, new) function upgrade.compareTable(entities, option, new)
local changed = false local changed = false
if (entities[option] ~= new) then if (entities[option] ~= new) then

View File

@@ -1,5 +1,5 @@
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
Version: 1.2.0 Version: 2.0.0
Date: 23. 11. 2021 Date: 23. 11. 2021
Contributions: Contributions:
- Astorin has provide an updated RU locale up through Rampant 1.1.1 - Astorin has provide an updated RU locale up through Rampant 1.1.1
@@ -42,6 +42,8 @@ Date: 23. 11. 2021
- Fixed regional bases would not be corrected distributed or cleaned up on spawners - Fixed regional bases would not be corrected distributed or cleaned up on spawners
- Fixed chunks that became impassable would not return an impassable chunk flag when pass scanned - Fixed chunks that became impassable would not return an impassable chunk flag when pass scanned
- Fixed kastorio creep code be spawned when the building failed to upgrade - Fixed kastorio creep code be spawned when the building failed to upgrade
- Potential desync fix in relation to reference comparison and deserialization
- Fixed squad attack move would not properly place warding pheromone on taken path
Framework: Framework:
- Fixed Rampant in-memory map visualization tool for debugging - Fixed Rampant in-memory map visualization tool for debugging
- Added debug mod settings for showing enemy structures being upgraded in place - Added debug mod settings for showing enemy structures being upgraded in place

View File

@@ -41,6 +41,8 @@ local ENERGY_THIEF_LOOKUP = constants.ENERGY_THIEF_LOOKUP
-- imported functions -- imported functions
local prepMap = upgrade.prepMap
local registerEnemyBaseStructure = chunkUtils.registerEnemyBaseStructure local registerEnemyBaseStructure = chunkUtils.registerEnemyBaseStructure
local queueGeneratedChunk = mapUtils.queueGeneratedChunk local queueGeneratedChunk = mapUtils.queueGeneratedChunk
@@ -260,135 +262,6 @@ local function onModSettingsChange(event)
return true return true
end end
local function prepMap(surface)
surface.print("Rampant - Indexing surface:" .. tostring(surface.index) .. ", please wait.")
local surfaceIndex = surface.index
if not universe.maps then
universe.maps = {}
end
local map = universe.maps[surfaceIndex]
if not map then
map = {}
universe.maps[surfaceIndex] = map
end
map.maxAggressiveGroups = 1
map.sentAggressiveGroups = 0
map.processedChunks = 0
map.processQueue = {}
map.processIndex = 1
map.cleanupIndex = 1
map.scanPlayerIndex = 1
map.scanResourceIndex = 1
map.scanEnemyIndex = 1
map.processStaticIndex = 1
map.outgoingScanWave = true
map.outgoingStaticScanWave = true
map.pendingUpgrades = {}
map.pendingChunks = {}
map.chunkToBase = {}
map.chunkToNests = {}
map.chunkToTurrets = {}
map.chunkToTraps = {}
map.chunkToUtilities = {}
map.chunkToHives = {}
map.chunkToNestIds = {}
map.chunkToHiveIds = {}
map.chunkToTrapIds = {}
map.chunkToTurretIds = {}
map.chunkToUtilityIds = {}
map.chunkToPlayerBase = {}
map.chunkToResource = {}
map.chunkToPlayerCount = {}
map.playerToChunk = {}
map.pendingChunks = {}
map.chunkToPassScan = {}
map.chunkToSquad = {}
map.chunkToRetreats = {}
map.chunkToRallys = {}
map.chunkToPassable = {}
map.chunkToPathRating = {}
map.chunkToDeathGenerator = {}
map.chunkToDrained = {}
map.chunkToVictory = {}
map.chunkToActiveNest = {}
map.chunkToActiveRaidNest = {}
map.pendingUpgradeIterator = nil
map.squadIterator = nil
map.regroupIterator = nil
map.deployVengenceIterator = nil
map.recycleBaseIterator = nil
map.processActiveSpawnerIterator = nil
map.processActiveRaidSpawnerIterator = nil
map.processMigrationIterator = nil
map.processNestIterator = nil
map.victoryScentIterator = nil
map.chunkScanCounts = {}
map.chunkRemovals = {}
map.processActiveNest = {}
map.tickActiveNest = {}
map.emptySquadsOnChunk = {}
map.surface = surface
map.universe = universe
map.vengenceQueue = {}
map.bases = {}
map.baseIndex = 1
map.baseIncrement = 0
map.points = 0
map.state = constants.AI_STATE_AGGRESSIVE
map.baseId = 0
map.squads = nil
map.pendingAttack = nil
map.building = nil
map.evolutionLevel = game.forces.enemy.evolution_factor
map.canAttackTick = 0
map.drainPylons = {}
map.groupNumberToSquad = {}
map.activeRaidNests = 0
map.activeNests = 0
map.destroyPlayerBuildings = 0
map.lostEnemyUnits = 0
map.lostEnemyBuilding = 0
map.rocketLaunched = 0
map.builtEnemyBuilding = 0
map.ionCannonBlasts = 0
map.artilleryBlasts = 0
map.temperament = 0.5
map.temperamentScore = 0
map.stateTick = 0
map.random = universe.random
-- queue all current chunks that wont be generated during play
local tick = game.tick
for chunk in surface.get_chunks() do
if surface.is_chunk_generated(chunk) then
onChunkGenerated({ surface = surface,
tick = tick,
area = { left_top = { x = chunk.x * 32,
y = chunk.y * 32}}})
end
end
processPendingChunks(map, tick, true)
end
local function onConfigChanged() local function onConfigChanged()
local version = upgrade.attempt(universe) local version = upgrade.attempt(universe)
if version then if version then
@@ -426,7 +299,7 @@ local function onConfigChanged()
universe.maps = {} universe.maps = {}
end end
if not universe.maps[surface.index] then if not universe.maps[surface.index] then
prepMap(surface) prepMap(universe, surface)
end end
end end
end end
@@ -520,13 +393,13 @@ local function onDeath(event)
if pair then if pair then
local target = pair[1] local target = pair[1]
local pole = pair[2] local pole = pair[2]
if target == entity then if target.unit_number == entityUnitNumber then
map.drainPylons[entityUnitNumber] = nil map.drainPylons[entityUnitNumber] = nil
if pole.valid then if pole.valid then
map.drainPylons[pole.unit_number] = nil map.drainPylons[pole.unit_number] = nil
pole.die() pole.die()
end end
elseif (pole == entity) then elseif (pole.unit_number == entityUnitNumber) then
map.drainPylons[entityUnitNumber] = nil map.drainPylons[entityUnitNumber] = nil
if target.valid then if target.valid then
map.drainPylons[target.unit_number] = nil map.drainPylons[target.unit_number] = nil
@@ -576,11 +449,12 @@ local function onDeath(event)
local creditNatives = false local creditNatives = false
if (event.force ~= nil) and (event.force.name == "enemy") then if (event.force ~= nil) and (event.force.name == "enemy") then
creditNatives = true creditNatives = true
local drained
if (chunk ~= -1) then if (chunk ~= -1) then
victoryScent(map, chunk, entityType) victoryScent(map, chunk, entityType)
drained = (entityType == "electric-turret") and map.chunkToDrained[chunk.id]
end end
local drained = (entityType == "electric-turret") and map.chunkToDrained[chunk]
if cause or (drained and (drained - tick) > 0) then if cause or (drained and (drained - tick) > 0) then
if ((cause and ENERGY_THIEF_LOOKUP[cause.name]) or (not cause)) then if ((cause and ENERGY_THIEF_LOOKUP[cause.name]) or (not cause)) then
local conversion = ENERGY_THIEF_CONVERSION_TABLE[entityType] local conversion = ENERGY_THIEF_CONVERSION_TABLE[entityType]
@@ -698,7 +572,7 @@ local function onSurfaceTileChange(event)
local chunk = getChunkByPosition(map, position) local chunk = getChunkByPosition(map, position)
if (chunk ~= -1) then if (chunk ~= -1) then
map.chunkToPassScan[chunk] = true map.chunkToPassScan[chunk.id] = true
else else
local x,y = positionToChunkXY(position) local x,y = positionToChunkXY(position)
local addMe = true local addMe = true
@@ -727,7 +601,7 @@ local function onSurfaceTileChange(event)
local chunk = getChunkByPosition(map, position) local chunk = getChunkByPosition(map, position)
if (chunk ~= -1) then if (chunk ~= -1) then
map.chunkToPassScan[chunk] = true map.chunkToPassScan[chunk.id] = true
else else
local x,y = positionToChunkXY(position) local x,y = positionToChunkXY(position)
local addMe = true local addMe = true
@@ -804,7 +678,7 @@ local function onTriggerEntityCreated(event)
local map = universe.maps[event.surface_index] local map = universe.maps[event.surface_index]
local chunk = getChunkByPosition(map, entity.position) local chunk = getChunkByPosition(map, entity.position)
if (chunk ~= -1) then if (chunk ~= -1) then
map.chunkToDrained[chunk] = event.tick + 60 map.chunkToDrained[chunk.id] = event.tick + 60
end end
end end
end end
@@ -1003,7 +877,7 @@ local function onForceMerged(event)
end end
local function onSurfaceCreated(event) local function onSurfaceCreated(event)
prepMap(game.surfaces[event.surface_index]) prepMap(universe, game.surfaces[event.surface_index])
end end
local function onSurfaceDeleted(event) local function onSurfaceDeleted(event)

View File

@@ -1,7 +1,7 @@
{ {
"name" : "Rampant", "name" : "Rampant",
"factorio_version" : "1.1", "factorio_version" : "1.1",
"version" : "1.2.0", "version" : "2.0.0",
"title" : "Rampant", "title" : "Rampant",
"author" : "Veden", "author" : "Veden",
"homepage" : "https://forums.factorio.com/viewtopic.php?f=94&t=31445", "homepage" : "https://forums.factorio.com/viewtopic.php?f=94&t=31445",

View File

@@ -175,12 +175,12 @@ function aiAttackWave.rallyUnits(chunk, map, tick)
if (x ~= cX) and (y ~= cY) then if (x ~= cX) and (y ~= cY) then
local rallyChunk = getChunkByXY(map, x, y) local rallyChunk = getChunkByXY(map, x, y)
if (rallyChunk ~= -1) and (getNestCount(map, rallyChunk) > 0) then if (rallyChunk ~= -1) and (getNestCount(map, rallyChunk) > 0) then
local count = vengenceQueue[rallyChunk] local count = vengenceQueue[rallyChunk.id]
if not count then if not count then
count = 0 count = 0
vengenceQueue[rallyChunk] = count vengenceQueue[rallyChunk.id] = count
end end
vengenceQueue[rallyChunk] = count + 1 vengenceQueue[rallyChunk.id] = count + 1
end end
end end
end end

View File

@@ -407,7 +407,7 @@ function aiPlanning.temperamentPlanner(map)
map.temperament = ((map.temperamentScore + 10000) * 0.00005) map.temperament = ((map.temperamentScore + 10000) * 0.00005)
if universe.debugTemperament then if universe.debugTemperament then
if game.tick % 240 == 0 then if game.tick % 243 == 0 then
game.print("Rampant Stats:") game.print("Rampant Stats:")
game.print("aN:" .. map.activeNests .. ", aRN:" .. map.activeRaidNests .. ", dPB:" .. map.destroyPlayerBuildings .. game.print("aN:" .. map.activeNests .. ", aRN:" .. map.activeRaidNests .. ", dPB:" .. map.destroyPlayerBuildings ..
", lEU:" .. map.lostEnemyUnits .. ", lEB:" .. map.lostEnemyBuilding .. ", rL:" .. map.rocketLaunched .. ", bEB:" .. map.builtEnemyBuilding .. ", lEU:" .. map.lostEnemyUnits .. ", lEB:" .. map.lostEnemyBuilding .. ", rL:" .. map.rocketLaunched .. ", bEB:" .. map.builtEnemyBuilding ..

View File

@@ -284,9 +284,10 @@ function baseUtils.upgradeEntity(entity, base, map, disPos, evolve, register)
["name"] = spawnerName, ["name"] = spawnerName,
["position"] = disPos, ["position"] = disPos,
["register"] = register, ["register"] = register,
["base"] = base ["base"] = base,
["entity"] = entity
} }
map.pendingUpgrades[entity] = entityData map.pendingUpgrades[entity.unit_number] = entityData
return spawnerName return spawnerName
end end
return nil return nil
@@ -299,7 +300,7 @@ local function pickMutationFromDamageType(map, damageType, roll, base)
local mutation local mutation
if (damageFactions and (#damageFactions > 0)) then if (damageFactions and (#damageFactions > 0)) then
mutation = damageFactions[math.random(#damageFactions)] mutation = damageFactions[mRandom(#damageFactions)]
if baseAlignment[2] then if baseAlignment[2] then
if (roll < 0.05) then if (roll < 0.05) then
baseAlignment[2] = nil baseAlignment[2] = nil

View File

@@ -49,7 +49,7 @@ end
local function removeProcessQueueChunk(processQueue, chunk) local function removeProcessQueueChunk(processQueue, chunk)
local insertionPoint = findInsertionPoint(processQueue, chunk) local insertionPoint = findInsertionPoint(processQueue, chunk)
for i=insertionPoint,1,-1 do for i=insertionPoint,1,-1 do
if (processQueue[i] == chunk) then if (processQueue[i].id == chunk.id) then
tRemove(processQueue, i) tRemove(processQueue, i)
end end
end end
@@ -64,17 +64,20 @@ function chunkProcessor.processPendingChunks(map, tick, flush)
local topOffset = area[1] local topOffset = area[1]
local bottomOffset = area[2] local bottomOffset = area[2]
local event = map.chunkProcessorIterator local eventId = map.chunkProcessorIterator
if not event then local event
event = next(pendingChunks, nil) if not eventId then
eventId, event = next(pendingChunks, nil)
else
event = pendingChunks[eventId]
end end
local endCount = 1 local endCount = 1
if flush then if flush then
endCount = table_size(pendingChunks) endCount = table_size(pendingChunks)
event = next(pendingChunks, nil) eventId, event = next(pendingChunks, nil)
end end
for _=1,endCount do for _=1,endCount do
if not event then if not eventId then
map.chunkProcessorIterator = nil map.chunkProcessorIterator = nil
if (table_size(pendingChunks) == 0) then if (table_size(pendingChunks) == 0) then
-- this is needed as the next command remembers the max length a table has been -- this is needed as the next command remembers the max length a table has been
@@ -83,7 +86,7 @@ function chunkProcessor.processPendingChunks(map, tick, flush)
break break
else else
if not flush and (event.tick > tick) then if not flush and (event.tick > tick) then
map.chunkProcessorIterator = event map.chunkProcessorIterator = eventId
return return
end end
local topLeft = event.area.left_top local topLeft = event.area.left_top
@@ -100,48 +103,52 @@ function chunkProcessor.processPendingChunks(map, tick, flush)
end end
if map[x][y] then if map[x][y] then
local chunk = initialScan(map[x][y], map, tick) local oldChunk = map[x][y]
local chunk = initialScan(oldChunk, map, tick)
if (chunk == -1) then if (chunk == -1) then
removeProcessQueueChunk(processQueue, map[x][y]) removeProcessQueueChunk(processQueue, oldChunk)
map.chunkIdToChunk[oldChunk.id] = nil
map[x][y] = nil map[x][y] = nil
end end
else else
local chunk = createChunk(x, y) local initialChunk = createChunk(map, x, y)
map[x][y] = chunk map[x][y] = initialChunk
chunk = initialScan(chunk, map, tick) map.chunkIdToChunk[initialChunk.id] = initialChunk
local chunk = initialScan(initialChunk, map, tick)
if (chunk ~= -1) then if (chunk ~= -1) then
map[x][y] = chunk
tInsert( tInsert(
processQueue, processQueue,
findInsertionPoint(processQueue, chunk), findInsertionPoint(processQueue, chunk),
chunk chunk
) )
else else
map.chunkIdToChunk[initialChunk.id] = nil
map[x][y] = nil map[x][y] = nil
end end
end end
local newEvent = next(pendingChunks, event) local newEventId, newEvent = next(pendingChunks, eventId)
pendingChunks[event] = nil pendingChunks[eventId] = nil
eventId = newEventId
event = newEvent event = newEvent
end end
end end
map.chunkProcessorIterator = event map.chunkProcessorIterator = eventId
end end
function chunkProcessor.processPendingUpgrades(map, tick) function chunkProcessor.processPendingUpgrades(map, tick)
local pendingUpgrades = map.pendingUpgrades local entityId = map.pendingUpgradeIterator
local entity = map.pendingUpgradeIterator
local entityData local entityData
if not entity then if not entityId then
entity, entityData = next(pendingUpgrades, nil) entityId, entityData = next(map.pendingUpgrades, nil)
else else
entityData = pendingUpgrades[entity] entityData = map.pendingUpgrades[entityId]
end end
if entity then if entityId then
local entity = entityData.entity
if entity.valid then if entity.valid then
map.pendingUpgradeIterator = next(pendingUpgrades, entity) map.pendingUpgradeIterator = next(map.pendingUpgrades, entityId)
pendingUpgrades[entity] = nil map.pendingUpgrades[entityId] = nil
local universe = map.universe local universe = map.universe
local query = universe.upgradeEntityQuery local query = universe.upgradeEntityQuery
query.position = entityData.position or entity.position query.position = entityData.position or entity.position
@@ -157,47 +164,46 @@ function chunkProcessor.processPendingUpgrades(map, tick)
end end
end end
else else
map.pendingUpgradeIterator = next(pendingUpgrades, entity) map.pendingUpgradeIterator = next(map.pendingUpgrades, entityId)
pendingUpgrades[entity] = nil map.pendingUpgrades[entityId] = nil
end end
end end
end end
function chunkProcessor.processScanChunks(map) function chunkProcessor.processScanChunks(map)
local area = map.universe.area local area = map.universe.area
local topOffset = area[1] local topOffset = area[1]
local bottomOffset = area[2] local bottomOffset = area[2]
local removals = map.chunkRemovals local chunkId = map.chunkToPassScanIterator
local chunk
local chunkCount = 0 if not chunkId then
chunkId, chunk = next(map.chunkToPassScan, nil)
local chunkToPassScan = map.chunkToPassScan else
chunk = map.chunkToPassScan[chunkId]
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 end
if (chunkCount > 0) then if not chunkId then
local processQueue = map.processQueue map.chunkToPassScanIterator = nil
for ri=chunkCount,1,-1 do if (table_size(map.chunkToPassScan) == 0) then
removeProcessQueueChunk(processQueue, removals[ri]) -- this is needed as the next command remembers the max length a table has been
map.chunkToPassScan = {}
end
else
map.chunkToPassScanIterator = next(map.chunkToPassScan, chunkId)
map.chunkToPassScan[chunkId] = nil
topOffset[1] = chunk.x
topOffset[2] = chunk.y
bottomOffset[1] = chunk.x + CHUNK_SIZE
bottomOffset[2] = chunk.y + CHUNK_SIZE
if (chunkPassScan(chunk, map) == -1) then
removeProcessQueueChunk(map.processQueue, chunk)
map[chunk.x][chunk.y] = nil
map.chunkIdToChunk[chunk.id] = nil
end end
end end
end end

View File

@@ -22,130 +22,130 @@ local mMin = math.min
-- module code -- module code
function chunkPropertyUtils.getNestCount(map, chunk) function chunkPropertyUtils.getNestCount(map, chunk)
return map.chunkToNests[chunk] or 0 return map.chunkToNests[chunk.id] or 0
end end
function chunkPropertyUtils.getTurretCount(map, chunk) function chunkPropertyUtils.getTurretCount(map, chunk)
return map.chunkToTurrets[chunk] or 0 return map.chunkToTurrets[chunk.id] or 0
end end
function chunkPropertyUtils.getTrapCount(map, chunk) function chunkPropertyUtils.getTrapCount(map, chunk)
return map.chunkToTraps[chunk] or 0 return map.chunkToTraps[chunk.id] or 0
end end
function chunkPropertyUtils.getUtilityCount(map, chunk) function chunkPropertyUtils.getUtilityCount(map, chunk)
return map.chunkToUtilities[chunk] or 0 return map.chunkToUtilities[chunk.id] or 0
end end
function chunkPropertyUtils.getHiveCount(map, chunk) function chunkPropertyUtils.getHiveCount(map, chunk)
return map.chunkToHives[chunk] or 0 return map.chunkToHives[chunk.id] or 0
end end
function chunkPropertyUtils.addTurretCount(map, chunk, unitNumber) function chunkPropertyUtils.addTurretCount(map, chunk, unitNumber)
if not map.chunkToTurretIds[chunk] then if not map.chunkToTurretIds[chunk.id] then
map.chunkToTurretIds[chunk] = {} map.chunkToTurretIds[chunk.id] = {}
end end
if not map.chunkToTurretIds[chunk][unitNumber] then if not map.chunkToTurretIds[chunk.id][unitNumber] then
map.chunkToTurretIds[chunk][unitNumber] = true map.chunkToTurretIds[chunk.id][unitNumber] = true
map.chunkToTurrets[chunk] = (map.chunkToTurrets[chunk] or 0) + 1 map.chunkToTurrets[chunk.id] = (map.chunkToTurrets[chunk.id] or 0) + 1
end end
end end
function chunkPropertyUtils.removeTurretCount(map, chunk, unitNumber) function chunkPropertyUtils.removeTurretCount(map, chunk, unitNumber)
if map.chunkToTurretIds[chunk] and map.chunkToTurretIds[chunk][unitNumber] then if map.chunkToTurretIds[chunk.id] and map.chunkToTurretIds[chunk.id][unitNumber] then
map.chunkToTurretIds[chunk][unitNumber] = nil map.chunkToTurretIds[chunk.id][unitNumber] = nil
map.chunkToTurrets[chunk] = map.chunkToTurrets[chunk] - 1 map.chunkToTurrets[chunk.id] = map.chunkToTurrets[chunk.id] - 1
if map.chunkToTurrets[chunk] == 0 then if map.chunkToTurrets[chunk.id] == 0 then
map.chunkToTurretIds[chunk] = nil map.chunkToTurretIds[chunk.id] = nil
map.chunkToTurrets[chunk] = nil map.chunkToTurrets[chunk.id] = nil
end end
end end
end end
function chunkPropertyUtils.addTrapCount(map, chunk, unitNumber) function chunkPropertyUtils.addTrapCount(map, chunk, unitNumber)
if not map.chunkToTrapIds[chunk] then if not map.chunkToTrapIds[chunk.id] then
map.chunkToTrapIds[chunk] = {} map.chunkToTrapIds[chunk.id] = {}
end end
if not map.chunkToTrapIds[chunk][unitNumber] then if not map.chunkToTrapIds[chunk.id][unitNumber] then
map.chunkToTrapIds[chunk][unitNumber] = true map.chunkToTrapIds[chunk.id][unitNumber] = true
map.chunkToTraps[chunk] = (map.chunkToTraps[chunk] or 0) + 1 map.chunkToTraps[chunk.id] = (map.chunkToTraps[chunk.id] or 0) + 1
end end
end end
function chunkPropertyUtils.removeTrapCount(map, chunk, unitNumber) function chunkPropertyUtils.removeTrapCount(map, chunk, unitNumber)
if map.chunkToTrapIds[chunk] and map.chunkToTrapIds[chunk][unitNumber] then if map.chunkToTrapIds[chunk.id] and map.chunkToTrapIds[chunk.id][unitNumber] then
map.chunkToTrapIds[chunk][unitNumber] = nil map.chunkToTrapIds[chunk.id][unitNumber] = nil
map.chunkToTraps[chunk] = map.chunkToTraps[chunk] - 1 map.chunkToTraps[chunk.id] = map.chunkToTraps[chunk.id] - 1
if map.chunkToTraps[chunk] == 0 then if map.chunkToTraps[chunk.id] == 0 then
map.chunkToTrapIds[chunk] = nil map.chunkToTrapIds[chunk.id] = nil
map.chunkToTraps[chunk] = nil map.chunkToTraps[chunk.id] = nil
end end
end end
end end
function chunkPropertyUtils.addUtilitiesCount(map, chunk, unitNumber) function chunkPropertyUtils.addUtilitiesCount(map, chunk, unitNumber)
if not map.chunkToUtilityIds[chunk] then if not map.chunkToUtilityIds[chunk.id] then
map.chunkToUtilityIds[chunk] = {} map.chunkToUtilityIds[chunk.id] = {}
end end
if not map.chunkToUtilityIds[chunk][unitNumber] then if not map.chunkToUtilityIds[chunk.id][unitNumber] then
map.chunkToUtilityIds[chunk][unitNumber] = true map.chunkToUtilityIds[chunk.id][unitNumber] = true
map.chunkToUtilities[chunk] = (map.chunkToUtilities[chunk] or 0) + 1 map.chunkToUtilities[chunk.id] = (map.chunkToUtilities[chunk.id] or 0) + 1
end end
end end
function chunkPropertyUtils.removeUtilitiesCount(map, chunk, unitNumber) function chunkPropertyUtils.removeUtilitiesCount(map, chunk, unitNumber)
if map.chunkToUtilityIds[chunk] and map.chunkToUtilityIds[chunk][unitNumber] then if map.chunkToUtilityIds[chunk.id] and map.chunkToUtilityIds[chunk.id][unitNumber] then
map.chunkToUtilityIds[chunk][unitNumber] = nil map.chunkToUtilityIds[chunk.id][unitNumber] = nil
map.chunkToUtilities[chunk] = map.chunkToUtilities[chunk] - 1 map.chunkToUtilities[chunk.id] = map.chunkToUtilities[chunk.id] - 1
if map.chunkToUtilities[chunk] == 0 then if map.chunkToUtilities[chunk.id] == 0 then
map.chunkToUtilityIds[chunk] = nil map.chunkToUtilityIds[chunk.id] = nil
map.chunkToUtilities[chunk] = nil map.chunkToUtilities[chunk.id] = nil
end end
end end
end end
function chunkPropertyUtils.addHiveCount(map, chunk, unitNumber) function chunkPropertyUtils.addHiveCount(map, chunk, unitNumber)
if not map.chunkToHiveIds[chunk] then if not map.chunkToHiveIds[chunk.id] then
map.chunkToHiveIds[chunk] = {} map.chunkToHiveIds[chunk.id] = {}
end end
if not map.chunkToHiveIds[chunk][unitNumber] then if not map.chunkToHiveIds[chunk.id][unitNumber] then
map.chunkToHiveIds[chunk][unitNumber] = true map.chunkToHiveIds[chunk.id][unitNumber] = true
map.chunkToHives[chunk] = (map.chunkToHives[chunk] or 0) + 1 map.chunkToHives[chunk.id] = (map.chunkToHives[chunk.id] or 0) + 1
end end
end end
function chunkPropertyUtils.removeHiveCount(map, chunk, unitNumber) function chunkPropertyUtils.removeHiveCount(map, chunk, unitNumber)
if map.chunkToHiveIds[chunk] and map.chunkToHiveIds[chunk][unitNumber] then if map.chunkToHiveIds[chunk.id] and map.chunkToHiveIds[chunk.id][unitNumber] then
map.chunkToHiveIds[chunk][unitNumber] = nil map.chunkToHiveIds[chunk.id][unitNumber] = nil
map.chunkToHives[chunk] = map.chunkToHives[chunk] - 1 map.chunkToHives[chunk.id] = map.chunkToHives[chunk.id] - 1
if map.chunkToHives[chunk] == 0 then if map.chunkToHives[chunk.id] == 0 then
map.chunkToHiveIds[chunk] = nil map.chunkToHiveIds[chunk.id] = nil
map.chunkToHives[chunk] = nil map.chunkToHives[chunk.id] = nil
end end
end end
end end
function chunkPropertyUtils.addNestCount(map, chunk, unitNumber) function chunkPropertyUtils.addNestCount(map, chunk, unitNumber)
if not map.chunkToNestIds[chunk] then if not map.chunkToNestIds[chunk.id] then
map.chunkToNestIds[chunk] = {} map.chunkToNestIds[chunk.id] = {}
end end
if not map.chunkToNestIds[chunk][unitNumber] then if not map.chunkToNestIds[chunk.id][unitNumber] then
map.chunkToNestIds[chunk][unitNumber] = true map.chunkToNestIds[chunk.id][unitNumber] = true
map.chunkToNests[chunk] = (map.chunkToNests[chunk] or 0) + 1 map.chunkToNests[chunk.id] = (map.chunkToNests[chunk.id] or 0) + 1
end end
end end
function chunkPropertyUtils.removeNestCount(map, chunk, unitNumber) function chunkPropertyUtils.removeNestCount(map, chunk, unitNumber)
if map.chunkToNestIds[chunk] and map.chunkToNestIds[chunk][unitNumber] then if map.chunkToNestIds[chunk.id] and map.chunkToNestIds[chunk.id][unitNumber] then
map.chunkToNestIds[chunk][unitNumber] = nil map.chunkToNestIds[chunk.id][unitNumber] = nil
map.chunkToNests[chunk] = map.chunkToNests[chunk] - 1 map.chunkToNests[chunk.id] = map.chunkToNests[chunk.id] - 1
if map.chunkToNests[chunk] == 0 then if map.chunkToNests[chunk.id] == 0 then
map.chunkToNestIds[chunk] = nil map.chunkToNestIds[chunk.id] = nil
map.chunkToNests[chunk] = nil map.chunkToNests[chunk.id] = nil
if (map.processMigrationIterator == chunk) then if (map.processMigrationIterator == chunk.id) then
map.processMigrationIterator = nil map.processMigrationIterator = nil
end end
if (map.processNestIterator == chunk) then if (map.processNestIterator == chunk.id) then
map.processNestIterator = nil map.processNestIterator = nil
end end
end end
@@ -153,164 +153,164 @@ function chunkPropertyUtils.removeNestCount(map, chunk, unitNumber)
end end
function chunkPropertyUtils.getNestCount(map, chunk) function chunkPropertyUtils.getNestCount(map, chunk)
return map.chunkToNests[chunk] or 0 return map.chunkToNests[chunk.id] or 0
end end
function chunkPropertyUtils.getChunkBase(map, chunk) function chunkPropertyUtils.getChunkBase(map, chunk)
return map.chunkToBase[chunk] return map.chunkToBase[chunk.id]
end end
function chunkPropertyUtils.removeChunkBase(map, chunk, base) function chunkPropertyUtils.removeChunkBase(map, chunk, base)
if map.chunkToBase[chunk] then if map.chunkToBase[chunk.id] then
base.chunkCount = base.chunkCount - 1 base.chunkCount = base.chunkCount - 1
map.chunkToBase[chunk] = nil map.chunkToBase[chunk.id] = nil
end end
end end
function chunkPropertyUtils.setChunkBase(map, chunk, base) function chunkPropertyUtils.setChunkBase(map, chunk, base)
if not map.chunkToBase[chunk] then if not map.chunkToBase[chunk.id] then
base.chunkCount = base.chunkCount + 1 base.chunkCount = base.chunkCount + 1
map.chunkToBase[chunk] = base map.chunkToBase[chunk.id] = base
end end
end end
function chunkPropertyUtils.getEnemyStructureCount(map, chunk) function chunkPropertyUtils.getEnemyStructureCount(map, chunk)
return (map.chunkToNests[chunk] or 0) + (map.chunkToTurrets[chunk] or 0) + (map.chunkToTraps[chunk] or 0) + return (map.chunkToNests[chunk.id] or 0) + (map.chunkToTurrets[chunk.id] or 0) + (map.chunkToTraps[chunk.id] or 0) +
(map.chunkToUtilities[chunk] or 0) + (map.chunkToHives[chunk] or 0) (map.chunkToUtilities[chunk.id] or 0) + (map.chunkToHives[chunk.id] or 0)
end end
function chunkPropertyUtils.getRetreatTick(map, chunk) function chunkPropertyUtils.getRetreatTick(map, chunk)
return map.chunkToRetreats[chunk] or 0 return map.chunkToRetreats[chunk.id] or 0
end end
function chunkPropertyUtils.getRallyTick(map, chunk) function chunkPropertyUtils.getRallyTick(map, chunk)
return map.chunkToRallys[chunk] or 0 return map.chunkToRallys[chunk.id] or 0
end end
function chunkPropertyUtils.setRallyTick(map, chunk, tick) function chunkPropertyUtils.setRallyTick(map, chunk, tick)
map.chunkToRallys[chunk] = tick map.chunkToRallys[chunk.id] = tick
end end
function chunkPropertyUtils.setRetreatTick(map, chunk, tick) function chunkPropertyUtils.setRetreatTick(map, chunk, tick)
map.chunkToRetreats[chunk] = tick map.chunkToRetreats[chunk.id] = tick
end end
function chunkPropertyUtils.setResourceGenerator(map, chunk, resourceGenerator) function chunkPropertyUtils.setResourceGenerator(map, chunk, resourceGenerator)
if (resourceGenerator <= 0) then if (resourceGenerator <= 0) then
map.chunkToResource[chunk] = nil map.chunkToResource[chunk.id] = nil
else else
map.chunkToResource[chunk] = resourceGenerator map.chunkToResource[chunk.id] = resourceGenerator
end end
end end
function chunkPropertyUtils.getResourceGenerator(map, chunk) function chunkPropertyUtils.getResourceGenerator(map, chunk)
return map.chunkToResource[chunk] or 0 return map.chunkToResource[chunk.id] or 0
end end
function chunkPropertyUtils.addResourceGenerator(map, chunk, delta) function chunkPropertyUtils.addResourceGenerator(map, chunk, delta)
map.chunkToResource[chunk] = (map.chunkToResource[chunk] or 0) + delta map.chunkToResource[chunk.id] = (map.chunkToResource[chunk.id] or 0) + delta
end end
function chunkPropertyUtils.getDeathGenerator(map, chunk) function chunkPropertyUtils.getDeathGenerator(map, chunk)
return map.chunkToDeathGenerator[chunk] or 0 return map.chunkToDeathGenerator[chunk.id] or 0
end end
function chunkPropertyUtils.getPassable(map, chunk) function chunkPropertyUtils.getPassable(map, chunk)
return map.chunkToPassable[chunk] or CHUNK_ALL_DIRECTIONS return map.chunkToPassable[chunk.id] or CHUNK_ALL_DIRECTIONS
end end
function chunkPropertyUtils.getRaidNestActiveness(map, chunk) function chunkPropertyUtils.getRaidNestActiveness(map, chunk)
return map.chunkToActiveRaidNest[chunk] or 0 return map.chunkToActiveRaidNest[chunk.id] or 0
end end
function chunkPropertyUtils.setRaidNestActiveness(map, chunk, value) function chunkPropertyUtils.setRaidNestActiveness(map, chunk, value)
if (value <= 0) then if (value <= 0) then
if (map.chunkToActiveRaidNest[chunk] ~= nil) then if map.chunkToActiveRaidNest[chunk.id] then
map.activeRaidNests = map.activeRaidNests - 1 map.activeRaidNests = map.activeRaidNests - 1
end end
if (map.processActiveRaidSpawnerIterator == chunk) then if (map.processActiveRaidSpawnerIterator == chunk.id) then
map.processActiveRaidSpawnerIterator = nil map.processActiveRaidSpawnerIterator = nil
end end
map.chunkToActiveRaidNest[chunk] = nil map.chunkToActiveRaidNest[chunk.id] = nil
else else
if (map.chunkToActiveRaidNest[chunk] == nil) then if not map.chunkToActiveRaidNest[chunk.id] then
map.activeRaidNests = map.activeRaidNests + 1 map.activeRaidNests = map.activeRaidNests + 1
end end
map.chunkToActiveRaidNest[chunk] = value map.chunkToActiveRaidNest[chunk.id] = value
end end
end end
function chunkPropertyUtils.getNestActiveTick(map, chunk) function chunkPropertyUtils.getNestActiveTick(map, chunk)
return map.tickActiveNest[chunk] or 0 return map.tickActiveNest[chunk.id] or 0
end end
function chunkPropertyUtils.setNestActiveTick(map, chunk, tick) function chunkPropertyUtils.setNestActiveTick(map, chunk, tick)
if (tick == 0) then if (tick == 0) then
map.tickActiveNest[chunk] = nil map.tickActiveNest[chunk.id] = nil
else else
map.tickActiveNest[chunk] = tick map.tickActiveNest[chunk.id] = tick
end end
end end
function chunkPropertyUtils.getNestActiveness(map, chunk) function chunkPropertyUtils.getNestActiveness(map, chunk)
return map.chunkToActiveNest[chunk] or 0 return map.chunkToActiveNest[chunk.id] or 0
end end
function chunkPropertyUtils.setNestActiveness(map, chunk, value) function chunkPropertyUtils.setNestActiveness(map, chunk, value)
if (value <= 0) then if (value <= 0) then
if (map.chunkToActiveNest[chunk] ~= nil) then if map.chunkToActiveNest[chunk.id] then
map.activeNests = map.activeNests - 1 map.activeNests = map.activeNests - 1
end end
if (map.processActiveSpawnerIterator == chunk) then if (map.processActiveSpawnerIterator == chunk.id) then
map.processActiveSpawnerIterator = nil map.processActiveSpawnerIterator = nil
end end
map.chunkToActiveNest[chunk] = nil map.chunkToActiveNest[chunk.id] = nil
else else
if (map.chunkToActiveNest[chunk] == nil) then if not map.chunkToActiveNest[chunk.id] then
map.activeNests = map.activeNests + 1 map.activeNests = map.activeNests + 1
end end
map.chunkToActiveNest[chunk] = value map.chunkToActiveNest[chunk.id] = value
end end
end end
function chunkPropertyUtils.setPassable(map, chunk, value) function chunkPropertyUtils.setPassable(map, chunk, value)
if (value == CHUNK_ALL_DIRECTIONS) then if (value == CHUNK_ALL_DIRECTIONS) then
map.chunkToPassable[chunk] = nil map.chunkToPassable[chunk.id] = nil
else else
map.chunkToPassable[chunk] = value map.chunkToPassable[chunk.id] = value
end end
end end
function chunkPropertyUtils.getPathRating(map, chunk) function chunkPropertyUtils.getPathRating(map, chunk)
return map.chunkToPathRating[chunk] or 1 return map.chunkToPathRating[chunk.id] or 1
end end
function chunkPropertyUtils.setPathRating(map, chunk, value) function chunkPropertyUtils.setPathRating(map, chunk, value)
if (value == 1) then if (value == 1) then
map.chunkToPathRating[chunk] = nil map.chunkToPathRating[chunk.id] = nil
else else
map.chunkToPathRating[chunk] = value map.chunkToPathRating[chunk.id] = value
end end
end end
function chunkPropertyUtils.addDeathGenerator(map, chunk, value) function chunkPropertyUtils.addDeathGenerator(map, chunk, value)
map.chunkToDeathGenerator[chunk] = (map.chunkToDeathGenerator[chunk] or 0) + value map.chunkToDeathGenerator[chunk.id] = (map.chunkToDeathGenerator[chunk.id] or 0) + value
end end
function chunkPropertyUtils.addVictoryGenerator(map, chunk, value) function chunkPropertyUtils.addVictoryGenerator(map, chunk, value)
map.chunkToVictory[chunk] = (map.chunkToVictory[chunk] or 0) + value map.chunkToVictory[chunk.id] = (map.chunkToVictory[chunk.id] or 0) + value
end end
function chunkPropertyUtils.decayDeathGenerator(map, chunk) function chunkPropertyUtils.decayDeathGenerator(map, chunk)
local gen = map.chunkToDeathGenerator[chunk] local gen = map.chunkToDeathGenerator[chunk.id]
if gen then if gen then
gen = gen * MOVEMENT_GENERATOR_PERSISTANCE gen = gen * MOVEMENT_GENERATOR_PERSISTANCE
if (gen >= -2) and (gen <= 2) then if (gen >= -2) and (gen <= 2) then
map.chunkToDeathGenerator[chunk] = nil map.chunkToDeathGenerator[chunk.id] = nil
else else
map.chunkToDeathGenerator[chunk] = gen map.chunkToDeathGenerator[chunk.id] = gen
end end
end end
end end
@@ -321,50 +321,50 @@ function chunkPropertyUtils.addPlayerToChunk(map, chunk, name)
local playerChunk = playerChunks[name] local playerChunk = playerChunks[name]
if not playerChunk then if not playerChunk then
playerChunks[name] = chunk playerChunks[name] = chunk
local playerCount = playerCountChunks[chunk] local playerCount = playerCountChunks[chunk.id]
if not playerCount then if not playerCount then
playerCountChunks[chunk] = 1 playerCountChunks[chunk.id] = 1
else else
playerCountChunks[chunk] = playerCount + 1 playerCountChunks[chunk.id] = playerCount + 1
end end
elseif (playerChunk ~= chunk) then elseif (playerChunk.id ~= chunk.id) then
playerChunks[name] = chunk playerChunks[name] = chunk
local playerCount = playerCountChunks[playerChunk] local playerCount = playerCountChunks[playerChunk.id]
chunkPropertyUtils.setPlayersOnChunk(map, playerChunk, playerCount - 1) chunkPropertyUtils.setPlayersOnChunk(map, playerChunk, playerCount - 1)
playerCount = playerCountChunks[chunk] playerCount = playerCountChunks[chunk.id]
if not playerCount then if not playerCount then
playerCountChunks[chunk] = 1 playerCountChunks[chunk.id] = 1
else else
playerCountChunks[chunk] = playerCount + 1 playerCountChunks[chunk.id] = playerCount + 1
end end
end end
end end
function chunkPropertyUtils.setPlayersOnChunk(map, chunk, value) function chunkPropertyUtils.setPlayersOnChunk(map, chunk, value)
if (value <= 0) then if (value <= 0) then
map.chunkToPlayerCount[chunk] = nil map.chunkToPlayerCount[chunk.id] = nil
else else
map.chunkToPlayerCount[chunk] = value map.chunkToPlayerCount[chunk.id] = value
end end
end end
function chunkPropertyUtils.getPlayersOnChunk(map, chunk) function chunkPropertyUtils.getPlayersOnChunk(map, chunk)
return map.chunkToPlayerCount[chunk] or 0 return map.chunkToPlayerCount[chunk.id] or 0
end end
function chunkPropertyUtils.getPlayerBaseGenerator(map, chunk) function chunkPropertyUtils.getPlayerBaseGenerator(map, chunk)
return map.chunkToPlayerBase[chunk] or 0 return map.chunkToPlayerBase[chunk.id] or 0
end end
function chunkPropertyUtils.addSquadToChunk(map, chunk, squad) function chunkPropertyUtils.addSquadToChunk(map, chunk, squad)
local chunkToSquad = map.chunkToSquad local chunkToSquad = map.chunkToSquad
if (chunk ~= -1) and (squad.chunk ~= chunk) then if (chunk ~= -1) and ((squad.chunk == -1) or (squad.chunk.id ~= chunk.id)) then
chunkPropertyUtils.removeSquadFromChunk(map, squad) chunkPropertyUtils.removeSquadFromChunk(map, squad)
local squads = chunkToSquad[chunk] local squads = chunkToSquad[chunk.id]
if not squads then if not squads then
squads = {} squads = {}
chunkToSquad[chunk] = squads chunkToSquad[chunk.id] = squads
end end
squads[squad.groupNumber] = squad squads[squad.groupNumber] = squad
squad.chunk = chunk squad.chunk = chunk
@@ -374,29 +374,31 @@ end
function chunkPropertyUtils.removeSquadFromChunk(map, squad) function chunkPropertyUtils.removeSquadFromChunk(map, squad)
local chunkToSquad = map.chunkToSquad local chunkToSquad = map.chunkToSquad
local chunk = squad.chunk local chunk = squad.chunk
local squads = chunkToSquad[chunk] if (chunk ~= -1) then
if squads then local squads = chunkToSquad[chunk.id]
squads[squad.groupNumber] = nil if squads then
if (table_size(squads) == 0) then squads[squad.groupNumber] = nil
chunkToSquad[chunk] = nil if (table_size(squads) == 0) then
chunkToSquad[chunk.id] = nil
end
end end
end end
end end
function chunkPropertyUtils.getSquadsOnChunk(map, chunk) function chunkPropertyUtils.getSquadsOnChunk(map, chunk)
return map.chunkToSquad[chunk] or map.emptySquadsOnChunk return map.chunkToSquad[chunk.id] or map.emptySquadsOnChunk
end end
function chunkPropertyUtils.setPlayerBaseGenerator(map, chunk, playerGenerator) function chunkPropertyUtils.setPlayerBaseGenerator(map, chunk, playerGenerator)
if (playerGenerator <= 0) then if (playerGenerator <= 0) then
map.chunkToPlayerBase[chunk] = nil map.chunkToPlayerBase[chunk.id] = nil
else else
map.chunkToPlayerBase[chunk] = playerGenerator map.chunkToPlayerBase[chunk.id] = playerGenerator
end end
end end
function chunkPropertyUtils.addPlayerBaseGenerator(map, chunk, playerGenerator) function chunkPropertyUtils.addPlayerBaseGenerator(map, chunk, playerGenerator)
map.chunkToPlayerBase[chunk] = (map.chunkToPlayerBase[chunk] or 0) + playerGenerator map.chunkToPlayerBase[chunk.id] = (map.chunkToPlayerBase[chunk.id] or 0) + playerGenerator
end end
function chunkPropertyUtils.processNestActiveness(map, chunk) function chunkPropertyUtils.processNestActiveness(map, chunk)
@@ -409,12 +411,12 @@ function chunkPropertyUtils.processNestActiveness(map, chunk)
if universe.attackUsePlayer and (chunk[PLAYER_PHEROMONE] > universe.attackPlayerThreshold) then if universe.attackUsePlayer and (chunk[PLAYER_PHEROMONE] > universe.attackPlayerThreshold) then
chunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20)) chunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20))
elseif (chunk[BASE_PHEROMONE] > 0) then elseif (chunk[BASE_PHEROMONE] > 0) then
local position = universe.position
if (surface.get_pollution(chunk) > 0) then if (surface.get_pollution(chunk) > 0) then
chunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20)) chunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20))
else else
local x = chunk.x local x = chunk.x
local y = chunk.y local y = chunk.y
local position = {x=0,y=0}
position.x = x + 32 position.x = x + 32
position.y = y position.y = y
if (surface.get_pollution(position) > 0) then if (surface.get_pollution(position) > 0) then

View File

@@ -351,16 +351,23 @@ function chunkUtils.entityForPassScan(map, entity)
for i=1,#overlapArray do for i=1,#overlapArray do
local chunk = overlapArray[i] local chunk = overlapArray[i]
if (chunk ~= -1) then if (chunk ~= -1) then
map.chunkToPassScan[chunk] = true map.chunkToPassScan[chunk.id] = chunk
end end
end end
end end
function chunkUtils.createChunk(topX, topY) function chunkUtils.newChunkId(map)
local id = map.chunkId
map.chunkId = map.chunkId + 1
return id
end
function chunkUtils.createChunk(map, topX, topY)
local chunk = { local chunk = {
x = topX, x = topX,
y = topY, y = topY,
dOrigin = euclideanDistancePoints(topX, topY, 0, 0) dOrigin = euclideanDistancePoints(topX, topY, 0, 0),
id = chunkUtils.newChunkId(map)
} }
chunk[BASE_PHEROMONE] = 0 chunk[BASE_PHEROMONE] = 0
chunk[PLAYER_PHEROMONE] = 0 chunk[PLAYER_PHEROMONE] = 0

View File

@@ -63,6 +63,7 @@ local formSettlers = aiAttackWave.formSettlers
local getChunkByPosition = mapUtils.getChunkByPosition local getChunkByPosition = mapUtils.getChunkByPosition
local getChunkByXY = mapUtils.getChunkByXY local getChunkByXY = mapUtils.getChunkByXY
local getChunkById = mapUtils.getChunkById
local validPlayer = playerUtils.validPlayer local validPlayer = playerUtils.validPlayer
@@ -253,7 +254,7 @@ function mapProcessor.processPlayers(players, map, tick)
queueNestSpawners(map, chunk, tick) queueNestSpawners(map, chunk, tick)
if vengence then if vengence then
map.vengenceQueue[chunk] = (map.vengenceQueue[chunk] or 0) + 1 map.vengenceQueue[chunk.id] = (map.vengenceQueue[chunk.id] or 0) + 1
end end
end end
end end
@@ -448,27 +449,28 @@ function mapProcessor.processActiveNests(map, tick)
end end
function mapProcessor.processVengence(map) function mapProcessor.processVengence(map)
local ss = map.vengenceQueue local vengence = map.vengenceQueue
local chunk = map.deployVengenceIterator local chunkId = map.deployVengenceIterator
if not chunk then if not chunkId then
chunk = next(ss, nil) chunkId = next(vengence, nil)
end end
if not chunk then if not chunkId then
map.deployVengenceIterator = nil map.deployVengenceIterator = nil
if (tableSize(ss) == 0) then if (tableSize(vengence) == 0) then
map.vengenceQueue = {} map.vengenceQueue = {}
end end
else else
map.deployVengenceIterator = next(ss, chunk) map.deployVengenceIterator = next(vengence, chunkId)
formVengenceSquad(map, chunk) formVengenceSquad(map, getChunkById(map, chunkId))
ss[chunk] = nil vengence[chunkId] = nil
end end
end end
function mapProcessor.processNests(map, tick) function mapProcessor.processNests(map, tick)
local chunk = next(map.chunkToNests, map.processNestIterator) local chunkId = next(map.chunkToNests, map.processNestIterator)
map.processNestIterator = chunk map.processNestIterator = chunkId
if chunk then if chunkId then
local chunk = getChunkById(map, chunkId)
processNestActiveness(map, chunk) processNestActiveness(map, chunk)
queueNestSpawners(map, chunk, tick) queueNestSpawners(map, chunk, tick)
@@ -481,10 +483,11 @@ function mapProcessor.processNests(map, tick)
end end
end end
local function processSpawners(map, iterator, chunks) local function processSpawnersBody(map, iterator, chunks)
local chunk = next(chunks, map[iterator]) local chunkId = next(chunks, map[iterator])
map[iterator] = chunk map[iterator] = chunkId
if chunk then if chunkId then
local chunk = getChunkById(map, chunkId)
local migrate = canMigrate(map) local migrate = canMigrate(map)
local attack = canAttack(map) local attack = canAttack(map)
if migrate then if migrate then
@@ -499,30 +502,30 @@ function mapProcessor.processSpawners(map)
if (map.state ~= AI_STATE_PEACEFUL) then if (map.state ~= AI_STATE_PEACEFUL) then
if (map.state == AI_STATE_MIGRATING) then if (map.state == AI_STATE_MIGRATING) then
processSpawners(map, processSpawnersBody(map,
"processMigrationIterator", "processMigrationIterator",
map.chunkToNests) map.chunkToNests)
elseif (map.state == AI_STATE_AGGRESSIVE) then elseif (map.state == AI_STATE_AGGRESSIVE) then
processSpawners(map, processSpawnersBody(map,
"processActiveSpawnerIterator", "processActiveSpawnerIterator",
map.chunkToActiveNest) map.chunkToActiveNest)
elseif (map.state == AI_STATE_SIEGE) then elseif (map.state == AI_STATE_SIEGE) then
processSpawners(map, processSpawnersBody(map,
"processActiveSpawnerIterator", "processActiveSpawnerIterator",
map.chunkToActiveNest) map.chunkToActiveNest)
processSpawners(map, processSpawnersBody(map,
"processActiveRaidSpawnerIterator", "processActiveRaidSpawnerIterator",
map.chunkToActiveRaidNest) map.chunkToActiveRaidNest)
processSpawners(map, processSpawnersBody(map,
"processMigrationIterator", "processMigrationIterator",
map.chunkToNests) map.chunkToNests)
else else
processSpawners(map, processSpawnersBody(map,
"processActiveSpawnerIterator", "processActiveSpawnerIterator",
map.chunkToActiveNest) map.chunkToActiveNest)
processSpawners(map, processSpawnersBody(map,
"processActiveRaidSpawnerIterator", "processActiveRaidSpawnerIterator",
map.chunkToActiveRaidNest) map.chunkToActiveRaidNest)
end end
end end
end end

View File

@@ -43,6 +43,10 @@ function mapUtils.getChunkByPosition(map, position)
return -1 return -1
end end
function mapUtils.getChunkById(map, chunkId)
return map.chunkIdToChunk[chunkId] or -1
end
function mapUtils.positionToChunkXY(position) function mapUtils.positionToChunkXY(position)
local chunkX = mFloor(position.x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE local chunkX = mFloor(position.x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
local chunkY = mFloor(position.y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE local chunkY = mFloor(position.y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
@@ -51,7 +55,10 @@ end
function mapUtils.queueGeneratedChunk(universe, event) function mapUtils.queueGeneratedChunk(universe, event)
event.tick = (event.tick or game.tick) + 20 event.tick = (event.tick or game.tick) + 20
universe.maps[event.surface.index].pendingChunks[event] = true local map = universe.maps[event.surface.index]
event.id = map.eventId
map.pendingChunks[event.id] = event
map.eventId = map.eventId + 1
end end
--[[ --[[
@@ -220,6 +227,5 @@ function mapUtils.positionFromDirectionAndFlat(direction, startPosition, endPosi
endPosition.y = ly endPosition.y = ly
end end
mapUtilsG = mapUtils mapUtilsG = mapUtils
return mapUtils return mapUtils

View File

@@ -51,7 +51,7 @@ function movementUtils.addMovementPenalty(squad, chunk)
local penaltyCount = #penalties local penaltyCount = #penalties
for i=1,penaltyCount do for i=1,penaltyCount do
local penalty = penalties[i] local penalty = penalties[i]
if (penalty.c == chunk) then if (penalty.c.id == chunk.id) then
penalty.v = penalty.v + 1 penalty.v = penalty.v + 1
if (penalty.v > 2) then if (penalty.v > 2) then
squad.kamikaze = true squad.kamikaze = true
@@ -79,7 +79,7 @@ function movementUtils.scoreNeighborsForAttack(map, chunk, neighborDirectionChun
for x=1,8 do for x=1,8 do
local neighborChunk = neighborDirectionChunks[x] local neighborChunk = neighborDirectionChunks[x]
if (neighborChunk ~= -1) then if (neighborChunk ~= -1) then
if canMoveChunkDirection(map, x, chunk, neighborChunk) or (chunk == -1) then if (chunk == -1) or canMoveChunkDirection(map, x, chunk, neighborChunk) then
local score = scoreFunction(map, neighborChunk) local score = scoreFunction(map, neighborChunk)
if (score > highestScore) then if (score > highestScore) then
highestScore = score highestScore = score
@@ -98,7 +98,7 @@ function movementUtils.scoreNeighborsForAttack(map, chunk, neighborDirectionChun
neighborDirectionChunks = getNeighborChunks(map, highestChunk.x, highestChunk.y) neighborDirectionChunks = getNeighborChunks(map, highestChunk.x, highestChunk.y)
for x=1,8 do for x=1,8 do
local neighborChunk = neighborDirectionChunks[x] local neighborChunk = neighborDirectionChunks[x]
if ((neighborChunk ~= -1) and (neighborChunk ~= chunk) and if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then
local score = scoreFunction(map, neighborChunk) local score = scoreFunction(map, neighborChunk)
if (score > nextHighestScore) then if (score > nextHighestScore) then
@@ -125,7 +125,7 @@ function movementUtils.scoreNeighborsForSettling(map, chunk, neighborDirectionCh
for x=1,8 do for x=1,8 do
local neighborChunk = neighborDirectionChunks[x] local neighborChunk = neighborDirectionChunks[x]
if (neighborChunk ~= -1) then if (neighborChunk ~= -1) then
if canMoveChunkDirection(map, x, chunk, neighborChunk) or (chunk == -1) then if (chunk == -1) or canMoveChunkDirection(map, x, chunk, neighborChunk) then
local score = scoreFunction(map, neighborChunk) local score = scoreFunction(map, neighborChunk)
if (score > highestScore) then if (score > highestScore) then
highestScore = score highestScore = score
@@ -148,7 +148,7 @@ function movementUtils.scoreNeighborsForSettling(map, chunk, neighborDirectionCh
neighborDirectionChunks = getNeighborChunks(map, highestChunk.x, highestChunk.y) neighborDirectionChunks = getNeighborChunks(map, highestChunk.x, highestChunk.y)
for x=1,8 do for x=1,8 do
local neighborChunk = neighborDirectionChunks[x] local neighborChunk = neighborDirectionChunks[x]
if ((neighborChunk ~= -1) and (neighborChunk ~= chunk) and if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then
local score = scoreFunction(map, neighborChunk) local score = scoreFunction(map, neighborChunk)
if (score > nextHighestScore) then if (score > nextHighestScore) then
@@ -203,7 +203,7 @@ function movementUtils.scoreNeighborsForRetreat(chunk, neighborDirectionChunks,
for x=1,8 do for x=1,8 do
local neighborChunk = neighborDirectionChunks[x] local neighborChunk = neighborDirectionChunks[x]
if (neighborChunk ~= -1) then if (neighborChunk ~= -1) then
if canMoveChunkDirection(map, x, chunk, neighborChunk) or (chunk == -1) then if (chunk == -1) or canMoveChunkDirection(map, x, chunk, neighborChunk) then
local score = scoreFunction(map, neighborChunk) local score = scoreFunction(map, neighborChunk)
if (score > highestScore) then if (score > highestScore) then
highestScore = score highestScore = score
@@ -223,7 +223,7 @@ function movementUtils.scoreNeighborsForRetreat(chunk, neighborDirectionChunks,
for x=1,8 do for x=1,8 do
local neighborChunk = neighborDirectionChunks[x] local neighborChunk = neighborDirectionChunks[x]
if ((neighborChunk ~= -1) and (neighborChunk ~= chunk) and if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then
local score = scoreFunction(map, neighborChunk) local score = scoreFunction(map, neighborChunk)
if (score > nextHighestScore) then if (score > nextHighestScore) then

View File

@@ -37,6 +37,7 @@ local addVictoryGenerator = chunkPropertyUtils.addVictoryGenerator
local getPlayersOnChunk = chunkPropertyUtils.getPlayersOnChunk local getPlayersOnChunk = chunkPropertyUtils.getPlayersOnChunk
local getNeighborChunks = mapUtils.getNeighborChunks local getNeighborChunks = mapUtils.getNeighborChunks
local getChunkById = mapUtils.getChunkById
local getEnemyStructureCount = chunkPropertyUtils.getEnemyStructureCount local getEnemyStructureCount = chunkPropertyUtils.getEnemyStructureCount
local getPathRating = chunkPropertyUtils.getPathRating local getPathRating = chunkPropertyUtils.getPathRating
@@ -63,18 +64,20 @@ function pheromoneUtils.victoryScent(map, chunk, entityType)
end end
function pheromoneUtils.disperseVictoryScent(map) function pheromoneUtils.disperseVictoryScent(map)
local chunk = map.victoryScentIterator local chunkId = map.victoryScentIterator
local chunkToVictory = map.chunkToVictory local chunkToVictory = map.chunkToVictory
local pheromone local pheromone
if not chunk then if not chunkId then
chunk, pheromone = next(chunkToVictory, nil) chunkId, pheromone = next(chunkToVictory, nil)
else else
pheromone = chunkToVictory[chunk] pheromone = chunkToVictory[chunkId]
end end
if not chunk then if not chunkId then
map.victoryScentIterator = nil map.victoryScentIterator = nil
else else
map.victoryScentIterator = next(chunkToVictory, chunk) map.victoryScentIterator = next(chunkToVictory, chunkId)
chunkToVictory[chunkId] = nil
local chunk = getChunkById(map, chunkId)
local chunkX = chunk.x local chunkX = chunk.x
local chunkY = chunk.y local chunkY = chunk.y
local i = 1 local i = 1
@@ -87,8 +90,6 @@ function pheromoneUtils.disperseVictoryScent(map)
i = i + 1 i = i + 1
end end
end end
chunkToVictory[chunk] = nil
end end
end end

View File

@@ -118,9 +118,14 @@ local function settleMove(map, squad)
elseif squad.kamikaze then elseif squad.kamikaze then
scoreFunction = scoreResourceLocationKamikaze scoreFunction = scoreResourceLocationKamikaze
end end
addDeathGenerator(map, chunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) local squadChunk = squad.chunk
addSquadToChunk(map, chunk, squad) if squadChunk ~= -1 then
addMovementPenalty(squad, chunk) addDeathGenerator(map, squadChunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
end
if chunk ~= -1 then
addSquadToChunk(map, chunk, squad)
addMovementPenalty(squad, chunk)
end
local distance = euclideanDistancePoints(groupPosition.x, local distance = euclideanDistancePoints(groupPosition.x,
groupPosition.y, groupPosition.y,
squad.originPosition.x, squad.originPosition.x,
@@ -129,7 +134,8 @@ local function settleMove(map, squad)
local position local position
local surface = map.surface local surface = map.surface
if (distance >= squad.maxDistance) or ((getResourceGenerator(map, chunk) ~= 0) and (getNestCount(map, chunk) == 0)) if (chunk ~= -1) and
((distance >= squad.maxDistance) or ((getResourceGenerator(map, chunk) ~= 0) and (getNestCount(map, chunk) == 0)))
then then
position = findMovementPosition(surface, groupPosition) position = findMovementPosition(surface, groupPosition)
@@ -244,9 +250,13 @@ local function attackMove(map, squad)
attackScorer = scoreAttackKamikazeLocation attackScorer = scoreAttackKamikazeLocation
end end
local squadChunk = squad.chunk local squadChunk = squad.chunk
addDeathGenerator(map, squadChunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) if squadChunk ~= -1 then
addSquadToChunk(map, chunk, squad) addDeathGenerator(map, squadChunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
addMovementPenalty(squad, chunk) end
if chunk ~= -1 then
addSquadToChunk(map, chunk, squad)
addMovementPenalty(squad, chunk)
end
squad.frenzy = (squad.frenzy and (euclideanDistanceNamed(groupPosition, squad.frenzyPosition) < 100)) squad.frenzy = (squad.frenzy and (euclideanDistanceNamed(groupPosition, squad.frenzyPosition) < 100))
local attackChunk, attackDirection, local attackChunk, attackDirection,
nextAttackChunk, nextAttackDirection = scoreNeighborsForAttack(map, nextAttackChunk, nextAttackDirection = scoreNeighborsForAttack(map,
@@ -275,7 +285,7 @@ local function attackMove(map, squad)
else else
targetPosition.x = position.x targetPosition.x = position.x
targetPosition.y = position.y targetPosition.y = position.y
if nextAttackChunk then if (nextAttackChunk ~= -1) then
addDeathGenerator(map, nextAttackChunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) addDeathGenerator(map, nextAttackChunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
else else
addDeathGenerator(map, attackChunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) addDeathGenerator(map, attackChunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
@@ -322,26 +332,28 @@ end
function squadAttack.cleanSquads(map, tick) function squadAttack.cleanSquads(map, tick)
local squads = map.groupNumberToSquad local squads = map.groupNumberToSquad
local k = map.squadIterator local groupId = map.squadIterator
local squad local squad
if not k then if not groupId then
k, squad = next(squads, k) groupId, squad = next(squads, groupId)
else else
squad = squads[k] squad = squads[groupId]
end end
if not k then if not groupId then
map.squadIterator = nil map.squadIterator = nil
if (table_size(squads) == 0) then if (table_size(squads) == 0) then
-- this is needed as the next command remembers the max length a table has been -- this is needed as the next command remembers the max length a table has been
map.groupNumberToSquad = {} map.groupNumberToSquad = {}
end end
else else
map.squadIterator = next(squads, k) map.squadIterator = next(squads, groupId)
local group = squad.group local group = squad.group
if not group.valid then if not group.valid then
addDeathGenerator(map, squad.chunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) if squad.chunk ~= -1 then
addDeathGenerator(map, squad.chunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
end
removeSquadFromChunk(map, squad) removeSquadFromChunk(map, squad)
if (map.regroupIterator == k) then if (map.regroupIterator == groupId) then
map.regroupIterator = nil map.regroupIterator = nil
end end
local universe = map.universe local universe = map.universe
@@ -350,7 +362,7 @@ function squadAttack.cleanSquads(map, tick)
else else
universe.squadCount = universe.squadCount - 1 universe.squadCount = universe.squadCount - 1
end end
squads[k] = nil squads[groupId] = nil
elseif (group.state == 4) then elseif (group.state == 4) then
squadAttack.squadDispatch(map, squad, tick) squadAttack.squadDispatch(map, squad, tick)
elseif (squad.commandTick and (squad.commandTick < tick)) then elseif (squad.commandTick and (squad.commandTick < tick)) then