1
0
mirror of https://github.com/veden/Rampant.git synced 2025-01-20 02:59:47 +02:00
Rampant/libs/AIAttack.lua
2017-05-26 22:56:45 -07:00

170 lines
6.4 KiB
Lua

local aiAttack = {}
-- imports
local constants = require("Constants")
local mapUtils = require("MapUtils")
local unitGroupUtils = require("UnitGroupUtils")
local playerUtils = require("PlayerUtils")
local neighborUtils = require("NeighborUtils")
-- constants
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
local BASE_PHEROMONE = constants.BASE_PHEROMONE
local SQUAD_RAIDING = constants.SQUAD_RAIDING
local SQUAD_GUARDING = constants.SQUAD_GUARDING
local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
local DEFINES_GROUP_FINISHED = defines.group_state.finished
local DEFINES_GROUP_GATHERING = defines.group_state.gathering
local DEFINES_GROUP_MOVING = defines.group_state.moving
local DEFINES_GROUP_ATTACKING_DISTRACTION = defines.group_state.attacking_distraction
local DEFINES_GROUP_ATTACKING_TARGET = defines.group_state.attacking_target
local DEFINES_DISTRACTION_BY_ENEMY = defines.distraction.by_enemy
local DEFINES_DISTRACTION_BY_ANYTHING = defines.distraction.by_anything
-- imported functions
local getNeighborChunksWithDirection = mapUtils.getNeighborChunksWithDirection
local getChunkByPosition = mapUtils.getChunkByPosition
local canMoveChunkDirection = mapUtils.canMoveChunkDirection
local addSquadMovementPenalty = unitGroupUtils.addSquadMovementPenalty
local lookupSquadMovementPenalty = unitGroupUtils.lookupSquadMovementPenalty
local calculateKamikazeThreshold = unitGroupUtils.calculateKamikazeThreshold
local positionFromDirectionAndChunk = mapUtils.positionFromDirectionAndChunk
local euclideanDistanceNamed = mapUtils.euclideanDistanceNamed
local playersWithinProximityToPosition = playerUtils.playersWithinProximityToPosition
local scoreNeighborsWithDirection = neighborUtils.scoreNeighborsWithDirection
-- module code
local function validLocation(x, chunk, neighborChunk)
return canMoveChunkDirection(x, chunk, neighborChunk)
end
local function scoreAttackLocation(position, squad, neighborChunk, surface)
local squadMovementPenalty = lookupSquadMovementPenalty(squad, neighborChunk.cX, neighborChunk.cY)
local r = surface.get_pollution(position) + neighborChunk[MOVEMENT_PHEROMONE] + neighborChunk[BASE_PHEROMONE] + (neighborChunk[PLAYER_PHEROMONE] * 25) --- neighborChunk[ENEMY_BASE_GENERATOR]
return r - squadMovementPenalty
end
function aiAttack.squadAttack(regionMap, surface, natives)
local squads = natives.squads
local attackPosition
local attackCmd
--[[
Constants populated by the factorio runtime
--]]
-- local DEFINES_GROUP_FINISHED
-- local DEFINES_GROUP_GATHERING
-- local DEFINES_GROUP_MOVING
-- local DEFINES_GROUP_ATTACKING_DISTRACTION
-- local DEFINES_GROUP_ATTACKING_TARGET
-- local DEFINES_DISTRACTION_BY_ENEMY
-- local DEFINES_DISTRACTION_BY_ANYTHING
if (#squads > 0) then
-- DEFINES_GROUP_FINISHED = defines.group_state.finished
-- DEFINES_GROUP_GATHERING = defines.group_state.gathering
-- DEFINES_GROUP_MOVING = defines.group_state.moving
-- DEFINES_GROUP_ATTACKING_DISTRACTION = defines.group_state.attacking_distraction
-- DEFINES_GROUP_ATTACKING_TARGET = defines.group_state.attacking_target
-- DEFINES_DISTRACTION_BY_ENEMY = defines.distraction.by_enemy
-- DEFINES_DISTRACTION_BY_ANYTHING = defines.distraction.by_anything
attackPosition = {x=0, y=0}
attackCmd = { type = defines.command.attack_area,
destination = attackPosition,
radius = 28,
distraction = DEFINES_DISTRACTION_BY_ENEMY }
end
for i=1,#squads do
local squad = squads[i]
local group = squad.group
if group.valid and (squad.status == SQUAD_RAIDING) then
local groupState = group.state
if (groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING) or ((groupState == DEFINES_GROUP_MOVING) and (squad.cycles == 0)) then
local groupPosition = group.position
local chunk = getChunkByPosition(regionMap, groupPosition.x, groupPosition.y)
if chunk then
local attackChunk, attackDirection = scoreNeighborsWithDirection(chunk,
getNeighborChunksWithDirection(regionMap, chunk.cX, chunk.cY),
validLocation,
scoreAttackLocation,
squad,
surface,
attackPosition,
true)
addSquadMovementPenalty(squad, chunk.cX, chunk.cY)
if attackChunk then
if (attackChunk[PLAYER_BASE_GENERATOR] == 0) or
((groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING)) then
positionFromDirectionAndChunk(attackDirection, groupPosition, attackPosition)
if (#squad.group.members > 80) then
squad.cycles = 6
else
squad.cycles = 4
end
local outsideFrenzyRadius = not squad.rabid and squad.frenzy and (euclideanDistanceNamed(groupPosition, squad.frenzyPosition) > 100)
squad.frenzy = not outsideFrenzyRadius
if squad.rabid or squad.frenzy then
attackCmd.distraction = DEFINES_DISTRACTION_BY_ANYTHING
else
attackCmd.distraction = DEFINES_DISTRACTION_BY_ENEMY
end
group.set_command(attackCmd)
group.start_moving()
elseif not squad.frenzy and not squad.rabid and
((groupState == DEFINES_GROUP_ATTACKING_DISTRACTION) or (groupState == DEFINES_GROUP_ATTACKING_TARGET) or
(attackChunk[PLAYER_BASE_GENERATOR] ~= 0)) then
squad.frenzy = true
squad.frenzyPosition.x = groupPosition.x
squad.frenzyPosition.y = groupPosition.y
end
end
end
end
end
end
end
function aiAttack.squadBeginAttack(natives, players, evolution_factor)
local squads = natives.squads
for i=1,#squads do
local squad = squads[i]
if (squad.status == SQUAD_GUARDING) and squad.group.valid then
local kamikazeThreshold = calculateKamikazeThreshold(squad, natives, evolution_factor)
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
if (math.random() < 0.70) then
if (math.random() < kamikazeThreshold) then
squad.kamikaze = true
end
squad.status = SQUAD_RAIDING
end
end
end
end
return aiAttack