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:
parent
8aa2939ff9
commit
3a9f5b05cd
@ -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"))))
|
||||
|
29
.luacheckrc
29
.luacheckrc
@ -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
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
||||
|
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_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)
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user