mirror of
https://github.com/veden/Rampant.git
synced 2024-12-28 21:08:22 +02:00
159 lines
6.5 KiB
Lua
Executable File
159 lines
6.5 KiB
Lua
Executable File
if aiDefenseG then
|
|
return aiDefenseG
|
|
end
|
|
local aiDefense = {}
|
|
|
|
-- imports
|
|
|
|
local constants = require("Constants")
|
|
local mapUtils = require("MapUtils")
|
|
local unitGroupUtils = require("UnitGroupUtils")
|
|
local movementUtils = require("MovementUtils")
|
|
local chunkPropetyUtils = require("ChunkPropertyUtils")
|
|
|
|
-- constants
|
|
|
|
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
|
|
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
|
|
local BASE_PHEROMONE = constants.BASE_PHEROMONE
|
|
|
|
local PLAYER_PHEROMONE_MULTIPLER = constants.PLAYER_PHEROMONE_MULTIPLER
|
|
|
|
local SQUAD_RETREATING = constants.SQUAD_RETREATING
|
|
|
|
local INTERVAL_RETREAT = constants.INTERVAL_RETREAT
|
|
|
|
-- imported functions
|
|
|
|
local mRandom = math.random
|
|
|
|
local addSquadToChunk = chunkPropetyUtils.addSquadToChunk
|
|
|
|
local calculateKamikazeThreshold = unitGroupUtils.calculateKamikazeThreshold
|
|
|
|
local positionFromDirectionAndFlat = mapUtils.positionFromDirectionAndFlat
|
|
local getNeighborChunks = mapUtils.getNeighborChunks
|
|
local findNearbyRetreatingSquad = unitGroupUtils.findNearbyRetreatingSquad
|
|
local addMovementPenalty = movementUtils.addMovementPenalty
|
|
local createSquad = unitGroupUtils.createSquad
|
|
local membersToSquad = unitGroupUtils.membersToSquad
|
|
local scoreNeighborsForRetreat = movementUtils.scoreNeighborsForRetreat
|
|
local findMovementPosition = movementUtils.findMovementPosition
|
|
|
|
local getRetreatTick = chunkPropetyUtils.getRetreatTick
|
|
local getPlayerBaseGenerator = chunkPropetyUtils.getPlayerBaseGenerator
|
|
local setRetreatTick = chunkPropetyUtils.setRetreatTick
|
|
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) * 1000))
|
|
end
|
|
|
|
function aiDefense.retreatUnits(chunk, position, squad, map, surface, tick, radius, artilleryBlast)
|
|
if (tick - getRetreatTick(map, chunk) > INTERVAL_RETREAT) and
|
|
((getEnemyStructureCount(map, chunk) == 0) or artilleryBlast)
|
|
then
|
|
local performRetreat = false
|
|
local enemiesToSquad = nil
|
|
|
|
if not squad then
|
|
enemiesToSquad = map.enemiesToSquad
|
|
local unitCount = 0
|
|
local units = surface.find_enemy_units(position, radius)
|
|
for i=1,#units do
|
|
local unit = units[i]
|
|
if not unit.unit_group then
|
|
unitCount = unitCount + 1
|
|
enemiesToSquad[unitCount] = unit
|
|
end
|
|
end
|
|
enemiesToSquad.len = unitCount
|
|
if (mRandom() < calculateKamikazeThreshold(unitCount, map.natives)) then
|
|
setRetreatTick(map, chunk, tick)
|
|
return
|
|
end
|
|
performRetreat = unitCount > 6
|
|
elseif squad.group and squad.group.valid and (squad.status ~= SQUAD_RETREATING) and not squad.kamikaze then
|
|
performRetreat = #squad.group.members > 6
|
|
end
|
|
|
|
if performRetreat then
|
|
setRetreatTick(map, chunk, tick)
|
|
local exitPath,exitDirection,nextExitPath,nextExitDirection = scoreNeighborsForRetreat(chunk,
|
|
getNeighborChunks(map,
|
|
chunk.x,
|
|
chunk.y),
|
|
scoreRetreatLocation,
|
|
map)
|
|
if (exitPath ~= -1) then
|
|
local targetPosition = map.position
|
|
local targetPosition2 = map.position2
|
|
|
|
positionFromDirectionAndFlat(exitDirection, position, targetPosition)
|
|
|
|
local retreatPosition = findMovementPosition(surface, targetPosition)
|
|
|
|
if not retreatPosition then
|
|
return
|
|
end
|
|
|
|
if (nextExitPath ~= -1) then
|
|
positionFromDirectionAndFlat(nextExitDirection, retreatPosition, targetPosition2)
|
|
|
|
local retreatPosition2 = findMovementPosition(surface, targetPosition2)
|
|
|
|
if retreatPosition2 then
|
|
retreatPosition.x = retreatPosition2.x
|
|
retreatPosition.y = retreatPosition2.y
|
|
end
|
|
end
|
|
|
|
-- 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 = findNearbyRetreatingSquad(map, exitPath)
|
|
|
|
if not newSquad then
|
|
newSquad = createSquad(retreatPosition, surface)
|
|
local squads = map.natives.squads
|
|
squads.len = squads.len+1
|
|
squads[squads.len] = newSquad
|
|
end
|
|
|
|
if newSquad then
|
|
newSquad.status = SQUAD_RETREATING
|
|
newSquad.cycles = 13
|
|
|
|
local cmd = map.retreatCommand
|
|
cmd.group = newSquad.group
|
|
if enemiesToSquad then
|
|
membersToSquad(cmd, enemiesToSquad.len, enemiesToSquad, artilleryBlast)
|
|
else
|
|
membersToSquad(cmd, #squad.group.members, squad.group.members, true)
|
|
if squad.rabid then
|
|
newSquad.rabid = true
|
|
end
|
|
end
|
|
|
|
if not newSquad.rabid then
|
|
newSquad.frenzy = true
|
|
local squadPosition = newSquad.group.position
|
|
newSquad.frenzyPosition.x = squadPosition.x
|
|
newSquad.frenzyPosition.y = squadPosition.y
|
|
end
|
|
addMovementPenalty(newSquad, chunk)
|
|
addSquadToChunk(map, chunk, newSquad)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
aiDefenseG = aiDefense
|
|
return aiDefense
|