mirror of
https://github.com/veden/Rampant.git
synced 2025-02-03 13:11:54 +02:00
smoothing out
This commit is contained in:
parent
2921d04e43
commit
5cf3e498e8
@ -6,6 +6,7 @@ Date: 3. 5. 2019
|
||||
- Increased chunk processing from 825 to 1020 chunks
|
||||
- Settler groups now occasionally disregard everything to reach a spot to build a base, instead of attacking player or buildings
|
||||
Tweaks:
|
||||
- Reduced full chunk scan threshold for water from 0.4 to 0.25
|
||||
- Removed old map path finder settings
|
||||
- Added new find position centered flag to positions searches
|
||||
- Adjusted new enemy worm ranges to vanilla levels
|
||||
@ -15,6 +16,7 @@ Date: 3. 5. 2019
|
||||
- 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 retreat command not disengaging biters
|
||||
- Fixed Poison faction poison death cloud crash
|
||||
|
||||
---------------------------------------------------------------------------------------------------
|
||||
Version: 0.17.3
|
||||
|
23
control.lua
23
control.lua
@ -48,11 +48,13 @@ local RETREAT_SPAWNER_GRAB_RADIUS = constants.RETREAT_SPAWNER_GRAB_RADIUS
|
||||
local DEFINES_COMMAND_GROUP = defines.command.group
|
||||
local DEFINES_COMMAND_BUILD_BASE = defines.command.build_base
|
||||
local DEFINES_COMMAND_ATTACK_AREA = defines.command.attack_area
|
||||
local DEFINES_COMMAND_GO_TO_LOCATION = defines.command.go_to_location
|
||||
|
||||
local CHUNK_SIZE = constants.CHUNK_SIZE
|
||||
|
||||
local DEFINES_DISTRACTION_NONE = defines.distraction.none
|
||||
local DEFINES_DISTRACTION_BY_ENEMY = defines.distraction.by_enemy
|
||||
local DEFINES_DISTRACTION_BY_ANYTHING = defines.distraction.by_anything
|
||||
|
||||
local DEFINES_WIRE_TYPE_RED = defines.wire_type.red
|
||||
local DEFINES_WIRE_TYPE_GREEN = defines.wire_type.green
|
||||
@ -255,10 +257,18 @@ local function rebuildMap()
|
||||
map.canPlaceQuery = { name="", position={0,0} }
|
||||
map.filteredTilesQuery = { name=WATER_TILE_NAMES, area=map.area }
|
||||
|
||||
map.attackAreaCommand = {
|
||||
map.attackCommand = {
|
||||
type = DEFINES_COMMAND_ATTACK_AREA,
|
||||
destination = map.position,
|
||||
radius = CHUNK_SIZE,
|
||||
distraction = DEFINES_DISTRACTION_BY_ANYTHING
|
||||
}
|
||||
|
||||
map.moveCommand = {
|
||||
type = DEFINES_COMMAND_GO_TO_LOCATION,
|
||||
destination = map.position,
|
||||
radius = 2,
|
||||
pathfind_flags = { prefer_straight_paths = true },
|
||||
distraction = DEFINES_DISTRACTION_BY_ENEMY
|
||||
}
|
||||
|
||||
@ -367,6 +377,8 @@ local function prepWorld(rebuild)
|
||||
y = chunk.y * 32 }}})
|
||||
end
|
||||
|
||||
game.forces.enemy.kill_all_units()
|
||||
|
||||
processPendingChunks(natives, map, surface, pendingChunks, tick, game.forces.enemy.evolution_factor, rebuild)
|
||||
end
|
||||
end
|
||||
@ -436,14 +448,13 @@ end)
|
||||
script.on_nth_tick(INTERVAL_SQUAD,
|
||||
function (event)
|
||||
local gameRef = game
|
||||
|
||||
squadsBeginAttack(natives)
|
||||
squadsDispatch(map, gameRef.surfaces[natives.activeSurface], natives)
|
||||
|
||||
-- cleanSquads(natives, map)
|
||||
regroupSquads(natives, map)
|
||||
regroupSquads(natives, map)
|
||||
|
||||
cleanBuilders(natives)
|
||||
|
||||
squadsBeginAttack(natives, gameRef.players)
|
||||
squadsDispatch(map, gameRef.surfaces[natives.activeSurface], natives)
|
||||
end)
|
||||
|
||||
local function onBuild(event)
|
||||
|
@ -5,6 +5,8 @@ local chunkPropertyUtils = {}
|
||||
|
||||
local constants = require("Constants")
|
||||
|
||||
local tRemove = table.remove
|
||||
|
||||
-- imported functions
|
||||
|
||||
local MOVEMENT_GENERATOR_PERSISTANCE = constants.MOVEMENT_GENERATOR_PERSISTANCE
|
||||
@ -189,10 +191,12 @@ function chunkPropertyUtils.addSquadToChunk(map, chunk, squad)
|
||||
chunkPropertyUtils.removeSquadFromChunk(map, squad)
|
||||
end
|
||||
|
||||
if not chunkToSquad[chunk] then
|
||||
chunkToSquad[chunk] = {}
|
||||
local squads = chunkToSquad[chunk]
|
||||
if not squads then
|
||||
squads = {}
|
||||
chunkToSquad[chunk] = squads
|
||||
end
|
||||
chunkToSquad[chunk][squad] = squad
|
||||
squads[#squads+1] = squad
|
||||
|
||||
squad.chunk = chunk
|
||||
end
|
||||
@ -203,13 +207,13 @@ function chunkPropertyUtils.removeSquadFromChunk(map, squad)
|
||||
if chunk then
|
||||
local squads = chunkToSquad[chunk]
|
||||
if squads then
|
||||
squads[squad] = nil
|
||||
local i = 0
|
||||
for _,_ in pairs(squads) do
|
||||
i = i + 1
|
||||
break
|
||||
for i=1,#squads do
|
||||
if (squads[i] == squad) then
|
||||
tRemove(squads, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
if (i == 0) then
|
||||
if (#squads == 0) then
|
||||
chunkToSquad[chunk] = nil
|
||||
end
|
||||
end
|
||||
|
@ -79,49 +79,6 @@ local mRandom = math.random
|
||||
|
||||
-- module code
|
||||
|
||||
function chunkUtils.fullScan(chunk,
|
||||
count_entities_filtered,
|
||||
count_tiles_filtered,
|
||||
filteredEntitiesCliffQuery,
|
||||
filteredTilesPathQuery)
|
||||
local x = chunk.x
|
||||
local y = chunk.y
|
||||
|
||||
local passableNorthSouth = false
|
||||
local passableEastWest = false
|
||||
|
||||
local topPosition = filteredEntitiesCliffQuery.area[1]
|
||||
local bottomPosition = filteredEntitiesCliffQuery.area[2]
|
||||
topPosition[2] = y
|
||||
bottomPosition[2] = y + 32
|
||||
|
||||
for xi=x, x + 32 do
|
||||
topPosition[1] = xi
|
||||
bottomPosition[1] = xi + 1
|
||||
if (count_entities_filtered(filteredEntitiesCliffQuery) == 0) and
|
||||
(count_tiles_filtered(filteredTilesPathQuery) == 0)
|
||||
then
|
||||
passableNorthSouth = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
topPosition[1] = x
|
||||
bottomPosition[1] = x + 32
|
||||
|
||||
for yi=y, y + 32 do
|
||||
topPosition[2] = yi
|
||||
bottomPosition[2] = yi + 1
|
||||
if (count_entities_filtered(filteredEntitiesCliffQuery) == 0) and
|
||||
(count_tiles_filtered(filteredTilesPathQuery) == 0)
|
||||
then
|
||||
passableEastWest = true
|
||||
break
|
||||
end
|
||||
end
|
||||
return passableNorthSouth, passableEastWest
|
||||
end
|
||||
|
||||
local function addEnemyStructureToChunk(map, chunk, entity, base)
|
||||
local lookup
|
||||
if (entity.type == "unit-spawner") then
|
||||
@ -227,12 +184,48 @@ end
|
||||
|
||||
function chunkUtils.scanChunkPaths(chunk, surface, map)
|
||||
local pass = CHUNK_IMPASSABLE
|
||||
local passableNorthSouth, passableEastWest = chunkUtils.fullScan(chunk,
|
||||
surface.count_entities_filtered,
|
||||
surface.count_tiles_filtered,
|
||||
map.filteredEntitiesCliffQuery,
|
||||
map.filteredTilesPathQuery)
|
||||
|
||||
local x = chunk.x
|
||||
local y = chunk.y
|
||||
|
||||
local filteredEntitiesCliffQuery = map.filteredEntitiesCliffQuery
|
||||
local filteredTilesPathQuery = map.filteredTilesPathQuery
|
||||
local count_entities_filtered = surface.count_entities_filtered
|
||||
local count_tiles_filtered = surface.count_tiles_filtered
|
||||
|
||||
local passableNorthSouth = false
|
||||
local passableEastWest = false
|
||||
|
||||
local topPosition = filteredEntitiesCliffQuery.area[1]
|
||||
local bottomPosition = filteredEntitiesCliffQuery.area[2]
|
||||
topPosition[2] = y
|
||||
bottomPosition[2] = y + 32
|
||||
|
||||
for xi=x, x + 32 do
|
||||
topPosition[1] = xi
|
||||
bottomPosition[1] = xi + 1
|
||||
if (count_entities_filtered(filteredEntitiesCliffQuery) == 0) and
|
||||
(count_tiles_filtered(filteredTilesPathQuery) == 0)
|
||||
then
|
||||
passableNorthSouth = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
topPosition[1] = x
|
||||
bottomPosition[1] = x + 32
|
||||
|
||||
for yi=y, y + 32 do
|
||||
topPosition[2] = yi
|
||||
bottomPosition[2] = yi + 1
|
||||
if (count_entities_filtered(filteredEntitiesCliffQuery) == 0) and
|
||||
(count_tiles_filtered(filteredTilesPathQuery) == 0)
|
||||
then
|
||||
passableEastWest = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if passableEastWest and passableNorthSouth then
|
||||
pass = CHUNK_ALL_DIRECTIONS
|
||||
elseif passableEastWest then
|
||||
@ -279,11 +272,11 @@ end
|
||||
function chunkUtils.initialScan(chunk, natives, surface, map, tick, evolutionFactor, rebuilding)
|
||||
local passScore = chunkUtils.calculatePassScore(surface, map)
|
||||
|
||||
if (passScore >= 0.40) then
|
||||
if (passScore >= 0.25) then
|
||||
local pass = chunkUtils.scanChunkPaths(chunk, surface, map)
|
||||
|
||||
local playerObjects = scorePlayerBuildings(surface, map, natives)
|
||||
|
||||
|
||||
local nests = surface.find_entities_filtered(map.filteredEntitiesUnitSpawnereQuery)
|
||||
local worms = surface.find_entities_filtered(map.filteredEntitiesWormQuery)
|
||||
|
||||
@ -363,7 +356,7 @@ end
|
||||
function chunkUtils.chunkPassScan(chunk, surface, map)
|
||||
local passScore = chunkUtils.calculatePassScore(surface, map)
|
||||
|
||||
if (passScore >= 0.40) then
|
||||
if (passScore >= 0.25) then
|
||||
local pass = chunkUtils.scanChunkPaths(chunk, surface, map)
|
||||
|
||||
local playerObjects = getPlayerBaseGenerator(map, chunk)
|
||||
@ -403,9 +396,7 @@ function chunkUtils.createChunk(topX, topY)
|
||||
chunk[BASE_PHEROMONE] = 0
|
||||
chunk[PLAYER_PHEROMONE] = 0
|
||||
chunk[RESOURCE_PHEROMONE] = 0
|
||||
-- chunk[PASSABLE] = 0
|
||||
chunk[CHUNK_TICK] = 0
|
||||
-- chunk[PATH_RATING] = 0
|
||||
|
||||
return chunk
|
||||
end
|
||||
|
@ -577,8 +577,9 @@ constants.POISON_LOOKUP = {}
|
||||
|
||||
for tier=1, unitTiers do
|
||||
local t = ((unitTiers == 5) and constants.TIER_NAMING_SET_5[tier]) or constants.TIER_NAMING_SET_10[tier]
|
||||
local ct = ((unitTiers == 5) and constants.TIER_UPGRADE_SET_5[tier]) or constants.TIER_UPGRADE_SET_10[tier]
|
||||
for i=1,unitVariations do
|
||||
constants.POISON_LOOKUP["poison-biter-v" .. i .. "-t" .. t .. "-rampant"] = "poison-cloud-v" .. i .. "-cloud-rampant"
|
||||
constants.POISON_LOOKUP["poison-biter-v" .. i .. "-t" .. t .. "-rampant"] = "poison-cloud-v" .. ct .. "-cloud-rampant"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -37,7 +37,7 @@ local distortPosition = mathUtils.distortPosition
|
||||
function movementUtils.findMovementPosition(surface, position, distort)
|
||||
local pos = position
|
||||
if not surface.can_place_entity({name="behemoth-biter", position=position}) then
|
||||
pos = surface.find_non_colliding_position("behemoth-biter", position, 5, 2)
|
||||
pos = surface.find_non_colliding_position("behemoth-biter", position, 5, 1, true)
|
||||
end
|
||||
return (distort and distortPosition(pos)) or pos
|
||||
end
|
||||
@ -95,9 +95,9 @@ function movementUtils.scoreNeighborsForAttack(map, natives, chunk, neighborDire
|
||||
end
|
||||
end
|
||||
|
||||
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) and (scoreFunction(natives, squad, chunk) > highestScore) then
|
||||
return SENTINEL_IMPASSABLE_CHUNK, -1
|
||||
end
|
||||
-- if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) and (scoreFunction(natives, squad, chunk) > highestScore) then
|
||||
-- return SENTINEL_IMPASSABLE_CHUNK, -1
|
||||
-- end
|
||||
|
||||
return highestChunk, highestDirection
|
||||
end
|
||||
|
@ -179,66 +179,71 @@ local function settleMove(map, attackPosition, attackCmd, settleCmd, squad, grou
|
||||
end
|
||||
|
||||
|
||||
local function attackMove(map, attackPosition, attackCmd, squad, group, natives, surface)
|
||||
local groupState = group.state
|
||||
local function attackMove(map, squad, natives, surface)
|
||||
local attackPosition = map.position
|
||||
local group = squad.group
|
||||
|
||||
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 x, y = positionToChunkXY(groupPosition)
|
||||
local chunk = getChunkByXY(map, x, y)
|
||||
local attackScorer = scoreAttackLocation
|
||||
if (squad.attackScoreFunction == ATTACK_SCORE_KAMIKAZE) then
|
||||
attackScorer = scoreAttackKamikazeLocation
|
||||
local groupPosition = group.position
|
||||
local x, y = positionToChunkXY(groupPosition)
|
||||
local chunk = getChunkByXY(map, x, y)
|
||||
local attackScorer = scoreAttackLocation
|
||||
if (squad.attackScoreFunction == ATTACK_SCORE_KAMIKAZE) then
|
||||
attackScorer = scoreAttackKamikazeLocation
|
||||
end
|
||||
local attackChunk, attackDirection = scoreNeighborsForAttack(map,
|
||||
natives,
|
||||
chunk,
|
||||
getNeighborChunks(map, x, y),
|
||||
attackScorer,
|
||||
squad)
|
||||
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
addSquadToChunk(map, chunk, squad)
|
||||
addMovementPenalty(natives, squad, chunk)
|
||||
end
|
||||
if (attackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
local playerBaseGenerator = getPlayerBaseGenerator(map, attackChunk)
|
||||
local playerPheromone = attackChunk[PLAYER_PHEROMONE]
|
||||
local cmd
|
||||
local position
|
||||
if (playerBaseGenerator == 0) and (playerPheromone < natives.attackPlayerThreshold) then
|
||||
squad.cycles = ((#squad.group.members > 80) and 6) or 4
|
||||
|
||||
squad.frenzy = (squad.frenzy and (euclideanDistanceNamed(groupPosition, squad.frenzyPosition) < 100))
|
||||
|
||||
cmd = map.moveCommand
|
||||
if squad.rabid or squad.frenzy then
|
||||
cmd.distraction = DEFINES_DISTRACTION_BY_ANYTHING
|
||||
else
|
||||
cmd.distraction = DEFINES_DISTRACTION_BY_ENEMY
|
||||
end
|
||||
else
|
||||
squad.cycles = ((#squad.group.members > 80) and 6) or 4
|
||||
cmd = map.attackCommand
|
||||
|
||||
if not squad.rabid then
|
||||
squad.frenzy = true
|
||||
squad.frenzyPosition.x = groupPosition.x
|
||||
squad.frenzyPosition.y = groupPosition.y
|
||||
end
|
||||
end
|
||||
local attackChunk, attackDirection = scoreNeighborsForAttack(map,
|
||||
natives,
|
||||
chunk,
|
||||
getNeighborChunks(map, x, y),
|
||||
attackScorer,
|
||||
squad)
|
||||
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
addSquadToChunk(map, chunk, squad)
|
||||
addMovementPenalty(natives, squad, chunk)
|
||||
-- elseif (attackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
-- addSquadToChunk(map, attackChunk, squad)
|
||||
-- addMovementPenalty(natives, squad, attackChunk)
|
||||
end
|
||||
if group.valid and (attackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
local playerBaseGenerator = getPlayerBaseGenerator(map, attackChunk)
|
||||
-- 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
|
||||
|
||||
local moreFrenzy = not squad.rabid and squad.frenzy and (euclideanDistanceNamed(groupPosition, squad.frenzyPosition) < 100)
|
||||
squad.frenzy = moreFrenzy
|
||||
position = findMovementPosition(surface,
|
||||
positionFromDirectionAndChunk(attackDirection,
|
||||
groupPosition,
|
||||
attackPosition,
|
||||
1.35))
|
||||
|
||||
if position then
|
||||
attackPosition.x = position.x
|
||||
attackPosition.y = position.y
|
||||
|
||||
if squad.rabid or squad.frenzy then
|
||||
attackCmd.distraction = DEFINES_DISTRACTION_BY_ANYTHING
|
||||
else
|
||||
attackCmd.distraction = DEFINES_DISTRACTION_BY_ENEMY
|
||||
end
|
||||
|
||||
local position = findMovementPosition(surface, positionFromDirectionAndChunk(attackDirection, groupPosition, attackPosition, 1.35))
|
||||
if position then
|
||||
attackPosition.x = position.x
|
||||
attackPosition.y = position.y
|
||||
|
||||
group.set_command(attackCmd)
|
||||
group.start_moving()
|
||||
else
|
||||
addMovementPenalty(natives, squad, attackChunk)
|
||||
end
|
||||
elseif not squad.frenzy and not squad.rabid and
|
||||
((groupState == DEFINES_GROUP_ATTACKING_DISTRACTION) or (groupState == DEFINES_GROUP_ATTACKING_TARGET) or
|
||||
(playerBaseGenerator ~= 0)) then
|
||||
squad.frenzy = true
|
||||
squad.frenzyPosition.x = groupPosition.x
|
||||
squad.frenzyPosition.y = groupPosition.y
|
||||
end
|
||||
end
|
||||
group.set_command(cmd)
|
||||
group.start_moving()
|
||||
else
|
||||
addMovementPenalty(natives, squad, attackChunk)
|
||||
end
|
||||
else
|
||||
print("attack: bad attack chunk", squad.group.group_number)
|
||||
end
|
||||
end
|
||||
|
||||
@ -267,9 +272,15 @@ function squadAttack.squadsDispatch(map, surface, natives)
|
||||
else
|
||||
local status = squad.status
|
||||
local cycles = squad.cycles
|
||||
local groupState = group.state
|
||||
|
||||
if (status == SQUAD_RAIDING) then
|
||||
attackMove(map, attackPosition, attackCmd, squad, group, natives, surface)
|
||||
if (groupState == DEFINES_GROUP_FINISHED) or
|
||||
(groupState == DEFINES_GROUP_GATHERING) or
|
||||
((groupState == DEFINES_GROUP_MOVING) and (cycles <= 0))
|
||||
then
|
||||
attackMove(map, squad, natives, surface)
|
||||
end
|
||||
elseif (status == SQUAD_SETTLING) then
|
||||
settleMove(map, attackPosition, attackCmd, settleCmd, squad, group, natives, surface)
|
||||
elseif (status == SQUAD_RETREATING) and (cycles == 0) then
|
||||
@ -292,7 +303,7 @@ function squadAttack.squadsDispatch(map, surface, natives)
|
||||
end
|
||||
end
|
||||
|
||||
function squadAttack.squadsBeginAttack(natives, players)
|
||||
function squadAttack.squadsBeginAttack(natives)
|
||||
local squads = natives.pendingAttack
|
||||
for i=1,#squads do
|
||||
local squad = squads[i]
|
||||
@ -303,25 +314,15 @@ function squadAttack.squadsBeginAttack(natives, players)
|
||||
squad.kamikaze = (mRandom() < kamikazeThreshold)
|
||||
end
|
||||
if squad.settlers then
|
||||
-- if (squad.status == SQUAD_GUARDING) then
|
||||
squad.status = SQUAD_SETTLING
|
||||
natives.squads[#natives.squads+1] = squad
|
||||
else
|
||||
-- if (squad.status == SQUAD_GUARDING) then
|
||||
local groupPosition = group.position
|
||||
if playersWithinProximityToPosition(players, groupPosition, 100, natives) then
|
||||
squad.frenzy = true
|
||||
squad.frenzyPosition.x = groupPosition.x
|
||||
squad.frenzyPosition.y = groupPosition.y
|
||||
end
|
||||
|
||||
else
|
||||
if squad.kamikaze and (mRandom() < (kamikazeThreshold * 0.75)) then
|
||||
squad.attackScoreFunction = ATTACK_SCORE_KAMIKAZE
|
||||
end
|
||||
squad.status = SQUAD_RAIDING
|
||||
natives.squads[#natives.squads+1] = squad
|
||||
end
|
||||
-- end
|
||||
end
|
||||
end
|
||||
natives.pendingAttack = {}
|
||||
|
@ -51,7 +51,10 @@ local getEnemyStructureCount = chunkPropetyUtils.getEnemyStructureCount
|
||||
-- module code
|
||||
|
||||
local function scoreRetreatLocation(map, neighborChunk)
|
||||
return -(neighborChunk[BASE_PHEROMONE] + neighborChunk[MOVEMENT_PHEROMONE] + -(neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER) + -(getPlayerBaseGenerator(map, neighborChunk)))
|
||||
return -(neighborChunk[BASE_PHEROMONE] +
|
||||
neighborChunk[MOVEMENT_PHEROMONE] +
|
||||
-(neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER) +
|
||||
-(getPlayerBaseGenerator(map, neighborChunk)))
|
||||
end
|
||||
|
||||
function aiDefense.retreatUnits(chunk, position, squad, map, surface, natives, tick, radius, artilleryBlast, force)
|
||||
@ -64,10 +67,10 @@ function aiDefense.retreatUnits(chunk, position, squad, map, surface, natives, t
|
||||
performRetreat = #enemiesToSquad > 0
|
||||
if (mRandom() < calculateKamikazeThreshold(#enemiesToSquad, natives)) then
|
||||
setRetreatTick(map, chunk, tick)
|
||||
performRetreat = false
|
||||
return
|
||||
end
|
||||
elseif squad.group and squad.group.valid and (squad.status ~= SQUAD_RETREATING) and not squad.kamikaze then
|
||||
performRetreat = #squad.group.members > 1
|
||||
performRetreat = #squad.group.members > 3
|
||||
end
|
||||
|
||||
if performRetreat then
|
||||
@ -78,8 +81,7 @@ function aiDefense.retreatUnits(chunk, position, squad, map, surface, natives, t
|
||||
map)
|
||||
if (exitPath ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
local retreatPosition = findMovementPosition(surface,
|
||||
positionFromDirectionAndChunk(exitDirection, position, map.position, 0.98),
|
||||
false)
|
||||
positionFromDirectionAndChunk(exitDirection, position, map.position, 0.98))
|
||||
|
||||
if not retreatPosition then
|
||||
return
|
||||
@ -88,7 +90,7 @@ function aiDefense.retreatUnits(chunk, position, squad, map, surface, natives, t
|
||||
-- in order for units in a group attacking to retreat, we have to create a new group and give the command to join
|
||||
-- to each unit, this is the only way I have found to have snappy mid battle retreats even after 0.14.4
|
||||
|
||||
local newSquad = findNearbySquadFiltered(map, exitPath, retreatPosition)
|
||||
local newSquad = findNearbySquadFiltered(map, exitPath)
|
||||
|
||||
if not newSquad then
|
||||
newSquad = createSquad(retreatPosition, surface)
|
||||
@ -97,12 +99,7 @@ function aiDefense.retreatUnits(chunk, position, squad, map, surface, natives, t
|
||||
|
||||
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
|
||||
newSquad.cycles = 4
|
||||
|
||||
local cmd = map.retreatCommand
|
||||
cmd.group = newSquad.group
|
||||
@ -115,6 +112,13 @@ function aiDefense.retreatUnits(chunk, position, squad, map, surface, natives, t
|
||||
newSquad.rabid = true
|
||||
end
|
||||
end
|
||||
|
||||
if not newSquad.rapid then
|
||||
newSquad.frenzy = true
|
||||
local squadPosition = newSquad.group.position
|
||||
newSquad.frenzyPosition.x = squadPosition.x
|
||||
newSquad.frenzyPosition.y = squadPosition.y
|
||||
end
|
||||
addSquadToChunk(map, chunk, newSquad)
|
||||
addMovementPenalty(natives, newSquad, chunk)
|
||||
end
|
||||
|
74
tests.lua
74
tests.lua
@ -62,51 +62,75 @@ function tests.killActiveSquads()
|
||||
end
|
||||
|
||||
function tests.activeSquads()
|
||||
print("--")
|
||||
print("-----")
|
||||
print("Squads", #global.natives.squads)
|
||||
for i=1, #global.natives.squads do
|
||||
print("-")
|
||||
local squad = global.natives.squads[i]
|
||||
local squadHealth = 0
|
||||
local squadMakeup = {}
|
||||
local squadResistances = {}
|
||||
if squad.group.valid then
|
||||
for x=1,#squad.group.members do
|
||||
local member = squad.group.members[x].prototype
|
||||
if not squadMakeup[member.name] then
|
||||
squadMakeup[member.name] = 0
|
||||
end
|
||||
local resistances = member.resistances
|
||||
if resistances then
|
||||
for key,resistance in pairs(resistances) do
|
||||
local pack = squadResistances[key]
|
||||
if not pack then
|
||||
pack = {}
|
||||
squadResistances[key] = pack
|
||||
end
|
||||
if resistance.percent then
|
||||
if (pack.percent == nil) then
|
||||
pack.percent = 0
|
||||
end
|
||||
pack.percent = pack.percent + resistance.percent
|
||||
end
|
||||
if resistance.decrease then
|
||||
if (pack.decrease == nil) then
|
||||
pack.decrease = 0
|
||||
end
|
||||
pack.decrease = pack.decrease + resistance.decrease
|
||||
end
|
||||
end
|
||||
|
||||
squadHealth = squadHealth + member.max_health
|
||||
squadMakeup[member.name] = squadMakeup[member.name] + 1
|
||||
end
|
||||
print(math.floor(squad.group.position.x * 0.03125), math.floor(squad.group.position.y * 0.03125), squad.status, squad.group.state, #squad.group.members, squad.cycles, squadHealth)
|
||||
-- print(serpent.dump(squadResistances))
|
||||
print(serpent.dump(squadMakeup))
|
||||
print(serpent.dump(squad))
|
||||
end
|
||||
end
|
||||
print("---")
|
||||
print("pending", #global.natives.pendingAttack)
|
||||
for i=1, #global.natives.pendingAttack do
|
||||
print("-")
|
||||
local squad = global.natives.pendingAttack[i]
|
||||
local squadHealth = 0
|
||||
local squadMakeup = {}
|
||||
if squad.group.valid then
|
||||
for x=1,#squad.group.members do
|
||||
local member = squad.group.members[x].prototype
|
||||
if not squadMakeup[member.name] then
|
||||
squadMakeup[member.name] = 0
|
||||
end
|
||||
|
||||
squadHealth = squadHealth + member.max_health
|
||||
squadMakeup[member.name] = squadMakeup[member.name] + 1
|
||||
end
|
||||
print(math.floor(squad.group.position.x * 0.03125), math.floor(squad.group.position.y * 0.03125), squad.status, squad.group.state, #squad.group.members, squadHealth)
|
||||
print(serpent.dump(squadResistances))
|
||||
print(math.floor(squad.group.position.x * 0.03125), math.floor(squad.group.position.y * 0.03125), squad.status, squad.group.state, #squad.group.members, squad.cycles, squadHealth)
|
||||
-- print(serpent.dump(squadResistances))
|
||||
print(serpent.dump(squadMakeup))
|
||||
print(serpent.dump(squad))
|
||||
end
|
||||
end
|
||||
print("---")
|
||||
print("building", #global.natives.building)
|
||||
for i=1, #global.natives.building do
|
||||
print("-")
|
||||
local squad = global.natives.pendingAttack[i]
|
||||
local squadHealth = 0
|
||||
local squadMakeup = {}
|
||||
if squad.group.valid then
|
||||
for x=1,#squad.group.members do
|
||||
local member = squad.group.members[x].prototype
|
||||
if not squadMakeup[member.name] then
|
||||
squadMakeup[member.name] = 0
|
||||
end
|
||||
|
||||
squadHealth = squadHealth + member.max_health
|
||||
squadMakeup[member.name] = squadMakeup[member.name] + 1
|
||||
end
|
||||
print(math.floor(squad.group.position.x * 0.03125), math.floor(squad.group.position.y * 0.03125), squad.status, squad.group.state, #squad.group.members, squad.cycles, squadHealth)
|
||||
-- print(serpent.dump(squadResistances))
|
||||
print(serpent.dump(squadMakeup))
|
||||
print(serpent.dump(squad))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function tests.entitiesOnPlayerChunk()
|
||||
|
Loading…
x
Reference in New Issue
Block a user