1
0
mirror of https://github.com/veden/Rampant.git synced 2025-01-28 03:29:34 +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
No known key found for this signature in database
GPG Key ID: FF5990B1C6DD3F84
11 changed files with 176 additions and 334 deletions

View File

@ -19,8 +19,14 @@
((nil . ((projectile-project-install-cmd . "./make.sh copy")
(projectile-install-buffer-suffix . "install")
(projectile-project-compile-cmd . "luacheck .")
(projectile-compile-buffer-suffix . "lint")
(projectile-project-package-cmd . "./make.sh zip")
(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-project-run-cmd . "factorio"))))
(projectile-project-run-cmd . "factorio"))))

View File

@ -11,27 +11,16 @@ globals = {
"table_size",
"script",
"defines",
"mapProcessorG",
"pheromoneUtilsG",
"aiAttackWaveG",
"aiPlanningG",
"aiPredicatesG",
"constantsG",
"chunkProcessorG",
"chunkPropertyUtilsG",
"chunkUtilsG",
"interopG",
"mapUtilsG",
"mathUtilsG",
"movementUtilsG",
"playerUtilsG",
"squadAttackG",
"aiDefenseG",
"stringUtilsG",
"unitGroupUtilsG",
"ProcessorG",
"ConstantsG",
"ChunkPropertyUtilsG",
"ChunkUtilsG",
"MapUtilsG",
"MathUtilsG",
"SquadG",
"unitUtilsG",
"baseUtilsG",
"queryUtilsG"
"BaseUtilsG",
"UtilsG"
}
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
- 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
- Vengence settlers now cost ~3x of vengence squad
Bugfixes:
- Removed layer-13 from projectiles
- script_raised_built now looks for enemy faction and registers as needed

View File

@ -786,7 +786,7 @@ local function onUnitGroupCreated(event)
return
end
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.random() < 0.25)
@ -887,7 +887,7 @@ local function onGroupFinishedGathering(event)
group.destroy()
return
end
local settler = canMigrate(map, base) and
local settler = canMigrate(base) and
(Universe.builderCount < Universe.AI_MAX_VANILLA_BUILDER_COUNT) and
(Universe.random() < 0.25)

View File

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

View File

@ -85,8 +85,6 @@ local addNestCount = ChunkPropertyUtils.addNestCount
local removeNestCount = ChunkPropertyUtils.removeNestCount
local addHiveCount = ChunkPropertyUtils.addHiveCount
local removeHiveCount = ChunkPropertyUtils.removeHiveCount
local addTrapCount = ChunkPropertyUtils.addTrapCount
local removeTrapCount = ChunkPropertyUtils.removeTrapCount
local addTurretCount = ChunkPropertyUtils.addTurretCount
local removeTurretCount = ChunkPropertyUtils.removeTurretCount
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_WORM_COST = constants.AI_SQUAD_COST * 0.5
constants.AI_VENGENCE_SQUAD_COST = 45
constants.AI_VENGENCE_SETTLER_COST = 120
constants.AI_SETTLER_COST = 300
constants.AI_BASE_BUILDING_COST = 500
constants.AI_TUNNEL_COST = 100

View File

@ -395,7 +395,7 @@ end
/|\
6 7 8
]]--
function MapUtils.canMoveChunkDirection(map, direction, startChunk, endChunk)
function MapUtils.canMoveChunkDirection(direction, startChunk, endChunk)
local canMove = false
local startPassable = getPassable(startChunk)
local endPassable = getPassable(endChunk)
@ -425,33 +425,6 @@ function MapUtils.canMoveChunkDirection(map, direction, startChunk, endChunk)
return canMove
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)
local endPosition = {}
if (direction == 1) then
@ -560,7 +533,7 @@ function MapUtils.deathScent(chunk, structure)
addPermanentDeathGenerator(chunk, amount)
end
function MapUtils.processPheromone(map, chunk, tick, player)
function MapUtils.processPheromone(chunk, tick, player)
if chunk[CHUNK_TICK] > tick then
return
end
@ -576,12 +549,12 @@ function MapUtils.processPheromone(map, chunk, tick, player)
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
local tempPheromone
local neighbor = tempNeighbors[i]
if (neighbor ~= -1) then
if MapUtils.canMoveChunkDirection(map, i, chunk, neighbor) then
if MapUtils.canMoveChunkDirection(i, chunk, neighbor) then
chunkCount = chunkCount + 1
chunkPlayer = chunkPlayer + neighbor[PLAYER_PHEROMONE]
chunkEnemy = chunkEnemy + neighbor[ENEMY_PHEROMONE]

View File

@ -154,7 +154,7 @@ function Processor.processMap(map, tick)
Universe.processedChunks = Universe.processedChunks + ((startIndex - endIndex) * step)
for x=startIndex,endIndex,step do
processPheromone(map, processQueue[x], tick)
processPheromone(processQueue[x], tick)
end
end
@ -209,7 +209,7 @@ function Processor.processPlayers(players, tick)
local chunk = getChunkByXY(map, x, y)
if (chunk ~= -1) then
processPheromone(map, chunk, tick, true)
processPheromone(chunk, tick, true)
if chunk.nestCount then
processNestActiveness(chunk, tick)
@ -254,7 +254,7 @@ end
--[[
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 processQueue = map.processQueue
@ -300,7 +300,7 @@ function Processor.scanEnemyMap(map, tick)
end
end
function Processor.scanResourceMap(map, tick)
function Processor.scanResourceMap(map)
local index = map.scanResourceIndex
local processQueue = map.processQueue
@ -340,9 +340,9 @@ function Processor.processVengence()
end
local base = chunk.base
if canMigrate(base) and (Universe.random() < 0.075) then
formVengenceSettler(chunk, base)
formVengenceSettler(chunk)
else
formVengenceSquad(chunk, base)
formVengenceSquad(chunk)
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_SETTLER_COST = Constants.AI_SETTLER_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
-- imported functions
@ -113,19 +114,19 @@ local positionFromDirectionAndFlat = MapUtils.positionFromDirectionAndFlat
local euclideanDistanceNamed = MathUtils.euclideanDistanceNamed
-- module code
local function scoreRetreatLocation(map, neighborChunk)
local function scoreRetreatLocation(neighborChunk)
return (-neighborChunk[BASE_PHEROMONE] +
-(neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER) +
-((neighborChunk.playerBaseGenerator or 0) * 1000))
end
local function scoreResourceLocation(map, neighborChunk)
local function scoreResourceLocation(neighborChunk)
return neighborChunk[RESOURCE_PHEROMONE]
- (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
- neighborChunk[ENEMY_PHEROMONE]
end
local function scoreSiegeLocation(map, neighborChunk)
local function scoreSiegeLocation(neighborChunk)
local settle = neighborChunk[BASE_PHEROMONE]
+ neighborChunk[RESOURCE_PHEROMONE] * 0.5
+ (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
@ -133,16 +134,30 @@ local function scoreSiegeLocation(map, neighborChunk)
return settle - neighborChunk[ENEMY_PHEROMONE]
end
local function scoreAttackLocation(map, neighborChunk)
local function scoreAttackLocation(neighborChunk)
local damage = neighborChunk[BASE_PHEROMONE] +
(neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
return damage
end
local function findMovementPosition(surface, position)
local pos = position
pos = surface.find_non_colliding_position("behemoth-biter", pos, 10, 2, false)
return pos
return surface.find_non_colliding_position(
"behemoth-biter",
position,
10,
2,
false
)
end
local function findDeploymentPosition(surface, position)
return surface.find_non_colliding_position(
"biter-spawner",
position,
CHUNK_SIZE,
4,
true
)
end
local function calculateSettlerMaxDistance()
@ -204,7 +219,7 @@ end
--[[
Expects all neighbors adjacent to a chunk
--]]
function scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFunction)
local function scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFunction)
local highestChunk = -1
local highestScore = -MAGIC_MAXIMUM_NUMBER
local highestDirection = 0
@ -212,8 +227,8 @@ function scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFun
for x=1,8 do
local neighborChunk = neighborDirectionChunks[x]
if (neighborChunk ~= -1) then
if (chunk == -1) or canMoveChunkDirection(map, x, chunk, neighborChunk) then
local score = scoreFunction(map, neighborChunk)
if (chunk == -1) or canMoveChunkDirection(x, chunk, neighborChunk) then
local score = scoreFunction(neighborChunk)
if (score > highestScore) then
highestScore = score
highestChunk = neighborChunk
@ -223,7 +238,7 @@ function scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFun
end
end
if (chunk ~= -1) and (scoreFunction(map, chunk) > highestScore) then
if (chunk ~= -1) and (scoreFunction(chunk) > highestScore) then
return chunk, 0, -1, 0
end
@ -236,8 +251,8 @@ function scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFun
for x=1,8 do
local neighborChunk = neighborDirectionChunks[x]
if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then
local score = scoreFunction(map, neighborChunk)
canMoveChunkDirection(x, highestChunk, neighborChunk)) then
local score = scoreFunction(neighborChunk)
if (score > nextHighestScore) then
nextHighestScore = score
nextHighestChunk = neighborChunk
@ -426,8 +441,8 @@ local function scoreNeighborsForAttack(map, chunk, neighborDirectionChunks, scor
for x=1,8 do
local neighborChunk = neighborDirectionChunks[x]
if (neighborChunk ~= -1) then
if (chunk == -1) or canMoveChunkDirection(map, x, chunk, neighborChunk) then
local score = scoreFunction(map, neighborChunk)
if (chunk == -1) or canMoveChunkDirection(x, chunk, neighborChunk) then
local score = scoreFunction(neighborChunk)
if (score > highestScore) then
highestScore = score
highestChunk = neighborChunk
@ -446,8 +461,8 @@ local function scoreNeighborsForAttack(map, chunk, neighborDirectionChunks, scor
for x=1,8 do
local neighborChunk = neighborDirectionChunks[x]
if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then
local score = scoreFunction(map, neighborChunk)
canMoveChunkDirection(x, highestChunk, neighborChunk)) then
local score = scoreFunction(neighborChunk)
if (score > nextHighestScore) then
nextHighestScore = score
nextHighestChunk = neighborChunk
@ -674,8 +689,8 @@ local function scoreNeighborsForRetreat(chunk, neighborDirectionChunks, scoreFun
for x=1,8 do
local neighborChunk = neighborDirectionChunks[x]
if (neighborChunk ~= -1) then
if (chunk == -1) or canMoveChunkDirection(map, x, chunk, neighborChunk) then
local score = scoreFunction(map, neighborChunk)
if (chunk == -1) or canMoveChunkDirection(x, chunk, neighborChunk) then
local score = scoreFunction(neighborChunk)
if (score > highestScore) then
highestScore = score
highestChunk = neighborChunk
@ -695,8 +710,8 @@ local function scoreNeighborsForRetreat(chunk, neighborDirectionChunks, scoreFun
local neighborChunk = neighborDirectionChunks[x]
if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then
local score = scoreFunction(map, neighborChunk)
canMoveChunkDirection(x, highestChunk, neighborChunk)) then
local score = scoreFunction(neighborChunk)
if (score > nextHighestScore) then
nextHighestScore = score
nextHighestChunk = neighborChunk
@ -914,35 +929,23 @@ local function attackWaveValidCandidate(chunk)
return false
end
local function scoreSettlerLocation(map, neighborChunk)
local function scoreSettlerLocation(neighborChunk)
return neighborChunk[RESOURCE_PHEROMONE] + -neighborChunk[PLAYER_PHEROMONE]
end
local function scoreSiegeSettlerLocation(map, neighborChunk)
local function scoreSiegeSettlerLocation(neighborChunk)
return (neighborChunk[RESOURCE_PHEROMONE] + neighborChunk[BASE_PHEROMONE]) + -neighborChunk[PLAYER_PHEROMONE]
end
local function scoreUnitGroupLocation(map, neighborChunk)
local function scoreUnitGroupLocation(neighborChunk)
return neighborChunk[PLAYER_PHEROMONE] + neighborChunk[BASE_PHEROMONE]
end
local function validSiegeSettlerLocation(map, neighborChunk)
local function validUnitGroupLocation(neighborChunk)
return (getPassable(neighborChunk) == CHUNK_ALL_DIRECTIONS) and
(not neighborChunk.nestCount)
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 startX
local endX
@ -985,43 +988,15 @@ end
--[[
Expects all neighbors adjacent to a chunk
--]]
local function scoreNeighborsForResource(chunk, neighborDirectionChunks, validFunction, scoreFunction, map)
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 function scoreNeighborsForFormation(chunk, validFunction, scoreFunction)
local highestChunk = -1
local highestScore = -MAGIC_MAXIMUM_NUMBER
local highestDirection
local neighborChunks = getNeighborChunks(chunk.map, chunk.x, chunk.y)
for x=1,8 do
local neighborChunk = neighborChunks[x]
if (neighborChunk ~= -1) and validFunction(map, neighborChunk) then
local score = scoreFunction(map, neighborChunk)
if (neighborChunk ~= -1) and validFunction(neighborChunk) then
local score = scoreFunction(neighborChunk)
if (score > highestScore) then
highestScore = score
highestChunk = neighborChunk
@ -1060,213 +1035,116 @@ function Squad.rallyUnits(chunk, tick)
end
end
function Squad.formSettlers(chunk)
local function deploySquad(name, chunk, cost, vengence, attacker)
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 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)
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
local lackingPoints = ((base.unitPoints - cost) < 0)
if attacker then
if lackingPoints
or ((chunk[BASE_PHEROMONE] < 0.0001) and (chunk[PLAYER_PHEROMONE] < 0.0001))
or (Universe.squadCount > Universe.AI_MAX_SQUAD_COUNT)
or (not vengence and not attackWaveValidCandidate(chunk))
or (Universe.random() > Universe.formSquadThreshold)
then
return
end
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, 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
else
if lackingPoints
or (Universe.builderCount > Universe.AI_MAX_BUILDER_COUNT)
or (not vengence and (base.sentExpansionGroups > base.maxExpansionGroups))
or (Universe.random() > Universe.formSquadThreshold)
then
return
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
function Squad.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,
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)
function Squad.formSettlers(chunk)
deploySquad("Settler", chunk, AI_SETTLER_COST, false, false)
end
squad.rabid = Universe.random() < 0.03
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
function Squad.formVengenceSettler(chunk)
deploySquad("Vengence Settler", chunk, AI_VENGENCE_SETTLER_COST, true, false)
end
function Squad.formSquads(chunk)
local base = chunk.base
if (Universe.squadCount < Universe.AI_MAX_SQUAD_COUNT)
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
deploySquad("Squad", chunk, AI_SQUAD_COST, false, true)
end
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, 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
function Squad.formVengenceSquad(chunk)
deploySquad("Vengence Squad", chunk, AI_VENGENCE_SQUAD_COST, true, true)
end
function Squad.init(universe)

View File

@ -19,8 +19,6 @@ local Upgrade = {}
-- imports
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
local addBaseResourceChunk = ChunkPropertyUtils.addBaseResourceChunk
-- module code
local function addCommandSet(queriesAndCommands)