1
0
mirror of https://github.com/veden/Rampant.git synced 2025-01-03 22:52:20 +02:00
Rampant/libs/AIAttack.lua

150 lines
6.2 KiB
Lua
Raw Normal View History

local aiAttack = {}
-- imports
local constants = require("Constants")
local mapUtils = require("MapUtils")
local unitGroupUtils = require("UnitGroupUtils")
local playerUtils = require("PlayerUtils")
local neighborUtils = require("NeighborUtils")
2016-10-15 02:00:18 +02:00
package.path = "../?.lua;" .. package.path
local config = require("config")
-- constants
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
2016-10-15 02:00:18 +02:00
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
local BASE_PHEROMONE = constants.BASE_PHEROMONE
local SQUAD_RAIDING = constants.SQUAD_RAIDING
local SQUAD_SUICIDE_RAID = constants.SQUAD_SUICIDE_RAID
local SQUAD_GUARDING = constants.SQUAD_GUARDING
2016-10-15 02:00:18 +02:00
local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
2016-10-15 02:00:18 +02:00
local NO_RETREAT_BASE_PERCENT = constants.NO_RETREAT_BASE_PERCENT
local NO_RETREAT_EVOLUTION_BONUS_MAX = constants.NO_RETREAT_EVOLUTION_BONUS_MAX
local NO_RETREAT_SQUAD_SIZE_BONUS_MAX = constants.NO_RETREAT_SQUAD_SIZE_BONUS_MAX
2016-10-15 02:00:18 +02:00
local CONFIG_ATTACK_WAVE_MAX_SIZE = config.attackWaveMaxSize
-- imported functions
2016-08-26 00:20:06 +02:00
local getCardinalChunksWithDirection = mapUtils.getCardinalChunksWithDirection
2016-08-28 02:57:20 +02:00
local getChunkByPosition = mapUtils.getChunkByPosition
local canMoveChunkDirectionCardinal = mapUtils.canMoveChunkDirectionCardinal
local addSquadMovementPenalty = unitGroupUtils.addSquadMovementPenalty
local lookupSquadMovementPenalty = unitGroupUtils.lookupSquadMovementPenalty
local positionFromDirectionAndChunkCardinal = mapUtils.positionFromDirectionAndChunkCardinal
local euclideanDistanceNamed = mapUtils.euclideanDistanceNamed
local playersWithinProximityToPosition = playerUtils.playersWithinProximityToPosition
local scoreNeighborsWithDirection = neighborUtils.scoreNeighborsWithDirection
2016-10-15 02:00:18 +02:00
local mLog = math.log10
2016-08-28 02:57:20 +02:00
-- module code
local function validLocation(x, chunk, neighborChunk)
2016-08-28 02:57:20 +02:00
return canMoveChunkDirectionCardinal(x, chunk, neighborChunk)
end
local function scoreAttackLocation(position, squad, neighborChunk, surface)
local squadMovementPenalty = lookupSquadMovementPenalty(squad, neighborChunk.cX, neighborChunk.cY)
2016-10-15 02:00:18 +02:00
local r = surface.get_pollution(position) + neighborChunk[MOVEMENT_PHEROMONE] + neighborChunk[BASE_PHEROMONE] + neighborChunk[PLAYER_PHEROMONE]
return r - squadMovementPenalty
end
function aiAttack.squadAttack(regionMap, surface, natives)
2016-08-26 00:20:06 +02:00
local squads = natives.squads
local attackPosition
local attackCmd
if (#squads > 0) then
attackPosition = {x=0, y=0}
attackCmd = { type = defines.command.attack_area,
destination = attackPosition,
radius = 16,
distraction = defines.distraction.by_enemy }
end
2016-08-26 00:20:06 +02:00
for i=1,#squads do
local squad = squads[i]
local group = squad.group
2016-10-15 02:00:18 +02:00
if group.valid and ((squad.status == SQUAD_RAIDING) or (squad.status == SQUAD_SUICIDE_RAID)) then
if (group.state == defines.group_state.finished) or (group.state == defines.group_state.gathering) or ((group.state == defines.group_state.moving) and (squad.cycles == 0)) then
2016-08-28 02:57:20 +02:00
local chunk = getChunkByPosition(regionMap, group.position.x, group.position.y)
if (chunk ~= nil) then
addSquadMovementPenalty(squad, chunk.cX, chunk.cY)
local attackChunk, attackDirection = scoreNeighborsWithDirection(chunk,
getCardinalChunksWithDirection(regionMap, chunk.cX, chunk.cY),
validLocation,
2016-10-15 02:00:18 +02:00
scoreAttackLocation,
squad,
surface,
attackPosition)
if (attackChunk ~= nil) then
2016-10-15 02:00:18 +02:00
if (attackChunk[PLAYER_BASE_GENERATOR] == 0) or
((group.state == defines.group_state.finished) or (group.state == defines.group_state.gathering)) then
2016-10-15 02:00:18 +02:00
positionFromDirectionAndChunkCardinal(attackDirection, squad.group.position, attackPosition)
squad.cycles = 3
if not squad.rabid and squad.frenzy and (euclideanDistanceNamed(squad.group.position, squad.frenzyPosition) > 100) then
squad.frenzy = false
end
if squad.rabid or squad.frenzy then
attackCmd.distraction = defines.distraction.by_anything
else
attackCmd.distraction = defines.distraction.by_enemy
end
2016-10-15 02:00:18 +02:00
group.set_command(attackCmd)
group.start_moving()
elseif not squad.frenzy and not squad.rabid and
2016-10-15 02:00:18 +02:00
((group.state == defines.group_state.attacking_distraction) or (group.state == defines.group_state.attacking_distraction) or
(attackChunk[PLAYER_BASE_GENERATOR] ~= 0)) then
squad.frenzy = true
squad.frenzyPosition.x = squad.group.position.x
squad.frenzyPosition.y = squad.group.position.y
end
end
end
end
end
end
end
function aiAttack.squadBeginAttack(natives, players, evolution_factor)
2016-08-26 00:20:06 +02:00
local squads = natives.squads
for i=1,#squads do
local squad = squads[i]
if (squad.status == SQUAD_GUARDING) and squad.group.valid then
2016-10-15 02:00:18 +02:00
local threshold = NO_RETREAT_BASE_PERCENT + (evolution_factor * NO_RETREAT_EVOLUTION_BONUS_MAX)
local a = (#squad.group.members / CONFIG_ATTACK_WAVE_MAX_SIZE) ^ 1.4
local squadSizeBonus = mLog(a + 0.1) + 1
threshold = threshold + (NO_RETREAT_SQUAD_SIZE_BONUS_MAX * squadSizeBonus)
local playerNearby = playersWithinProximityToPosition(players, squad.group.position, 100)
if playerNearby then
squad.frenzy = true
squad.frenzyPosition.x = squad.group.position.x
squad.frenzyPosition.y = squad.group.position.y
end
2016-10-15 02:00:18 +02:00
-- check to raid base
if (math.random() < 0.70) then
if (math.random() < threshold) then
2016-10-15 02:00:18 +02:00
squad.status = SQUAD_SUICIDE_RAID
else
squad.status = SQUAD_RAIDING
end
end
end
end
end
return aiAttack