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:
@@ -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"))))
|
||||||
|
29
.luacheckrc
29
.luacheckrc
@@ -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
|
@@ -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
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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]
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
404
libs/Squad.lua
404
libs/Squad.lua
@@ -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)
|
||||||
|
@@ -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)
|
||||||
|
Reference in New Issue
Block a user