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:
parent
36a6e4da33
commit
3a52b5322a
13
README.md
13
README.md
@ -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
|
||||
|
34
config.lua
34
config.lua
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
6
data.lua
6
data.lua
@ -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")
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -51,4 +51,4 @@ function neighborUtils.scoreNeighbors(chunk, neighborChunks, validFunction, scor
|
||||
return highestChunk, highestScore
|
||||
end
|
||||
|
||||
return neighborUtils
|
||||
return neighborUtils
|
||||
|
20
make.rkt
20
make.rkt
@ -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)
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user