1
0
mirror of https://github.com/veden/Rampant.git synced 2025-01-28 03:29:34 +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
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.
@ -32,6 +33,14 @@ Base Expansion
# 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
adjusted squad attack pattern (https://forums.factorio.com/viewtopic.php?f=94&t=31445&start=20#p203861)
Fixed migration issue
@ -39,6 +48,8 @@ Base Expansion
0.14.1 - fixed ai created bases not being counted in logic
Optimization to offset ai created bases scanning
0.13.3 = 0.14.3
0.13.2 = 0.14.2
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 natives
-- local pheromoneTotals
local pendingChunks
-- hook functions
@ -49,7 +48,7 @@ local function onLoad()
regionMap = global.regionMap
natives = global.natives
pendingChunks = global.pendingChunks
-- pheromoneTotals = global.pheromoneTotals
-- pheromoneTotals = global.pheromoneTotals
end
local function onChunkGenerated(event)

View File

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

View File

@ -1,7 +1,7 @@
{
"name" : "Rampant",
"factorio_version" : "0.14",
"version" : "0.14.2",
"version" : "0.14.3",
"title" : "Rampant AI",
"author" : "Veden",
"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 unitGroupUtils = require("UnitGroupUtils")
local neighborUtils = require("NeighborUtils")
package.path = "../?.lua;" .. package.path
local config = require("config")
-- constants
local SQUAD_GUARDING = constants.SQUAD_GUARDING
local SQUAD_BURROWING = constants.SQUAD_BURROWING
-- local SQUAD_GUARDING = constants.SQUAD_GUARDING
-- local SQUAD_BURROWING = constants.SQUAD_BURROWING
local PLAYER_BASE_PHEROMONE = constants.PLAYER_BASE_PHEROMONE
local PLAYER_PHEROMONE = constants.PLAYER_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 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 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_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_SIZE = constants.AI_MAX_SQUAD_SIZE
local HALF_CHUNK_SIZE = constants.HALF_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 EAST_WEST_PASSABLE = constants.EAST_WEST_PASSABLE
local COMMAND_GROUP = defines.command.group
local DISTRACTION_BY_DAMAGE = defines.distraction.by_damage
-- local COMMAND_GROUP = defines.command.group
-- 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
local getNeighborChunks = mapUtils.getNeighborChunks
local scoreNeighbors = neighborUtils.scoreNeighbors
local createSquad = unitGroupUtils.createSquad
local attackWaveScaling = config.attackWaveScaling
local tableRemove = table.remove
-- 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 attackScore = surface.get_pollution(position) + neighborChunk[PLAYER_PHEROMONE] + neighborChunk[PLAYER_DEFENSE_PHEROMONE]
local avoidScore = neighborChunk[DEATH_PHEROMONE]
@ -61,88 +91,91 @@ local function validUnitGroupLocation(x, chunk, neighborChunk)
end
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
function aiBuilding.removeScout(entity, natives)
--[[
local scouts = natives.scouts
for i=1, #scouts do
local scout = scouts[i]
if (scout == entity) then
tableRemove(scouts, i)
return
end
end
local scouts = natives.scouts
for i=1, #scouts do
local scout = scouts[i]
if (scout == entity) then
tableRemove(scouts, i)
return
end
end
--]]
end
function aiBuilding.makeScouts(surface, natives, chunk, evolution_factor)
--[[
if (natives.points > AI_SCOUT_COST) then
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,
y = chunk.pY + HALF_CHUNK_SIZE },
max_distance = 100})
if (natives.points > AI_SCOUT_COST) then
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,
y = chunk.pY + HALF_CHUNK_SIZE },
max_distance = 100})
if (enemy ~= nil) and enemy.valid and (enemy.type == "unit") then
natives.points = natives.points - AI_SCOUT_COST
global.natives.scouts[#global.natives.scouts+1] = enemy
-- print(enemy, enemy.unit_number)
end
end
end
if (enemy ~= nil) and enemy.valid and (enemy.type == "unit") then
natives.points = natives.points - AI_SCOUT_COST
global.natives.scouts[#global.natives.scouts+1] = enemy
-- print(enemy, enemy.unit_number)
end
end
end
--]]
end
function aiBuilding.scouting(regionMap, natives)
--[[
local scouts = natives.scouts
for i=1,#scouts do
local scout = scouts[i]
if scout.valid then
scout.set_command({type=defines.command.attack_area,
destination={0,0},
radius=32,
distraction=defines.distraction.none})
end
end
local scouts = natives.scouts
for i=1,#scouts do
local scout = scouts[i]
if scout.valid then
scout.set_command({type=defines.command.attack_area,
destination={0,0},
radius=32,
distraction=defines.distraction.none})
end
end
--]]
end
function aiBuilding.formSquads(regionMap, surface, natives, chunk, evolution_factor)
if (natives.points > AI_SQUAD_COST) then
local score = chunk[PLAYER_BASE_PHEROMONE] + chunk[PLAYER_PHEROMONE] + chunk[PLAYER_DEFENSE_PHEROMONE] + surface.get_pollution({chunk.pX, chunk.pY})
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 (natives.points > AI_SQUAD_COST) and (chunk[ENEMY_BASE_GENERATOR] ~= 0) and (#natives.squads < (AI_MAX_SQUAD_COUNT * evolution_factor)) then
local valid = attackWaveValidCandidate(chunk, surface)
if valid and (math.random() < 0.03) then
local squadPosition = {x=0, y=0}
local squadPath, squadScore = scoreNeighbors(chunk,
getNeighborChunks(regionMap, chunk.cX, chunk.cY),
validUnitGroupLocation,
scoreUnitGroupLocation,
nil,
surface,
squadPosition)
if (squadPath ~= nil) and (squadScore > 0) then
squadPosition.x = squadPath.pX + HALF_CHUNK_SIZE
squadPosition.y = squadPath.pY + HALF_CHUNK_SIZE
local squadPath, squadScore = scoreNeighbors(chunk,
getNeighborChunks(regionMap, chunk.cX, chunk.cY),
validUnitGroupLocation,
scoreUnitGroupLocation,
nil,
surface,
squadPosition)
if (squadPath ~= nil) and (squadScore > 0) then
squadPosition.x = squadPath.pX + 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
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,
distraction = defines.distraction.none },
unit_count = evolution_factor * AI_MAX_SQUAD_SIZE,
unit_count = attackWaveScaling(evolution_factor),
unit_search_distance = (CHUNK_SIZE * 2)})
if (foundUnits > 0) then
natives.points = natives.points - AI_SQUAD_COST
end
end
end
if (foundUnits > 0) then
natives.points = natives.points - AI_SQUAD_COST
end
end
end
end
end

View File

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

View File

@ -32,14 +32,15 @@ constants.SCAN_QUEUE_SIZE = 10
-- ai
constants.AI_POINT_GENERATOR_AMOUNT = 5
constants.AI_POINT_GENERATOR_AMOUNT = 6
constants.AI_SCOUT_COST = 45
constants.AI_SQUAD_COST = 150
constants.AI_SETTLER_COST = 75
constants.AI_BASE_BUILDING_COST = 500
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
-- chunk properties

View File

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

View File

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