1
0
mirror of https://github.com/veden/Rampant.git synced 2024-12-28 21:08:22 +02:00
Rampant/libs/SquadDefense.lua
2018-02-06 23:57:41 -08:00

115 lines
4.1 KiB
Lua
Executable File

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 RETREAT_SPAWNER_GRAB_RADIUS = constants.RETREAT_SPAWNER_GRAB_RADIUS
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
local BASE_PHEROMONE = constants.BASE_PHEROMONE
local SQUAD_RETREATING = constants.SQUAD_RETREATING
local INTERVAL_LOGIC = constants.INTERVAL_LOGIC
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
-- imported functions
local mRandom = math.random
local addSquadToChunk = chunkPropetyUtils.addSquadToChunk
local calculateKamikazeThreshold = unitGroupUtils.calculateKamikazeThreshold
local positionFromDirectionAndChunk = mapUtils.positionFromDirectionAndChunk
local getNeighborChunks = mapUtils.getNeighborChunks
local findNearbySquadFiltered = unitGroupUtils.findNearbySquadFiltered
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] * 100) + (getPlayerBaseGenerator(map, neighborChunk) * 20))
end
function aiDefense.retreatUnits(chunk, position, squad, map, surface, natives, tick, radius, force)
if (tick - getRetreatTick(map, chunk) > INTERVAL_LOGIC) and ((getEnemyStructureCount(map, chunk) == 0) or force) then
local performRetreat = false
local enemiesToSquad = nil
if not squad then
enemiesToSquad = surface.find_enemy_units(position, radius)
performRetreat = #enemiesToSquad > 0
if (mRandom() < calculateKamikazeThreshold(#enemiesToSquad, natives)) then
setRetreatTick(map, chunk, tick + (INTERVAL_LOGIC * 10))
performRetreat = false
end
elseif squad.group and squad.group.valid and (squad.status ~= SQUAD_RETREATING) and not squad.kamikaze then
performRetreat = #squad.group.members > 1
end
if performRetreat then
setRetreatTick(map, chunk, tick)
local exitPath,exitDirection = scoreNeighborsForRetreat(chunk,
getNeighborChunks(map, chunk.x, chunk.y),
scoreRetreatLocation,
map)
if (exitPath ~= SENTINEL_IMPASSABLE_CHUNK) then
local retreatPosition = findMovementPosition(surface,
positionFromDirectionAndChunk(exitDirection, position, map.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 = findNearbySquadFiltered(map, exitPath, retreatPosition)
if not newSquad then
newSquad = createSquad(retreatPosition, surface, natives)
newSquad.status = SQUAD_RETREATING
newSquad.cycles = 4
end
if newSquad then
local cmd = map.retreatCommand
cmd.group = newSquad.group
if enemiesToSquad then
membersToSquad(cmd, enemiesToSquad, force)
else
membersToSquad(cmd, squad.group.members, true)
newSquad.penalties = squad.penalties
if squad.rabid then
newSquad.rabid = true
end
end
addSquadToChunk(map, chunk, newSquad)
addMovementPenalty(natives, newSquad, chunk)
end
end
end
end
end
return aiDefense