mirror of
https://github.com/veden/Rampant.git
synced 2024-12-26 20:54:12 +02:00
see readme
This commit is contained in:
parent
82753933b0
commit
65aa977f1e
@ -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
|
||||
|
16
config.lua
16
config.lua
@ -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,
|
||||
|
59
control.lua
59
control.lua
@ -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)
|
||||
|
1
data.lua
1
data.lua
@ -7,4 +7,3 @@ require("prototypes/tile/fillableDirt")
|
||||
|
||||
require("prototypes/enemies/UnitSuicideBiters")
|
||||
require("prototypes/enemies/UnitFireSpitters")
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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 },
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
--]]--
|
||||
|
@ -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
65
libs/Interop.lua
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
]]--
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
36
settings.lua
36
settings.lua
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user