diff --git a/changelog.txt b/changelog.txt index ecb5515..d825e6b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -61,6 +61,7 @@ Version: 3.2.0 - Centralized base points manipulation and chat messaging (Dagothur) - Base point deductions for unit losses are now batched in 20 to reduce chat spam when using the print AI points to chat options (Dagothur) - Reduced corpse and particle variation to optimize increased entity times due to high entity counts + - Moved map properties directly into chunk object --------------------------------------------------------------------------------------------------- Version: 3.1.2 diff --git a/control.lua b/control.lua index 8c47f27..a7645fe 100644 --- a/control.lua +++ b/control.lua @@ -189,10 +189,10 @@ local function onIonCannonFired(event) local chunk = getChunkByPosition(map, event.position) if (chunk ~= -1) then - local base = findNearbyBase(map, chunk) + local base = findNearbyBase(chunk) if base then base.ionCannonBlasts = base.ionCannonBlasts + 1 - rallyUnits(chunk, map, event.tick, base) + rallyUnits(chunk, event.tick, base) modifyBaseUnitPoints(base, 4000, "Ion Cannon") end end @@ -240,8 +240,6 @@ end local function onLoad() Universe = global.universe - initializeLibraries() - hookEvents() end @@ -353,7 +351,7 @@ local function onConfigChanged() prepMap(surface) end end - addBasesToAllEnemyStructures(game.tick) + -- addBasesToAllEnemyStructures(game.tick) if not Universe.ranIncompatibleMessage and Universe.newEnemies and (game.active_mods["bobenemies"] or game.active_mods["Natural_Evolution_Enemies"]) then @@ -372,14 +370,14 @@ local function onEnemyBaseBuild(event) map.activeSurface = true local chunk = getChunkByPosition(map, entity.position) if (chunk ~= -1) then - local base = findNearbyBase(map, chunk) + local base = findNearbyBase(chunk) if not base then base = createBase(map, chunk, event.tick) end - registerEnemyBaseStructure(map, entity, base) + registerEnemyBaseStructure(map, entity, base, event.tick) if Universe.NEW_ENEMIES then queueUpgrade(entity, @@ -483,7 +481,7 @@ local function onDeath(event) if (chunk ~= -1) then if not base then - base = findNearbyBase(map, chunk) + base = findNearbyBase(chunk) end local artilleryBlast = (cause and ((cause.type == "artillery-wagon") or (cause.type == "artillery-turret"))) @@ -499,14 +497,14 @@ local function onDeath(event) modifyBaseUnitPoints(base, -(20*UNIT_DEATH_POINT_COST), "20 Units Lost") end if (Universe.random() < Universe.rallyThreshold) and not surface.peaceful_mode then - rallyUnits(chunk, map, tick, base) + rallyUnits(chunk, tick, base) end if artilleryBlast then base.artilleryBlasts = base.artilleryBlasts + 1 end end - if (getCombinedDeathGeneratorRating(map, chunk) < Universe.retreatThreshold) and cause and cause.valid then + if (getCombinedDeathGeneratorRating(chunk) < Universe.retreatThreshold) and cause and cause.valid then retreatUnits(chunk, cause, map, @@ -517,14 +515,14 @@ local function onDeath(event) (entityType == "unit-spawner") or (entityType == "turret") then - deathScent(map, chunk, true) + deathScent(chunk, true) if base then if (entityType == "unit-spawner") then modifyBaseUnitPoints(base, RECOVER_NEST_COST, "Nest Lost") elseif (entityType == "turret") then modifyBaseUnitPoints(base, RECOVER_WORM_COST, "Worm Lost") end - rallyUnits(chunk, map, tick, base) + rallyUnits(chunk, tick, base) if artilleryBlast then base.artilleryBlasts = base.artilleryBlasts + 1 end @@ -545,7 +543,7 @@ local function onDeath(event) creditNatives = true local drained = false if chunk ~= -1 then - victoryScent(map, chunk, entityType) + victoryScent(chunk, entityType) drained = (entityType == "electric-turret") and isDrained(chunk, tick) if cause and cause.type == "unit" then local group = cause.unit_group @@ -557,7 +555,7 @@ local function onDeath(event) end end if not base then - base = findNearbyBase(map, chunk) + base = findNearbyBase(chunk) end end @@ -680,7 +678,7 @@ local function onRocketLaunch(event) end local chunk = getChunkByPosition(map, entity.position) if (chunk ~= -1) then - local base = findNearbyBase(map, chunk) + local base = findNearbyBase(chunk) if base then base.rocketLaunched = base.rocketLaunched + 1 modifyBaseUnitPoints(base, 5000, "Rocket Launch") @@ -701,7 +699,7 @@ local function onEntitySpawned(entity, tick) local chunk = getChunkByPosition(map, disPos) if (chunk ~= -1) then - local base = findNearbyBase(map, chunk) + local base = findNearbyBase(chunk) if not base then base = createBase(map, chunk, @@ -750,7 +748,7 @@ local function onTriggerEntityCreated(event) end local chunk = getChunkByPosition(map, entity.position) if (chunk ~= -1) then - setDrainedTick(map, chunk, event.tick) + setDrainedTick(chunk, event.tick) end elseif (event.target_position) then local map = Universe.maps[event.surface_index] @@ -759,7 +757,7 @@ local function onTriggerEntityCreated(event) end local chunk = getChunkByPosition(map, event.target_position) if (chunk ~= -1) then - setDrainedTick(map, chunk, event.tick) + setDrainedTick(chunk, event.tick) end end elseif (event.effect_id == "deathLandfillParticle--rampant") then @@ -806,7 +804,7 @@ local function onUnitGroupCreated(event) if (chunk == -1) then base = findNearbyBaseByPosition(map, position.x, position.y) else - base = findNearbyBase(map, chunk) + base = findNearbyBase(chunk) end if not base then group.destroy() @@ -908,7 +906,7 @@ local function onGroupFinishedGathering(event) if chunk == -1 then base = findNearbyBaseByPosition(map, position.x, position.y) else - base = findNearbyBase(map, chunk) + base = findNearbyBase(chunk) end if not base then group.destroy() @@ -1057,7 +1055,6 @@ script.on_event(defines.events.on_tick, elseif (pick == 3) then disperseVictoryScent() processAttackWaves() - processNests(tick) processClouds(tick) elseif (pick == 4) then if map then @@ -1083,7 +1080,7 @@ script.on_event(defines.events.on_tick, end processBaseAIs(tick) - processActiveNests(tick) + processNests(tick) processPendingUpgrades(tick) processPendingUpgrades(tick) cleanSquads(tick) @@ -1229,13 +1226,14 @@ local function removeNewEnemies() }) local chunk = getChunkByPosition(map, position) if chunk ~= -1 then - local base = findNearbyBase(map, chunk) + local tick = game.tick + local base = findNearbyBase(chunk) if not base then base = createBase(map, chunk, - game.tick) + tick) end - registerEnemyBaseStructure(map, newEntity, base) + registerEnemyBaseStructure(map, newEntity, base, tick) end end end @@ -1324,13 +1322,14 @@ local function removeFaction(cmd) }) local chunk = getChunkByPosition(map, position) if chunk ~= -1 then - local base = findNearbyBase(map, chunk) + local tick = game.tick + local base = findNearbyBase(chunk) if not base then base = createBase(map, chunk, - game.tick) + tick) end - registerEnemyBaseStructure(map, newEntity, base) + registerEnemyBaseStructure(map, newEntity, base, tick) end end end diff --git a/libs/AIAttackWave.lua b/libs/AIAttackWave.lua index d62cbb0..93fc1f2 100644 --- a/libs/AIAttackWave.lua +++ b/libs/AIAttackWave.lua @@ -64,9 +64,8 @@ local calculateKamikazeSquadThreshold = unitGroupUtils.calculateKamikazeSquadThr local positionFromDirectionAndChunk = mapUtils.positionFromDirectionAndChunk local getPassable = chunkPropertyUtils.getPassable -local getNestCount = chunkPropertyUtils.getNestCount -local getRaidNestActiveness = chunkPropertyUtils.getRaidNestActiveness -local getNestActiveness = chunkPropertyUtils.getNestActiveness +local isActiveRaidNest = chunkPropertyUtils.isActiveRaidNest +local isActiveNest = chunkPropertyUtils.isActiveNest local getRallyTick = chunkPropertyUtils.getRallyTick local setRallyTick = chunkPropertyUtils.setRallyTick @@ -101,14 +100,16 @@ local function attackWaveScaling() end local function attackWaveValidCandidate(chunk, base) - local isValid = getNestActiveness(chunk) + if isActiveNest(chunk) then + return true + end if (base.stateAI == BASE_AI_STATE_RAIDING) or (base.stateAI == BASE_AI_STATE_SIEGE) or (base.stateAI == BASE_AI_STATE_ONSLAUGHT) then - isValid = isValid + getRaidNestActiveness(chunk) + return isActiveRaidNest(chunk) end - return (isValid > 0) + return false end local function scoreSettlerLocation(map, neighborChunk) @@ -124,20 +125,20 @@ local function scoreUnitGroupLocation(map, neighborChunk) end local function validSiegeSettlerLocation(map, neighborChunk) - return (getPassable(map, neighborChunk) == CHUNK_ALL_DIRECTIONS) and - (getNestCount(neighborChunk) == 0) + return (getPassable(neighborChunk) == CHUNK_ALL_DIRECTIONS) and + (not neighborChunk.nestCount) end local function validSettlerLocation(map, chunk, neighborChunk) local chunkResource = chunk[RESOURCE_PHEROMONE] - return (getPassable(map, neighborChunk) == CHUNK_ALL_DIRECTIONS) and - (getNestCount(neighborChunk) == 0) and + return (getPassable(neighborChunk) == CHUNK_ALL_DIRECTIONS) and + (not neighborChunk.nestCount) and (neighborChunk[RESOURCE_PHEROMONE] >= chunkResource) end local function validUnitGroupLocation(map, neighborChunk) - return getPassable(map, neighborChunk) == CHUNK_ALL_DIRECTIONS and - (getNestCount(neighborChunk) == 0) + return getPassable(neighborChunk) == CHUNK_ALL_DIRECTIONS and + (not neighborChunk.nestCount) end local function visitPattern(o, cX, cY, distance) @@ -179,18 +180,19 @@ local function visitPattern(o, cX, cY, distance) return startX, endX, stepX, startY, endY, stepY end -function aiAttackWave.rallyUnits(chunk, map, tick, base) +function aiAttackWave.rallyUnits(chunk, tick, base) if ((tick - getRallyTick(chunk) > COOLDOWN_RALLY) and (base.unitPoints >= AI_VENGENCE_SQUAD_COST)) then - setRallyTick(map, chunk, tick) + setRallyTick(chunk, tick) local cX = chunk.x local cY = chunk.y local startX, endX, stepX, startY, endY, stepY = visitPattern(tick % 4, cX, cY, RALLY_CRY_DISTANCE) local vengenceQueue = Universe.vengenceQueue + local map = chunk.map for x=startX, endX, stepX do for y=startY, endY, stepY do if (x ~= cX) and (y ~= cY) then local rallyChunk = getChunkByXY(map, x, y) - if (rallyChunk ~= -1) and (getNestCount(rallyChunk) > 0) then + if (rallyChunk ~= -1) and rallyChunk.nestCount then local pack = vengenceQueue[rallyChunk.id] if not pack then pack = { @@ -210,12 +212,13 @@ function aiAttackWave.rallyUnits(chunk, map, tick, base) end end -function aiAttackWave.formSettlers(map, chunk, base) +function aiAttackWave.formSettlers(chunk, base) if (Universe.builderCount < Universe.AI_MAX_BUILDER_COUNT) and (base.sentExpansionGroups < base.maxExpansionGroups) and ((base.unitPoints - AI_SETTLER_COST) > 0) and (Universe.random() < Universe.formSquadThreshold) then + local map = chunk.map local surface = map.surface local squadPath, squadDirection if (base.stateAI == BASE_AI_STATE_SIEGE) then @@ -269,7 +272,7 @@ function aiAttackWave.formSettlers(map, chunk, base) end end -function aiAttackWave.formVengenceSquad(map, chunk, base) +function aiAttackWave.formVengenceSquad(chunk, base) if (Universe.squadCount < Universe.AI_MAX_SQUAD_COUNT) and ((base.unitPoints - AI_VENGENCE_SQUAD_COST) > 0) and (Universe.random() < Universe.formSquadThreshold) @@ -277,6 +280,7 @@ function aiAttackWave.formVengenceSquad(map, chunk, base) if (chunk[BASE_PHEROMONE] < 0.0001) or (chunk[PLAYER_PHEROMONE] < 0.0001) then return end + local map = chunk.map local surface = map.surface local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y), @@ -316,12 +320,13 @@ function aiAttackWave.formVengenceSquad(map, chunk, base) end end -function aiAttackWave.formVengenceSettler(map, chunk, base) +function aiAttackWave.formVengenceSettler(chunk, base) if (Universe.builderCount < Universe.AI_MAX_BUILDER_COUNT) and (base.sentExpansionGroups < base.maxExpansionGroups) and ((base.unitPoints - AI_VENGENCE_SQUAD_COST) > 0) and (Universe.random() < Universe.formSquadThreshold) then + local map = chunk.map local surface = map.surface local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y), validUnitGroupLocation, @@ -362,7 +367,7 @@ function aiAttackWave.formVengenceSettler(map, chunk, base) end end -function aiAttackWave.formSquads(map, chunk, base) +function aiAttackWave.formSquads(chunk, base) if (Universe.squadCount < Universe.AI_MAX_SQUAD_COUNT) and attackWaveValidCandidate(chunk, base) and ((base.unitPoints - AI_SQUAD_COST) > 0) @@ -372,6 +377,7 @@ function aiAttackWave.formSquads(map, chunk, base) return end + local map = chunk.map local surface = map.surface local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y), validUnitGroupLocation, diff --git a/libs/BaseUtils.lua b/libs/BaseUtils.lua index fff9113..ef7871f 100644 --- a/libs/BaseUtils.lua +++ b/libs/BaseUtils.lua @@ -81,8 +81,6 @@ local tableRemove = table.remove local mMin = math.min local mMax = math.max -local getResourceGenerator = chunkPropertyUtils.getResourceGenerator - local next = next -- module code @@ -255,7 +253,7 @@ function BaseUtils.findEntityUpgrade(baseAlignment, currentEvo, evoIndex, origin or ( (roll <= 0.210) and - (getResourceGenerator(map, chunk) > 0) + chunk.resourceGenerator ) ) return initialEntityUpgrade(baseAlignment, tier, maxTier, map, (makeHive and "hive"), entityType) diff --git a/libs/ChunkProcessor.lua b/libs/ChunkProcessor.lua index 5ef45ff..37f0b50 100644 --- a/libs/ChunkProcessor.lua +++ b/libs/ChunkProcessor.lua @@ -165,7 +165,7 @@ function ChunkProcessor.processPendingUpgrades(tick) local pickedBaseAlignment if baseAlignment[2] then - if map.random() < 0.75 then + if Universe.random() < 0.75 then pickedBaseAlignment = baseAlignment[2] else pickedBaseAlignment = baseAlignment[1] @@ -213,7 +213,7 @@ function ChunkProcessor.processPendingUpgrades(tick) }) if createdEntity and createdEntity.valid then if entityData.register then - registerEnemyBaseStructure(map, createdEntity, base, true) + registerEnemyBaseStructure(map, createdEntity, base, tick, true) end if not entityData.evolve and Universe.printBaseUpgrades then surface.print("["..base.id.."]:"..surface.name.." Upgrading ".. entityName .. " to " .. name .. " [gps=".. position.x ..",".. position.y .."]") diff --git a/libs/ChunkPropertyUtils.lua b/libs/ChunkPropertyUtils.lua index 6be72e1..a95462b 100644 --- a/libs/ChunkPropertyUtils.lua +++ b/libs/ChunkPropertyUtils.lua @@ -22,6 +22,7 @@ local ChunkPropertyUtils = {} -- local Universe +local Position -- @@ -30,6 +31,8 @@ local MathUtils = require("MathUtils") -- Constants +local DURATION_ACTIVE_NEST = Constants.DURATION_ACTIVE_NEST + local PLAYER_GENERATOR_PERSISTANCE = Constants.PLAYER_GENERATOR_PERSISTANCE local PLAYER_PHEROMONE_GENERATOR_AMOUNT = Constants.PLAYER_PHEROMONE_GENERATOR_AMOUNT @@ -54,217 +57,179 @@ local mMin = math.min -- module code -function ChunkPropertyUtils.getTurretCount(map, chunk) - return map.chunkToTurrets[chunk.id] or 0 +local function getActiveTick(chunk) + return chunk.activeTick or 0 end -function ChunkPropertyUtils.getTrapCount(map, chunk) - return map.chunkToTraps[chunk.id] or 0 +local function registerActiveSpawner(chunk, register, activeType, tick) + if Universe[register][chunk.id] then + return + end + + chunk.activeTick = tick + DURATION_ACTIVE_NEST + + local base = chunk.base + base[activeType] = base[activeType] + 1 + Universe[register][chunk.id] = chunk end -function ChunkPropertyUtils.getUtilityCount(map, chunk) - return map.chunkToUtilities[chunk.id] or 0 +local function unregisterActiveSpawner(chunk, register, activeType) + if not Universe[register][chunk.id] then + return + end + + chunk.activeTick = nil + + local base = chunk.base + base[activeType] = base[activeType] - 1 + if (Universe.processActiveSpawnerIterator == chunk.id) then + Universe.processActiveSpawnerIterator = nil + end + Universe[register][chunk.id] = nil end -function ChunkPropertyUtils.getHiveCount(map, chunk) - return map.chunkToHives[chunk.id] or 0 +local function registerActiveNest(chunk, tick) + registerActiveSpawner(chunk, "chunkToActiveNest", "activeNests", tick) end -function ChunkPropertyUtils.addTurretCount(map, chunk, unitNumber) - map.activeSurface = true - if not map.chunkToTurretIds[chunk.id] then - map.chunkToTurretIds[chunk.id] = {} - end - if not map.chunkToTurretIds[chunk.id][unitNumber] then - map.chunkToTurretIds[chunk.id][unitNumber] = true - map.chunkToTurrets[chunk.id] = (map.chunkToTurrets[chunk.id] or 0) + 1 - return true - end - return false +local function registerActiveRaidNest(chunk, tick) + registerActiveSpawner(chunk, "chunkToActiveRaidNest", "activeRaidNests", tick) end -function ChunkPropertyUtils.removeTurretCount(map, chunk, unitNumber) - if map.chunkToTurretIds[chunk.id] and map.chunkToTurretIds[chunk.id][unitNumber] then - map.chunkToTurretIds[chunk.id][unitNumber] = nil - map.chunkToTurrets[chunk.id] = map.chunkToTurrets[chunk.id] - 1 - if map.chunkToTurrets[chunk.id] == 0 then - map.chunkToTurretIds[chunk.id] = nil - map.chunkToTurrets[chunk.id] = nil - end - return true - end - return false +local function unregisterActiveNest(chunk) + unregisterActiveSpawner(chunk, "chunkToActiveNest", "activeNests") end -function ChunkPropertyUtils.addTrapCount(map, chunk, unitNumber) - map.activeSurface = true - if not map.chunkToTrapIds[chunk.id] then - map.chunkToTrapIds[chunk.id] = {} - end - if not map.chunkToTrapIds[chunk.id][unitNumber] then - map.chunkToTrapIds[chunk.id][unitNumber] = true - map.chunkToTraps[chunk.id] = (map.chunkToTraps[chunk.id] or 0) + 1 - return true - end - return false +local function unregisterActiveRaidNest(chunk) + unregisterActiveSpawner(chunk, "chunkToActiveRaidNest", "activeRaidNests") end -function ChunkPropertyUtils.removeTrapCount(map, chunk, unitNumber) - if map.chunkToTrapIds[chunk.id] and map.chunkToTrapIds[chunk.id][unitNumber] then - map.chunkToTrapIds[chunk.id][unitNumber] = nil - map.chunkToTraps[chunk.id] = map.chunkToTraps[chunk.id] - 1 - if map.chunkToTraps[chunk.id] == 0 then - map.chunkToTrapIds[chunk.id] = nil - map.chunkToTraps[chunk.id] = nil - end - return true - end - return false -end - -function ChunkPropertyUtils.addUtilitiesCount(map, chunk, unitNumber) - map.activeSurface = true - if not map.chunkToUtilityIds[chunk.id] then - map.chunkToUtilityIds[chunk.id] = {} - end - if not map.chunkToUtilityIds[chunk.id][unitNumber] then - map.chunkToUtilityIds[chunk.id][unitNumber] = true - map.chunkToUtilities[chunk.id] = (map.chunkToUtilities[chunk.id] or 0) + 1 - return true - end - return false -end - -function ChunkPropertyUtils.removeUtilitiesCount(map, chunk, unitNumber) - if map.chunkToUtilityIds[chunk.id] and map.chunkToUtilityIds[chunk.id][unitNumber] then - map.chunkToUtilityIds[chunk.id][unitNumber] = nil - map.chunkToUtilities[chunk.id] = map.chunkToUtilities[chunk.id] - 1 - if map.chunkToUtilities[chunk.id] == 0 then - map.chunkToUtilityIds[chunk.id] = nil - map.chunkToUtilities[chunk.id] = nil - end - return true - end - return false -end - -function ChunkPropertyUtils.addHiveCount(map, chunk, unitNumber) - map.activeSurface = true - if not map.chunkToHiveIds[chunk.id] then - map.chunkToHiveIds[chunk.id] = {} - end - if not map.chunkToHiveIds[chunk.id][unitNumber] then - map.chunkToHiveIds[chunk.id][unitNumber] = true - map.chunkToHives[chunk.id] = (map.chunkToHives[chunk.id] or 0) + 1 - return true - end - return false -end - -function ChunkPropertyUtils.removeHiveCount(map, chunk, unitNumber) - if map.chunkToHiveIds[chunk.id] and map.chunkToHiveIds[chunk.id][unitNumber] then - map.chunkToHiveIds[chunk.id][unitNumber] = nil - map.chunkToHives[chunk.id] = map.chunkToHives[chunk.id] - 1 - if map.chunkToHives[chunk.id] == 0 then - map.chunkToHiveIds[chunk.id] = nil - map.chunkToHives[chunk.id] = nil - end - return true - end - return false -end - -function ChunkPropertyUtils.addNestCount(map, chunk, unitNumber) - map.activeSurface = true +local function addEnemyStructure(chunk, unitNumber, ids, counts, register) + chunk.map.activeSurface = true local chunkId = chunk.id - if not map.chunkToNestIds[chunkId] then - map.chunkToNestIds[chunkId] = {} + local entityIds = chunk[ids] + if not entityIds then + entityIds = {} + chunk[ids] = entityIds end - if not map.chunkToNestIds[chunkId][unitNumber] then - map.chunkToNestIds[chunkId][unitNumber] = true - local cToN = Universe.chunkToNests - local pack = cToN[chunkId] - if not pack then - cToN[chunkId] = { - map = map, - v = 0 - } + if not entityIds[unitNumber] then + entityIds[unitNumber] = true + chunk[counts] = (chunk[counts] or 0) + 1 + if register then + Universe[register][chunkId] = chunk end - cToN[chunkId].v = cToN[chunkId].v + 1 return true end return false end -function ChunkPropertyUtils.removeNestCount(map, chunk, unitNumber) +local function removeEnemyStructure(chunk, unitNumber, ids, counts, register) local chunkId = chunk.id - if map.chunkToNestIds[chunkId] and map.chunkToNestIds[chunkId][unitNumber] then - map.chunkToNestIds[chunkId][unitNumber] = nil - local cToN = Universe.chunkToNests - cToN[chunkId].v = cToN[chunkId].v - 1 - if cToN[chunkId].v == 0 then - map.chunkToNestIds[chunkId] = nil - cToN[chunkId] = nil - if (Universe.processMigrationIterator == chunkId) then - Universe.processMigrationIterator = nil - end - if (Universe.processNestIterator == chunkId) then - Universe.processNestIterator = nil - end + local entityIds = chunk[ids] + if entityIds and entityIds[unitNumber] then + entityIds[unitNumber] = nil + chunk[counts] = chunk[counts] - 1 + if chunk[counts] > 0 then + return true + end + + chunk[ids] = nil + chunk[counts] = nil + if register then + Universe[register][chunkId] = nil + end + if (Universe.processMigrationIterator == chunkId) then + Universe.processMigrationIterator = nil + end + if (Universe.processNestIterator == chunkId) then + Universe.processNestIterator = nil end return true end return false end -function ChunkPropertyUtils.getNestCount(chunk) - local nestPack = Universe.chunkToNests[chunk.id] - if not nestPack then - return 0 - end - return nestPack.v +function ChunkPropertyUtils.addTurretCount(chunk, unitNumber) + return addEnemyStructure(chunk, unitNumber, "turretIds", "turretCount") +end + +function ChunkPropertyUtils.removeTurretCount(chunk, unitNumber) + return removeEnemyStructure(chunk, unitNumber, "turretIds", "turretCount") +end + +function ChunkPropertyUtils.addUtilitiesCount(chunk, unitNumber) + return addEnemyStructure(chunk, unitNumber, "utilityIds", "utilityCount", "chunkToUtilities") +end + +function ChunkPropertyUtils.removeUtilitiesCount(chunk, unitNumber) + return removeEnemyStructure(chunk, unitNumber, "utilityIds", "utilityCount", "chunkToUtilities") +end + +function ChunkPropertyUtils.addHiveCount(chunk, unitNumber) + return addEnemyStructure(chunk, unitNumber, "hiveIds", "hiveCount", "chunkToHives") +end + +function ChunkPropertyUtils.removeHiveCount(chunk, unitNumber) + return removeEnemyStructure(chunk, unitNumber, "hiveIds", "hiveCount", "chunkToHives") +end + +function ChunkPropertyUtils.addNestCount(chunk, unitNumber) + return addEnemyStructure(chunk, unitNumber, "nestIds", "nestCount", "chunkToNests") +end + +function ChunkPropertyUtils.removeNestCount(chunk, unitNumber) + return removeEnemyStructure(chunk, unitNumber, "nestIds", "nestCount", "chunkToNests") +end + +function ChunkPropertyUtils.isActiveNest(chunk) + return Universe.chunkToActiveNest[chunk.id] ~= nil +end + +function ChunkPropertyUtils.isActiveRaidNest(chunk) + return Universe.chunkToActiveRaidNest[chunk.id] ~= nil end function ChunkPropertyUtils.addBaseResourceChunk(base, chunk) - if ChunkPropertyUtils.getResourceGenerator(base.map, chunk) > 0 then - base.resourceChunkCount = base.resourceChunkCount + 1 - base.resourceChunks[chunk.id] = true + if not chunk.resourceGenerator then + return end + + base.resourceChunkCount = base.resourceChunkCount + 1 + base.resourceChunks[chunk.id] = true end function ChunkPropertyUtils.removeBaseResourceChunk(base, chunk) - if base.resourceChunks[chunk.id] then - base.resourceChunkCount = base.resourceChunkCount - 1 - base.resourceChunks[chunk.id] = nil + if not base.resourceChunks[chunk.id] then + return end + + base.resourceChunkCount = base.resourceChunkCount - 1 + base.resourceChunks[chunk.id] = nil end -function ChunkPropertyUtils.getChunkBase(map, chunk) - return map.chunkToBase[chunk.id] +function ChunkPropertyUtils.removeChunkBase(chunk, base) + if not chunk.base then + return + end + + base.chunkCount = base.chunkCount - 1 + chunk.base = nil end -function ChunkPropertyUtils.removeChunkBase(map, chunk, base) - if map.chunkToBase[chunk.id] then - base.chunkCount = base.chunkCount - 1 - map.chunkToBase[chunk.id] = nil +function ChunkPropertyUtils.setChunkBase(chunk, base) + if chunk.base then + return end + + base.chunkCount = base.chunkCount + 1 + chunk.base = base end -function ChunkPropertyUtils.setChunkBase(map, chunk, base) - if not map.chunkToBase[chunk.id] then - base.chunkCount = base.chunkCount + 1 - map.chunkToBase[chunk.id] = base - end -end - -function ChunkPropertyUtils.getEnemyStructureCount(map, chunk) - local nests = 0 - local nestPack = Universe.chunkToNests[chunk.id] - if nestPack then - nests = nestPack.v - end - return nests + (map.chunkToTurrets[chunk.id] or 0) + (map.chunkToTraps[chunk.id] or 0) + - (map.chunkToUtilities[chunk.id] or 0) + (map.chunkToHives[chunk.id] or 0) +function ChunkPropertyUtils.getEnemyStructureCount(chunk) + return (chunk.nestCount or 0) + + (chunk.turretCount or 0) + + (chunk.utilityCount or 0) + + (chunk.hiveCount or 0) end function ChunkPropertyUtils.setDrainPylons(map, entity1, entity2) @@ -299,173 +264,79 @@ function ChunkPropertyUtils.getDrainPylonPair(map, unitNumber) end function ChunkPropertyUtils.isDrained(chunk, tick) - local pack = Universe.chunkToDrained[chunk.id] - if not pack then + local drainTick = Universe.chunkToDrained[chunk.id] + if not drainTick then return false end - return (tick - pack.tick) < COOLDOWN_DRAIN + return (tick - drainTick) < COOLDOWN_DRAIN end -function ChunkPropertyUtils.setDrainedTick(map, chunk, tick) - local chunkId = chunk.id - local pack = Universe.chunkToDrained[chunkId] - if not pack then - pack = { - map = map, - tick = 0 - } - Universe.chunkToDrained[chunkId] = pack - end - pack.tick = tick +function ChunkPropertyUtils.setDrainedTick(chunk, tick) + Universe.chunkToDrained[chunk.id] = tick end function ChunkPropertyUtils.getRetreatTick(chunk) - local pack = Universe.chunkToRetreats[chunk.id] - if not pack then - return 0 - end - return pack.tick + return Universe.chunkToRetreats[chunk.id] or 0 end function ChunkPropertyUtils.getRallyTick(chunk) - local pack = Universe.chunkToRallys[chunk.id] - if not pack then - return 0 - end - return pack.tick + return Universe.chunkToRallys[chunk.id] or 0 end -function ChunkPropertyUtils.setRallyTick(map, chunk, tick) - local chunkId = chunk.id - local pack = Universe.chunkToRallys[chunkId] - if not pack then - pack = { - map = map, - tick = tick - } - Universe.chunkToRallys[chunkId] = pack - end - pack.tick = tick +function ChunkPropertyUtils.setRallyTick(chunk, tick) + Universe.chunkToRallys[chunk.id] = tick end -function ChunkPropertyUtils.setRetreatTick(map, chunk, tick) - local chunkId = chunk.id - local pack = Universe.chunkToRetreats[chunkId] - if not pack then - pack = { - map = map, - tick = tick - } - Universe.chunkToRetreats[chunkId] = pack - end - pack.tick = tick +function ChunkPropertyUtils.setRetreatTick(chunk, tick) + Universe.chunkToRetreats[chunk.id] = tick end -function ChunkPropertyUtils.setResourceGenerator(map, chunk, resourceGenerator) +function ChunkPropertyUtils.setResourceGenerator(chunk, resourceGenerator) if (resourceGenerator <= 0) then - map.chunkToResource[chunk.id] = nil + chunk.resourceGenerator = nil else - map.chunkToResource[chunk.id] = resourceGenerator + chunk.resourceGenerator = resourceGenerator end end -function ChunkPropertyUtils.getResourceGenerator(map, chunk) - return map.chunkToResource[chunk.id] or 0 +function ChunkPropertyUtils.getResourceGenerator(chunk) + return chunk.resourceGenerator or 0 end -function ChunkPropertyUtils.addResourceGenerator(map, chunk, delta) - map.chunkToResource[chunk.id] = (map.chunkToResource[chunk.id] or 0) + delta +function ChunkPropertyUtils.addResourceGenerator(chunk, delta) + chunk.resourceGenerator = (chunk.resourceGenerator or 0) + delta end -function ChunkPropertyUtils.getPassable(map, chunk) - return map.chunkToPassable[chunk.id] or CHUNK_ALL_DIRECTIONS +function ChunkPropertyUtils.getPassable(chunk) + return chunk.passable or CHUNK_ALL_DIRECTIONS end - -function ChunkPropertyUtils.getRaidNestActiveness(chunk) - local activeness = Universe.chunkToActiveRaidNest[chunk.id] - if not activeness then - return 0 - end - return activeness.v or 0 -end - -function ChunkPropertyUtils.setRaidNestActiveness(map, chunk, value, base) - if (value <= 0) then - if Universe.chunkToActiveRaidNest[chunk.id] then - base.activeRaidNests = base.activeRaidNests - 1 - end - if (Universe.processActiveRaidSpawnerIterator == chunk.id) then - Universe.processActiveRaidSpawnerIterator = nil - end - Universe.chunkToActiveRaidNest[chunk.id] = nil - else - if not Universe.chunkToActiveRaidNest[chunk.id] then - base.activeRaidNests = base.activeRaidNests + 1 - Universe.chunkToActiveRaidNest[chunk.id] = { - map = map, - v = 0 - } - end - Universe.chunkToActiveRaidNest[chunk.id].v = value - end -end - -function ChunkPropertyUtils.getNestActiveness(chunk) - local activeness = Universe.chunkToActiveNest[chunk.id] - if not activeness then - return 0 - end - return activeness.v or 0 -end - -function ChunkPropertyUtils.setNestActiveness(map, chunk, value, base) - if (value <= 0) then - if Universe.chunkToActiveNest[chunk.id] then - base.activeNests = base.activeNests - 1 - end - if (Universe.processActiveSpawnerIterator == chunk.id) then - Universe.processActiveSpawnerIterator = nil - end - Universe.chunkToActiveNest[chunk.id] = nil - else - if not Universe.chunkToActiveNest[chunk.id] then - base.activeNests = base.activeNests + 1 - Universe.chunkToActiveNest[chunk.id] = { - map = map, - v = 0 - } - end - Universe.chunkToActiveNest[chunk.id].v = value - end -end - -function ChunkPropertyUtils.setPassable(map, chunk, value) +function ChunkPropertyUtils.setPassable(chunk, value) if (value == CHUNK_ALL_DIRECTIONS) then - map.chunkToPassable[chunk.id] = nil + chunk.passable = nil else - map.chunkToPassable[chunk.id] = value + chunk.passable = value end end -function ChunkPropertyUtils.getPathRating(map, chunk) - return map.chunkToPathRating[chunk.id] or 1 +function ChunkPropertyUtils.getPathRating(chunk) + return chunk.pathRating or 1 end -function ChunkPropertyUtils.setPathRating(map, chunk, value) +function ChunkPropertyUtils.setPathRating(chunk, value) if (value == 1) then - map.chunkToPathRating[chunk.id] = nil + chunk.pathRating = nil else - map.chunkToPathRating[chunk.id] = value + chunk.pathRating = value end end -function ChunkPropertyUtils.getDeathGeneratorRating(map, chunk) - return 1 + (map.chunkToDeathGenerator[chunk.id] or 0) +function ChunkPropertyUtils.getDeathGeneratorRating(chunk) + return 1 + (chunk.deathGenerator or 0) end -function ChunkPropertyUtils.getCombinedDeathGeneratorRating(map, chunk) - local amount = 1 + ((map.chunkToDeathGenerator[chunk.id] or 0) + (map.chunkToPermanentDeathGenerator[chunk.id] or 0)) +function ChunkPropertyUtils.getCombinedDeathGeneratorRating(chunk) + local amount = 1 + ((chunk.deathGenerator or 0) + (chunk.permanentDeathGenerator or 0)) if (amount > 1) then return 1 elseif (amount < 0) then @@ -475,16 +346,16 @@ function ChunkPropertyUtils.getCombinedDeathGeneratorRating(map, chunk) end end -function ChunkPropertyUtils.getDeathGenerator(map, chunk) - return map.chunkToDeathGenerator[chunk.id] or 0 +function ChunkPropertyUtils.getDeathGenerator(chunk) + return chunk.deathGenerator or 0 end -function ChunkPropertyUtils.getPermanentDeathGeneratorRating(map, chunk) - return 1 + (map.chunkToPermanentDeathGenerator[chunk.id] or 0) +function ChunkPropertyUtils.getPermanentDeathGeneratorRating(chunk) + return 1 + (chunk.permanentDeathGenerator or 0) end -function ChunkPropertyUtils.getCombinedDeathGenerator(map, chunk) - local amount = (map.chunkToDeathGenerator[chunk.id] or 0) + (map.chunkToPermanentDeathGenerator[chunk.id] or 0) +function ChunkPropertyUtils.getCombinedDeathGenerator(chunk) + local amount = (chunk.deathGenerator or 0) + (chunk.permanentDeathGenerator or 0) if (amount > 1) then return 1 elseif (amount < -1) then @@ -494,159 +365,156 @@ function ChunkPropertyUtils.getCombinedDeathGenerator(map, chunk) end end -function ChunkPropertyUtils.addPermanentDeathGenerator(map, chunk, amount) - local adjustedAmount = (amount * 0.25) + (map.chunkToPermanentDeathGenerator[chunk.id] or 0) +function ChunkPropertyUtils.addPermanentDeathGenerator(chunk, amount) + local adjustedAmount = (amount * 0.25) + (chunk.permanentDeathGenerator or 0) if (adjustedAmount > 0.75) then - map.chunkToPermanentDeathGenerator[chunk.id] = 0.75 + chunk.permanentDeathGenerator = 0.75 elseif (adjustedAmount < -0.75) then - map.chunkToPermanentDeathGenerator[chunk.id] = -0.75 + chunk.permanentDeathGenerator = -0.75 else - map.chunkToPermanentDeathGenerator[chunk.id] = adjustedAmount + chunk.permanentDeathGenerator = adjustedAmount end end -function ChunkPropertyUtils.addDeathGenerator(map, chunk, value) - local currentAmount = (map.chunkToDeathGenerator[chunk.id] or 0) + value +function ChunkPropertyUtils.addDeathGenerator(chunk, value) + local currentAmount = (chunk.deathGenerator or 0) + value if (currentAmount > 1) then - map.chunkToDeathGenerator[chunk.id] = 1 + chunk.deathGenerator = 1 elseif (currentAmount < -1) then - map.chunkToDeathGenerator[chunk.id] = -1 + chunk.deathGenerator = -1 else - map.chunkToDeathGenerator[chunk.id] = currentAmount + chunk.deathGenerator = currentAmount end end -function ChunkPropertyUtils.setDeathGenerator(map, chunk, value) +function ChunkPropertyUtils.setDeathGenerator(chunk, value) if (value > 1) then - map.chunkToDeathGenerator[chunk.id] = 1 + chunk.deathGenerator = 1 elseif (value < -1) then - map.chunkToDeathGenerator[chunk.id] = -1 + chunk.deathGenerator = -1 else - map.chunkToDeathGenerator[chunk.id] = value + chunk.deathGenerator = value end end -function ChunkPropertyUtils.addVictoryGenerator(map, chunk, value) +function ChunkPropertyUtils.addVictoryGenerator(chunk, value) local cToV = Universe.chunkToVictory local chunkId = chunk.id if not cToV[chunkId] then cToV[chunkId] = { - map = map, + chunk = chunk, v = 0 } end cToV[chunkId].v = cToV[chunkId].v + value end -function ChunkPropertyUtils.decayDeathGenerator(map, chunk) - local gen = map.chunkToDeathGenerator[chunk.id] +function ChunkPropertyUtils.decayDeathGenerator(chunk) + local gen = chunk.deathGenerator if gen then local v = gen * MOVEMENT_GENERATOR_PERSISTANCE if (v < 0.0001) and (v > -0.0001) then - map.chunkToDeathGenerator[chunk.id] = nil + chunk.deathGenerator = nil else - map.chunkToDeathGenerator[chunk.id] = v + chunk.deathGenerator = v end end end -function ChunkPropertyUtils.decayPlayerGenerator(map, chunk) - local gen = map.chunkToPlayerGenerator[chunk.id] +function ChunkPropertyUtils.decayPlayerGenerator(chunk) + local gen = chunk.playerGenerator if gen then local v = gen * PLAYER_GENERATOR_PERSISTANCE if (v < 0.0001) and (v > -0.0001) then - map.chunkToPlayerGenerator[chunk.id] = nil + chunk.playerGenerator = nil else - map.chunkToPlayerGenerator[chunk.id] = v + chunk.playerGenerator = v end end end -function ChunkPropertyUtils.addPlayerGenerator(map, chunk, playerMaxGenerator) - local value = map.chunkToPlayerGenerator[chunk.id] +function ChunkPropertyUtils.addPlayerGenerator(chunk, playerMaxGenerator) + local value = chunk.playerGenerator if value then - map.chunkToPlayerGenerator[chunk.id] = mMin( + chunk.playerGenerator = mMin( value + PLAYER_PHEROMONE_GENERATOR_AMOUNT, playerMaxGenerator ) else - map.chunkToPlayerGenerator[chunk.id] = PLAYER_PHEROMONE_GENERATOR_AMOUNT + chunk.playerGenerator = PLAYER_PHEROMONE_GENERATOR_AMOUNT end end -function ChunkPropertyUtils.getPlayerGenerator(map, chunk) - return map.chunkToPlayerGenerator[chunk.id] or 0 +function ChunkPropertyUtils.getPlayerGenerator(chunk) + return chunk.playerGenerator or 0 end -function ChunkPropertyUtils.getPlayerBaseGenerator(map, chunk) - return map.chunkToPlayerBase[chunk.id] or 0 +function ChunkPropertyUtils.getPlayerBaseGenerator(chunk) + return chunk.playerBaseGenerator or 0 end -function ChunkPropertyUtils.addSquadToChunk(map, chunk, squad) - local chunkToSquad = map.chunkToSquad - - if (chunk ~= -1) and ((squad.chunk == -1) or (squad.chunk.id ~= chunk.id)) then - ChunkPropertyUtils.removeSquadFromChunk(map, squad) - local squads = chunkToSquad[chunk.id] +function ChunkPropertyUtils.addSquadToChunk(chunk, squad) + if (chunk ~= -1) + and ( + (squad.chunk == -1) + or (squad.chunk.id ~= chunk.id) + ) + then + ChunkPropertyUtils.removeSquadFromChunk(squad) + local squads = chunk.squads if not squads then squads = {} - chunkToSquad[chunk.id] = squads + chunk.squads = squads end squads[squad.groupNumber] = squad squad.chunk = chunk end end -function ChunkPropertyUtils.removeSquadFromChunk(map, squad) - local chunkToSquad = map.chunkToSquad +function ChunkPropertyUtils.removeSquadFromChunk(squad) local chunk = squad.chunk if (chunk ~= -1) then - local squads = chunkToSquad[chunk.id] + local squads = chunk.squads if squads then squads[squad.groupNumber] = nil if (tableSize(squads) == 0) then - chunkToSquad[chunk.id] = nil + chunk.squads = nil end end end end -function ChunkPropertyUtils.getSquadsOnChunk(map, chunk) - return map.chunkToSquad[chunk.id] or map.emptySquadsOnChunk -end - -function ChunkPropertyUtils.setPlayerBaseGenerator(map, chunk, playerGenerator) - if (playerGenerator <= 0) then - map.chunkToPlayerBase[chunk.id] = nil +function ChunkPropertyUtils.setPlayerBaseGenerator(chunk, playerBaseGenerator) + if (playerBaseGenerator <= 0) then + chunk.playerBaseGenerator = nil return 0 else - map.chunkToPlayerBase[chunk.id] = playerGenerator - return playerGenerator + chunk.playerBaseGenerator = playerBaseGenerator + return playerBaseGenerator end end -function ChunkPropertyUtils.addPlayerBaseGenerator(map, chunk, playerGenerator) - local amount = (map.chunkToPlayerBase[chunk.id] or 0) + playerGenerator +function ChunkPropertyUtils.addPlayerBaseGenerator(chunk, playerBaseGenerator) + local amount = (chunk.playerBaseGenerator or 0) + playerBaseGenerator if amount <= 0 then - map.chunkToPlayerBase[chunk.id] = nil + chunk.playerBaseGenerator = nil return 0 else - map.chunkToPlayerBase[chunk.id] = amount + chunk.playerBaseGenerator = amount return amount end end -function ChunkPropertyUtils.findNearbyBase(map, chunk) - local x = chunk.x - local y = chunk.y - - local foundBase = ChunkPropertyUtils.getChunkBase(map, chunk) +function ChunkPropertyUtils.findNearbyBase(chunk) + local foundBase = chunk.base if foundBase then return foundBase end + local x = chunk.x + local y = chunk.y local closest = MAGIC_MAXIMUM_NUMBER - for _, base in pairs(map.bases) do + for _, base in pairs(chunk.map.bases) do local distance = manhattenDistancePoints(base.x, base.y, x, y) if (distance <= base.distanceThreshold) and (distance < closest) then closest = distance @@ -672,46 +540,46 @@ function ChunkPropertyUtils.findNearbyBaseByPosition(map, x, y) return foundBase end -function ChunkPropertyUtils.processNestActiveness(map, chunk) - local nests = ChunkPropertyUtils.getNestCount(chunk) - local base = ChunkPropertyUtils.findNearbyBase(map, chunk) - if (nests > 0) then - local surface = map.surface - local activeness = ChunkPropertyUtils.getNestActiveness(chunk) - local raidActiveness = ChunkPropertyUtils.getRaidNestActiveness(chunk) +function ChunkPropertyUtils.processNestActiveness(chunk, tick) + if getActiveTick(chunk) > tick then + return + end + + if chunk.nestCount then + local surface = chunk.map.surface if Universe.attackUsePlayer and (chunk[PLAYER_PHEROMONE] > Universe.attackPlayerThreshold) then - ChunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base) + registerActiveNest(chunk, tick) elseif (chunk[BASE_PHEROMONE] > 0) then - if (surface.get_pollution(chunk) > 0) then - ChunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base) + local getPollution = surface.get_pollution + if (getPollution(chunk) > 0) then + registerActiveNest(chunk, tick) else local x = chunk.x local y = chunk.y - local position = {x=0,y=0} local pollutionThreshold = Universe.pollutionDiffuseMinimum - position.x = x + 32 - position.y = y - if (surface.get_pollution(position) > pollutionThreshold) then - ChunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base) + Position.x = x + 32 + Position.y = y + if (getPollution(Position) > pollutionThreshold) then + registerActiveNest(chunk, tick) else - position.x = x - 32 - if (surface.get_pollution(position) > pollutionThreshold) then - ChunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base) + Position.x = x - 32 + if (getPollution(Position) > pollutionThreshold) then + registerActiveNest(chunk, tick) else - position.x = x - position.y = y - 32 - if (surface.get_pollution(position) > pollutionThreshold) then - ChunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base) + Position.x = x + Position.y = y - 32 + if (getPollution(Position) > pollutionThreshold) then + registerActiveNest(chunk, tick) else - position.y = y + 32 - if (surface.get_pollution(position) > pollutionThreshold) then - ChunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base) + Position.y = y + 32 + if (getPollution(Position) > pollutionThreshold) then + registerActiveNest(chunk, tick) else - ChunkPropertyUtils.setNestActiveness(map, chunk, activeness - 2, base) + unregisterActiveNest(chunk) if (chunk[BASE_PHEROMONE] > RAIDING_MINIMUM_BASE_THRESHOLD) then - ChunkPropertyUtils.setRaidNestActiveness(map, chunk, mMin(raidActiveness + 3, 20), base) + registerActiveRaidNest(chunk, tick) else - ChunkPropertyUtils.setRaidNestActiveness(map, chunk, raidActiveness - 1, base) + unregisterActiveRaidNest(chunk) end end end @@ -719,17 +587,18 @@ function ChunkPropertyUtils.processNestActiveness(map, chunk) end end else - ChunkPropertyUtils.setNestActiveness(map, chunk, activeness - 5, base) - ChunkPropertyUtils.setRaidNestActiveness(map, chunk, raidActiveness - 5, base) + unregisterActiveNest(chunk) + unregisterActiveRaidNest(chunk) end - elseif base then - ChunkPropertyUtils.setNestActiveness(map, chunk, 0, base) - ChunkPropertyUtils.setRaidNestActiveness(map, chunk, 0, base) + else + unregisterActiveNest(chunk) + unregisterActiveRaidNest(chunk) end end function ChunkPropertyUtils.init(universe) Universe = universe + Position = universe.chunkPropertyUtilsQueries.position end ChunkPropertyUtilsG = ChunkPropertyUtils diff --git a/libs/ChunkUtils.lua b/libs/ChunkUtils.lua index 4160bb2..b312149 100644 --- a/libs/ChunkUtils.lua +++ b/libs/ChunkUtils.lua @@ -93,10 +93,7 @@ local removeTurretCount = ChunkPropertyUtils.removeTurretCount local addUtilityCount = ChunkPropertyUtils.addUtilityCount local removeUtilityCount = ChunkPropertyUtils.removeUtilityCount -local getPlayerBaseGenerator = ChunkPropertyUtils.getPlayerBaseGenerator -local setRaidNestActiveness = ChunkPropertyUtils.setRaidNestActiveness -local setNestActiveness = ChunkPropertyUtils.setNestActiveness -local getChunkById = MapUtils.getChunkById +local setChunkBase = ChunkPropertyUtils.setChunkBase local processNestActiveness = ChunkPropertyUtils.processNestActiveness @@ -111,8 +108,6 @@ local modifyBaseUnitPoints = BaseUtils.modifyBaseUnitPoints local euclideanDistancePoints = MathUtils.euclideanDistancePoints -local getChunkBase = ChunkPropertyUtils.getChunkBase -local setChunkBase = ChunkPropertyUtils.setChunkBase local setPassable = ChunkPropertyUtils.setPassable local setPathRating = ChunkPropertyUtils.setPathRating @@ -239,14 +234,14 @@ function ChunkUtils.initialScan(chunk, map, tick) mMin(1 - (surface.count_entities_filtered(Universe.isFilteredEntitiesChunkNeutral) * 0.005), 1) * 0.20) - setPassable(map, chunk, pass) + setPassable(chunk, pass) local waterTiles = (1 - (surface.count_tiles_filtered(Universe.isFilteredTilesQuery) * 0.0009765625)) * 0.80 - setPathRating(map, chunk, waterTiles + neutralObjects) - setPlayerBaseGenerator(map, chunk, playerObjects) + setPathRating(chunk, waterTiles + neutralObjects) + setPlayerBaseGenerator(chunk, playerObjects) local resources = surface.count_entities_filtered(Universe.isCountResourcesQuery) * RESOURCE_NORMALIZER - setResourceGenerator(map, chunk, resources) + setResourceGenerator(chunk, resources) local counts = map.chunkScanCounts for i=1,#HIVE_BUILDINGS_TYPES do @@ -254,7 +249,7 @@ function ChunkUtils.initialScan(chunk, map, tick) end if (#enemyBuildings > 0) then - local base = findNearbyBase(map, chunk) + local base = findNearbyBase(chunk) if not base then base = createBase(map, chunk, tick) end @@ -270,7 +265,7 @@ function ChunkUtils.initialScan(chunk, map, tick) for i = 1, #enemyBuildings do local enemyBuilding = enemyBuildings[i] - ChunkUtils.registerEnemyBaseStructure(map, enemyBuilding, base) + ChunkUtils.registerEnemyBaseStructure(map, enemyBuilding, base, tick) local entityName = enemyBuilding.name local isVanilla = VANILLA_ENTITY_TYPE_LOOKUP[entityName] if isVanilla or (not isVanilla and not BUILDING_HIVE_TYPE_LOOKUP[entityName]) then @@ -284,7 +279,7 @@ function ChunkUtils.initialScan(chunk, map, tick) else for i=1,#enemyBuildings do local building = enemyBuildings[i] - ChunkUtils.registerEnemyBaseStructure(map, building, base) + ChunkUtils.registerEnemyBaseStructure(map, building, base, tick) end end end @@ -301,9 +296,9 @@ function ChunkUtils.chunkPassScan(chunk, map) setAreaInQueryChunkSize(Universe.cpsFilteredTilesQuery, chunk) local pass = scanPaths(chunk, map) local enemyCount = surface.count_entities_filtered(Universe.cpsFilteredEnemyAnyFound) - local playerObjects = getPlayerBaseGenerator(map, chunk) + local playerObjects = chunk.playerBaseGenerator - if (pass ~= CHUNK_IMPASSABLE) or (enemyCount > 0) or (playerObjects > 0) then + if (pass ~= CHUNK_IMPASSABLE) or (enemyCount > 0) or playerObjects then local neutralObjects = mMax(0, mMin(1 - (surface.count_entities_filtered(Universe.cpsFilteredEntitiesChunkNeutral) * 0.005), 1) * 0.20) @@ -313,8 +308,8 @@ function ChunkUtils.chunkPassScan(chunk, map) pass = CHUNK_ALL_DIRECTIONS end - setPassable(map, chunk, pass) - setPathRating(map, chunk, waterTiles + neutralObjects) + setPassable(chunk, pass) + setPathRating(chunk, waterTiles + neutralObjects) return chunk end @@ -324,19 +319,19 @@ end function ChunkUtils.mapScanPlayerChunk(chunk, map) local playerObjects = scorePlayerBuildings(map, chunk) - setPlayerBaseGenerator(map, chunk, playerObjects) + setPlayerBaseGenerator(chunk, playerObjects) end function ChunkUtils.mapScanResourceChunk(chunk, map) setAreaInQueryChunkSize(Universe.msrcCountResourcesQuery, chunk) local surface = map.surface local resources = surface.count_entities_filtered(Universe.msrcCountResourcesQuery) * RESOURCE_NORMALIZER - setResourceGenerator(map, chunk, resources) + setResourceGenerator(chunk, resources) local waterTiles = (1 - (surface.count_tiles_filtered(Universe.msrcFilteredTilesQuery) * 0.0009765625)) * 0.80 local neutralObjects = mMax(0, mMin(1 - (surface.count_entities_filtered(Universe.msrcFilteredEntitiesChunkNeutral) * 0.005), 1) * 0.20) - setPathRating(map, chunk, waterTiles + neutralObjects) + setPathRating(chunk, waterTiles + neutralObjects) end function ChunkUtils.mapScanEnemyChunk(chunk, map, tick) @@ -347,67 +342,67 @@ function ChunkUtils.mapScanEnemyChunk(chunk, map, tick) counts[HIVE_BUILDINGS_TYPES[i]] = 0 end if (#buildings > 0) then - local base = findNearbyBase(map, chunk) + local base = findNearbyBase(chunk) if not base then base = createBase(map, chunk, tick) end for i=1,#buildings do local building = buildings[i] - ChunkUtils.registerEnemyBaseStructure(map, building, base) + ChunkUtils.registerEnemyBaseStructure(map, building, base, tick) end end end -function ChunkUtils.addBasesToAllEnemyStructures(tick) - for chunkId, chunkPack in pairs(Universe.chunkToNests) do - local map = chunkPack.map - if map.surface.valid then - local chunk = getChunkById(chunkId) - local base = findNearbyBase(map, chunk) - if not base then - base = createBase(map, chunk, tick) - end - setChunkBase(map, chunk, base) - end - end - for _, map in pairs(Universe.maps) do - if map.surface.valid then - for chunkId in pairs(map.chunkToTurrets) do - local chunk = getChunkById(chunkId) - local base = findNearbyBase(map, chunk) - if not base then - base = createBase(map, chunk, tick) - end - setChunkBase(map, chunk, base) - end - for chunkId in pairs(map.chunkToHives) do - local chunk = getChunkById(chunkId) - local base = findNearbyBase(map, chunk) - if not base then - base = createBase(map, chunk, tick) - end - setChunkBase(map, chunk, base) - end - for chunkId in pairs(map.chunkToUtilities) do - local chunk = getChunkById(chunkId) - local base = findNearbyBase(map, chunk) - if not base then - base = createBase(map, chunk, tick) - end - setChunkBase(map, chunk, base) - end - for chunkId in pairs(map.chunkToTraps) do - local chunk = getChunkById(chunkId) - local base = findNearbyBase(map, chunk) - if not base then - base = createBase(map, chunk, tick) - end - setChunkBase(map, chunk, base) - end - end - end -end +-- function ChunkUtils.addBasesToAllEnemyStructures(tick) +-- for chunkId, chunkPack in pairs(Universe.chunkToNests) do +-- local map = chunkPack.map +-- if map.surface.valid then +-- local chunk = getChunkById(chunkId) +-- local base = findNearbyBase(chunk) +-- if not base then +-- base = createBase(map, chunk, tick) +-- end +-- setChunkBase(chunk, base) +-- end +-- end +-- for _, map in pairs(Universe.maps) do +-- if map.surface.valid then +-- for chunkId in pairs(map.chunkToTurrets) do +-- local chunk = getChunkById(chunkId) +-- local base = findNearbyBase(chunk) +-- if not base then +-- base = createBase(map, chunk, tick) +-- end +-- setChunkBase(chunk, base) +-- end +-- for chunkId in pairs(map.chunkToHives) do +-- local chunk = getChunkById(chunkId) +-- local base = findNearbyBase(chunk) +-- if not base then +-- base = createBase(map, chunk, tick) +-- end +-- setChunkBase(chunk, base) +-- end +-- for chunkId in pairs(map.chunkToUtilities) do +-- local chunk = getChunkById(chunkId) +-- local base = findNearbyBase(chunk) +-- if not base then +-- base = createBase(map, chunk, tick) +-- end +-- setChunkBase(chunk, base) +-- end +-- for chunkId in pairs(map.chunkToTraps) do +-- local chunk = getChunkById(chunkId) +-- local base = findNearbyBase(chunk) +-- if not base then +-- base = createBase(map, chunk, tick) +-- end +-- setChunkBase(chunk, base) +-- end +-- end +-- end +-- end function ChunkUtils.entityForPassScan(map, entity) local overlapArray = getEntityOverlapChunks(map, entity) @@ -434,7 +429,8 @@ function ChunkUtils.createChunk(map, topX, topY) x = topX, y = topY, dOrigin = euclideanDistancePoints(topX, topY, 0, 0), - id = newChunkId() + id = newChunkId(), + map = map } chunk[BASE_PHEROMONE] = 0 chunk[PLAYER_PHEROMONE] = 0 @@ -479,7 +475,7 @@ function ChunkUtils.colorXY(x, y, surface, color) }) end -function ChunkUtils.registerEnemyBaseStructure(map, entity, base, skipCount) +function ChunkUtils.registerEnemyBaseStructure(map, entity, base, tick, skipCount) local entityType = entity.type local addFunc @@ -508,13 +504,13 @@ function ChunkUtils.registerEnemyBaseStructure(map, entity, base, skipCount) for i=1,#chunks do local chunk = chunks[i] if (chunk ~= -1) then - if addFunc(map, chunk, entityUnitNumber) then + if addFunc(chunk, entityUnitNumber) then added = true - setChunkBase(map, chunk, base) + setChunkBase(chunk, base) addBaseResourceChunk(base, chunk) end if (hiveType == "spitter-spawner") or (hiveType == "biter-spawner") then - processNestActiveness(map, chunk) + processNestActiveness(chunk, tick) end end end @@ -553,12 +549,8 @@ function ChunkUtils.unregisterEnemyBaseStructure(map, entity, damageTypeName, sk for i=1,#chunks do local chunk = chunks[i] if (chunk ~= -1) then - local base = getChunkBase(map, chunk) - if (hiveType == "spitter-spawner") or (hiveType == "biter-spawner") then - setRaidNestActiveness(map, chunk, 0, base) - setNestActiveness(map, chunk, 0, base) - end - if removeFunc(map, chunk, entityUnitNumber) then + if removeFunc(chunk, entityUnitNumber) then + local base = chunk.base if not usedBases[base.id] then usedBases[base.id] = true if damageTypeName then @@ -569,9 +561,9 @@ function ChunkUtils.unregisterEnemyBaseStructure(map, entity, damageTypeName, sk base.lostEnemyBuilding = base.lostEnemyBuilding + 1 end end - if (getEnemyStructureCount(map, chunk) <= 0) then + if (getEnemyStructureCount(chunk) <= 0) then removeBaseResourceChunk(base, chunk) - removeChunkBase(map, chunk, base) + removeChunkBase(chunk, base) end end end @@ -600,7 +592,7 @@ function ChunkUtils.accountPlayerEntity(entity, map, addObject, base) for i=1,#overlapArray do local chunk = overlapArray[i] if (chunk ~= -1) then - local amount = addPlayerBaseGenerator(map, chunk, entityValue) + local amount = addPlayerBaseGenerator(chunk, entityValue) if (amount == 0) then chunk[BASE_PHEROMONE] = 0 end @@ -619,7 +611,7 @@ function ChunkUtils.unregisterResource(entity, map) for i=1,#overlapArray do local chunk = overlapArray[i] if (chunk ~= -1) then - addResourceGenerator(map, chunk, -RESOURCE_NORMALIZER) + addResourceGenerator(chunk, -RESOURCE_NORMALIZER) end end end @@ -630,7 +622,7 @@ function ChunkUtils.registerResource(entity, map) for i=1,#overlapArray do local chunk = overlapArray[i] if (chunk ~= -1) then - addResourceGenerator(map, chunk, RESOURCE_NORMALIZER) + addResourceGenerator(chunk, RESOURCE_NORMALIZER) end end end diff --git a/libs/MapProcessor.lua b/libs/MapProcessor.lua index 2dd613d..a9ecc4c 100644 --- a/libs/MapProcessor.lua +++ b/libs/MapProcessor.lua @@ -76,7 +76,6 @@ local getCombinedDeathGeneratorRating = ChunkPropertyUtils.getCombinedDeathGener local processBaseMutation = BaseUtils.processBaseMutation local processNestActiveness = ChunkPropertyUtils.processNestActiveness -local getChunkBase = ChunkPropertyUtils.getChunkBase local formSquads = AiAttackWave.formSquads local formVengenceSquad = AiAttackWave.formVengenceSquad @@ -93,11 +92,7 @@ local mapScanEnemyChunk = ChunkUtils.mapScanEnemyChunk local mapScanPlayerChunk = ChunkUtils.mapScanPlayerChunk local mapScanResourceChunk = ChunkUtils.mapScanResourceChunk -local getNestCount = ChunkPropertyUtils.getNestCount local getEnemyStructureCount = ChunkPropertyUtils.getEnemyStructureCount -local getNestActiveness = ChunkPropertyUtils.getNestActiveness - -local getRaidNestActiveness = ChunkPropertyUtils.getRaidNestActiveness local canAttack = AiPredicates.canAttack local canMigrate = AiPredicates.canMigrate @@ -155,21 +150,6 @@ function MapProcessor.processMap(map, tick) end end -local function queueNestSpawners(map, chunk, tick) - local processActiveNest = Universe.processActiveNest - - local chunkId = chunk.id - if not processActiveNest[chunkId] then - if (getNestActiveness(chunk) > 0) or (getRaidNestActiveness(chunk) > 0) then - processActiveNest[chunkId] = { - map = map, - chunk = chunk, - tick = tick + DURATION_ACTIVE_NEST - } - end - end -end - --[[ Localized player radius were processing takes place in realtime, doesn't store state between calls. @@ -191,7 +171,7 @@ function MapProcessor.processPlayers(players, tick) local playerChunk = getChunkByPosition(map, char.position) if (playerChunk ~= -1) then - addPlayerGenerator(map, playerChunk, playerMaxGenerator) + addPlayerGenerator(playerChunk, playerMaxGenerator) end end end @@ -206,15 +186,15 @@ function MapProcessor.processPlayers(players, tick) local playerChunk = getChunkByPosition(map, char.position) if (playerChunk ~= -1) then - local base = findNearbyBase(map, playerChunk) + local base = findNearbyBase(playerChunk) if not base then return end local allowingAttacks = canAttack(map, base) local vengence = allowingAttacks and (base.unitPoints >= AI_VENGENCE_SQUAD_COST) and - ((getEnemyStructureCount(map, playerChunk) > 0) or - (getCombinedDeathGeneratorRating(map, playerChunk) < Universe.retreatThreshold)) + ((getEnemyStructureCount(playerChunk) > 0) or + (getCombinedDeathGeneratorRating(playerChunk) < Universe.retreatThreshold)) for x=playerChunk.x - PROCESS_PLAYER_BOUND, playerChunk.x + PROCESS_PLAYER_BOUND, 32 do for y=playerChunk.y - PROCESS_PLAYER_BOUND, playerChunk.y + PROCESS_PLAYER_BOUND, 32 do @@ -223,9 +203,8 @@ function MapProcessor.processPlayers(players, tick) if (chunk ~= -1) then processPheromone(map, chunk, tick, true) - if (getNestCount(chunk) > 0) then - processNestActiveness(map, chunk) - queueNestSpawners(map, chunk, tick) + if chunk.nestCount then + processNestActiveness(chunk, tick) if vengence then local pack = Universe.vengenceQueue[chunk.id] @@ -251,17 +230,17 @@ end local function processCleanUp(chunks, iterator, tick, duration) local chunkId = Universe[iterator] - local chunkPack + local eventTick if not chunkId then - chunkId, chunkPack = next(chunks, nil) + chunkId, eventTick = next(chunks, nil) else - chunkPack = chunks[chunkId] + eventTick = chunks[chunkId] end if not chunkId then Universe[iterator] = nil else Universe[iterator] = next(chunks, chunkId) - if (tick - chunkPack.tick) > duration then + if (tick - eventTick) > duration then chunks[chunkId] = nil end end @@ -367,36 +346,6 @@ function MapProcessor.scanResourceMap(map, tick) end end -function MapProcessor.processActiveNests(tick) - local processActiveNest = Universe.processActiveNest - local chunkId = Universe.processActiveNestIterator - local chunkPack - if not chunkId then - chunkId, chunkPack = next(processActiveNest, nil) - else - chunkPack = processActiveNest[chunkId] - end - if not chunkId then - Universe.processActiveNestIterator = nil - else - Universe.processActiveNestIterator = next(processActiveNest, chunkId) - if chunkPack.tick < tick then - local map = chunkPack.map - if not map.surface.valid then - processActiveNest[chunkId] = nil - return - end - local chunk = chunkPack.chunk - processNestActiveness(map, chunk) - if (getNestActiveness(chunk) == 0) and (getRaidNestActiveness(chunk) == 0) then - processActiveNest[chunkId] = nil - else - chunkPack.tick = tick + DURATION_ACTIVE_NEST - end - end - end -end - function MapProcessor.processVengence() local vengenceQueue = Universe.vengenceQueue local chunkId = Universe.deployVengenceIterator @@ -446,13 +395,12 @@ function MapProcessor.processNests(tick) return end local chunk = getChunkById(chunkId) - processNestActiveness(map, chunk) - queueNestSpawners(map, chunk, tick) + processNestActiveness(chunk, tick) if Universe.NEW_ENEMIES then processBaseMutation(chunk, map, - getChunkBase(map, chunk)) + chunk.base) end end end @@ -479,7 +427,7 @@ local function processSpawnersBody(iterator, chunks) return end local chunk = getChunkById(chunkId) - local base = findNearbyBase(map, chunk) + local base = findNearbyBase(chunk) if base.stateAI == BASE_AI_STATE_PEACEFUL then return end diff --git a/libs/MapUtils.lua b/libs/MapUtils.lua index d229631..408d89c 100644 --- a/libs/MapUtils.lua +++ b/libs/MapUtils.lua @@ -268,8 +268,8 @@ end ]]-- function MapUtils.canMoveChunkDirection(map, direction, startChunk, endChunk) local canMove = false - local startPassable = getPassable(map, startChunk) - local endPassable = getPassable(map, endChunk) + local startPassable = getPassable(startChunk) + local endPassable = getPassable(endChunk) if (startPassable == CHUNK_ALL_DIRECTIONS) then if ((direction == 1) or (direction == 3) or (direction == 6) or (direction == 8)) then canMove = (endPassable == CHUNK_ALL_DIRECTIONS) diff --git a/libs/PheromoneUtils.lua b/libs/PheromoneUtils.lua index 5b4d573..d93813a 100644 --- a/libs/PheromoneUtils.lua +++ b/libs/PheromoneUtils.lua @@ -57,8 +57,6 @@ local getCombinedDeathGenerator = ChunkPropertyUtils.getCombinedDeathGenerator local getCombinedDeathGeneratorRating = ChunkPropertyUtils.getCombinedDeathGeneratorRating local setDeathGenerator = ChunkPropertyUtils.setDeathGenerator -local getPlayerGenerator = ChunkPropertyUtils.getPlayerGenerator - local addPermanentDeathGenerator = ChunkPropertyUtils.addPermanentDeathGenerator local canMoveChunkDirection = MapUtils.canMoveChunkDirection @@ -67,8 +65,6 @@ local getChunkById = MapUtils.getChunkById local getEnemyStructureCount = ChunkPropertyUtils.getEnemyStructureCount local getPathRating = ChunkPropertyUtils.getPathRating -local getPlayerBaseGenerator = ChunkPropertyUtils.getPlayerBaseGenerator -local getResourceGenerator = ChunkPropertyUtils.getResourceGenerator local addDeathGenerator = ChunkPropertyUtils.addDeathGenerator local decayDeathGenerator = ChunkPropertyUtils.decayDeathGenerator @@ -116,8 +112,8 @@ function PheromoneUtils.disperseVictoryScent() local c = getChunkByXY(map, x, y) if (c ~= -1) then local amount = pheromonePack.v * VICTORY_SCENT_MULTIPLER[i] - addDeathGenerator(map, c, amount) - addPermanentDeathGenerator(map, c, amount) + addDeathGenerator(c, amount) + addPermanentDeathGenerator(c, amount) end i = i + 1 end @@ -130,8 +126,8 @@ function PheromoneUtils.deathScent(map, chunk, structure) if structure then amount = -TEN_DEATH_PHEROMONE_GENERATOR_AMOUNT end - addDeathGenerator(map, chunk, amount) - addPermanentDeathGenerator(map, chunk, amount) + addDeathGenerator(chunk, amount) + addPermanentDeathGenerator(chunk, amount) end function PheromoneUtils.processPheromone(map, chunk, tick, player) @@ -142,13 +138,13 @@ function PheromoneUtils.processPheromone(map, chunk, tick, player) local chunkPlayer = chunk[PLAYER_PHEROMONE] local chunkBase = -MAGIC_MAXIMUM_NUMBER - local chunkDeath = getCombinedDeathGenerator(map, chunk) + local chunkDeath = getCombinedDeathGenerator(chunk) local chunkResource = -MAGIC_MAXIMUM_NUMBER local chunkEnemy = chunk[ENEMY_PHEROMONE] local chunkCount = 1 - local enemyStructureCount = getEnemyStructureCount(map, chunk) + local enemyStructureCount = getEnemyStructureCount(chunk) local tempNeighbors = getNeighborChunks(map, chunk.x, chunk.y) for i=1,8 do @@ -159,7 +155,7 @@ function PheromoneUtils.processPheromone(map, chunk, tick, player) chunkCount = chunkCount + 1 chunkPlayer = chunkPlayer + neighbor[PLAYER_PHEROMONE] chunkEnemy = chunkEnemy + neighbor[ENEMY_PHEROMONE] - chunkDeath = chunkDeath + getCombinedDeathGenerator(map, neighbor) + chunkDeath = chunkDeath + getCombinedDeathGenerator(neighbor) tempPheromone = neighbor[BASE_PHEROMONE] if chunkBase < tempPheromone then chunkBase = tempPheromone @@ -172,23 +168,23 @@ function PheromoneUtils.processPheromone(map, chunk, tick, player) end end - setDeathGenerator(map, chunk, (chunkDeath / chunkCount) * 0.75) + setDeathGenerator(chunk, (chunkDeath / chunkCount) * 0.75) if not player then - decayDeathGenerator(map, chunk) + decayDeathGenerator(chunk) end - decayPlayerGenerator(map, chunk) + decayPlayerGenerator(chunk) - local chunkDeathRating = getCombinedDeathGeneratorRating(map, chunk) * getPathRating(map, chunk) + local chunkDeathRating = getCombinedDeathGeneratorRating(chunk) * getPathRating(chunk) chunk[PLAYER_PHEROMONE] = chunkDeathRating * mMax( - getPlayerGenerator(map, chunk), + chunk.playerGenerator or 0, (chunkPlayer / chunkCount) * 0.98 ) chunk[BASE_PHEROMONE] = chunkDeathRating * mMax( - getPlayerBaseGenerator(map, chunk), + chunk.playerBaseGenerator or 0, chunkBase * 0.9 ) @@ -197,7 +193,7 @@ function PheromoneUtils.processPheromone(map, chunk, tick, player) (chunkEnemy / chunkCount) * 0.9 ) - local resourcePheromoneGenerator = getResourceGenerator(map, chunk) + local resourcePheromoneGenerator = chunk.resourceGenerator or 0 if (resourcePheromoneGenerator > 0) then chunkResource = linearInterpolation(resourcePheromoneGenerator, 15000, 20000) end diff --git a/libs/SquadAttack.lua b/libs/SquadAttack.lua index 2cffb2f..9d7cafc 100644 --- a/libs/SquadAttack.lua +++ b/libs/SquadAttack.lua @@ -61,7 +61,7 @@ local DEFINES_DISTRACTION_BY_ANYTHING = defines.distraction.by_anything -- imported functions -local getPlayerGenerator = ChunkPropertyUtils.getPlayerGenerator +local tableSize = table_size local setPositionInCommand = QueryUtils.setPositionInCommand local euclideanDistancePoints = MathUtils.euclideanDistancePoints @@ -71,9 +71,6 @@ local findMovementPosition = MovementUtils.findMovementPosition local removeSquadFromChunk = ChunkPropertyUtils.removeSquadFromChunk local addDeathGenerator = ChunkPropertyUtils.addDeathGenerator -local getHiveCount = ChunkPropertyUtils.getHiveCount -local getNestCount = ChunkPropertyUtils.getNestCount - local getNeighborChunks = MapUtils.getNeighborChunks local addSquadToChunk = ChunkPropertyUtils.addSquadToChunk local getChunkByXY = MapUtils.getChunkByXY @@ -83,9 +80,6 @@ local positionFromDirectionAndFlat = MapUtils.positionFromDirectionAndFlat local euclideanDistanceNamed = MathUtils.euclideanDistanceNamed -local getPlayerBaseGenerator = ChunkPropertyUtils.getPlayerBaseGenerator -local getResourceGenerator = ChunkPropertyUtils.getResourceGenerator - local scoreNeighborsForAttack = MovementUtils.scoreNeighborsForAttack local scoreNeighborsForSettling = MovementUtils.scoreNeighborsForSettling @@ -123,10 +117,10 @@ local function settleMove(map, squad) end local squadChunk = squad.chunk if squadChunk ~= -1 then - addDeathGenerator(map, squadChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) + addDeathGenerator(squadChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) end if chunk ~= -1 then - addSquadToChunk(map, chunk, squad) + addSquadToChunk(chunk, squad) addMovementPenalty(squad, chunk) if not squad.group.valid then return @@ -144,7 +138,7 @@ local function settleMove(map, squad) ( (distance >= squad.maxDistance) or ( - (getResourceGenerator(map, chunk) ~= 0) and (getNestCount(chunk) == 0) and (getHiveCount(map, chunk) == 0) + chunk.resourceGenerator and (not chunk.nestCount) and (not chunk.hiveCount) ) ) then @@ -183,8 +177,8 @@ local function settleMove(map, squad) local attackPlayerThreshold = Universe.attackPlayerThreshold if (nextAttackChunk ~= -1) then - if (getPlayerBaseGenerator(map, nextAttackChunk) == 0) - and (getPlayerGenerator(map, nextAttackChunk) < PLAYER_PHEROMONE_GENERATOR_THRESHOLD) + if (not nextAttackChunk.playerBaseGenerator) + and ((nextAttackChunk.playerGenerator or 0) < PLAYER_PHEROMONE_GENERATOR_THRESHOLD) then attackChunk = nextAttackChunk position = findMovementPosition( @@ -214,9 +208,9 @@ local function settleMove(map, squad) targetPosition.x = position.x targetPosition.y = position.y if nextAttackChunk ~= -1 then - addDeathGenerator(map, nextAttackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) + addDeathGenerator(nextAttackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) else - addDeathGenerator(map, attackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) + addDeathGenerator(attackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) end else cmd = Universe.wanderCommand @@ -224,9 +218,11 @@ local function settleMove(map, squad) return end - if (nextAttackChunk ~= -1) and - ((getPlayerBaseGenerator(map, nextAttackChunk) ~= 0) - or (getPlayerGenerator(map, nextAttackChunk) >= PLAYER_PHEROMONE_GENERATOR_THRESHOLD)) + if (nextAttackChunk ~= -1) + and ( + nextAttackChunk.playerBaseGenerator + or ((nextAttackChunk.playerBaseGenerator or 0) >= PLAYER_PHEROMONE_GENERATOR_THRESHOLD) + ) then cmd = Universe.settleCommand squad.status = SQUAD_BUILDING @@ -235,8 +231,8 @@ local function settleMove(map, squad) else cmd.distraction = DEFINES_DISTRACTION_BY_ENEMY end - elseif (getPlayerBaseGenerator(map, attackChunk) ~= 0) or - (attackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold) + elseif attackChunk.playerBaseGenerator + or (attackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold) then cmd = Universe.attackCommand @@ -286,10 +282,10 @@ local function attackMove(map, squad) local attackScorer = scoreAttackLocation local squadChunk = squad.chunk if squadChunk ~= -1 then - addDeathGenerator(map, squadChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) + addDeathGenerator(squadChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) end if chunk ~= -1 then - addSquadToChunk(map, chunk, squad) + addSquadToChunk(chunk, squad) addMovementPenalty(squad, chunk) if not squad.group.valid then return @@ -338,13 +334,13 @@ local function attackMove(map, squad) targetPosition.x = position.x targetPosition.y = position.y if (nextAttackChunk ~= -1) then - addDeathGenerator(map, nextAttackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) + addDeathGenerator(nextAttackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) else - addDeathGenerator(map, attackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) + addDeathGenerator(attackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) end end - if (getPlayerBaseGenerator(map, attackChunk) ~= 0) and + if attackChunk.playerBaseGenerator and (attackChunk[PLAYER_PHEROMONE] >= Universe.attackPlayerThreshold) then cmd = Universe.attackCommand @@ -392,7 +388,7 @@ function SquadAttack.cleanSquads(tick) end if not groupId then Universe.squadIterator = nil - if (table_size(squads) == 0) then + if (tableSize(squads) == 0) then -- this is needed as the next command remembers the max length a table has been Universe.groupNumberToSquad = {} end @@ -401,9 +397,9 @@ function SquadAttack.cleanSquads(tick) local group = squad.group if not group.valid then if squad.chunk ~= -1 then - addDeathGenerator(squad.map, squad.chunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) + addDeathGenerator(squad.chunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) end - removeSquadFromChunk(squad.map, squad) + removeSquadFromChunk(squad) if squad.settlers then Universe.builderCount = Universe.builderCount - 1 if Universe.builderCount < 0 then @@ -461,7 +457,7 @@ function SquadAttack.squadDispatch(map, squad, tick) end elseif (status == SQUAD_BUILDING) then squad.commandTick = tick + COMMAND_TIMEOUT - removeSquadFromChunk(map, squad) + removeSquadFromChunk(squad) buildMove(map, squad) elseif (status == SQUAD_GUARDING) then squad.commandTick = tick + COMMAND_TIMEOUT diff --git a/libs/SquadDefense.lua b/libs/SquadDefense.lua index faf0471..a154d50 100644 --- a/libs/SquadDefense.lua +++ b/libs/SquadDefense.lua @@ -56,7 +56,6 @@ local scoreNeighborsForRetreat = MovementUtils.scoreNeighborsForRetreat local findMovementPosition = MovementUtils.findMovementPosition local getRetreatTick = ChunkPropertyUtils.getRetreatTick -local getPlayerBaseGenerator = ChunkPropertyUtils.getPlayerBaseGenerator local setRetreatTick = ChunkPropertyUtils.setRetreatTick local getEnemyStructureCount = ChunkPropertyUtils.getEnemyStructureCount @@ -65,13 +64,13 @@ local getEnemyStructureCount = ChunkPropertyUtils.getEnemyStructureCount local function scoreRetreatLocation(map, neighborChunk) return (-neighborChunk[BASE_PHEROMONE] + -(neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER) + - -(getPlayerBaseGenerator(map, neighborChunk) * 1000)) + -((neighborChunk.playerBaseGenerator or 0) * 1000)) end function AiDefense.retreatUnits(chunk, cause, map, tick, radius) - if (tick - getRetreatTick(chunk) > COOLDOWN_RETREAT) and (getEnemyStructureCount(map, chunk) == 0) then + if (tick - getRetreatTick(chunk) > COOLDOWN_RETREAT) and (getEnemyStructureCount(chunk) == 0) then - setRetreatTick(map, chunk, tick) + setRetreatTick(chunk, tick) local exitPath,exitDirection, nextExitPath,nextExitDirection = scoreNeighborsForRetreat(chunk, getNeighborChunks(map, @@ -122,7 +121,7 @@ function AiDefense.retreatUnits(chunk, cause, map, tick, radius) if not newSquad then if (Universe.squadCount < Universe.AI_MAX_SQUAD_COUNT) then created = true - local base = findNearbyBase(map, chunk) + local base = findNearbyBase(chunk) if not base then return end @@ -153,7 +152,7 @@ function AiDefense.retreatUnits(chunk, cause, map, tick, radius) newSquad.status = SQUAD_RETREATING - addSquadToChunk(map, chunk, newSquad) + addSquadToChunk(chunk, newSquad) newSquad.frenzy = true local squadPosition = newSquad.group.position diff --git a/libs/UnitGroupUtils.lua b/libs/UnitGroupUtils.lua index ea5742c..1ca6fe0 100644 --- a/libs/UnitGroupUtils.lua +++ b/libs/UnitGroupUtils.lua @@ -40,18 +40,18 @@ local SQUAD_GUARDING = Constants.SQUAD_GUARDING local gaussianRandomRangeRG = MathUtils.gaussianRandomRangeRG -local getSquadsOnChunk = ChunkPropertyUtils.getSquadsOnChunk - local getNeighborChunks = MapUtils.getNeighborChunks -- module code function UnitGroupUtils.findNearbyRetreatingSquad(map, chunk) - for _,squad in pairs(getSquadsOnChunk(map, chunk)) do - local unitGroup = squad.group - if (squad.status == SQUAD_RETREATING) and unitGroup and unitGroup.valid then - return squad + if chunk.squads then + for _,squad in pairs(chunk.squads) do + local unitGroup = squad.group + if (squad.status == SQUAD_RETREATING) and unitGroup and unitGroup.valid then + return squad + end end end @@ -59,8 +59,8 @@ function UnitGroupUtils.findNearbyRetreatingSquad(map, chunk) for i=1,#neighbors do local neighbor = neighbors[i] - if neighbor ~= -1 then - for _,squad in pairs(getSquadsOnChunk(map, neighbor)) do + if (neighbor ~= -1) and neighbor.squads then + for _,squad in pairs(neighbor.squads) do local unitGroup = squad.group if (squad.status == SQUAD_RETREATING) and unitGroup and unitGroup.valid then return squad @@ -73,10 +73,12 @@ end function UnitGroupUtils.findNearbySquad(map, chunk) - for _,squad in pairs(getSquadsOnChunk(map, chunk)) do - local unitGroup = squad.group - if unitGroup and unitGroup.valid then - return squad + if chunk.squads then + for _,squad in pairs(chunk.squads) do + local unitGroup = squad.group + if unitGroup and unitGroup.valid then + return squad + end end end @@ -84,8 +86,8 @@ function UnitGroupUtils.findNearbySquad(map, chunk) for i=1,#neighbors do local neighbor = neighbors[i] - if neighbor ~= -1 then - for _,squad in pairs(getSquadsOnChunk(map, neighbor)) do + if (neighbor ~= -1) and neighbor.squads then + for _,squad in pairs(neighbor.squads) do local unitGroup = squad.group if unitGroup and unitGroup.valid then return squad diff --git a/libs/Upgrade.lua b/libs/Upgrade.lua index c7d633a..b2ca50d 100644 --- a/libs/Upgrade.lua +++ b/libs/Upgrade.lua @@ -56,8 +56,6 @@ local TICKS_A_MINUTE = Constants.TICKS_A_MINUTE -- imported functions local addBaseResourceChunk = ChunkPropertyUtils.addBaseResourceChunk -local getChunkBase = ChunkPropertyUtils.getChunkBase -local getResourceGenerator = ChunkPropertyUtils.getResourceGenerator local sFind = string.find local queueGeneratedChunk = MapUtils.queueGeneratedChunk local processPendingChunks = ChunkProcessor.processPendingChunks @@ -116,6 +114,9 @@ local function addCommandSet(queriesAndCommands) queriesAndCommands.npcForces = {} queriesAndCommands.nonPlayerForces = {} + queriesAndCommands.chunkPropertyUtilsQueries = {} + queriesAndCommands.chunkPropertyUtilsQueries.position = {0,0} + -- pb queriesAndCommands.pbFilteredEntitiesPointQueryLimited = { position = {0, 0}, @@ -468,7 +469,7 @@ function Upgrade.addUniverseProperties() global[key] = nil end end - + for key in pairs(Universe) do Universe[key] = nil end @@ -529,6 +530,8 @@ function Upgrade.addUniverseProperties() Universe.builderCount = 0 Universe.squadCount = 0 Universe.chunkToNests = {} + Universe.chunkToHives = {} + Universe.chunkToUtilities = {} Universe.processActiveSpawnerIterator = nil Universe.processActiveRaidSpawnerIterator = nil Universe.processMigrationIterator = nil @@ -553,7 +556,7 @@ function Upgrade.addUniverseProperties() addCommandSet(Universe) Universe.bases = {} - + Universe.processBaseAIIterator = nil for _,map in pairs(Universe.maps) do @@ -562,9 +565,10 @@ function Upgrade.addUniverseProperties() local chunk = processQueue[i] chunk[CHUNK_TICK] = chunk[ENEMY_PHEROMONE] chunk[ENEMY_PHEROMONE] = 0 + chunk.map = map end end - + Universe.excludedSurfaces = {} Universe.pendingUpgrades = {} @@ -630,8 +634,8 @@ function Upgrade.attempt() for _,map in pairs(Universe.maps) do if (map.surface.valid) then for _, chunk in pairs(map.processQueue) do - if getResourceGenerator(map, chunk) > 0 then - local base = getChunkBase(map, chunk) + if chunk.resourceGenerator then + local base = chunk.base if base then addBaseResourceChunk(base, chunk) end