1
0
mirror of https://github.com/veden/Rampant.git synced 2024-12-30 21:19:46 +02:00
Rampant/libs/SquadDefense.lua

109 lines
3.6 KiB
Lua

local aiDefense = {}
-- imports
local constants = require("Constants")
local mapUtils = require("MapUtils")
local unitGroupUtils = require("UnitGroupUtils")
local neighborUtils = require("NeighborUtils")
local movementUtils = require("MovementUtils")
-- constants
local RETREAT_GRAB_RADIUS = constants.RETREAT_GRAB_RADIUS
local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
local BASE_PHEROMONE = constants.BASE_PHEROMONE
local HALF_CHUNK_SIZE = constants.HALF_CHUNK_SIZE
local SQUAD_RETREATING = constants.SQUAD_RETREATING
local RETREAT_FILTER = constants.RETREAT_FILTER
local RETREAT_TRIGGERED = constants.RETREAT_TRIGGERED
local INTERVAL_LOGIC = constants.INTERVAL_LOGIC
local NEST_COUNT = constants.NEST_COUNT
local WORM_COUNT = constants.WORM_COUNT
-- imported functions
local positionFromDirectionAndChunk = mapUtils.positionFromDirectionAndChunk
local getNeighborChunks = mapUtils.getNeighborChunks
local findNearBySquad = unitGroupUtils.findNearBySquad
local addMovementPenalty = movementUtils.addMovementPenalty
local createSquad = unitGroupUtils.createSquad
local membersToSquad = unitGroupUtils.membersToSquad
local scoreNeighborsForRetreat = neighborUtils.scoreNeighborsForRetreat
local findMovementPosition = movementUtils.findMovementPosition
-- module code
local function scoreRetreatLocation(neighborChunk)
return -(neighborChunk[BASE_PHEROMONE] + -neighborChunk[MOVEMENT_PHEROMONE] + (neighborChunk[PLAYER_PHEROMONE] * 100) + (neighborChunk[PLAYER_BASE_GENERATOR] * 20))
end
function aiDefense.retreatUnits(chunk, position, squad, regionMap, surface, natives, tick)
if (tick - chunk[RETREAT_TRIGGERED] > INTERVAL_LOGIC) and (chunk[NEST_COUNT] == 0) and (chunk[WORM_COUNT] == 0) then
local performRetreat = false
local enemiesToSquad = nil
if not squad then
enemiesToSquad = surface.find_enemy_units(chunk, RETREAT_GRAB_RADIUS)
performRetreat = #enemiesToSquad > 0
elseif squad.group.valid and (squad.status ~= SQUAD_RETREATING) and not squad.kamikaze then
performRetreat = #squad.group.members > 1
end
if performRetreat then
chunk[RETREAT_TRIGGERED] = tick
local exitPath,exitDirection = scoreNeighborsForRetreat(chunk,
getNeighborChunks(regionMap,
chunk.cX,
chunk.cY),
scoreRetreatLocation)
if exitPath then
local retreatPosition = findMovementPosition(surface,
positionFromDirectionAndChunk(exitDirection,
position,
regionMap.position,
0.98),
false)
if not retreatPosition then
return
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 = findNearBySquad(natives, retreatPosition, HALF_CHUNK_SIZE, RETREAT_FILTER)
if not newSquad then
newSquad = createSquad(retreatPosition, surface, natives)
newSquad.status = SQUAD_RETREATING
newSquad.cycles = 4
end
if enemiesToSquad then
membersToSquad(newSquad, enemiesToSquad, false)
else
membersToSquad(newSquad, squad.group.members, true)
newSquad.penalties = squad.penalties
if squad.rabid then
newSquad.rabid = true
end
end
addMovementPenalty(natives, newSquad, chunk.cX, chunk.cY)
end
end
end
end
return aiDefense