1
0
mirror of https://github.com/veden/Rampant.git synced 2025-01-30 04:30:52 +02:00

added configuration parameters, updated attack frequeny, update ramp up

This commit is contained in:
Aaron Veden 2016-10-07 07:30:31 -07:00
parent 36a6e4da33
commit 3a52b5322a
10 changed files with 161 additions and 86 deletions

View File

@ -7,7 +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 0.14.10 factorio version fixed more pathing issues
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.
@ -32,6 +33,14 @@ Base Expansion
# Version History # Version History
0.14.3 - slightly lowered Rampant attack wave frequency
Altered attack wave size to ramp up slower
Added configuration options for:
attack wave generation area
attack wave threshold
attack wave size
turn off rampant attack waves
0.14.2 - adjusted unit retreat group size threshold 0.14.2 - adjusted unit retreat group size threshold
adjusted squad attack pattern (https://forums.factorio.com/viewtopic.php?f=94&t=31445&start=20#p203861) adjusted squad attack pattern (https://forums.factorio.com/viewtopic.php?f=94&t=31445&start=20#p203861)
Fixed migration issue Fixed migration issue
@ -39,6 +48,8 @@ Base Expansion
0.14.1 - fixed ai created bases not being counted in logic 0.14.1 - fixed ai created bases not being counted in logic
Optimization to offset ai created bases scanning Optimization to offset ai created bases scanning
0.13.3 = 0.14.3
0.13.2 = 0.14.2 0.13.2 = 0.14.2
0.13.1 - backported 0.14 factorio version to 0.13 factorio version 0.13.1 - backported 0.14 factorio version to 0.13 factorio version

View File

@ -0,0 +1,34 @@
local config = {}
--[[
the attackWaveGenerationUse* options are used to score chunks with biter nests that will generate a Rampant attack wave.
Pollution, the vanilla pollution mechanic (shown on the minimap).
Player Proximity, if a player moves near a biter nest there is a chance for the nest to spawn attack waves (not shown on the minimap).
Player Base Proximity, if the player builds near biters nest there is a chance for the nest to spawn attack waves (not shown on the minimap).
Player Defense Proximity, if the player builds defense near biters nest there is a chance for the nest to spawn attack waves (not shown on the minimap).
switching all to false will turn off Rampant biter waves, does not turn off vanilla biter waves.
--]]
config.attackWaveGenerationUsePollution = true
config.attackWaveGenerationUsePlayerProximity = true
config.attackWaveGenerationUsePlayerBaseProximity = true
config.attackWaveGenerationUsePlayerDefenseProximity = true
--[[
attackWaveGenerationThreshold is the score that the attackWaveGenerationUse* has to reach in order for an attack wave to spawn.
increasing this will reduce the radius of attack wave generation.
default number is 70
--]]
config.attackWaveGenerationThreshold = 70
--[[
attackWaveScaling is used to calculate the attack wave size from the evolutionFactor
default is 150 * (evolutionFactor ^ 1.666667)
150 is the max group size
--]]
config.attackWaveScaling = function (evolutionFactor)
return math.ceil(150 * (evolutionFactor ^ 1.666667))
end
return config

View File

@ -39,7 +39,6 @@ local addRemoveEntity = entityUtils.addRemoveEntity
local regionMap local regionMap
local natives local natives
-- local pheromoneTotals
local pendingChunks local pendingChunks
-- hook functions -- hook functions
@ -49,7 +48,7 @@ local function onLoad()
regionMap = global.regionMap regionMap = global.regionMap
natives = global.natives natives = global.natives
pendingChunks = global.pendingChunks pendingChunks = global.pendingChunks
-- pheromoneTotals = global.pheromoneTotals -- pheromoneTotals = global.pheromoneTotals
end end
local function onChunkGenerated(event) local function onChunkGenerated(event)

View File

@ -1,10 +1,8 @@
if RampantConfig == nil then -- local config = require("config")
RampantConfig = {}
end
require("prototypes/buildings/tunnel") require("prototypes/buildings/tunnel")
require("prototypes/tile/fillableDirt") require("prototypes/tile/fillableDirt")
require("prototypes/enemies/suicideBiters") require("prototypes/enemies/suicideBiters")
require("prototypes/enemies/fireSpitters") require("prototypes/enemies/fireSpitters")

View File

@ -1,7 +1,7 @@
{ {
"name" : "Rampant", "name" : "Rampant",
"factorio_version" : "0.14", "factorio_version" : "0.14",
"version" : "0.14.2", "version" : "0.14.3",
"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

@ -6,50 +6,80 @@ local constants = require("Constants")
local mapUtils = require("MapUtils") local mapUtils = require("MapUtils")
local unitGroupUtils = require("UnitGroupUtils") local unitGroupUtils = require("UnitGroupUtils")
local neighborUtils = require("NeighborUtils") local neighborUtils = require("NeighborUtils")
package.path = "../?.lua;" .. package.path
local config = require("config")
-- constants -- constants
local SQUAD_GUARDING = constants.SQUAD_GUARDING -- local SQUAD_GUARDING = constants.SQUAD_GUARDING
local SQUAD_BURROWING = constants.SQUAD_BURROWING -- local SQUAD_BURROWING = constants.SQUAD_BURROWING
local PLAYER_BASE_PHEROMONE = constants.PLAYER_BASE_PHEROMONE local PLAYER_BASE_PHEROMONE = constants.PLAYER_BASE_PHEROMONE
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
local PLAYER_DEFENSE_PHEROMONE = constants.PLAYER_DEFENSE_PHEROMONE local PLAYER_DEFENSE_PHEROMONE = constants.PLAYER_DEFENSE_PHEROMONE
local ENEMY_BASE_PHEROMONE = constants.ENEMY_BASE_PHEROMONE -- local ENEMY_BASE_PHEROMONE = constants.ENEMY_BASE_PHEROMONE
local DEATH_PHEROMONE = constants.DEATH_PHEROMONE local DEATH_PHEROMONE = constants.DEATH_PHEROMONE
local AI_POINT_GENERATOR_AMOUNT = constants.AI_POINT_GENERATOR_AMOUNT local AI_POINT_GENERATOR_AMOUNT = constants.AI_POINT_GENERATOR_AMOUNT
local AI_MAX_POINTS = constants.AI_MAX_POINTS
local ENEMY_BASE_GENERATOR = constants.ENEMY_BASE_GENERATOR local ENEMY_BASE_GENERATOR = constants.ENEMY_BASE_GENERATOR
local AI_SCOUT_COST = constants.AI_SCOUT_COST -- local AI_SCOUT_COST = constants.AI_SCOUT_COST
local AI_SQUAD_COST = constants.AI_SQUAD_COST local AI_SQUAD_COST = constants.AI_SQUAD_COST
local AI_TUNNEL_COST = constants.AI_TUNNEL_COST -- local AI_TUNNEL_COST = constants.AI_TUNNEL_COST
local AI_MAX_SQUAD_COUNT = constants.AI_MAX_SQUAD_COUNT local AI_MAX_SQUAD_COUNT = constants.AI_MAX_SQUAD_COUNT
local AI_MAX_SQUAD_SIZE = constants.AI_MAX_SQUAD_SIZE
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 MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER -- local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER
local NORTH_SOUTH_PASSABLE = constants.NORTH_SOUTH_PASSABLE local NORTH_SOUTH_PASSABLE = constants.NORTH_SOUTH_PASSABLE
local EAST_WEST_PASSABLE = constants.EAST_WEST_PASSABLE local EAST_WEST_PASSABLE = constants.EAST_WEST_PASSABLE
local COMMAND_GROUP = defines.command.group -- local COMMAND_GROUP = defines.command.group
local DISTRACTION_BY_DAMAGE = defines.distraction.by_damage -- local DISTRACTION_BY_DAMAGE = defines.distraction.by_damage
local CONFIG_USE_PLAYER_PROXIMITY = config.attackWaveGenerationUsePlayerProximity
local CONFIG_USE_PLAYER_BASE_PROXIMITY = config.attackWaveGenerationUsePlayerBaseProximity
local CONFIG_USE_PLAYER_DEFENSE_PROXIMITY = config.attackWaveGenerationUsePlayerDefenseProximity
local CONFIG_USE_POLLUTION_PROXIMITY = config.attackWaveGenerationUsePollution
local CONFIG_USE_THRESHOLD = config.attackWaveGenerationThreshold
-- imported functions -- imported functions
local getNeighborChunks = mapUtils.getNeighborChunks local getNeighborChunks = mapUtils.getNeighborChunks
local scoreNeighbors = neighborUtils.scoreNeighbors local scoreNeighbors = neighborUtils.scoreNeighbors
local createSquad = unitGroupUtils.createSquad local createSquad = unitGroupUtils.createSquad
local attackWaveScaling = config.attackWaveScaling
local tableRemove = table.remove
-- module code -- module code
local function attackWaveValidCandidate(chunk, surface)
local total = 0;
if CONFIG_USE_PLAYER_PROXIMITY then
total = total + chunk[PLAYER_PHEROMONE]
end
if CONFIG_USE_PLAYER_BASE_PROXIMITY then
total = total + chunk[PLAYER_BASE_PHEROMONE]
end
if CONFIG_USE_PLAYER_DEFENSE_PROXIMITY then
total = total + chunk[PLAYER_DEFENSE_PHEROMONE]
end
if CONFIG_USE_POLLUTION_PROXIMITY then
total = total + surface.get_pollution({chunk.pX, chunk.pY})
end
if (total >= CONFIG_USE_THRESHOLD) then
return true
else
return false
end
end
local function scoreUnitGroupLocation(position, squad, neighborChunk, surface) local function scoreUnitGroupLocation(position, squad, neighborChunk, surface)
local attackScore = surface.get_pollution(position) + neighborChunk[PLAYER_PHEROMONE] + neighborChunk[PLAYER_DEFENSE_PHEROMONE] local attackScore = surface.get_pollution(position) + neighborChunk[PLAYER_PHEROMONE] + neighborChunk[PLAYER_DEFENSE_PHEROMONE]
local avoidScore = neighborChunk[DEATH_PHEROMONE] local avoidScore = neighborChunk[DEATH_PHEROMONE]
@ -61,88 +91,91 @@ local function validUnitGroupLocation(x, chunk, neighborChunk)
end end
function aiBuilding.accumulatePoints(natives) function aiBuilding.accumulatePoints(natives)
natives.points = natives.points + AI_POINT_GENERATOR_AMOUNT if (natives.points < AI_MAX_POINTS) then
natives.points = natives.points + math.floor(AI_POINT_GENERATOR_AMOUNT * math.random())
end
end end
function aiBuilding.removeScout(entity, natives) function aiBuilding.removeScout(entity, natives)
--[[ --[[
local scouts = natives.scouts local scouts = natives.scouts
for i=1, #scouts do for i=1, #scouts do
local scout = scouts[i] local scout = scouts[i]
if (scout == entity) then if (scout == entity) then
tableRemove(scouts, i) tableRemove(scouts, i)
return return
end end
end end
--]] --]]
end end
function aiBuilding.makeScouts(surface, natives, chunk, evolution_factor) function aiBuilding.makeScouts(surface, natives, chunk, evolution_factor)
--[[ --[[
if (natives.points > AI_SCOUT_COST) then if (natives.points > AI_SCOUT_COST) then
if (#global.natives.scouts < 5) and (math.random() < 0.05) then -- TODO scaled with evolution factor if (#global.natives.scouts < 5) and (math.random() < 0.05) then -- TODO scaled with evolution factor
local enemy = surface.find_nearest_enemy({ position = { x = chunk.pX + HALF_CHUNK_SIZE, local enemy = surface.find_nearest_enemy({ position = { x = chunk.pX + HALF_CHUNK_SIZE,
y = chunk.pY + HALF_CHUNK_SIZE }, y = chunk.pY + HALF_CHUNK_SIZE },
max_distance = 100}) max_distance = 100})
if (enemy ~= nil) and enemy.valid and (enemy.type == "unit") then if (enemy ~= nil) and enemy.valid and (enemy.type == "unit") then
natives.points = natives.points - AI_SCOUT_COST natives.points = natives.points - AI_SCOUT_COST
global.natives.scouts[#global.natives.scouts+1] = enemy global.natives.scouts[#global.natives.scouts+1] = enemy
-- print(enemy, enemy.unit_number) -- print(enemy, enemy.unit_number)
end end
end end
end end
--]] --]]
end end
function aiBuilding.scouting(regionMap, natives) function aiBuilding.scouting(regionMap, natives)
--[[ --[[
local scouts = natives.scouts local scouts = natives.scouts
for i=1,#scouts do for i=1,#scouts do
local scout = scouts[i] local scout = scouts[i]
if scout.valid then if scout.valid then
scout.set_command({type=defines.command.attack_area, scout.set_command({type=defines.command.attack_area,
destination={0,0}, destination={0,0},
radius=32, radius=32,
distraction=defines.distraction.none}) distraction=defines.distraction.none})
end end
end end
--]] --]]
end end
function aiBuilding.formSquads(regionMap, surface, natives, chunk, evolution_factor) function aiBuilding.formSquads(regionMap, surface, natives, chunk, evolution_factor)
if (natives.points > AI_SQUAD_COST) then if (natives.points > AI_SQUAD_COST) and (chunk[ENEMY_BASE_GENERATOR] ~= 0) and (#natives.squads < (AI_MAX_SQUAD_COUNT * evolution_factor)) then
local score = chunk[PLAYER_BASE_PHEROMONE] + chunk[PLAYER_PHEROMONE] + chunk[PLAYER_DEFENSE_PHEROMONE] + surface.get_pollution({chunk.pX, chunk.pY}) local valid = attackWaveValidCandidate(chunk, surface)
if (score > 70) and (chunk[ENEMY_BASE_GENERATOR] ~= 0) and (#natives.squads < (AI_MAX_SQUAD_COUNT * evolution_factor)) and (math.random() < 0.03) then if valid and (math.random() < 0.03) then
local squadPosition = {x=0, y=0} local squadPosition = {x=0, y=0}
local squadPath, squadScore = scoreNeighbors(chunk,
local squadPath, squadScore = scoreNeighbors(chunk, getNeighborChunks(regionMap, chunk.cX, chunk.cY),
getNeighborChunks(regionMap, chunk.cX, chunk.cY), validUnitGroupLocation,
validUnitGroupLocation, scoreUnitGroupLocation,
scoreUnitGroupLocation, nil,
nil, surface,
surface, squadPosition)
squadPosition) if (squadPath ~= nil) and (squadScore > 0) then
if (squadPath ~= nil) and (squadScore > 0) then squadPosition.x = squadPath.pX + HALF_CHUNK_SIZE
squadPosition.x = squadPath.pX + HALF_CHUNK_SIZE 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.03) then if (math.random() < 0.03) then
squad.rabid = true squad.rabid = true
end 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 = attackWaveScaling(evolution_factor),
unit_search_distance = (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
end end
end end
end end
end end

View File

@ -38,7 +38,6 @@ local addSquadMovementPenalty = unitGroupUtils.addSquadMovementPenalty
local createSquad = unitGroupUtils.createSquad local createSquad = unitGroupUtils.createSquad
local membersToSquad = unitGroupUtils.membersToSquad local membersToSquad = unitGroupUtils.membersToSquad
local scoreNeighborsWithDirection = neighborUtils.scoreNeighborsWithDirection local scoreNeighborsWithDirection = neighborUtils.scoreNeighborsWithDirection
local addSquadMovementPenalty = unitGroupUtils.addSquadMovementPenalty
-- module code -- module code

View File

@ -32,14 +32,15 @@ constants.SCAN_QUEUE_SIZE = 10
-- ai -- ai
constants.AI_POINT_GENERATOR_AMOUNT = 5 constants.AI_POINT_GENERATOR_AMOUNT = 6
constants.AI_SCOUT_COST = 45 constants.AI_SCOUT_COST = 45
constants.AI_SQUAD_COST = 150 constants.AI_SQUAD_COST = 150
constants.AI_SETTLER_COST = 75 constants.AI_SETTLER_COST = 75
constants.AI_BASE_BUILDING_COST = 500 constants.AI_BASE_BUILDING_COST = 500
constants.AI_TUNNEL_COST = 100 constants.AI_TUNNEL_COST = 100
constants.AI_MAX_POINTS = 30000
constants.AI_MAX_SQUAD_SIZE = 150 --constants.AI_MAX_SQUAD_SIZE = 150
constants.AI_MAX_SQUAD_COUNT = 30 constants.AI_MAX_SQUAD_COUNT = 30
-- chunk properties -- chunk properties

View File

@ -51,4 +51,4 @@ function neighborUtils.scoreNeighbors(chunk, neighborChunks, validFunction, scor
return highestChunk, highestScore return highestChunk, highestScore
end end
return neighborUtils return neighborUtils

View File

@ -6,10 +6,10 @@
;(define modFolder "C:/Users/veden/AppData/Roaming/Factorio/mods/") ;(define modFolder "C:/Users/veden/AppData/Roaming/Factorio/mods/")
;(define zipModFolder "C:/Program Files/Factorio_0.14.1/mods/") ;(define zipModFolder "C:/Program Files/Factorio_0.14.1/mods/")
(define modFolder "/home/veden/.factorio/mods/") (define modFolder "/home/veden/.factorio/mods/")
(define zipModFolder "/home/veden/.factorio/mods/") (define zipModFolder "/data/games/factorio14.13/mods/")
(define configuration (call-with-input-file "info.json" (define configuration (call-with-input-file "info.json"
(lambda (port) (lambda (port)
(string->jsexpr (port->string port))))) (string->jsexpr (port->string port)))))
(define packageName (string-append (string-replace (hash-ref configuration 'name) " " "_") (define packageName (string-append (string-replace (hash-ref configuration 'name) " " "_")
"_" "_"
(hash-ref configuration 'version))) (hash-ref configuration 'version)))
@ -26,11 +26,11 @@
#:path-prefix packageName #:path-prefix packageName
(string->path "info.json") (string->path "info.json")
(string->path "control.lua") (string->path "control.lua")
;(string->path "config.lua") (string->path "config.lua")
(string->path "data.lua") (string->path "data.lua")
(string->path "LICENSE.md") (string->path "LICENSE.md")
(string->path "tests.lua") (string->path "tests.lua")
; (string->path "setupUtils.lua") ; (string->path "setupUtils.lua")
(string->path "README.md") (string->path "README.md")
; (string->path "setup.lua") ; (string->path "setup.lua")
(string->path "NOTICE") (string->path "NOTICE")
@ -63,9 +63,9 @@
(sleep 0.1) (sleep 0.1)
(make-directory packagePath) (make-directory packagePath)
(copyFile "control.lua" modFolder) (copyFile "control.lua" modFolder)
; (copyFile "config.lua" modFolder) (copyFile "config.lua" modFolder)
(copyFile "info.json" modFolder) (copyFile "info.json" modFolder)
; (copyFile "setupUtils.lua" modFolder) ; (copyFile "setupUtils.lua" modFolder)
(copyFile "data.lua" modFolder) (copyFile "data.lua" modFolder)
(copyFile "tests.lua" modFolder) (copyFile "tests.lua" modFolder)
(copyDirectory "libs" modFolder) (copyDirectory "libs" modFolder)
@ -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)
) )