mirror of
https://github.com/veden/Rampant.git
synced 2025-09-16 09:16:43 +02:00
Cleaned up settlers
This commit is contained in:
@@ -268,13 +268,17 @@ function upgrade.attempt(natives)
|
|||||||
game.surfaces[natives.activeSurface].print("Rampant - Version 0.16.42")
|
game.surfaces[natives.activeSurface].print("Rampant - Version 0.16.42")
|
||||||
global.version = constants.VERSION_77
|
global.version = constants.VERSION_77
|
||||||
end
|
end
|
||||||
if (global.version < constants.VERSION_79) then
|
if (global.version < constants.VERSION_85) then
|
||||||
|
|
||||||
--REMOVE ME
|
--REMOVE ME
|
||||||
natives.expansion = true
|
natives.expansion = true
|
||||||
|
natives.building = {}
|
||||||
|
natives.pendingAttack = {}
|
||||||
|
|
||||||
|
natives.cleanBuildingIndex = 1
|
||||||
|
|
||||||
game.surfaces[natives.activeSurface].print("Rampant - Version 0.17.4")
|
game.surfaces[natives.activeSurface].print("Rampant - Version 0.17.4")
|
||||||
global.version = constants.VERSION_79
|
global.version = constants.VERSION_85
|
||||||
end
|
end
|
||||||
|
|
||||||
return starting ~= global.version, natives
|
return starting ~= global.version, natives
|
||||||
|
@@ -9,9 +9,12 @@ Date: 3. 5. 2019
|
|||||||
- Removed old map path finder settings
|
- Removed old map path finder settings
|
||||||
- Added new find position centered flag to positions searches
|
- Added new find position centered flag to positions searches
|
||||||
- Adjusted new enemy worm ranges to vanilla levels
|
- Adjusted new enemy worm ranges to vanilla levels
|
||||||
|
Optimizations:
|
||||||
|
- Improved squad processing and squad cleanup
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
- Fixed player pheromone not having highest value on chunk player was on
|
- Fixed player pheromone not having highest value on chunk player was on
|
||||||
- Fixed settlers not being able to see chunks with resources on them
|
- Fixed settlers not being able to see chunks with resources on them
|
||||||
|
- Fixed retreat command not disengaging biters
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
||||||
Version: 0.17.3
|
Version: 0.17.3
|
||||||
|
22
control.lua
22
control.lua
@@ -93,7 +93,7 @@ local recycleBases = baseUtils.recycleBases
|
|||||||
local deathScent = pheromoneUtils.deathScent
|
local deathScent = pheromoneUtils.deathScent
|
||||||
local victoryScent = pheromoneUtils.victoryScent
|
local victoryScent = pheromoneUtils.victoryScent
|
||||||
|
|
||||||
local cleanSquads = unitGroupUtils.cleanSquads
|
local cleanBuilders = unitGroupUtils.cleanBuilders
|
||||||
local regroupSquads = unitGroupUtils.regroupSquads
|
local regroupSquads = unitGroupUtils.regroupSquads
|
||||||
local convertUnitGroupToSquad = unitGroupUtils.convertUnitGroupToSquad
|
local convertUnitGroupToSquad = unitGroupUtils.convertUnitGroupToSquad
|
||||||
|
|
||||||
@@ -269,16 +269,12 @@ local function rebuildMap()
|
|||||||
ignore_planner = true
|
ignore_planner = true
|
||||||
}
|
}
|
||||||
|
|
||||||
map.retreatCommand = { type = DEFINES_COMMAND_GROUP,
|
map.retreatCommand = {
|
||||||
group = nil,
|
type = DEFINES_COMMAND_GROUP,
|
||||||
distraction = DEFINES_DISTRACTION_NONE }
|
group = nil,
|
||||||
|
distraction = DEFINES_DISTRACTION_NONE,
|
||||||
-- switched over to tick event
|
use_group_distraction = false
|
||||||
-- map.logicTick = roundToNearest(game.tick + INTERVAL_LOGIC, INTERVAL_LOGIC)
|
}
|
||||||
-- map.scanTick = roundToNearest(game.tick + INTERVAL_SCAN, INTERVAL_SCAN)
|
|
||||||
-- map.processTick = roundToNearest(game.tick + INTERVAL_PROCESS, INTERVAL_PROCESS)
|
|
||||||
-- map.chunkTick = roundToNearest(game.tick + INTERVAL_CHUNK, INTERVAL_CHUNK)
|
|
||||||
-- map.squadTick = roundToNearest(game.tick + INTERVAL_SQUAD, INTERVAL_SQUAD)
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -441,9 +437,11 @@ script.on_nth_tick(INTERVAL_SQUAD,
|
|||||||
function (event)
|
function (event)
|
||||||
local gameRef = game
|
local gameRef = game
|
||||||
|
|
||||||
cleanSquads(natives, map)
|
-- cleanSquads(natives, map)
|
||||||
regroupSquads(natives, map)
|
regroupSquads(natives, map)
|
||||||
|
|
||||||
|
cleanBuilders(natives)
|
||||||
|
|
||||||
squadsBeginAttack(natives, gameRef.players)
|
squadsBeginAttack(natives, gameRef.players)
|
||||||
squadsDispatch(map, gameRef.surfaces[natives.activeSurface], natives)
|
squadsDispatch(map, gameRef.surfaces[natives.activeSurface], natives)
|
||||||
end)
|
end)
|
||||||
|
@@ -146,7 +146,7 @@ local function noNearbySettlers(map, chunk, tick)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function aiAttackWave.formSettlers(map, surface, natives, chunk, tick)
|
function aiAttackWave.formSettlers(map, surface, natives, chunk, tick)
|
||||||
if (mRandom() < natives.formSquadThreshold) and (#natives.squads < AI_MAX_SQUAD_COUNT) then
|
if (mRandom() < natives.formSquadThreshold) and ((#natives.squads + #natives.building) < AI_MAX_SQUAD_COUNT) then
|
||||||
|
|
||||||
local squadPath, squadDirection
|
local squadPath, squadDirection
|
||||||
if (natives.state == AI_STATE_SIEGE) then
|
if (natives.state == AI_STATE_SIEGE) then
|
||||||
@@ -172,7 +172,7 @@ function aiAttackWave.formSettlers(map, surface, natives, chunk, tick)
|
|||||||
4,
|
4,
|
||||||
true)
|
true)
|
||||||
if squadPosition then
|
if squadPosition then
|
||||||
local squad = createSquad(squadPosition, surface, natives, nil, true)
|
local squad = createSquad(squadPosition, surface, nil, true)
|
||||||
|
|
||||||
squad.maxDistance = gaussianRandomRange(natives.expansionMaxDistance,
|
squad.maxDistance = gaussianRandomRange(natives.expansionMaxDistance,
|
||||||
natives.expansionMaxDistanceDerivation,
|
natives.expansionMaxDistanceDerivation,
|
||||||
@@ -189,10 +189,15 @@ function aiAttackWave.formSettlers(map, surface, natives, chunk, tick)
|
|||||||
unit_search_distance = TRIPLE_CHUNK_SIZE })
|
unit_search_distance = TRIPLE_CHUNK_SIZE })
|
||||||
if (foundUnits > 0) then
|
if (foundUnits > 0) then
|
||||||
setChunkSettlerTick(map, squadPath, tick + natives.settlerCooldown)
|
setChunkSettlerTick(map, squadPath, tick + natives.settlerCooldown)
|
||||||
|
natives.pendingAttack[#natives.pendingAttack+1] = squad
|
||||||
natives.points = natives.points - AI_SETTLER_COST
|
natives.points = natives.points - AI_SETTLER_COST
|
||||||
end
|
else
|
||||||
end
|
if (squad.group.valid) then
|
||||||
end
|
squad.group.destroy()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return (natives.points - AI_SETTLER_COST) > 0
|
return (natives.points - AI_SETTLER_COST) > 0
|
||||||
@@ -216,7 +221,7 @@ function aiAttackWave.formVengenceSquad(map, surface, natives, chunk)
|
|||||||
4,
|
4,
|
||||||
true)
|
true)
|
||||||
if squadPosition then
|
if squadPosition then
|
||||||
local squad = createSquad(squadPosition, surface, natives)
|
local squad = createSquad(squadPosition, surface)
|
||||||
|
|
||||||
squad.rabid = mRandom() < 0.03
|
squad.rabid = mRandom() < 0.03
|
||||||
|
|
||||||
@@ -227,7 +232,12 @@ function aiAttackWave.formVengenceSquad(map, surface, natives, chunk)
|
|||||||
unit_count = scaledWaveSize,
|
unit_count = scaledWaveSize,
|
||||||
unit_search_distance = TRIPLE_CHUNK_SIZE })
|
unit_search_distance = TRIPLE_CHUNK_SIZE })
|
||||||
if (foundUnits > 0) then
|
if (foundUnits > 0) then
|
||||||
|
natives.pendingAttack[#natives.pendingAttack+1] = squad
|
||||||
natives.points = natives.points - AI_VENGENCE_SQUAD_COST
|
natives.points = natives.points - AI_VENGENCE_SQUAD_COST
|
||||||
|
else
|
||||||
|
if (squad.group.valid) then
|
||||||
|
squad.group.destroy()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -255,7 +265,7 @@ function aiAttackWave.formSquads(map, surface, natives, chunk)
|
|||||||
4,
|
4,
|
||||||
true)
|
true)
|
||||||
if squadPosition then
|
if squadPosition then
|
||||||
local squad = createSquad(squadPosition, surface, natives)
|
local squad = createSquad(squadPosition, surface)
|
||||||
|
|
||||||
squad.rabid = mRandom() < 0.03
|
squad.rabid = mRandom() < 0.03
|
||||||
|
|
||||||
@@ -266,10 +276,15 @@ function aiAttackWave.formSquads(map, surface, natives, chunk)
|
|||||||
unit_count = scaledWaveSize,
|
unit_count = scaledWaveSize,
|
||||||
unit_search_distance = TRIPLE_CHUNK_SIZE })
|
unit_search_distance = TRIPLE_CHUNK_SIZE })
|
||||||
if (foundUnits > 0) then
|
if (foundUnits > 0) then
|
||||||
|
natives.pendingAttack[#natives.pendingAttack+1] = squad
|
||||||
natives.points = natives.points - AI_SQUAD_COST
|
natives.points = natives.points - AI_SQUAD_COST
|
||||||
|
else
|
||||||
|
if (squad.group.valid) then
|
||||||
|
squad.group.destroy()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return (natives.points - AI_SQUAD_COST) > 0
|
return (natives.points - AI_SQUAD_COST) > 0
|
||||||
|
@@ -29,7 +29,7 @@ constants.VERSION_73 = 73
|
|||||||
constants.VERSION_75 = 75
|
constants.VERSION_75 = 75
|
||||||
constants.VERSION_76 = 76
|
constants.VERSION_76 = 76
|
||||||
constants.VERSION_77 = 77
|
constants.VERSION_77 = 77
|
||||||
constants.VERSION_79 = 79
|
constants.VERSION_85 = 85
|
||||||
|
|
||||||
-- misc
|
-- misc
|
||||||
|
|
||||||
|
@@ -84,7 +84,7 @@ function interop.getAttackUsePlayer()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function interop.registerUnitGroup(unitGroup)
|
function interop.registerUnitGroup(unitGroup)
|
||||||
unitGroupUtils.createSquad(unitGroup.position, unitGroup.surface, global.natives, unitGroup)
|
unitGroupUtils.createSquad(unitGroup.position, unitGroup.surface, unitGroup)
|
||||||
end
|
end
|
||||||
|
|
||||||
interopG = interop
|
interopG = interop
|
||||||
|
@@ -28,6 +28,9 @@ local SQUAD_BUILDING = constants.SQUAD_BUILDING
|
|||||||
local SQUAD_RAIDING = constants.SQUAD_RAIDING
|
local SQUAD_RAIDING = constants.SQUAD_RAIDING
|
||||||
local SQUAD_SETTLING = constants.SQUAD_SETTLING
|
local SQUAD_SETTLING = constants.SQUAD_SETTLING
|
||||||
local SQUAD_GUARDING = constants.SQUAD_GUARDING
|
local SQUAD_GUARDING = constants.SQUAD_GUARDING
|
||||||
|
local SQUAD_RETREATING = constants.SQUAD_RETREATING
|
||||||
|
|
||||||
|
local AI_MAX_BITER_GROUP_SIZE = constants.AI_MAX_BITER_GROUP_SIZE
|
||||||
|
|
||||||
local AI_STATE_SIEGE = constants.AI_STATE_SIEGE
|
local AI_STATE_SIEGE = constants.AI_STATE_SIEGE
|
||||||
|
|
||||||
@@ -47,11 +50,14 @@ local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
|||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
local mRandom = math.random
|
local mRandom = math.random
|
||||||
|
local tRemove = table.remove
|
||||||
|
|
||||||
local euclideanDistancePoints = mathUtils.euclideanDistancePoints
|
local euclideanDistancePoints = mathUtils.euclideanDistancePoints
|
||||||
|
|
||||||
local findMovementPosition = movementUtils.findMovementPosition
|
local findMovementPosition = movementUtils.findMovementPosition
|
||||||
|
|
||||||
|
local removeSquadFromChunk = chunkPropertyUtils.removeSquadFromChunk
|
||||||
|
|
||||||
local getNestCount = chunkPropertyUtils.getNestCount
|
local getNestCount = chunkPropertyUtils.getNestCount
|
||||||
|
|
||||||
local getNeighborChunks = mapUtils.getNeighborChunks
|
local getNeighborChunks = mapUtils.getNeighborChunks
|
||||||
@@ -105,7 +111,7 @@ end
|
|||||||
local function settleMove(map, attackPosition, attackCmd, settleCmd, squad, group, natives, surface)
|
local function settleMove(map, attackPosition, attackCmd, settleCmd, squad, group, natives, surface)
|
||||||
local groupState = group.state
|
local groupState = group.state
|
||||||
|
|
||||||
if (groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING) or ((groupState == DEFINES_GROUP_MOVING) and (squad.cycles == 0)) then
|
if (groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING) or ((groupState == DEFINES_GROUP_MOVING) and (squad.cycles <= 0)) then
|
||||||
local groupPosition = group.position
|
local groupPosition = group.position
|
||||||
local x, y = positionToChunkXY(groupPosition)
|
local x, y = positionToChunkXY(groupPosition)
|
||||||
local chunk = getChunkByXY(map, x, y)
|
local chunk = getChunkByXY(map, x, y)
|
||||||
@@ -121,9 +127,9 @@ local function settleMove(map, attackPosition, attackCmd, settleCmd, squad, grou
|
|||||||
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
addSquadToChunk(map, chunk, squad)
|
addSquadToChunk(map, chunk, squad)
|
||||||
addMovementPenalty(natives, squad, chunk)
|
addMovementPenalty(natives, squad, chunk)
|
||||||
-- elseif (attackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
-- elseif (attackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
-- addSquadToChunk(map, attackChunk, squad)
|
-- addSquadToChunk(map, attackChunk, squad)
|
||||||
-- addMovementPenalty(natives, squad, attackChunk)
|
-- addMovementPenalty(natives, squad, attackChunk)
|
||||||
end
|
end
|
||||||
if group.valid and (attackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
if group.valid and (attackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
local resourceGenerator = getResourceGenerator(map, chunk)
|
local resourceGenerator = getResourceGenerator(map, chunk)
|
||||||
@@ -176,7 +182,7 @@ end
|
|||||||
local function attackMove(map, attackPosition, attackCmd, squad, group, natives, surface)
|
local function attackMove(map, attackPosition, attackCmd, squad, group, natives, surface)
|
||||||
local groupState = group.state
|
local groupState = group.state
|
||||||
|
|
||||||
if (groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING) or ((groupState == DEFINES_GROUP_MOVING) and (squad.cycles == 0)) then
|
if (groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING) or ((groupState == DEFINES_GROUP_MOVING) and (squad.cycles <= 0)) then
|
||||||
local groupPosition = group.position
|
local groupPosition = group.position
|
||||||
local x, y = positionToChunkXY(groupPosition)
|
local x, y = positionToChunkXY(groupPosition)
|
||||||
local chunk = getChunkByXY(map, x, y)
|
local chunk = getChunkByXY(map, x, y)
|
||||||
@@ -193,14 +199,17 @@ local function attackMove(map, attackPosition, attackCmd, squad, group, natives,
|
|||||||
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
addSquadToChunk(map, chunk, squad)
|
addSquadToChunk(map, chunk, squad)
|
||||||
addMovementPenalty(natives, squad, chunk)
|
addMovementPenalty(natives, squad, chunk)
|
||||||
-- elseif (attackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
-- elseif (attackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
-- addSquadToChunk(map, attackChunk, squad)
|
-- addSquadToChunk(map, attackChunk, squad)
|
||||||
-- addMovementPenalty(natives, squad, attackChunk)
|
-- addMovementPenalty(natives, squad, attackChunk)
|
||||||
end
|
end
|
||||||
if group.valid and (attackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
if group.valid and (attackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
local playerBaseGenerator = getPlayerBaseGenerator(map, attackChunk)
|
local playerBaseGenerator = getPlayerBaseGenerator(map, attackChunk)
|
||||||
if (playerBaseGenerator == 0) or ((groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING)) then
|
-- local playerPheromone = attackChunk[PLAYER_PHEROMONE]
|
||||||
|
if (playerBaseGenerator == 0) or
|
||||||
|
((groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING))-- or
|
||||||
|
-- (playerPheromone < natives.attackPlayerThreshold)
|
||||||
|
then
|
||||||
squad.cycles = ((#squad.group.members > 80) and 6) or 4
|
squad.cycles = ((#squad.group.members > 80) and 6) or 4
|
||||||
|
|
||||||
local moreFrenzy = not squad.rabid and squad.frenzy and (euclideanDistanceNamed(groupPosition, squad.frenzyPosition) < 100)
|
local moreFrenzy = not squad.rabid and squad.frenzy and (euclideanDistanceNamed(groupPosition, squad.frenzyPosition) < 100)
|
||||||
@@ -239,56 +248,83 @@ function squadAttack.squadsDispatch(map, surface, natives)
|
|||||||
local attackCmd = map.attackAreaCommand
|
local attackCmd = map.attackAreaCommand
|
||||||
local settleCmd = map.settleCommand
|
local settleCmd = map.settleCommand
|
||||||
|
|
||||||
for i=1,#squads do
|
for i=#squads,1,-1 do
|
||||||
local squad = squads[i]
|
local squad = squads[i]
|
||||||
local group = squad.group
|
local group = squad.group
|
||||||
if group and group.valid then
|
if group and group.valid then
|
||||||
|
|
||||||
if (squad.status == SQUAD_RAIDING) then
|
local memberCount = #group.members
|
||||||
attackMove(map, attackPosition, attackCmd, squad, group, natives, surface)
|
if (memberCount == 0) then
|
||||||
elseif (squad.status == SQUAD_SETTLING) then
|
tRemove(squads, i)
|
||||||
settleMove(map, attackPosition, attackCmd, settleCmd, squad, group, natives, surface)
|
removeSquadFromChunk(map, squad)
|
||||||
|
group.destroy()
|
||||||
|
elseif (memberCount > AI_MAX_BITER_GROUP_SIZE) then
|
||||||
|
local members = group.members
|
||||||
|
unitGroupUtils.recycleBiters(natives, members)
|
||||||
|
tRemove(squads, i)
|
||||||
|
removeSquadFromChunk(map, squad)
|
||||||
|
group.destroy()
|
||||||
|
else
|
||||||
|
local status = squad.status
|
||||||
|
local cycles = squad.cycles
|
||||||
|
|
||||||
|
if (status == SQUAD_RAIDING) then
|
||||||
|
attackMove(map, attackPosition, attackCmd, squad, group, natives, surface)
|
||||||
|
elseif (status == SQUAD_SETTLING) then
|
||||||
|
settleMove(map, attackPosition, attackCmd, settleCmd, squad, group, natives, surface)
|
||||||
|
elseif (status == SQUAD_RETREATING) and (cycles == 0) then
|
||||||
|
natives.pendingAttack[#natives.pendingAttack+1] = squad
|
||||||
|
squad.status = SQUAD_GUARDING
|
||||||
|
elseif (status == SQUAD_BUILDING) then
|
||||||
|
tRemove(squads, i)
|
||||||
|
removeSquadFromChunk(map, squad)
|
||||||
|
natives.building[#natives.building+1] = squad
|
||||||
|
end
|
||||||
|
if (cycles > 0) then
|
||||||
|
squad.cycles = cycles - 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
tRemove(squads, i)
|
||||||
|
removeSquadFromChunk(map, squad)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function squadAttack.squadsBeginAttack(natives, players)
|
function squadAttack.squadsBeginAttack(natives, players)
|
||||||
local squads = natives.squads
|
local squads = natives.pendingAttack
|
||||||
for i=1,#squads do
|
for i=1,#squads do
|
||||||
local squad = squads[i]
|
local squad = squads[i]
|
||||||
local group = squad.group
|
local group = squad.group
|
||||||
local kamikazeThreshold = calculateKamikazeThreshold(#squad.group.members, natives)
|
if group and group.valid then
|
||||||
if not squad.kamikaze then
|
local kamikazeThreshold = calculateKamikazeThreshold(#squad.group.members, natives)
|
||||||
squad.kamikaze = (mRandom() < kamikazeThreshold)
|
if not squad.kamikaze then
|
||||||
end
|
squad.kamikaze = (mRandom() < kamikazeThreshold)
|
||||||
if squad.settlers then
|
end
|
||||||
if (squad.status == SQUAD_GUARDING) and group and group.valid then
|
if squad.settlers then
|
||||||
-- local kamikazeThreshold = calculateKamikazeThreshold(#squad.group.members, natives)
|
-- if (squad.status == SQUAD_GUARDING) then
|
||||||
-- squad.kamikaze = mRandom() < kamikazeThreshold
|
squad.status = SQUAD_SETTLING
|
||||||
squad.status = SQUAD_SETTLING
|
natives.squads[#natives.squads+1] = squad
|
||||||
end
|
else
|
||||||
else
|
-- if (squad.status == SQUAD_GUARDING) then
|
||||||
if (squad.status == SQUAD_GUARDING) and group and group.valid then
|
local groupPosition = group.position
|
||||||
local groupPosition = group.position
|
if playersWithinProximityToPosition(players, groupPosition, 100, natives) then
|
||||||
if playersWithinProximityToPosition(players, groupPosition, 100, natives) then
|
squad.frenzy = true
|
||||||
squad.frenzy = true
|
squad.frenzyPosition.x = groupPosition.x
|
||||||
squad.frenzyPosition.x = groupPosition.x
|
squad.frenzyPosition.y = groupPosition.y
|
||||||
squad.frenzyPosition.y = groupPosition.y
|
end
|
||||||
end
|
|
||||||
|
|
||||||
-- local kamikazeThreshold = calculateKamikazeThreshold(#squad.group.members, natives)
|
|
||||||
-- if not squad.kamikaze then
|
|
||||||
-- squad.kamikaze = (mRandom() < kamikazeThreshold)
|
|
||||||
-- end
|
|
||||||
|
|
||||||
if squad.kamikaze and (mRandom() < (kamikazeThreshold * 0.75)) then
|
if squad.kamikaze and (mRandom() < (kamikazeThreshold * 0.75)) then
|
||||||
squad.attackScoreFunction = ATTACK_SCORE_KAMIKAZE
|
squad.attackScoreFunction = ATTACK_SCORE_KAMIKAZE
|
||||||
end
|
end
|
||||||
squad.status = SQUAD_RAIDING
|
squad.status = SQUAD_RAIDING
|
||||||
end
|
natives.squads[#natives.squads+1] = squad
|
||||||
end
|
end
|
||||||
|
-- end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
natives.pendingAttack = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
squadAttackG = squadAttack
|
squadAttackG = squadAttack
|
||||||
|
@@ -91,12 +91,19 @@ function aiDefense.retreatUnits(chunk, position, squad, map, surface, natives, t
|
|||||||
local newSquad = findNearbySquadFiltered(map, exitPath, retreatPosition)
|
local newSquad = findNearbySquadFiltered(map, exitPath, retreatPosition)
|
||||||
|
|
||||||
if not newSquad then
|
if not newSquad then
|
||||||
newSquad = createSquad(retreatPosition, surface, natives)
|
newSquad = createSquad(retreatPosition, surface)
|
||||||
newSquad.status = SQUAD_RETREATING
|
natives.squads[#natives.squads+1] = newSquad
|
||||||
newSquad.cycles = 4
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if newSquad then
|
if newSquad then
|
||||||
|
newSquad.status = SQUAD_RETREATING
|
||||||
|
newSquad.cycles = 4
|
||||||
|
|
||||||
|
squad.frenzy = true
|
||||||
|
local squadPosition = newSquad.group.position
|
||||||
|
squad.frenzyPosition.x = squadPosition.x
|
||||||
|
squad.frenzyPosition.y = squadPosition.y
|
||||||
|
|
||||||
local cmd = map.retreatCommand
|
local cmd = map.retreatCommand
|
||||||
cmd.group = newSquad.group
|
cmd.group = newSquad.group
|
||||||
if enemiesToSquad then
|
if enemiesToSquad then
|
||||||
|
@@ -16,17 +16,17 @@ local HALF_CHUNK_SIZE = constants.HALF_CHUNK_SIZE
|
|||||||
|
|
||||||
local SQUAD_QUEUE_SIZE = constants.SQUAD_QUEUE_SIZE
|
local SQUAD_QUEUE_SIZE = constants.SQUAD_QUEUE_SIZE
|
||||||
|
|
||||||
local DEFINES_GROUP_STATE_FINISHED = defines.group_state.finished
|
-- local DEFINES_GROUP_STATE_FINISHED = defines.group_state.finished
|
||||||
local DEFINES_GROUP_STATE_ATTACKING_TARGET = defines.group_state.attacking_target
|
local DEFINES_GROUP_STATE_ATTACKING_TARGET = defines.group_state.attacking_target
|
||||||
local DEFINES_GROUP_STATE_ATTACKING_DISTRACTION = defines.group_state.attacking_distraction
|
local DEFINES_GROUP_STATE_ATTACKING_DISTRACTION = defines.group_state.attacking_distraction
|
||||||
|
|
||||||
local SQUAD_RETREATING = constants.SQUAD_RETREATING
|
local SQUAD_RETREATING = constants.SQUAD_RETREATING
|
||||||
local SQUAD_GUARDING = constants.SQUAD_GUARDING
|
local SQUAD_GUARDING = constants.SQUAD_GUARDING
|
||||||
local SQUAD_SETTLING = constants.SQUAD_SETTLING
|
-- local SQUAD_SETTLING = constants.SQUAD_SETTLING
|
||||||
local SQUAD_BUILDING = constants.SQUAD_BUILDING
|
-- local SQUAD_BUILDING = constants.SQUAD_BUILDING
|
||||||
local GROUP_MERGE_DISTANCE = constants.GROUP_MERGE_DISTANCE
|
-- local GROUP_MERGE_DISTANCE = constants.GROUP_MERGE_DISTANCE
|
||||||
|
|
||||||
local RETREAT_FILTER = constants.RETREAT_FILTER
|
-- local RETREAT_FILTER = constants.RETREAT_FILTER
|
||||||
|
|
||||||
local NO_RETREAT_SQUAD_SIZE_BONUS_MAX = constants.NO_RETREAT_SQUAD_SIZE_BONUS_MAX
|
local NO_RETREAT_SQUAD_SIZE_BONUS_MAX = constants.NO_RETREAT_SQUAD_SIZE_BONUS_MAX
|
||||||
|
|
||||||
@@ -37,14 +37,18 @@ local AI_SQUAD_MERGE_THRESHOLD = constants.AI_SQUAD_MERGE_THRESHOLD
|
|||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
|
local tRemove = table.remove
|
||||||
|
|
||||||
local mRandom = math.random
|
local mRandom = math.random
|
||||||
|
|
||||||
local mLog = math.log10
|
local mLog = math.log10
|
||||||
|
|
||||||
|
local removeSquadFromChunk = chunkPropertyUtils.removeSquadFromChunk
|
||||||
|
|
||||||
local mMin = math.min
|
local mMin = math.min
|
||||||
|
|
||||||
local getSquadsOnChunk = chunkPropertyUtils.getSquadsOnChunk
|
local getSquadsOnChunk = chunkPropertyUtils.getSquadsOnChunk
|
||||||
local removeSquadFromChunk = chunkPropertyUtils.removeSquadFromChunk
|
-- local removeSquadFromChunk = chunkPropertyUtils.removeSquadFromChunk
|
||||||
|
|
||||||
local getNeighborChunks = mapUtils.getNeighborChunks
|
local getNeighborChunks = mapUtils.getNeighborChunks
|
||||||
|
|
||||||
@@ -104,7 +108,7 @@ function unitGroupUtils.findNearbySquad(map, chunk, position)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function unitGroupUtils.createSquad(position, surface, natives, group, settlers)
|
function unitGroupUtils.createSquad(position, surface, group, settlers)
|
||||||
local unitGroup = group or surface.create_unit_group({position=position})
|
local unitGroup = group or surface.create_unit_group({position=position})
|
||||||
|
|
||||||
local squad = {
|
local squad = {
|
||||||
@@ -124,7 +128,7 @@ function unitGroupUtils.createSquad(position, surface, natives, group, settlers)
|
|||||||
y = 0},
|
y = 0},
|
||||||
chunk = nil
|
chunk = nil
|
||||||
}
|
}
|
||||||
natives.squads[#natives.squads+1] = squad
|
|
||||||
return squad
|
return squad
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -150,7 +154,7 @@ function unitGroupUtils.convertUnitGroupToSquad(natives, unitGroup)
|
|||||||
return squad
|
return squad
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local squad = unitGroupUtils.createSquad(nil,nil,natives,unitGroup)
|
local squad = unitGroupUtils.createSquad(nil,nil,unitGroup)
|
||||||
squad.kamikaze = mRandom() < unitGroupUtils.calculateKamikazeThreshold(#unitGroup.members, natives)
|
squad.kamikaze = mRandom() < unitGroupUtils.calculateKamikazeThreshold(#unitGroup.members, natives)
|
||||||
return squad
|
return squad
|
||||||
end
|
end
|
||||||
@@ -165,49 +169,6 @@ local function isAttacking(group)
|
|||||||
return (state == DEFINES_GROUP_STATE_ATTACKING_TARGET) or (state == DEFINES_GROUP_STATE_ATTACKING_DISTRACTION)
|
return (state == DEFINES_GROUP_STATE_ATTACKING_TARGET) or (state == DEFINES_GROUP_STATE_ATTACKING_DISTRACTION)
|
||||||
end
|
end
|
||||||
|
|
||||||
function unitGroupUtils.cleanSquads(natives, map)
|
|
||||||
local squads = natives.squads
|
|
||||||
local squadCount = #squads
|
|
||||||
|
|
||||||
local cleanSquads = {}
|
|
||||||
for i=1, squadCount do
|
|
||||||
local squad = squads[i]
|
|
||||||
local group = squad.group
|
|
||||||
if group and group.valid then
|
|
||||||
local memberCount = #group.members
|
|
||||||
if (memberCount == 0) then
|
|
||||||
removeSquadFromChunk(map, squad)
|
|
||||||
group.destroy()
|
|
||||||
elseif (memberCount > AI_MAX_BITER_GROUP_SIZE) then
|
|
||||||
local members = group.members
|
|
||||||
unitGroupUtils.recycleBiters(natives, members)
|
|
||||||
removeSquadFromChunk(map, squad)
|
|
||||||
group.destroy()
|
|
||||||
else
|
|
||||||
local status = squad.status
|
|
||||||
local cycles = squad.cycles
|
|
||||||
if (status == SQUAD_RETREATING) and (cycles == 0) then
|
|
||||||
squad.status = SQUAD_GUARDING
|
|
||||||
squad.frenzy = true
|
|
||||||
local squadPosition = group.position
|
|
||||||
squad.frenzyPosition.x = squadPosition.x
|
|
||||||
squad.frenzyPosition.y = squadPosition.y
|
|
||||||
elseif (group.state == DEFINES_GROUP_STATE_FINISHED) and not squad.settlers then
|
|
||||||
squad.status = SQUAD_GUARDING
|
|
||||||
elseif (cycles > 0) then
|
|
||||||
squad.cycles = cycles - 1
|
|
||||||
end
|
|
||||||
|
|
||||||
cleanSquads[#cleanSquads+1] = squad
|
|
||||||
end
|
|
||||||
else
|
|
||||||
removeSquadFromChunk(map, squad)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
natives.squads = cleanSquads
|
|
||||||
end
|
|
||||||
|
|
||||||
function unitGroupUtils.recycleBiters(natives, biters)
|
function unitGroupUtils.recycleBiters(natives, biters)
|
||||||
local unitCount = #biters
|
local unitCount = #biters
|
||||||
for i=1,unitCount do
|
for i=1,unitCount do
|
||||||
@@ -220,7 +181,7 @@ function unitGroupUtils.recycleBiters(natives, biters)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function mergeGroups(squads, squad, group, status, position, memberCount)
|
local function mergeGroups(squads, squad, group, status, memberCount, map)
|
||||||
local merge = false
|
local merge = false
|
||||||
local maxed = false
|
local maxed = false
|
||||||
for _,mergeSquad in pairs(squads) do
|
for _,mergeSquad in pairs(squads) do
|
||||||
@@ -228,10 +189,9 @@ local function mergeGroups(squads, squad, group, status, position, memberCount)
|
|||||||
local mergeGroup = mergeSquad.group
|
local mergeGroup = mergeSquad.group
|
||||||
if mergeGroup and
|
if mergeGroup and
|
||||||
mergeGroup.valid and
|
mergeGroup.valid and
|
||||||
(squad.status ~= SQUAD_BUILDING) and
|
|
||||||
(mergeSquad.status == status) and
|
(mergeSquad.status == status) and
|
||||||
not isAttacking(mergeGroup) and
|
not isAttacking(mergeGroup) -- and
|
||||||
(euclideanDistanceNamed(position, mergeGroup.position) < GROUP_MERGE_DISTANCE)
|
-- (euclideanDistanceNamed(position, mergeGroup.position) < GROUP_MERGE_DISTANCE)
|
||||||
then
|
then
|
||||||
local mergeMembers = mergeGroup.members
|
local mergeMembers = mergeGroup.members
|
||||||
local mergeCount = #mergeMembers
|
local mergeCount = #mergeMembers
|
||||||
@@ -240,6 +200,7 @@ local function mergeGroups(squads, squad, group, status, position, memberCount)
|
|||||||
group.add_member(mergeMembers[memberIndex])
|
group.add_member(mergeMembers[memberIndex])
|
||||||
end
|
end
|
||||||
merge = true
|
merge = true
|
||||||
|
removeSquadFromChunk(map, mergeSquad)
|
||||||
mergeGroup.destroy()
|
mergeGroup.destroy()
|
||||||
end
|
end
|
||||||
memberCount = memberCount + mergeCount
|
memberCount = memberCount + mergeCount
|
||||||
@@ -253,6 +214,29 @@ local function mergeGroups(squads, squad, group, status, position, memberCount)
|
|||||||
return merge, memberCount, maxed
|
return merge, memberCount, maxed
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function unitGroupUtils.cleanBuilders(natives)
|
||||||
|
local squads = natives.building
|
||||||
|
local squadCount = #squads
|
||||||
|
|
||||||
|
local startIndex = natives.cleanBuildingIndex
|
||||||
|
|
||||||
|
local maxSquadIndex = mMin(startIndex + SQUAD_QUEUE_SIZE, squadCount)
|
||||||
|
for i=maxSquadIndex,startIndex,-1 do
|
||||||
|
local squad = squads[i]
|
||||||
|
local group = squad.group
|
||||||
|
if not (group and group.valid) then
|
||||||
|
tRemove(squads, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (maxSquadIndex == squadCount) then
|
||||||
|
natives.cleanBuildingIndex = 1
|
||||||
|
else
|
||||||
|
natives.cleanBuildingIndex = maxSquadIndex + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function unitGroupUtils.regroupSquads(natives, map)
|
function unitGroupUtils.regroupSquads(natives, map)
|
||||||
local squads = natives.squads
|
local squads = natives.squads
|
||||||
local squadCount = #squads
|
local squadCount = #squads
|
||||||
@@ -263,55 +247,29 @@ function unitGroupUtils.regroupSquads(natives, map)
|
|||||||
for i=startIndex,maxSquadIndex do
|
for i=startIndex,maxSquadIndex do
|
||||||
local squad = squads[i]
|
local squad = squads[i]
|
||||||
local group = squad.group
|
local group = squad.group
|
||||||
if group and group.valid and not isAttacking(group) and (squad.status ~= SQUAD_BUILDING) then
|
if group and group.valid and not isAttacking(group) then
|
||||||
local memberCount = #group.members
|
local memberCount = #group.members
|
||||||
if (memberCount < AI_SQUAD_MERGE_THRESHOLD) then
|
if (memberCount < AI_SQUAD_MERGE_THRESHOLD) then
|
||||||
local status = squad.status
|
local status = squad.status
|
||||||
local squadPosition = group.position
|
|
||||||
local mergedSquads = false
|
|
||||||
local maxed
|
|
||||||
local chunk = squad.chunk
|
local chunk = squad.chunk
|
||||||
|
|
||||||
if chunk then
|
if chunk then
|
||||||
mergedSquads, memberCount, maxed = mergeGroups(getSquadsOnChunk(map, chunk),
|
mergeGroups(getSquadsOnChunk(map, chunk),
|
||||||
squad,
|
squad,
|
||||||
group,
|
group,
|
||||||
status,
|
status,
|
||||||
squadPosition,
|
memberCount,
|
||||||
memberCount)
|
map)
|
||||||
|
|
||||||
if not maxed then
|
|
||||||
local neighbors = getNeighborChunks(map, chunk.x, chunk.y)
|
|
||||||
|
|
||||||
for x=1,#neighbors do
|
|
||||||
local maybeMerge
|
|
||||||
maybeMerge, memberCount, maxed = mergeGroups(getSquadsOnChunk(map, neighbors[x]),
|
|
||||||
squad,
|
|
||||||
group,
|
|
||||||
status,
|
|
||||||
squadPosition,
|
|
||||||
memberCount)
|
|
||||||
if maybeMerge then
|
|
||||||
mergedSquads = true
|
|
||||||
end
|
|
||||||
if maxed then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if mergedSquads then
|
|
||||||
squad.status = SQUAD_GUARDING
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if (maxSquadIndex == squadCount) then
|
if (maxSquadIndex == squadCount) then
|
||||||
natives.regroupIndex = 1
|
natives.regroupIndex = 1
|
||||||
else
|
else
|
||||||
natives.regroupIndex = maxSquadIndex + 1
|
natives.regroupIndex = maxSquadIndex + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user