1
0
mirror of https://github.com/veden/Rampant.git synced 2024-12-26 20:54:12 +02:00

Fix for attacked railroads and electric poles

This commit is contained in:
veden 2016-09-14 10:12:29 -07:00
parent 12585b823f
commit 31a3c6213f
9 changed files with 123 additions and 47 deletions

View File

@ -7,6 +7,8 @@ https://forums.factorio.com/viewtopic.php?f=94&t=31445
# Notes # Notes
The 0.14.4 factorio version fixed some issues with unit groups commands
There will be a slight pause the first time this is started up due to indexing all the chunks that have been generated. There will be a slight pause the first time this is started up due to indexing all the chunks that have been generated.
MP should be working MP should be working
@ -30,10 +32,13 @@ Base Expansion
# Version History # Version History
0.14.1 - fixed ai created bases not being counted in logic 0.14.2 - adjusted unit retreat group size threshold
Optimization to offset ai created bases scanning adjusted squad attack pattern (https://forums.factorio.com/viewtopic.php?f=94&t=31445&start=20#p203861) __
0.13.1 - backported 0.14 factorio version to 0.13 factorio version 0.14.1 - fixed ai created bases not being counted in logic
Optimization to offset ai created bases scanning
0.13.1 - backported 0.14 factorio version to 0.13 factorio version
0.0.8 - fixed retreat oscillations (https://forums.factorio.com/viewtopic.php?f=94&t=31445&start=10#p198750) 0.0.8 - fixed retreat oscillations (https://forums.factorio.com/viewtopic.php?f=94&t=31445&start=10#p198750)
added scaling for kamikaze attack (https://forums.factorio.com/viewtopic.php?f=94&t=31445&start=10#p199401) added scaling for kamikaze attack (https://forums.factorio.com/viewtopic.php?f=94&t=31445&start=10#p199401)

View File

@ -1,7 +1,7 @@
{ {
"name" : "Rampant", "name" : "Rampant",
"factorio_version" : "0.14", "factorio_version" : "0.14",
"version" : "0.14.1", "version" : "0.14.2",
"title" : "Rampant AI", "title" : "Rampant AI",
"author" : "Veden", "author" : "Veden",
"homepage" : "https://forums.factorio.com/viewtopic.php?f=94&t=31445", "homepage" : "https://forums.factorio.com/viewtopic.php?f=94&t=31445",

View File

@ -14,7 +14,7 @@ local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
local DEATH_PHEROMONE = constants.DEATH_PHEROMONE local DEATH_PHEROMONE = constants.DEATH_PHEROMONE
local ENEMY_BASE_PHEROMONE = constants.ENEMY_BASE_PHEROMONE local ENEMY_BASE_PHEROMONE = constants.ENEMY_BASE_PHEROMONE
local PLAYER_BASE_PHEROMONE = constants.PLAYER_BASE_PHEROMONE local PLAYER_BASE_PHEROMONE = constants.PLAYER_BASE_PHEROMONE
local PLAYER_DEFENSE_PHEROMONE = constants.PLAYER_DEFENSE_PHEROMONE --local PLAYER_DEFENSE_PHEROMONE = constants.PLAYER_DEFENSE_PHEROMONE
local SQUAD_RAIDING = constants.SQUAD_RAIDING local SQUAD_RAIDING = constants.SQUAD_RAIDING
local SQUAD_SUICIDE_RAID = constants.SQUAD_SUICIDE_RAID local SQUAD_SUICIDE_RAID = constants.SQUAD_SUICIDE_RAID
@ -22,11 +22,11 @@ local SQUAD_HUNTING = constants.SQUAD_HUNTING
local SQUAD_GUARDING = constants.SQUAD_GUARDING local SQUAD_GUARDING = constants.SQUAD_GUARDING
local SQUAD_SUICIDE_HUNT = constants.SQUAD_SUICIDE_HUNT local SQUAD_SUICIDE_HUNT = constants.SQUAD_SUICIDE_HUNT
local ENEMY_BASE_GENERATOR = constants.ENEMY_BASE_GENERATOR --local ENEMY_BASE_GENERATOR = constants.ENEMY_BASE_GENERATOR
local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER --local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER
local HALF_CHUNK_SIZE = constants.HALF_CHUNK_SIZE --local HALF_CHUNK_SIZE = constants.HALF_CHUNK_SIZE
local CHUNK_SIZE = constants.CHUNK_SIZE --local CHUNK_SIZE = constants.CHUNK_SIZE
local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
local PLAYER_DEFENSE_GENERATOR = constants.PLAYER_DEFENSE_GENERATOR local PLAYER_DEFENSE_GENERATOR = constants.PLAYER_DEFENSE_GENERATOR
@ -40,11 +40,13 @@ local addSquadMovementPenalty = unitGroupUtils.addSquadMovementPenalty
local lookupSquadMovementPenalty = unitGroupUtils.lookupSquadMovementPenalty local lookupSquadMovementPenalty = unitGroupUtils.lookupSquadMovementPenalty
local positionFromDirectionAndChunkCardinal = mapUtils.positionFromDirectionAndChunkCardinal local positionFromDirectionAndChunkCardinal = mapUtils.positionFromDirectionAndChunkCardinal
local euclideanDistanceNamed = mapUtils.euclideanDistanceNamed
local playersWithinProximityToPosition = playerUtils.playersWithinProximityToPosition local playersWithinProximityToPosition = playerUtils.playersWithinProximityToPosition
local scoreNeighborsWithDirection = neighborUtils.scoreNeighborsWithDirection local scoreNeighborsWithDirection = neighborUtils.scoreNeighborsWithDirection
local mMax = math.max
-- module code -- module code
@ -66,8 +68,17 @@ local function scoreHuntPlayerLocation(position, squad, neighborChunk, surface)
return damageScore - avoidScore - squadMovementPenalty return damageScore - avoidScore - squadMovementPenalty
end end
function aiAttack.squadAttack(regionMap, surface, natives, temps) function aiAttack.squadAttack(regionMap, surface, natives)
local squads = natives.squads 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
for i=1,#squads do for i=1,#squads do
local squad = squads[i] local squad = squads[i]
local group = squad.group local group = squad.group
@ -82,10 +93,9 @@ function aiAttack.squadAttack(regionMap, surface, natives, temps)
scoreLocation = scoreHuntPlayerLocation scoreLocation = scoreHuntPlayerLocation
end end
if group.valid and (raiding or hunting) then if group.valid and (raiding or hunting) then
if (group.state == defines.group_state.finished) or (group.state == defines.group_state.gathering) 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
local chunk = getChunkByPosition(regionMap, group.position.x, group.position.y) local chunk = getChunkByPosition(regionMap, group.position.x, group.position.y)
if (chunk ~= nil) then if (chunk ~= nil) then
local attackPosition = {x=0, y=0}
addSquadMovementPenalty(squad, chunk.cX, chunk.cY) addSquadMovementPenalty(squad, chunk.cX, chunk.cY)
local attackChunk, attackDirection = scoreNeighborsWithDirection(chunk, local attackChunk, attackDirection = scoreNeighborsWithDirection(chunk,
getCardinalChunksWithDirection(regionMap, chunk.cX, chunk.cY), getCardinalChunksWithDirection(regionMap, chunk.cX, chunk.cY),
@ -98,14 +108,29 @@ function aiAttack.squadAttack(regionMap, surface, natives, temps)
if ((attackChunk[PLAYER_BASE_GENERATOR] == 0) and (attackChunk[PLAYER_DEFENSE_GENERATOR] == 0)) or if ((attackChunk[PLAYER_BASE_GENERATOR] == 0) and (attackChunk[PLAYER_DEFENSE_GENERATOR] == 0)) or
((group.state == defines.group_state.finished) or (group.state == defines.group_state.gathering)) then ((group.state == defines.group_state.finished) or (group.state == defines.group_state.gathering)) then
positionFromDirectionAndChunkCardinal(attackDirection, attackChunk, attackPosition) positionFromDirectionAndChunkCardinal(attackDirection, squad.group.position, attackPosition)
group.set_command({ type = defines.command.attack_area, squad.cycles = 3
destination = attackPosition,
radius = 32, if not squad.rabid and squad.frenzy and (euclideanDistanceNamed(squad.group.position, squad.frenzyPosition) > 100) then
distraction = defines.distraction.by_anything }) 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
group.set_command(attackCmd)
group.start_moving() group.start_moving()
end elseif not squad.frenzy and not squad.rabid and
(((group.state == defines.group_state.attacking_distraction) or (group.state == defines.group_state.attacking_distraction)) or
(attackChunk[PLAYER_BASE_GENERATOR] ~= 0) or (attackChunk[PLAYER_DEFENSE_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
@ -119,9 +144,16 @@ function aiAttack.squadBeginAttack(natives, players, evolution_factor)
local squad = squads[i] local squad = squads[i]
if (squad.status == SQUAD_GUARDING) and squad.group.valid then if (squad.status == SQUAD_GUARDING) and squad.group.valid then
local threshold = 0.05 + (evolution_factor * 0.20) + (#squad.group.members * 0.0033) local threshold = 0.05 + (evolution_factor * 0.20) + (#squad.group.members * 0.0033)
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
-- check to hunt player -- check to hunt player
if (math.random() < 0.30) and playersWithinProximityToPosition(players, squad.group.position, 100) then if (math.random() < 0.30) and playerNearby then
if (math.random() < threshold) then if (math.random() < threshold) then
squad.status = SQUAD_SUICIDE_HUNT squad.status = SQUAD_SUICIDE_HUNT
else else
@ -131,7 +163,7 @@ function aiAttack.squadBeginAttack(natives, players, evolution_factor)
-- check to raid base -- check to raid base
if (squad.status == SQUAD_GUARDING) and (math.random() < 0.70) then if (squad.status == SQUAD_GUARDING) and (math.random() < 0.70) then
if (math.random() < threshold) then if (math.random() < threshold) then
squad.status = SQUAD_SUICIDE_RAID squad.status = SQUAD_SUICIDE_RAID
else else
squad.status = SQUAD_RAIDING squad.status = SQUAD_RAIDING

View File

@ -128,12 +128,16 @@ function aiBuilding.formSquads(regionMap, surface, natives, chunk, evolution_fac
squadPosition.y = squadPath.pY + HALF_CHUNK_SIZE squadPosition.y = squadPath.pY + HALF_CHUNK_SIZE
local squad = createSquad(squadPosition, surface, natives) local squad = createSquad(squadPosition, surface, natives)
if (math.random() < 0.05) then
squad.rabid = true
end
local foundUnits = surface.set_multi_command({ command = { type = defines.command.group, local foundUnits = surface.set_multi_command({ command = { type = defines.command.group,
group = squad.group, group = squad.group,
distraction = defines.distraction.none }, distraction = defines.distraction.none },
unit_count = evolution_factor * AI_MAX_SQUAD_SIZE, unit_count = evolution_factor * AI_MAX_SQUAD_SIZE,
unit_search_distance = (constants.CHUNK_SIZE * 2)}) unit_search_distance = (CHUNK_SIZE * 2)})
if (foundUnits > 0) then if (foundUnits > 0) then
natives.points = natives.points - AI_SQUAD_COST natives.points = natives.points - AI_SQUAD_COST
end end

View File

@ -58,11 +58,11 @@ function aiDefense.retreatUnits(position, squad, regionMap, surface, natives)
if (squad == nil) then if (squad == nil) then
enemiesToSquad = surface.find_enemy_units(position, 15) enemiesToSquad = surface.find_enemy_units(position, 15)
if (#enemiesToSquad > 0) then if (#enemiesToSquad > 1) then
performRetreat = true performRetreat = true
end end
elseif squad.group.valid and (squad.status ~= SQUAD_RETREATING) and (squad.status ~= SQUAD_SUICIDE_HUNT) and (squad.status ~= SQUAD_SUICIDE_RAID) then 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 ~= 0) then if (#squad.group.members > 1) then
performRetreat = true performRetreat = true
end end
end end
@ -90,13 +90,16 @@ function aiDefense.retreatUnits(position, squad, regionMap, surface, natives)
if (newSquad == nil) then if (newSquad == nil) then
newSquad = createSquad(retreatPosition, surface, natives) newSquad = createSquad(retreatPosition, surface, natives)
newSquad.status = SQUAD_RETREATING newSquad.status = SQUAD_RETREATING
newSquad.cycles = 4 newSquad.cycles = 6
end end
if (enemiesToSquad ~= nil) then if (enemiesToSquad ~= nil) then
membersToSquad(newSquad, enemiesToSquad, false) membersToSquad(newSquad, enemiesToSquad, false)
else else
membersToSquad(newSquad, squad.group.members, true) membersToSquad(newSquad, squad.group.members, true)
if squad.rabid then
newSquad.rabid = true
end
end end
end end
end end

View File

@ -105,7 +105,7 @@ constants.BUILDING_PHEROMONES["offshore-pump"] = 8
-- constants.buildingPheromones["constant-combinator"] = 1 -- constants.buildingPheromones["constant-combinator"] = 1
-- constants.buildingPheromones["train-stop"] = 2 -- constants.buildingPheromones["train-stop"] = 2
-- constants.buildingPheromones["rail-signal"] = 1 -- constants.buildingPheromones["rail-signal"] = 1
constants.BUILDING_PHEROMONES["electric-pole"] = 4 -- constants.BUILDING_PHEROMONES["electric-pole"] = 4
constants.BUILDING_PHEROMONES["transport-belt"] = 4 constants.BUILDING_PHEROMONES["transport-belt"] = 4
constants.BUILDING_PHEROMONES["accumulator"] = 40 constants.BUILDING_PHEROMONES["accumulator"] = 40
constants.BUILDING_PHEROMONES["solar-panel"] = 32 constants.BUILDING_PHEROMONES["solar-panel"] = 32

View File

@ -188,24 +188,43 @@ function mapUtils.canMoveChunkDirectionCardinal(direction, startChunk, endChunk)
return canMove return canMove
end end
function mapUtils.positionFromDirectionAndChunkCardinal(direction, chunk, position) function mapUtils.positionFromDirectionAndChunkCardinal(direction, startPosition, position)
-- local position = {x=0,y=0} -- local position = {x=0,y=0}
if (direction == 1) then if (direction == 1) then
position.x = chunk.pX + HALF_CHUNK_SIZE position.x = startPosition.x
position.y = chunk.pY position.y = startPosition.y - CHUNK_SIZE
elseif (direction == 2) then elseif (direction == 2) then
position.x = chunk.pX position.x = startPosition.x - CHUNK_SIZE
position.y = chunk.pY + HALF_CHUNK_SIZE position.y = startPosition.y
elseif (direction == 3) then elseif (direction == 3) then
position.x = chunk.pX + CHUNK_SIZE position.x = startPosition.x + CHUNK_SIZE
position.y = chunk.pY + HALF_CHUNK_SIZE position.y = startPosition.y
elseif (direction == 4) then elseif (direction == 4) then
position.x = chunk.pX + HALF_CHUNK_SIZE position.x = startPosition.x
position.y = chunk.pY + CHUNK_SIZE position.y = startPosition.y + CHUNK_SIZE
end end
-- return position -- return position
end end
-- function mapUtils.positionFromDirectionAndChunkCardinal(direction, chunk, position)
-- -- local position = {x=0,y=0}
-- if (direction == 1) then
-- position.x = chunk.pX + HALF_CHUNK_SIZE
-- position.y = chunk.pY
-- elseif (direction == 2) then
-- position.x = chunk.pX
-- position.y = chunk.pY + HALF_CHUNK_SIZE
-- elseif (direction == 3) then
-- position.x = chunk.pX + CHUNK_SIZE
-- position.y = chunk.pY + HALF_CHUNK_SIZE
-- elseif (direction == 4) then
-- position.x = chunk.pX + HALF_CHUNK_SIZE
-- position.y = chunk.pY + CHUNK_SIZE
-- end
-- -- return position
-- end
function mapUtils.positionFromDirectionAndChunk(direction, chunk) function mapUtils.positionFromDirectionAndChunk(direction, chunk)
local position = {x=0, y=0} local position = {x=0, y=0}
if (direction == 1) then if (direction == 1) then

View File

@ -41,6 +41,10 @@ function unitGroupUtils.createSquad(position, surface, natives)
local squad = { group = unitGroup, local squad = { group = unitGroup,
status = SQUAD_GUARDING, status = SQUAD_GUARDING,
penalties = {}, penalties = {},
rabid = false,
frenzy = false,
frenzyPosition = {x = 0,
y = 0},
cycles = 0 } cycles = 0 }
natives.squads[#natives.squads+1] = squad natives.squads[#natives.squads+1] = squad
return squad return squad
@ -48,12 +52,13 @@ end
function unitGroupUtils.membersToSquad(squad, members, overwriteGroup) function unitGroupUtils.membersToSquad(squad, members, overwriteGroup)
if (members ~= nil) then if (members ~= nil) then
local cmd = { type = defines.command.group,
group = squad.group,
distraction = defines.distraction.none }
for i=1,#members do for i=1,#members do
local member = members[i] local member = members[i]
if member.valid and (overwriteGroup or (not overwriteGroup and (member.unit_group == nil))) then if member.valid and (overwriteGroup or (not overwriteGroup and (member.unit_group == nil))) then
member.set_command({ type = defines.command.group, member.set_command(cmd)
group = squad.group,
distraction = defines.distraction.none })
end end
end end
end end
@ -72,6 +77,10 @@ function unitGroupUtils.convertUnitGroupToSquad(natives, unitGroup)
returnSquad = { group = unitGroup, returnSquad = { group = unitGroup,
status = SQUAD_GUARDING, status = SQUAD_GUARDING,
penalties = {}, penalties = {},
rabid = false,
frenzy = false,
frenzyPosition = {x = 0,
y = 0},
cycles = 0 } cycles = 0 }
squads[#squads+1] = returnSquad squads[#squads+1] = returnSquad
end end
@ -134,9 +143,13 @@ function unitGroupUtils.regroupSquads(natives)
squad.group.destroy() squad.group.destroy()
tableRemove(squads, i) tableRemove(squads, i)
else else
if (squad.status == SQUAD_RETREATING) and ((squad.cycles == 0) or (squad.group.state == GROUP_STATE_FINISHED)) then if (squad.status == SQUAD_RETREATING) and (squad.cycles == 0) then
squad.status = SQUAD_GUARDING squad.status = SQUAD_GUARDING
squad.cycles = 0 squad.frenzy = true
squad.frenzyPosition.x = squad.group.position.x
squad.frenzyPosition.y = squad.group.position.y
elseif (squad.group.state == GROUP_STATE_FINISHED) then
squad.status = SQUAD_GUARDING
elseif (squad.cycles > 0) then elseif (squad.cycles > 0) then
squad.cycles = squad.cycles - 1 squad.cycles = squad.cycles - 1
end end

View File

@ -73,7 +73,7 @@
(copyDirectory "graphics" modFolder) (copyDirectory "graphics" modFolder)
(copyDirectory "prototypes" modFolder))) (copyDirectory "prototypes" modFolder)))
; (copyFiles modFolder) (copyFiles modFolder)
; (copyFiles zipModFolder) ; (copyFiles zipModFolder)
(makeZip) ; (makeZip)
) )