1
0
mirror of https://github.com/veden/Rampant.git synced 2025-01-03 22:52:20 +02:00
Rampant/libs/AIDefense.lua
2016-09-14 11:18:25 -07:00

114 lines
4.6 KiB
Lua

local aiDefense = {}
-- imports
local constants = require("Constants")
local mapUtils = require("MapUtils")
local unitGroupUtils = require("UnitGroupUtils")
local neighborUtils = require("NeighborUtils")
-- constants
local DEATH_PHEROMONE = constants.DEATH_PHEROMONE
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
local ENEMY_BASE_PHEROMONE = constants.ENEMY_BASE_PHEROMONE
local PLAYER_DEFENSE_PHEROMONE = constants.PLAYER_DEFENSE_PHEROMONE
local RETREAT_DEATH_PHEROMONE_LEVEL = constants.RETREAT_DEATH_PHEROMONE_LEVEL
local ENEMY_BASE_GENERATOR = constants.ENEMY_BASE_GENERATOR
local HALF_CHUNK_SIZE = constants.HALF_CHUNK_SIZE
local SQUAD_RETREATING = constants.SQUAD_RETREATING
local SQUAD_SUICIDE_HUNT = constants.SQUAD_SUICIDE_HUNT
local SQUAD_SUICIDE_RAID = constants.SQUAD_SUICIDE_RAID
local RETREAT_FILTER = constants.RETREAT_FILTER
local NORTH_SOUTH_PASSABLE = constants.NORTH_SOUTH_PASSABLE
local EAST_WEST_PASSABLE = constants.EAST_WEST_PASSABLE
-- imported functions
local getChunkByPosition = mapUtils.getChunkByPosition
local getNeighborChunksWithDirection = mapUtils.getNeighborChunksWithDirection
local findNearBySquad = unitGroupUtils.findNearBySquad
local addSquadMovementPenalty = unitGroupUtils.addSquadMovementPenalty
local createSquad = unitGroupUtils.createSquad
local membersToSquad = unitGroupUtils.membersToSquad
local scoreNeighborsWithDirection = neighborUtils.scoreNeighborsWithDirection
local addSquadMovementPenalty = unitGroupUtils.addSquadMovementPenalty
-- module code
local function validRetreatLocation(x, chunk, neighborChunk)
return neighborChunk[NORTH_SOUTH_PASSABLE] and neighborChunk[EAST_WEST_PASSABLE]
end
local function scoreRetreatLocation(position, squad, neighborChunk, surface)
local safeScore = neighborChunk[ENEMY_BASE_PHEROMONE]
local dangerScore = neighborChunk[DEATH_PHEROMONE] + surface.get_pollution(position) + neighborChunk[PLAYER_PHEROMONE] + neighborChunk[PLAYER_DEFENSE_PHEROMONE] + (neighborChunk[ENEMY_BASE_GENERATOR] * 6)
return safeScore - dangerScore
end
function aiDefense.retreatUnits(position, squad, regionMap, surface, natives)
local chunk = getChunkByPosition(regionMap, position.x, position.y)
if (chunk ~= nil) and (chunk[DEATH_PHEROMONE] > (game.evolution_factor * RETREAT_DEATH_PHEROMONE_LEVEL)) then
local performRetreat = false
local enemiesToSquad
if (squad == nil) then
enemiesToSquad = surface.find_enemy_units(position, 15)
if (#enemiesToSquad > 1) then
performRetreat = true
end
elseif squad.group.valid and (squad.status ~= SQUAD_RETREATING) and (squad.status ~= SQUAD_SUICIDE_HUNT) and (squad.status ~= SQUAD_SUICIDE_RAID) then
if (#squad.group.members > 1) then
performRetreat = true
end
end
if performRetreat then
local retreatPosition = {x=0, y=0}
local exitPath,_ = scoreNeighborsWithDirection(chunk,
getNeighborChunksWithDirection(regionMap, chunk.cX, chunk.cY),
validRetreatLocation,
scoreRetreatLocation,
nil,
surface,
retreatPosition)
if (exitPath ~= nil) then
-- retreatPosition = positionDirectionToChunkCorner(exitDirection, exitPath)
retreatPosition.x = exitPath.pX + HALF_CHUNK_SIZE
retreatPosition.y = exitPath.pY + HALF_CHUNK_SIZE
-- 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 (newSquad == nil) then
newSquad = createSquad(retreatPosition, surface, natives)
newSquad.status = SQUAD_RETREATING
newSquad.cycles = 6
end
if (enemiesToSquad ~= nil) 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
addSquadMovementPenalty(newSquad, chunk.cX, chunk.cY)
end
end
end
end
return aiDefense