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

FACTO-256: Additional code consolidation, vengence settlers now have a

separate cost
This commit is contained in:
Aaron Veden
2023-03-12 16:13:32 -07:00
parent 8aa2939ff9
commit 3a9f5b05cd
11 changed files with 176 additions and 334 deletions

View File

@@ -19,8 +19,14 @@
((nil . ((projectile-project-install-cmd . "./make.sh copy") ((nil . ((projectile-project-install-cmd . "./make.sh copy")
(projectile-install-buffer-suffix . "install") (projectile-install-buffer-suffix . "install")
(projectile-project-compile-cmd . "luacheck .")
(projectile-compile-buffer-suffix . "lint")
(projectile-project-package-cmd . "./make.sh zip") (projectile-project-package-cmd . "./make.sh zip")
(projectile-package-buffer-suffix . "install") (projectile-package-buffer-suffix . "install")
(projectile-project-uninstall-cmd . "./make.sh clear")
(projectile-project-uninstall-cmd . "./make.sh clear")
(projectile-uninstall-buffer-suffix . "install") (projectile-uninstall-buffer-suffix . "install")
(projectile-project-run-cmd . "factorio"))))
(projectile-project-run-cmd . "factorio"))))

View File

@@ -11,27 +11,16 @@ globals = {
"table_size", "table_size",
"script", "script",
"defines", "defines",
"mapProcessorG", "ProcessorG",
"pheromoneUtilsG", "ConstantsG",
"aiAttackWaveG", "ChunkPropertyUtilsG",
"aiPlanningG", "ChunkUtilsG",
"aiPredicatesG", "MapUtilsG",
"constantsG", "MathUtilsG",
"chunkProcessorG", "SquadG",
"chunkPropertyUtilsG",
"chunkUtilsG",
"interopG",
"mapUtilsG",
"mathUtilsG",
"movementUtilsG",
"playerUtilsG",
"squadAttackG",
"aiDefenseG",
"stringUtilsG",
"unitGroupUtilsG",
"unitUtilsG", "unitUtilsG",
"baseUtilsG", "BaseUtilsG",
"queryUtilsG" "UtilsG"
} }
max_line_length = false max_line_length = false

View File

@@ -34,6 +34,7 @@ Version: 3.2.0
- Reduced the size of stickers applied by Rampant new enemies to player entities - Reduced the size of stickers applied by Rampant new enemies to player entities
- Recording the resource chunks covered by a given base as a property of a base - Recording the resource chunks covered by a given base as a property of a base
- Use the enemy seed value instead of the map seed for puesdo random generating used by AI - Use the enemy seed value instead of the map seed for puesdo random generating used by AI
- Vengence settlers now cost ~3x of vengence squad
Bugfixes: Bugfixes:
- Removed layer-13 from projectiles - Removed layer-13 from projectiles
- script_raised_built now looks for enemy faction and registers as needed - script_raised_built now looks for enemy faction and registers as needed

View File

@@ -786,7 +786,7 @@ local function onUnitGroupCreated(event)
return return
end end
if not Universe.aiNocturnalMode then if not Universe.aiNocturnalMode then
local settler = canMigrate(map, base) and local settler = canMigrate(base) and
(Universe.builderCount < Universe.AI_MAX_VANILLA_BUILDER_COUNT) and (Universe.builderCount < Universe.AI_MAX_VANILLA_BUILDER_COUNT) and
(Universe.random() < 0.25) (Universe.random() < 0.25)
@@ -887,7 +887,7 @@ local function onGroupFinishedGathering(event)
group.destroy() group.destroy()
return return
end end
local settler = canMigrate(map, base) and local settler = canMigrate(base) and
(Universe.builderCount < Universe.AI_MAX_VANILLA_BUILDER_COUNT) and (Universe.builderCount < Universe.AI_MAX_VANILLA_BUILDER_COUNT) and
(Universe.random() < 0.25) (Universe.random() < 0.25)

View File

@@ -171,7 +171,7 @@ local function findBaseMutation(targetEvolution, excludeFactions)
return availableAlignments[#availableAlignments] return availableAlignments[#availableAlignments]
end end
local function initialEntityUpgrade(baseAlignment, tier, maxTier, map, useHiveType, entityType) local function initialEntityUpgrade(baseAlignment, tier, maxTier, useHiveType, entityType)
local entity local entity
local useTier local useTier
@@ -228,7 +228,7 @@ local function initialEntityUpgrade(baseAlignment, tier, maxTier, map, useHiveTy
return entity return entity
end end
local function entityUpgrade(baseAlignment, tier, maxTier, originalEntity, map) local function entityUpgrade(baseAlignment, tier, maxTier, originalEntity)
local entity local entity
local hiveType = BUILDING_HIVE_TYPE_LOOKUP[originalEntity.name] local hiveType = BUILDING_HIVE_TYPE_LOOKUP[originalEntity.name]
@@ -298,9 +298,9 @@ function BaseUtils.findEntityUpgrade(baseAlignment, currentEvo, evoIndex, origin
chunk.resourceGenerator chunk.resourceGenerator
) )
) )
return initialEntityUpgrade(baseAlignment, tier, maxTier, map, (makeHive and "hive"), entityType) return initialEntityUpgrade(baseAlignment, tier, maxTier, (makeHive and "hive"), entityType)
else else
return entityUpgrade(baseAlignment, tier, maxTier, originalEntity, map) return entityUpgrade(baseAlignment, tier, maxTier, originalEntity)
end end
end end

View File

@@ -85,8 +85,6 @@ local addNestCount = ChunkPropertyUtils.addNestCount
local removeNestCount = ChunkPropertyUtils.removeNestCount local removeNestCount = ChunkPropertyUtils.removeNestCount
local addHiveCount = ChunkPropertyUtils.addHiveCount local addHiveCount = ChunkPropertyUtils.addHiveCount
local removeHiveCount = ChunkPropertyUtils.removeHiveCount local removeHiveCount = ChunkPropertyUtils.removeHiveCount
local addTrapCount = ChunkPropertyUtils.addTrapCount
local removeTrapCount = ChunkPropertyUtils.removeTrapCount
local addTurretCount = ChunkPropertyUtils.addTurretCount local addTurretCount = ChunkPropertyUtils.addTurretCount
local removeTurretCount = ChunkPropertyUtils.removeTurretCount local removeTurretCount = ChunkPropertyUtils.removeTurretCount
local addUtilityCount = ChunkPropertyUtils.addUtilityCount local addUtilityCount = ChunkPropertyUtils.addUtilityCount

View File

@@ -97,6 +97,7 @@ constants.AI_SQUAD_COST = 175
constants.RECOVER_NEST_COST = constants.AI_SQUAD_COST constants.RECOVER_NEST_COST = constants.AI_SQUAD_COST
constants.RECOVER_WORM_COST = constants.AI_SQUAD_COST * 0.5 constants.RECOVER_WORM_COST = constants.AI_SQUAD_COST * 0.5
constants.AI_VENGENCE_SQUAD_COST = 45 constants.AI_VENGENCE_SQUAD_COST = 45
constants.AI_VENGENCE_SETTLER_COST = 120
constants.AI_SETTLER_COST = 300 constants.AI_SETTLER_COST = 300
constants.AI_BASE_BUILDING_COST = 500 constants.AI_BASE_BUILDING_COST = 500
constants.AI_TUNNEL_COST = 100 constants.AI_TUNNEL_COST = 100

View File

@@ -395,7 +395,7 @@ end
/|\ /|\
6 7 8 6 7 8
]]-- ]]--
function MapUtils.canMoveChunkDirection(map, direction, startChunk, endChunk) function MapUtils.canMoveChunkDirection(direction, startChunk, endChunk)
local canMove = false local canMove = false
local startPassable = getPassable(startChunk) local startPassable = getPassable(startChunk)
local endPassable = getPassable(endChunk) local endPassable = getPassable(endChunk)
@@ -425,33 +425,6 @@ function MapUtils.canMoveChunkDirection(map, direction, startChunk, endChunk)
return canMove return canMove
end end
function MapUtils.getCardinalChunks(map, x, y)
local neighbors = Universe.cardinalNeighbors
local xChunks = map[x]
if xChunks then
neighbors[1] = xChunks[y-CHUNK_SIZE] or -1
neighbors[4] = xChunks[y+CHUNK_SIZE] or -1
else
neighbors[1] = -1
neighbors[4] = -1
end
xChunks = map[x-CHUNK_SIZE]
if xChunks then
neighbors[2] = xChunks[y] or -1
else
neighbors[2] = -1
end
xChunks = map[x+CHUNK_SIZE]
if xChunks then
neighbors[3] = xChunks[y] or -1
else
neighbors[3] = -1
end
return neighbors
end
function MapUtils.positionFromDirectionAndChunk(direction, startPosition, scaling) function MapUtils.positionFromDirectionAndChunk(direction, startPosition, scaling)
local endPosition = {} local endPosition = {}
if (direction == 1) then if (direction == 1) then
@@ -560,7 +533,7 @@ function MapUtils.deathScent(chunk, structure)
addPermanentDeathGenerator(chunk, amount) addPermanentDeathGenerator(chunk, amount)
end end
function MapUtils.processPheromone(map, chunk, tick, player) function MapUtils.processPheromone(chunk, tick, player)
if chunk[CHUNK_TICK] > tick then if chunk[CHUNK_TICK] > tick then
return return
end end
@@ -576,12 +549,12 @@ function MapUtils.processPheromone(map, chunk, tick, player)
local enemyStructureCount = getEnemyStructureCount(chunk) local enemyStructureCount = getEnemyStructureCount(chunk)
local tempNeighbors = MapUtils.getNeighborChunks(map, chunk.x, chunk.y) local tempNeighbors = MapUtils.getNeighborChunks(chunk.map, chunk.x, chunk.y)
for i=1,8 do for i=1,8 do
local tempPheromone local tempPheromone
local neighbor = tempNeighbors[i] local neighbor = tempNeighbors[i]
if (neighbor ~= -1) then if (neighbor ~= -1) then
if MapUtils.canMoveChunkDirection(map, i, chunk, neighbor) then if MapUtils.canMoveChunkDirection(i, chunk, neighbor) then
chunkCount = chunkCount + 1 chunkCount = chunkCount + 1
chunkPlayer = chunkPlayer + neighbor[PLAYER_PHEROMONE] chunkPlayer = chunkPlayer + neighbor[PLAYER_PHEROMONE]
chunkEnemy = chunkEnemy + neighbor[ENEMY_PHEROMONE] chunkEnemy = chunkEnemy + neighbor[ENEMY_PHEROMONE]

View File

@@ -154,7 +154,7 @@ function Processor.processMap(map, tick)
Universe.processedChunks = Universe.processedChunks + ((startIndex - endIndex) * step) Universe.processedChunks = Universe.processedChunks + ((startIndex - endIndex) * step)
for x=startIndex,endIndex,step do for x=startIndex,endIndex,step do
processPheromone(map, processQueue[x], tick) processPheromone(processQueue[x], tick)
end end
end end
@@ -209,7 +209,7 @@ function Processor.processPlayers(players, tick)
local chunk = getChunkByXY(map, x, y) local chunk = getChunkByXY(map, x, y)
if (chunk ~= -1) then if (chunk ~= -1) then
processPheromone(map, chunk, tick, true) processPheromone(chunk, tick, true)
if chunk.nestCount then if chunk.nestCount then
processNestActiveness(chunk, tick) processNestActiveness(chunk, tick)
@@ -254,7 +254,7 @@ end
--[[ --[[
Passive scan to find entities that have been generated outside the factorio event system Passive scan to find entities that have been generated outside the factorio event system
--]] --]]
function Processor.scanPlayerMap(map, tick) function Processor.scanPlayerMap(map)
local index = map.scanPlayerIndex local index = map.scanPlayerIndex
local processQueue = map.processQueue local processQueue = map.processQueue
@@ -300,7 +300,7 @@ function Processor.scanEnemyMap(map, tick)
end end
end end
function Processor.scanResourceMap(map, tick) function Processor.scanResourceMap(map)
local index = map.scanResourceIndex local index = map.scanResourceIndex
local processQueue = map.processQueue local processQueue = map.processQueue
@@ -340,9 +340,9 @@ function Processor.processVengence()
end end
local base = chunk.base local base = chunk.base
if canMigrate(base) and (Universe.random() < 0.075) then if canMigrate(base) and (Universe.random() < 0.075) then
formVengenceSettler(chunk, base) formVengenceSettler(chunk)
else else
formVengenceSquad(chunk, base) formVengenceSquad(chunk)
end end
end end

View File

@@ -71,6 +71,7 @@ local RALLY_CRY_DISTANCE = Constants.RALLY_CRY_DISTANCE
local AI_SQUAD_COST = Constants.AI_SQUAD_COST local AI_SQUAD_COST = Constants.AI_SQUAD_COST
local AI_SETTLER_COST = Constants.AI_SETTLER_COST local AI_SETTLER_COST = Constants.AI_SETTLER_COST
local AI_VENGENCE_SQUAD_COST = Constants.AI_VENGENCE_SQUAD_COST local AI_VENGENCE_SQUAD_COST = Constants.AI_VENGENCE_SQUAD_COST
local AI_VENGENCE_SETTLER_COST = Constants.AI_VENGENCE_SETTLER_COST
local CHUNK_ALL_DIRECTIONS = Constants.CHUNK_ALL_DIRECTIONS local CHUNK_ALL_DIRECTIONS = Constants.CHUNK_ALL_DIRECTIONS
-- imported functions -- imported functions
@@ -113,19 +114,19 @@ local positionFromDirectionAndFlat = MapUtils.positionFromDirectionAndFlat
local euclideanDistanceNamed = MathUtils.euclideanDistanceNamed local euclideanDistanceNamed = MathUtils.euclideanDistanceNamed
-- module code -- module code
local function scoreRetreatLocation(map, neighborChunk) local function scoreRetreatLocation(neighborChunk)
return (-neighborChunk[BASE_PHEROMONE] + return (-neighborChunk[BASE_PHEROMONE] +
-(neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER) + -(neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER) +
-((neighborChunk.playerBaseGenerator or 0) * 1000)) -((neighborChunk.playerBaseGenerator or 0) * 1000))
end end
local function scoreResourceLocation(map, neighborChunk) local function scoreResourceLocation(neighborChunk)
return neighborChunk[RESOURCE_PHEROMONE] return neighborChunk[RESOURCE_PHEROMONE]
- (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER) - (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
- neighborChunk[ENEMY_PHEROMONE] - neighborChunk[ENEMY_PHEROMONE]
end end
local function scoreSiegeLocation(map, neighborChunk) local function scoreSiegeLocation(neighborChunk)
local settle = neighborChunk[BASE_PHEROMONE] local settle = neighborChunk[BASE_PHEROMONE]
+ neighborChunk[RESOURCE_PHEROMONE] * 0.5 + neighborChunk[RESOURCE_PHEROMONE] * 0.5
+ (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER) + (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
@@ -133,16 +134,30 @@ local function scoreSiegeLocation(map, neighborChunk)
return settle - neighborChunk[ENEMY_PHEROMONE] return settle - neighborChunk[ENEMY_PHEROMONE]
end end
local function scoreAttackLocation(map, neighborChunk) local function scoreAttackLocation(neighborChunk)
local damage = neighborChunk[BASE_PHEROMONE] + local damage = neighborChunk[BASE_PHEROMONE] +
(neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER) (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
return damage return damage
end end
local function findMovementPosition(surface, position) local function findMovementPosition(surface, position)
local pos = position return surface.find_non_colliding_position(
pos = surface.find_non_colliding_position("behemoth-biter", pos, 10, 2, false) "behemoth-biter",
return pos position,
10,
2,
false
)
end
local function findDeploymentPosition(surface, position)
return surface.find_non_colliding_position(
"biter-spawner",
position,
CHUNK_SIZE,
4,
true
)
end end
local function calculateSettlerMaxDistance() local function calculateSettlerMaxDistance()
@@ -204,7 +219,7 @@ end
--[[ --[[
Expects all neighbors adjacent to a chunk Expects all neighbors adjacent to a chunk
--]] --]]
function scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFunction) local function scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFunction)
local highestChunk = -1 local highestChunk = -1
local highestScore = -MAGIC_MAXIMUM_NUMBER local highestScore = -MAGIC_MAXIMUM_NUMBER
local highestDirection = 0 local highestDirection = 0
@@ -212,8 +227,8 @@ function scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFun
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 (chunk == -1) or canMoveChunkDirection(map, x, chunk, neighborChunk) then if (chunk == -1) or canMoveChunkDirection(x, chunk, neighborChunk) then
local score = scoreFunction(map, neighborChunk) local score = scoreFunction(neighborChunk)
if (score > highestScore) then if (score > highestScore) then
highestScore = score highestScore = score
highestChunk = neighborChunk highestChunk = neighborChunk
@@ -223,7 +238,7 @@ function scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFun
end end
end end
if (chunk ~= -1) and (scoreFunction(map, chunk) > highestScore) then if (chunk ~= -1) and (scoreFunction(chunk) > highestScore) then
return chunk, 0, -1, 0 return chunk, 0, -1, 0
end end
@@ -236,8 +251,8 @@ function scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFun
for x=1,8 do for x=1,8 do
local neighborChunk = neighborDirectionChunks[x] local neighborChunk = neighborDirectionChunks[x]
if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then canMoveChunkDirection(x, highestChunk, neighborChunk)) then
local score = scoreFunction(map, neighborChunk) local score = scoreFunction(neighborChunk)
if (score > nextHighestScore) then if (score > nextHighestScore) then
nextHighestScore = score nextHighestScore = score
nextHighestChunk = neighborChunk nextHighestChunk = neighborChunk
@@ -426,8 +441,8 @@ local function scoreNeighborsForAttack(map, chunk, neighborDirectionChunks, scor
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 (chunk == -1) or canMoveChunkDirection(map, x, chunk, neighborChunk) then if (chunk == -1) or canMoveChunkDirection(x, chunk, neighborChunk) then
local score = scoreFunction(map, neighborChunk) local score = scoreFunction(neighborChunk)
if (score > highestScore) then if (score > highestScore) then
highestScore = score highestScore = score
highestChunk = neighborChunk highestChunk = neighborChunk
@@ -446,8 +461,8 @@ local function scoreNeighborsForAttack(map, chunk, neighborDirectionChunks, scor
for x=1,8 do for x=1,8 do
local neighborChunk = neighborDirectionChunks[x] local neighborChunk = neighborDirectionChunks[x]
if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then canMoveChunkDirection(x, highestChunk, neighborChunk)) then
local score = scoreFunction(map, neighborChunk) local score = scoreFunction(neighborChunk)
if (score > nextHighestScore) then if (score > nextHighestScore) then
nextHighestScore = score nextHighestScore = score
nextHighestChunk = neighborChunk nextHighestChunk = neighborChunk
@@ -674,8 +689,8 @@ local function scoreNeighborsForRetreat(chunk, neighborDirectionChunks, scoreFun
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 (chunk == -1) or canMoveChunkDirection(map, x, chunk, neighborChunk) then if (chunk == -1) or canMoveChunkDirection(x, chunk, neighborChunk) then
local score = scoreFunction(map, neighborChunk) local score = scoreFunction(neighborChunk)
if (score > highestScore) then if (score > highestScore) then
highestScore = score highestScore = score
highestChunk = neighborChunk highestChunk = neighborChunk
@@ -695,8 +710,8 @@ local function scoreNeighborsForRetreat(chunk, neighborDirectionChunks, scoreFun
local neighborChunk = neighborDirectionChunks[x] local neighborChunk = neighborDirectionChunks[x]
if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then canMoveChunkDirection(x, highestChunk, neighborChunk)) then
local score = scoreFunction(map, neighborChunk) local score = scoreFunction(neighborChunk)
if (score > nextHighestScore) then if (score > nextHighestScore) then
nextHighestScore = score nextHighestScore = score
nextHighestChunk = neighborChunk nextHighestChunk = neighborChunk
@@ -914,35 +929,23 @@ local function attackWaveValidCandidate(chunk)
return false return false
end end
local function scoreSettlerLocation(map, neighborChunk) local function scoreSettlerLocation(neighborChunk)
return neighborChunk[RESOURCE_PHEROMONE] + -neighborChunk[PLAYER_PHEROMONE] return neighborChunk[RESOURCE_PHEROMONE] + -neighborChunk[PLAYER_PHEROMONE]
end end
local function scoreSiegeSettlerLocation(map, neighborChunk) local function scoreSiegeSettlerLocation(neighborChunk)
return (neighborChunk[RESOURCE_PHEROMONE] + neighborChunk[BASE_PHEROMONE]) + -neighborChunk[PLAYER_PHEROMONE] return (neighborChunk[RESOURCE_PHEROMONE] + neighborChunk[BASE_PHEROMONE]) + -neighborChunk[PLAYER_PHEROMONE]
end end
local function scoreUnitGroupLocation(map, neighborChunk) local function scoreUnitGroupLocation(neighborChunk)
return neighborChunk[PLAYER_PHEROMONE] + neighborChunk[BASE_PHEROMONE] return neighborChunk[PLAYER_PHEROMONE] + neighborChunk[BASE_PHEROMONE]
end end
local function validSiegeSettlerLocation(map, neighborChunk) local function validUnitGroupLocation(neighborChunk)
return (getPassable(neighborChunk) == CHUNK_ALL_DIRECTIONS) and return (getPassable(neighborChunk) == CHUNK_ALL_DIRECTIONS) and
(not neighborChunk.nestCount) (not neighborChunk.nestCount)
end end
local function validSettlerLocation(map, chunk, neighborChunk)
local chunkResource = chunk[RESOURCE_PHEROMONE]
return (getPassable(neighborChunk) == CHUNK_ALL_DIRECTIONS) and
(not neighborChunk.nestCount) and
(neighborChunk[RESOURCE_PHEROMONE] >= chunkResource)
end
local function validUnitGroupLocation(map, neighborChunk)
return getPassable(neighborChunk) == CHUNK_ALL_DIRECTIONS and
(not neighborChunk.nestCount)
end
local function visitPattern(o, cX, cY, distance) local function visitPattern(o, cX, cY, distance)
local startX local startX
local endX local endX
@@ -985,43 +988,15 @@ end
--[[ --[[
Expects all neighbors adjacent to a chunk Expects all neighbors adjacent to a chunk
--]] --]]
local function scoreNeighborsForResource(chunk, neighborDirectionChunks, validFunction, scoreFunction, map) local function scoreNeighborsForFormation(chunk, validFunction, scoreFunction)
local highestChunk = -1
local highestScore = -MAGIC_MAXIMUM_NUMBER
local highestDirection
for x=1,8 do
local neighborChunk = neighborDirectionChunks[x]
if (neighborChunk ~= -1) and
canMoveChunkDirection(map, x, chunk, neighborChunk) and
validFunction(map, chunk, neighborChunk)
then
local score = scoreFunction(map, neighborChunk)
if (score > highestScore) then
highestScore = score
highestChunk = neighborChunk
highestDirection = x
end
end
end
if (chunk ~= -1) and (scoreFunction(map, chunk) > highestScore) then
return -1, -1
end
return highestChunk, highestDirection
end
--[[
Expects all neighbors adjacent to a chunk
--]]
local function scoreNeighborsForFormation(neighborChunks, validFunction, scoreFunction, map)
local highestChunk = -1 local highestChunk = -1
local highestScore = -MAGIC_MAXIMUM_NUMBER local highestScore = -MAGIC_MAXIMUM_NUMBER
local highestDirection local highestDirection
local neighborChunks = getNeighborChunks(chunk.map, chunk.x, chunk.y)
for x=1,8 do for x=1,8 do
local neighborChunk = neighborChunks[x] local neighborChunk = neighborChunks[x]
if (neighborChunk ~= -1) and validFunction(map, neighborChunk) then if (neighborChunk ~= -1) and validFunction(neighborChunk) then
local score = scoreFunction(map, neighborChunk) local score = scoreFunction(neighborChunk)
if (score > highestScore) then if (score > highestScore) then
highestScore = score highestScore = score
highestChunk = neighborChunk highestChunk = neighborChunk
@@ -1060,213 +1035,116 @@ function Squad.rallyUnits(chunk, tick)
end end
end end
function Squad.formSettlers(chunk) local function deploySquad(name, chunk, cost, vengence, attacker)
local base = chunk.base local base = 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
squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y),
validSiegeSettlerLocation,
scoreSiegeSettlerLocation,
map)
else
squadPath, squadDirection = scoreNeighborsForResource(chunk,
getNeighborChunks(map, chunk.x, chunk.y),
validSettlerLocation,
scoreSettlerLocation,
map)
end
if (squadPath ~= -1) then local lackingPoints = ((base.unitPoints - cost) < 0)
local squadPosition = surface.find_non_colliding_position("biter-spawner", if attacker then
positionFromDirectionAndChunk(squadDirection, if lackingPoints
chunk, or ((chunk[BASE_PHEROMONE] < 0.0001) and (chunk[PLAYER_PHEROMONE] < 0.0001))
0.98), or (Universe.squadCount > Universe.AI_MAX_SQUAD_COUNT)
CHUNK_SIZE, or (not vengence and not attackWaveValidCandidate(chunk))
4, or (Universe.random() > Universe.formSquadThreshold)
true) then
if squadPosition then
local squad = Squad.createSquad(squadPosition, map, nil, true, base)
local scaledWaveSize = settlerWaveScaling()
Universe.formGroupCommand.group = squad.group
Universe.formCommand.unit_count = scaledWaveSize
local foundUnits = surface.set_multi_command(Universe.formCommand)
if (foundUnits > 0) then
base.sentExpansionGroups = base.sentExpansionGroups + 1
squad.base = base
local kamikazeThreshold = Squad.calculateKamikazeSettlerThreshold(foundUnits)
if base.stateAI == BASE_AI_STATE_SIEGE then
kamikazeThreshold = kamikazeThreshold * 2.5
end
squad.kamikaze = Universe.random() < kamikazeThreshold
Universe.builderCount = Universe.builderCount + 1
modifyBaseUnitPoints(base, -AI_SETTLER_COST, "Settler", squadPosition.x, squadPosition.y)
Universe.groupNumberToSquad[squad.groupNumber] = squad
else
if (squad.group.valid) then
squad.group.destroy()
end
end
end
end
end
end
function Squad.formVengenceSquad(chunk, base)
if (Universe.squadCount < Universe.AI_MAX_SQUAD_COUNT)
and ((base.unitPoints - AI_VENGENCE_SQUAD_COST) > 0)
and (Universe.random() < Universe.formSquadThreshold)
then
if (chunk[BASE_PHEROMONE] < 0.0001) or (chunk[PLAYER_PHEROMONE] < 0.0001) then
return return
end end
local map = chunk.map else
if lackingPoints
local surface = map.surface or (Universe.builderCount > Universe.AI_MAX_BUILDER_COUNT)
local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y), or (not vengence and (base.sentExpansionGroups > base.maxExpansionGroups))
validUnitGroupLocation, or (Universe.random() > Universe.formSquadThreshold)
scoreUnitGroupLocation, then
map) return
if (squadPath ~= -1) then
local squadPosition = surface.find_non_colliding_position("biter-spawner",
positionFromDirectionAndChunk(squadDirection,
chunk,
0.98),
CHUNK_SIZE,
4,
true)
if squadPosition then
local squad = Squad.createSquad(squadPosition, map, nil, false, base)
squad.rabid = Universe.random() < 0.03
local scaledWaveSize = attackWaveScaling()
Universe.formGroupCommand.group = squad.group
Universe.formCommand.unit_count = scaledWaveSize
local foundUnits = surface.set_multi_command(Universe.formCommand)
if (foundUnits > 0) then
squad.base = base
squad.kamikaze = Universe.random() < Squad.calculateKamikazeSquadThreshold(foundUnits)
Universe.groupNumberToSquad[squad.groupNumber] = squad
Universe.squadCount = Universe.squadCount + 1
modifyBaseUnitPoints(base, -AI_VENGENCE_SQUAD_COST, "Vengence", squadPosition.x, squadPosition.y)
else
if (squad.group.valid) then
squad.group.destroy()
end
end
end
end end
end end
local scoringFunction
if attacker then
scoringFunction = scoreUnitGroupLocation
else
scoringFunction = scoreSettlerLocation
if base.stateAI == BASE_AI_STATE_SIEGE then
scoringFunction = scoreSiegeSettlerLocation
end
end
local squadPath, squadDirection = scoreNeighborsForFormation(
chunk,
validUnitGroupLocation,
scoringFunction
)
if (squadPath == -1) then
return
end
local map = chunk.map
local surface = map.surface
local squadPosition = findDeploymentPosition(
surface,
positionFromDirectionAndChunk(squadDirection,
chunk,
0.98)
)
if not squadPosition then
return
end
local squad = Squad.createSquad(squadPosition, map, nil, not attacker, base)
local scaledWaveSize
if attacker then
scaledWaveSize = attackWaveScaling()
else
scaledWaveSize = settlerWaveScaling()
end
Universe.formGroupCommand.group = squad.group
Universe.formCommand.unit_count = scaledWaveSize
local foundUnits = surface.set_multi_command(Universe.formCommand)
if (foundUnits == 0) then
if squad.group.valid then
squad.group.destroy()
end
return
end
if attacker then
squad.kamikaze = Universe.random() < Squad.calculateKamikazeSquadThreshold(foundUnits)
Universe.squadCount = Universe.squadCount + 1
if not vengence and (base.stateAI == BASE_AI_STATE_AGGRESSIVE) then
base.sentAggressiveGroups = base.sentAggressiveGroups + 1
end
else
local kamikazeThreshold = Squad.calculateKamikazeSettlerThreshold(foundUnits)
if base.stateAI == BASE_AI_STATE_SIEGE then
kamikazeThreshold = kamikazeThreshold * 2.5
end
squad.kamikaze = Universe.random() < kamikazeThreshold
base.sentExpansionGroups = base.sentExpansionGroups + 1
Universe.builderCount = Universe.builderCount + 1
end
squad.rabid = Universe.random() < 0.03
Universe.groupNumberToSquad[squad.groupNumber] = squad
modifyBaseUnitPoints(base, -cost, name, squadPosition.x, squadPosition.y)
end end
function Squad.formVengenceSettler(chunk, base) function Squad.formSettlers(chunk)
if (Universe.builderCount < Universe.AI_MAX_BUILDER_COUNT) deploySquad("Settler", chunk, AI_SETTLER_COST, false, false)
and (base.sentExpansionGroups < base.maxExpansionGroups) end
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,
scoreUnitGroupLocation,
map)
if (squadPath ~= -1) then
local squadPosition = surface.find_non_colliding_position("biter-spawner",
positionFromDirectionAndChunk(squadDirection,
chunk,
0.98),
CHUNK_SIZE,
4,
true)
if squadPosition then
local squad = Squad.createSquad(squadPosition, map, nil, true, base)
squad.rabid = Universe.random() < 0.03 function Squad.formVengenceSettler(chunk)
deploySquad("Vengence Settler", chunk, AI_VENGENCE_SETTLER_COST, true, false)
local scaledWaveSize = settlerWaveScaling()
Universe.formGroupCommand.group = squad.group
Universe.formCommand.unit_count = scaledWaveSize
local foundUnits = surface.set_multi_command(Universe.formCommand)
if (foundUnits > 0) then
base.sentExpansionGroups = base.sentExpansionGroups + 1
squad.base = base
squad.kamikaze = Universe.random() < Squad.calculateKamikazeSettlerThreshold(foundUnits)
Universe.groupNumberToSquad[squad.groupNumber] = squad
Universe.builderCount = Universe.builderCount + 1
modifyBaseUnitPoints(base, -AI_VENGENCE_SQUAD_COST, "Vengence Settlers", squadPosition.x, squadPosition.y)
else
if (squad.group.valid) then
squad.group.destroy()
end
end
end
end
end
end end
function Squad.formSquads(chunk) function Squad.formSquads(chunk)
local base = chunk.base deploySquad("Squad", chunk, AI_SQUAD_COST, false, true)
if (Universe.squadCount < Universe.AI_MAX_SQUAD_COUNT) end
and attackWaveValidCandidate(chunk)
and ((base.unitPoints - AI_SQUAD_COST) > 0)
and (Universe.random() < Universe.formSquadThreshold)
then
if (chunk[BASE_PHEROMONE] < 0.0001) or (chunk[PLAYER_PHEROMONE] < 0.0001) then
return
end
local map = chunk.map function Squad.formVengenceSquad(chunk)
local surface = map.surface deploySquad("Vengence Squad", chunk, AI_VENGENCE_SQUAD_COST, true, true)
local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y),
validUnitGroupLocation,
scoreUnitGroupLocation,
map)
if (squadPath ~= -1) then
local squadPosition = surface.find_non_colliding_position("biter-spawner",
positionFromDirectionAndChunk(squadDirection,
chunk,
0.98),
CHUNK_SIZE,
4,
true)
if squadPosition then
local squad = Squad.createSquad(squadPosition, map, nil, false, base)
squad.rabid = Universe.random() < 0.03
local scaledWaveSize = attackWaveScaling()
Universe.formGroupCommand.group = squad.group
Universe.formCommand.unit_count = scaledWaveSize
local foundUnits = surface.set_multi_command(Universe.formCommand)
if (foundUnits > 0) then
squad.base = base
squad.kamikaze = Universe.random() < Squad.calculateKamikazeSquadThreshold(foundUnits)
Universe.squadCount = Universe.squadCount + 1
Universe.groupNumberToSquad[squad.groupNumber] = squad
if (base.stateAI == BASE_AI_STATE_AGGRESSIVE) then
base.sentAggressiveGroups = base.sentAggressiveGroups + 1
end
modifyBaseUnitPoints(base, -AI_SQUAD_COST, "Squad", squadPosition.x, squadPosition.y)
else
if (squad.group.valid) then
squad.group.destroy()
end
end
end
end
end
end end
function Squad.init(universe) function Squad.init(universe)

View File

@@ -19,8 +19,6 @@ local Upgrade = {}
-- imports -- imports
local Constants = require("libs/Constants") local Constants = require("libs/Constants")
local ChunkPropertyUtils = require("libs/ChunkPropertyUtils")
local MapUtils = require("libs/MapUtils")
-- --
@@ -51,8 +49,6 @@ local TICKS_A_MINUTE = Constants.TICKS_A_MINUTE
-- imported functions -- imported functions
local addBaseResourceChunk = ChunkPropertyUtils.addBaseResourceChunk
-- module code -- module code
local function addCommandSet(queriesAndCommands) local function addCommandSet(queriesAndCommands)