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

see readme

This commit is contained in:
Aaron Veden 2017-05-06 02:03:28 -07:00
parent 82753933b0
commit 65aa977f1e
17 changed files with 405 additions and 222 deletions

View File

@ -48,8 +48,15 @@ Configure Options not in game menu:
# Version History
0.15.5 -
- Tweak: Increased ai refund from 2 to 3
- Fix: Signals, Chain Signals, and Train stops now correctly rebuild when the corresponding make safe is toggled
- Feature: Remote interfaces for adjusting wave size, thresholds, ai build points, ai state, player thresholds, and attack triggers
- Improvement: Added reactor, programmable speaker, radars, lights, and rocket silo to biter targets
- Improvement: Switched all configs to global runtime except Dumb projectiles and NE Unit Launcher Options
0.15.4 -
- Fixed: Changed setting name from "make buildings safe from biters" to "Enable building safety." This is to clarify what the setting does.
- Fix: Changed setting name from "make buildings safe from biters" to "Enable building safety." This is to clarify what the setting does.
0.15.3 -
- Improvement: Added configuration for safe buildings. This will be improved after a bug fix in factorio

View File

@ -3,23 +3,13 @@ local config = {}
local mathUtils = require("libs/MathUtils")
local gaussianRandomRange = mathUtils.gaussianRandomRange
--[[
Causes buildings to regenerate and become untargetable after they are destroyed by biters
--]]
config.safeBuildings = settings.startup["rampant-safeBuildings"].value
config.safeEntities = {}
config.safeEntityName = {}
config.safeEntities["curved-rail"] = settings.startup["rampant-safeBuildings-curvedRail"].value
config.safeEntities["straight-rail"] = settings.startup["rampant-safeBuildings-straightRail"].value
config.safeEntityName["big-electric-pole"] = settings.startup["rampant-safeBuildings-bigElectricPole"].value
--[[
attackWaveScaling is used to calculate the attack wave size from the evolutionFactor
default is config.attackWaveMaxSize * (evolutionFactor ^ 1.666667)
default is natives.attackWaveMaxSize * (evolutionFactor ^ 1.666667)
DOES NOT affect vanilla biters waves
--]]
config.attackWaveScaling = function (evolutionFactor)
local attackWaveMaxSize = settings.startup["rampant-attackWaveMaxSize"].value
config.attackWaveScaling = function (evolutionFactor, natives)
local attackWaveMaxSize = natives.attackWaveMaxSize
return math.ceil(gaussianRandomRange(attackWaveMaxSize * (evolutionFactor ^ 1.66667),
(attackWaveMaxSize * 0.5) * 0.333,
1,

View File

@ -12,8 +12,8 @@ local aiAttack = require("libs/AIAttack")
local aiBuilding = require("libs/AIBuilding")
local aiPlanning = require("libs/AIPlanning")
local mathUtils = require("libs/MathUtils")
local interop = require("libs/Interop")
local tests = require("tests")
local config = require("config")
-- constants
@ -21,7 +21,6 @@ local INTERVAL_LOGIC = constants.INTERVAL_LOGIC
local INTERVAL_PROCESS = constants.INTERVAL_PROCESS
local MAX_RALLY_CRIES = constants.MAX_RALLY_CRIES
local MAX_RETREATS = constants.MAX_RETREATS
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
@ -43,8 +42,6 @@ local processPlayers = mapProcessor.processPlayers
local scanMap = mapProcessor.scanMap
local planning = aiPlanning.planning
-- local removeScout = aiBuilding.removeScout
-- local scouting = aiBuilding.scouting
local rallyUnits = aiBuilding.rallyUnits
@ -60,7 +57,7 @@ local squadBeginAttack = aiAttack.squadBeginAttack
local retreatUnits = aiDefense.retreatUnits
local addRemoveEntity = entityUtils.addRemoveEntity
local makeImmortalEntity = entityUtils.makeImmortalEntity
--local makeImmortalEntity = entityUtils.makeImmortalEntity
local roundToNearest = mathUtils.roundToNearest
@ -86,6 +83,32 @@ local function onChunkGenerated(event)
end
end
local function onModSettingsChange(event)
if event and (string.sub(event.setting, 1, 7) ~= "rampant") then
return
end
natives.safeBuildings = settings.global["rampant-safeBuildings"].value
natives.safeEntities["curved-rail"] = settings.global["rampant-safeBuildings-curvedRail"].value
natives.safeEntities["straight-rail"] = settings.global["rampant-safeBuildings-straightRail"].value
natives.safeEntities["rail-signal"] = settings.global["rampant-safeBuildings-railSignals"].value
natives.safeEntities["rail-chain-signal"] = settings.global["rampant-safeBuildings-railChainSignals"].value
natives.safeEntities["train-stop"] = settings.global["rampant-safeBuildings-trainStops"].value
natives.safeEntityName["big-electric-pole"] = settings.global["rampant-safeBuildings-bigElectricPole"].value
natives.attackUsePlayer = settings.global["rampant-attackWaveGenerationUsePlayerProximity"].value
natives.attackUsePollution = settings.global["rampant-attackWaveGenerationUsePollution"].value
natives.attackThresholdMin = settings.global["rampant-attackWaveGenerationThresholdMin"].value
natives.attackThresholdMax = settings.global["rampant-attackWaveGenerationThresholdMax"].value
natives.attackThresholdRange = natives.attackThresholdMax - natives.attackThresholdMin
natives.attackWaveMaxSize = settings.global["rampant-attackWaveMaxSize"].value
natives.attackPlayerThreshold = settings.global["rampant-attackPlayerThreshold"].value
end
local function onConfigChanged()
if (global.version == nil) then
@ -171,7 +194,12 @@ local function onConfigChanged()
game.surfaces[1].print("Rampant - Version 0.14.13")
global.version = constants.VERSION_16
end
if (global.version < constants.VERSION_17) then
if (global.version < constants.VERSION_18) then
natives.safeEntities = {}
natives.safeEntityName = {}
onModSettingsChange(nil)
-- clear old regionMap processing Queue
-- prevents queue adding duplicate chunks
@ -182,7 +210,6 @@ local function onConfigChanged()
-- clear pending chunks, will be added when loop runs below
pendingChunks = {}
-- queue all current chunks that wont be generated during play
local surface = game.surfaces[1]
for chunk in surface.get_chunks() do
@ -191,8 +218,8 @@ local function onConfigChanged()
y = chunk.y * 32 }}})
end
game.surfaces[1].print("Rampant - Version 0.15.1")
global.version = constants.VERSION_17
game.surfaces[1].print("Rampant - Version 0.15.5")
global.version = constants.VERSION_18
end
end
@ -212,16 +239,12 @@ local function onTick(event)
natives.rallyCries = MAX_RALLY_CRIES
natives.retreats = MAX_RETREATS
planning(natives, evolutionFactor, tick, surface)
regroupSquads(natives, evolutionFactor)
processPlayers(players, regionMap, surface, natives, evolutionFactor, tick)
-- scouting(regionMap, natives)
squadBeginAttack(natives, players, evolutionFactor)
squadAttack(regionMap, surface, natives)
end
@ -287,7 +310,7 @@ local function onDeath(event)
local victoryChunk = getChunkByPosition(regionMap, entityPosition.x, entityPosition.y)
victoryScent(victoryChunk, entity.type)
end
if creditNatives and config.safeBuildings and (config.safeEntities[entity.type] or config.safeEntityName[entity.name]) then
if creditNatives and natives.safeBuildings and (natives.safeEntities[entity.type] or natives.safeEntityName[entity.name]) then
-- makeImmortalEntity(surface, entity)
-- patch (Needs to be removed)
@ -337,6 +360,8 @@ end
script.on_init(onInit)
script.on_load(onLoad)
script.on_event(defines.events.on_runtime_mod_setting_changed,
onModSettingsChange)
script.on_configuration_changed(onConfigChanged)
script.on_event(defines.events.on_player_built_tile, onSurfaceTileChange)
@ -352,7 +377,7 @@ script.on_event(defines.events.on_entity_died, onDeath)
script.on_event(defines.events.on_tick, onTick)
script.on_event(defines.events.on_chunk_generated, onChunkGenerated)
remote.add_interface("rampant", {
remote.add_interface("rampantTests", {
test1 = tests.test1,
test2 = tests.test2,
test3 = tests.test3,
@ -363,5 +388,7 @@ remote.add_interface("rampant", {
test8 = tests.test8,
test9 = tests.test9,
test10 = tests.test10,
test11 = tests.test11
test11 = tests.test11
})
remote.add_interface("rampant", interop)

View File

@ -7,4 +7,3 @@ require("prototypes/tile/fillableDirt")
require("prototypes/enemies/UnitSuicideBiters")
require("prototypes/enemies/UnitFireSpitters")

View File

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

View File

@ -118,7 +118,7 @@ function aiAttack.squadBeginAttack(natives, players, evolution_factor)
for i=1,#squads do
local squad = squads[i]
if (squad.status == SQUAD_GUARDING) and squad.group.valid then
local kamikazeThreshold = calculateKamikazeThreshold(squad, evolution_factor)
local kamikazeThreshold = calculateKamikazeThreshold(squad, natives, evolution_factor)
local playerNearby = playersWithinProximityToPosition(players, squad.group.position, 100)
if playerNearby then

View File

@ -27,20 +27,11 @@ local CHUNK_SIZE = constants.CHUNK_SIZE
local NORTH_SOUTH_PASSABLE = constants.NORTH_SOUTH_PASSABLE
local EAST_WEST_PASSABLE = constants.EAST_WEST_PASSABLE
local CONFIG_USE_PLAYER_PROXIMITY = settings.startup["rampant-attackWaveGenerationUsePlayerProximity"].value
local CONFIG_USE_POLLUTION_PROXIMITY = settings.startup["rampant-attackWaveGenerationUsePollution"].value
local CONFIG_USE_THRESHOLD_MIN = settings.startup["rampant-attackWaveGenerationThresholdMin"].value
local CONFIG_USE_THRESHOLD_MAX = settings.startup["rampant-attackWaveGenerationThresholdMax"].value
local CONFIG_USE_THRESHOLD_RANGE = CONFIG_USE_THRESHOLD_MAX - CONFIG_USE_THRESHOLD_MIN
local RETREAT_MOVEMENT_PHEROMONE_LEVEL = constants.RETREAT_MOVEMENT_PHEROMONE_LEVEL
local RALLY_CRY_DISTANCE = 3
-- imported functions
local getNeighborChunks = mapUtils.getNeighborChunks
local getChunkByPosition = mapUtils.getChunkByPosition
local getChunkByIndex = mapUtils.getChunkByIndex
local scoreNeighbors = neighborUtils.scoreNeighbors
local createSquad = unitGroupUtils.createSquad
@ -50,22 +41,23 @@ local mMax = math.max
-- module code
local function attackWaveValidCandidate(chunk, surface, evolutionFactor)
local function attackWaveValidCandidate(chunk, natives, surface, evolutionFactor)
local total = 0;
if CONFIG_USE_PLAYER_PROXIMITY then
if natives.attackUsePlayer then
local playerPheromone = chunk[PLAYER_PHEROMONE]
if (playerPheromone > 7) then
if (playerPheromone > natives.attackPlayerThreshold) then
total = total + chunk[PLAYER_PHEROMONE]
end
end
if CONFIG_USE_POLLUTION_PROXIMITY then
if natives.attackUsePollution then
total = total + surface.get_pollution({chunk.pX, chunk.pY})
end
local delta = CONFIG_USE_THRESHOLD_RANGE * evolutionFactor
local threshold = natives.attackThresholdRange
local delta = threshold * evolutionFactor
if (total > (CONFIG_USE_THRESHOLD_MAX - delta)) then
if (total > ((threshold - delta) + natives.attackThresholdMin)) then
return true
else
return false
@ -80,51 +72,51 @@ local function validUnitGroupLocation(x, chunk, neighborChunk)
return neighborChunk[NORTH_SOUTH_PASSABLE] and neighborChunk[EAST_WEST_PASSABLE] and neighborChunk[ENEMY_BASE_GENERATOR] == 0
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
--]]
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
-- --]]
-- 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})
-- 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 (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
-- 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
--]]
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
-- --]]
-- end
function aiBuilding.rallyUnits(chunk, regionMap, surface, natives, evolutionFactor)
local cX = chunk.cX
@ -146,19 +138,19 @@ function aiBuilding.formSquads(regionMap, surface, natives, chunk, evolution_fac
if (cost == AI_VENGENCE_SQUAD_COST) then
valid = true
elseif (cost == AI_SQUAD_COST) then
valid = attackWaveValidCandidate(chunk, surface, evolution_factor)
valid = attackWaveValidCandidate(chunk, natives, surface, evolution_factor)
end
end
if valid and (math.random() < mMax((0.25 * evolution_factor), 0.10)) then
local squadPosition = {x=0, y=0}
local squadPath, squadScore = scoreNeighbors(chunk,
getNeighborChunks(regionMap, chunk.cX, chunk.cY),
validUnitGroupLocation,
scoreUnitGroupLocation,
nil,
surface,
squadPosition,
false)
local squadPath, _ = scoreNeighbors(chunk,
getNeighborChunks(regionMap, chunk.cX, chunk.cY),
validUnitGroupLocation,
scoreUnitGroupLocation,
nil,
surface,
squadPosition,
false)
if (squadPath ~= nil) then
squadPosition.x = squadPath.pX + HALF_CHUNK_SIZE
squadPosition.y = squadPath.pY + HALF_CHUNK_SIZE
@ -169,7 +161,7 @@ function aiBuilding.formSquads(regionMap, surface, natives, chunk, evolution_fac
squad.rabid = true
end
local scaledWaveSize = attackWaveScaling(evolution_factor)
local scaledWaveSize = attackWaveScaling(evolution_factor, natives)
local foundUnits = surface.set_multi_command({ command = { type = defines.command.group,
group = squad.group,
distraction = defines.distraction.none },

View File

@ -27,7 +27,7 @@ local CHUNK_TICK = constants.CHUNK_TICK
local RETREAT_TRIGGERED = constants.RETREAT_TRIGGERED
-- module code
function chunkUtils.checkForDeadendTiles(constantCoordinate, iteratingCoordinate, direction, surface)
local get_tile = surface.get_tile
@ -72,17 +72,19 @@ function chunkUtils.scoreChunk(chunk, surface)
local x = chunk.pX
local y = chunk.pY
local areaBoundingBox = {{x, y},
{x + 32, y + 32}}
local areaBoundingBox = {
{x, y},
{x + 32, y + 32}
}
local enemyChunkQuery = {area=areaBoundingBox,
type="unit-spawner",
force="enemy"}
local enemyWormChunkQuery = {area=areaBoundingBox,
type="turret",
force="enemy"}
type="turret",
force="enemy"}
local playerChunkQuery = {area=areaBoundingBox,
force="player"}
local entities = surface.count_entities_filtered(enemyChunkQuery)
local worms = surface.count_entities_filtered(enemyWormChunkQuery)
local playerObjects = 0
@ -122,14 +124,14 @@ function chunkUtils.createChunk(topX, topY)
return chunk
end
-- function chunkUtils.colorChunk(x, y, tileType, surface)
-- local tiles = {}
-- for xi=x+5, x + 27 do
-- for yi=y+5, y + 27 do
-- tiles[#tiles+1] = {name=tileType, position={xi, yi}}
-- end
-- end
-- surface.set_tiles(tiles, false)
-- end
function chunkUtils.colorChunk(x, y, tileType, surface)
local tiles = {}
for xi=x+5, x + 27 do
for yi=y+5, y + 27 do
tiles[#tiles+1] = {name=tileType, position={xi, yi}}
end
end
surface.set_tiles(tiles, false)
end
return chunkUtils

View File

@ -12,6 +12,7 @@ constants.VERSION_14 = 14
constants.VERSION_15 = 15
constants.VERSION_16 = 16
constants.VERSION_17 = 17
constants.VERSION_18 = 18
-- misc
@ -39,7 +40,7 @@ constants.AI_BASE_BUILDING_COST = 500
constants.AI_TUNNEL_COST = 100
constants.AI_MAX_POINTS = 10000
constants.AI_UNIT_REFUND = 2
constants.AI_UNIT_REFUND = 3
constants.AI_MAX_SQUAD_COUNT = 40
constants.AI_MAX_BITER_GROUP_SIZE = 450
@ -110,18 +111,17 @@ constants.RETREAT_GRAB_RADIUS = 24
constants.BASE_RALLY_CHANCE = 0.01
constants.BONUS_RALLY_CHANCE = 0.01
constants.MAX_RETREATS = 7
constants.MAX_RALLY_CRIES = 2
constants.RALLY_CRY_DISTANCE = 3
constants.GROUP_MERGE_DISTANCE = 28
-- player building pheromones
constants.BUILDING_PHEROMONES = {}
constants.BUILDING_PHEROMONES["generator"] = 8
constants.BUILDING_PHEROMONES["pump"] = 2
constants.BUILDING_PHEROMONES["reactor"] = 16
constants.BUILDING_PHEROMONES["offshore-pump"] = 2
constants.BUILDING_PHEROMONES["transport-belt"] = 1
constants.BUILDING_PHEROMONES["accumulator"] = 10
@ -131,7 +131,11 @@ constants.BUILDING_PHEROMONES["assembling-machine"] = 10
constants.BUILDING_PHEROMONES["roboport"] = 10
constants.BUILDING_PHEROMONES["beacon"] = 10
constants.BUILDING_PHEROMONES["furnace"] = 12
constants.BUILDING_PHEROMONES["programmable-speaker"] = 8
constants.BUILDING_PHEROMONES["mining-drill"] = 15
constants.BUILDING_PHEROMONES["rocket-silo"] = 18
constants.BUILDING_PHEROMONES["lamp"] = 4
constants.BUILDING_PHEROMONES["radar"] = 10
-- player defense pheromones
@ -146,69 +150,176 @@ constants.retreatFilter[constants.SQUAD_RETREATING] = true
return constants
--[[ types
inserter
loader
--[[
offshore-pump
accumulator
power-switch
generator
pump
boiler
solar-panel
constant-combinator
arithmetic-combinator
decider-combinator
player-port
rocket-silo
roboport
assembling-machine
mining-drill
lab
beacon
radar
furnace
unit-spawner
lamp
land-mine
ammo-turret
wall
gate
electric-turret
fluid-turret
turret
resource
logistic-robot
construction-robot
unit
player
combat-robot
furnace
transport-belt
fish
boiler
container
electric-pole
generator
offshore-pump
inserter
pipe
radar
lamp
pipe-to-ground
assembling-machine
wall
mining-drill
projectile
resource
turret
ammo-turret
unit
unit-spawner
tree
smart-container
underground-belt
loader
splitter
car
solar-panel
locomotive
cargo-wagon
car
smart-container
logistic-container
container
storage-tank
transport-belt
underground-belt
splitter
pipe-to-ground
electric-pole
curved-rail
fluid-wagon
gate
player-port
straight-rail
curved-rail
land-mine
train-stop
rail-signal
rail-chain-signal
pipe
]]--
lab
logistic-robot
construction-robot
logistic-container
rocket-silo
roboport
storage-tank
pump
market
accumulator
beacon
combat-robot
arithmetic-combinator
decider-combinator
constant-combinator
power-switch
programmable-speaker
electric-energy-interface
reactor
heat-pipe
electric-turret
fluid-turret
night-vision-equipment
energy-shield-equipment
battery-equipment
solar-panel-equipment
generator-equipment
active-defense-equipment
movement-bonus-equipment
roboport-equipment
belt-immunity-equipment
tutorial
rocket-defense
item-with-entity-data
rail-planner
tool
blueprint
deconstruction-item
blueprint-book
selection-tool
item-with-tags
module
technology
custom-input
sprite
font
noise-layer
gui-style
utility-constants
utility-sounds
utility-sprites
ambient-sound
character-corpse
explosion
smoke
item-entity
arrow
flying-text
corpse
entity-ghost
tile-ghost
deconstructible-tile-proxy
item-request-proxy
particle
particle-source
leaf-particle
rail-remnants
simple-entity
decorative
ammo
armor
gun
item
capsule
repair-tool
mining-tool
item-group
item-subgroup
recipe
fluid
virtual-signal
autoplace-control
map-settings
map-gen-presets
tile
optimized-decorative
simple-entity-with-force
simple-entity-with-owner
beam
fire
stream
damage-type
ammo-category
rail-category
fuel-category
recipe-category
resource-category
module-category
equipment-grid
equipment-category
build-entity-achievement
research-achievement
finish-the-game-achievement
group-attack-achievement
construct-with-robots-achievement
deconstruct-with-robots-achievement
deliver-by-robots-achievement
train-path-achievement
player-damaged-achievement
produce-achievement
produce-per-hour-achievement
dont-use-entity-in-energy-production-achievement
kill-achievement
combat-robot-count
dont-craft-manually-achievement
dont-build-entity-achievement
achievement
rocket-silo-rocket
rocket-silo-rocket-shadow
smoke-with-trigger
sticker
--]]--

View File

@ -14,8 +14,6 @@ local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
local ENEMY_BASE_PHEROMONE_GENERATOR_AMOUNT = constants.ENEMY_BASE_PHEROMONE_GENERATOR_AMOUNT
local CHUNK_SIZE = constants.CHUNK_SIZE
-- imported functions
local getChunkByIndex = mapUtils.getChunkByIndex

65
libs/Interop.lua Normal file
View File

@ -0,0 +1,65 @@
local interop = {}
function interop.addAIPoints(value)
global.natives.points = global.natives.points + value
end
function interop.getAIPoints()
return global.natives.points
end
function interop.changeState(aiState)
global.natives.state = aiState
end
function interop.getState()
return global.natives.state
end
function interop.getNextStateTick()
return global.natives.stateTick
end
function interop.getMaxWaveSize()
return global.natives.attackMaxWaveSize
end
function interop.getThresholds()
return global.natives.attackThresholdMin, global.natives.attackThresholdMax
end
function interop.changeMaxWaveSize(waveSize)
global.natives.attackMaxWaveSize = waveSize
end
function interop.changeThreshold(min, max)
global.natives.attackThresholdMin = min
global.natives.attackThresholdMax = max
global.natives.attackThresholdRange = max - min
end
function interop.changePlayerThreshold(value)
global.natives.attackPlayerThreshold = value
end
function interop.getPlayerThreshold()
return global.natives.attackPlayerThreshold
end
function interop.changeAttackUsePollution(bool)
global.natives.attackUsePollution = bool
end
function interop.changeAttackUsePlayer(bool)
global.natives.attackUsePlayer = bool
end
function interop.getAttackUsePollution()
return global.natives.attackUsePollution
end
function interop.getAttackUsePlayer()
return global.natives.attackUsePlayer
end
return interop

View File

@ -37,7 +37,6 @@ local BUILDING_PHEROMONES = constants.BUILDING_PHEROMONES
local scents = pheromoneUtils.scents
local processPheromone = pheromoneUtils.processPheromone
local makeScouts = aiBuilding.makeScouts
local formSquads = aiBuilding.formSquads
local getChunkByIndex = mapUtils.getChunkByIndex
@ -73,18 +72,13 @@ end
function mapProcessor.processMap(regionMap, surface, natives, evolution_factor)
local roll = regionMap.processRoll
local index = regionMap.processPointer
local scouts = false
local squads = false
if (index == 1) then
roll = math.random()
regionMap.processRoll = roll
end
if (0.05 <= roll) and (roll <= 0.10) then
scouts = true
end
if (natives.state == AI_STATE_AGGRESSIVE) and (0.11 <= roll) and (roll <= 0.35) then
squads = true
end
@ -96,9 +90,6 @@ function mapProcessor.processMap(regionMap, surface, natives, evolution_factor)
processPheromone(regionMap, chunk)
if scouts then
makeScouts(surface, natives, chunk, evolution_factor)
end
if squads then
formSquads(regionMap, surface, natives, chunk, evolution_factor, AI_SQUAD_COST)
end
@ -124,15 +115,10 @@ function mapProcessor.processPlayers(players, regionMap, surface, natives, evolu
-- randomize player order to ensure a single player isn't singled out
local playerOrdering = nonRepeatingRandom(players)
local scouts = false
local squads = false
local vengenceThreshold = -(evolution_factor * RETREAT_MOVEMENT_PHEROMONE_LEVEL)
local roll = math.random()
if (0.05 <= roll) and (roll <= 0.7) then
scouts = true
end
if (natives.state == AI_STATE_AGGRESSIVE) and (0.11 <= roll) and (roll <= 0.20) then
squads = true
end
@ -168,9 +154,6 @@ function mapProcessor.processPlayers(players, regionMap, surface, natives, evolu
processPheromone(regionMap, chunk)
if scouts then
makeScouts(surface, natives, chunk, evolution_factor)
end
if squads then
formSquads(regionMap, surface, natives, chunk, evolution_factor, AI_SQUAD_COST)
end

View File

@ -9,7 +9,6 @@ local constants = require("Constants")
local NORTH_SOUTH_PASSABLE = constants.NORTH_SOUTH_PASSABLE
local EAST_WEST_PASSABLE = constants.EAST_WEST_PASSABLE
local HALF_CHUNK_SIZE = constants.HALF_CHUNK_SIZE
local CHUNK_SIZE = constants.CHUNK_SIZE
-- imported functions
@ -38,7 +37,6 @@ function mapUtils.positionToChunkOffset(position)
return mFloor(position.x * 0.03125), mFloor(position.y * 0.03125)
end
--[[
1 2 3
\|/
@ -121,7 +119,7 @@ end
--[[
1
|
2- -3
2- -3
|
4
]]--
@ -187,7 +185,7 @@ end
--[[
1
|
2- -3
2- -3
|
4
]]--

View File

@ -38,7 +38,7 @@ function pheromoneUtils.scents(chunk)
if not chunk[NORTH_SOUTH_PASSABLE] and not chunk[EAST_WEST_PASSABLE] then
chunk[BASE_PHEROMONE] = IMPASSABLE_TERRAIN_GENERATOR_AMOUNT;
else
chunk[BASE_PHEROMONE] = chunk[BASE_PHEROMONE] + chunk[PLAYER_BASE_GENERATOR] -- chunk[ENEMY_BASE_GENERATOR]
chunk[BASE_PHEROMONE] = chunk[BASE_PHEROMONE] + chunk[PLAYER_BASE_GENERATOR]
end
end

View File

@ -21,8 +21,6 @@ local NO_RETREAT_BASE_PERCENT = constants.NO_RETREAT_BASE_PERCENT
local NO_RETREAT_EVOLUTION_BONUS_MAX = constants.NO_RETREAT_EVOLUTION_BONUS_MAX
local NO_RETREAT_SQUAD_SIZE_BONUS_MAX = constants.NO_RETREAT_SQUAD_SIZE_BONUS_MAX
local CONFIG_ATTACK_WAVE_MAX_SIZE = settings.startup["rampant-attackWaveMaxSize"].value
local AI_MAX_BITER_GROUP_SIZE = constants.AI_MAX_BITER_GROUP_SIZE
-- imported functions
@ -131,9 +129,10 @@ function unitGroupUtils.lookupSquadMovementPenalty(squad, chunkX, chunkY)
return 0
end
function unitGroupUtils.calculateKamikazeThreshold(squad, evolution_factor)
function unitGroupUtils.calculateKamikazeThreshold(squad, natives, evolution_factor)
local maxSize = natives.attackWaveMaxSize
local kamikazeThreshold = NO_RETREAT_BASE_PERCENT + (evolution_factor * NO_RETREAT_EVOLUTION_BONUS_MAX)
local squadSizeBonus = mLog((#squad.group.members / CONFIG_ATTACK_WAVE_MAX_SIZE) + 0.1) + 1
local squadSizeBonus = mLog((#squad.group.members / maxSize) + 0.1) + 1
return kamikazeThreshold + (NO_RETREAT_SQUAD_SIZE_BONUS_MAX * squadSizeBonus)
end
@ -192,7 +191,7 @@ function unitGroupUtils.regroupSquads(natives, evolution_factor)
end
end
if mergedSquads and not squad.kamikaze then
local kamikazeThreshold = unitGroupUtils.calculateKamikazeThreshold(squad, evolution_factor)
local kamikazeThreshold = unitGroupUtils.calculateKamikazeThreshold(squad, natives, evolution_factor)
if (math.random() < kamikazeThreshold) then
squad.kamikaze = true
end

View File

@ -35,14 +35,15 @@ rampant-safeBuildings-bigElectricPole=Make big electric poles safe from biters
rampant-safeBuildings-railChainSignals=Make rail chain signals safe from biters
rampant-safeBuildings-railSignals=Make rail signals safe from biters
rampant-safeBuildings-trainStops=Make train stops safe from biters
rampant-attackPlayerThreshold=Player score contribution threshold
[mod-setting-description]
rampant-useDumbProjectiles=Turns off homing projectiles for worms and spitters
rampant-useNEUnitLaunchers=ONLY FOR USE WITH NATURAL EVOLUTION ENEMIES use the NE unit launchers with medium and big worms. if set to false this will still allow the dumb projectiles but without the unit spawning. A side effect of the dumb projectiles cause the units to be spawned as if two shots were fired
rampant-attackWaveGenerationUsePollution=Include pollution amount for threshold on chunks with biter nests that will generate a Rampant attack wave. DOES NOT affect vanilla biters waves
rampant-attackWaveGenerationUsePlayerProximity=Include player pheromones amount for threshold on chunks with biter nests that will generate a Rampant attack wave. DOES NOT affect vanilla biters waves
rampant-attackWaveGenerationThresholdMax=The score that a chunk must reach in order for an attack wave to spawn. DOES NOT affect vanilla biters waves. Scaling linearly with evolution factor (starting threshold @ 0.0 evolution)
rampant-attackWaveGenerationThresholdMin=The score that a chunk must reach in order for an attack wave to spawn. DOES NOT affect vanilla biters waves. Scaling linearly with evolution factor (ending threshold @ 100.0 evolution)
rampant-attackWaveGenerationThresholdMax=The total score that a chunk must reach in order for an attack wave to spawn. DOES NOT affect vanilla biters waves. Scaling linearly with evolution factor (starting threshold @ 0.0 evolution)
rampant-attackWaveGenerationThresholdMin=The total score that a chunk must reach in order for an attack wave to spawn. DOES NOT affect vanilla biters waves. Scaling linearly with evolution factor (ending threshold @ 100.0 evolution)
rampant-attackWaveMaxSize=If you wish to change how the attack wave scales with evolution you will need to modify the config.lua in the zip file.
rampant-safeBuildings=This needs to be toggle for the safe building toggles to work. Understand this can cause weird behavior due to the fact that this is a stopgap until a bug is fixed in factorio.
rampant-safeBuildings-curvedRail=Make curved rails safe from biters
@ -50,4 +51,5 @@ rampant-safeBuildings-straightRail=Make straight rails safe from biters
rampant-safeBuildings-bigElectricPole=Make big electric poles safe from biters
rampant-safeBuildings-railChainSignals=Make rail chain signals safe from biters
rampant-safeBuildings-railSignals=Make rail signals safe from biters
rampant-safeBuildings-trainStops=Make train stops safe from biters
rampant-safeBuildings-trainStops=Make train stops safe from biters
rampant-attackPlayerThreshold=The score that a chunk must reach for it to contribute to the attack threshold. Increasing reduces player pheromone cloud impact.

View File

@ -22,7 +22,7 @@ data:extend({
{
type = "bool-setting",
name = "rampant-attackWaveGenerationUsePollution",
setting_type = "startup",
setting_type = "runtime-global",
default_value = true,
order = "b[modifier]-a[trigger]",
per_user = false
@ -31,16 +31,26 @@ data:extend({
{
type = "bool-setting",
name = "rampant-attackWaveGenerationUsePlayerProximity",
setting_type = "startup",
setting_type = "runtime-global",
default_value = true,
order = "b[modifier]-b[trigger]",
per_user = false
},
{
type = "double-setting",
name = "rampant-attackPlayerThreshold",
setting_type = "runtime-global",
minimum_value = 0,
default_value = 7,
order = "c[modifier]-b[threshold]",
per_user = false
},
{
type = "double-setting",
name = "rampant-attackWaveGenerationThresholdMax",
setting_type = "startup",
setting_type = "runtime-global",
minimum_value = 0,
default_value = 20,
order = "c[modifier]-b[threshold]",
@ -50,7 +60,7 @@ data:extend({
{
type = "double-setting",
name = "rampant-attackWaveGenerationThresholdMin",
setting_type = "startup",
setting_type = "runtime-global",
minimum_value = 0,
default_value = 0,
order = "c[modifier]-a[threshold]",
@ -60,9 +70,9 @@ data:extend({
{
type = "int-setting",
name = "rampant-attackWaveMaxSize",
setting_type = "startup",
setting_type = "runtime-global",
minimum_value = 20,
maximum_value = 250,
maximum_value = 400,
default_value = 150,
order = "d[modifier]-a[wave]",
per_user = false
@ -71,7 +81,7 @@ data:extend({
{
type = "bool-setting",
name = "rampant-safeBuildings",
setting_type = "startup",
setting_type = "runtime-global",
default_value = false,
order = "e[modifier]-a[safe]",
per_user = false
@ -80,7 +90,7 @@ data:extend({
{
type = "bool-setting",
name = "rampant-safeBuildings-curvedRail",
setting_type = "startup",
setting_type = "runtime-global",
default_value = false,
order = "e[modifier]-b[safe]",
per_user = false
@ -90,7 +100,7 @@ data:extend({
{
type = "bool-setting",
name = "rampant-safeBuildings-straightRail",
setting_type = "startup",
setting_type = "runtime-global",
default_value = false,
order = "e[modifier]-c[safe]",
per_user = false
@ -99,7 +109,7 @@ data:extend({
{
type = "bool-setting",
name = "rampant-safeBuildings-bigElectricPole",
setting_type = "startup",
setting_type = "runtime-global",
default_value = false,
order = "e[modifier]-d[safe]",
per_user = false
@ -108,7 +118,7 @@ data:extend({
{
type = "bool-setting",
name = "rampant-safeBuildings-railSignals",
setting_type = "startup",
setting_type = "runtime-global",
default_value = false,
order = "e[modifier]-e[safe]",
per_user = false
@ -117,7 +127,7 @@ data:extend({
{
type = "bool-setting",
name = "rampant-safeBuildings-railChainSignals",
setting_type = "startup",
setting_type = "runtime-global",
default_value = false,
order = "e[modifier]-f[safe]",
per_user = false
@ -126,7 +136,7 @@ data:extend({
{
type = "bool-setting",
name = "rampant-safeBuildings-trainStops",
setting_type = "startup",
setting_type = "runtime-global",
default_value = false,
order = "e[modifier]-g[safe]",
per_user = false