mirror of
https://github.com/veden/Rampant.git
synced 2024-12-26 20:54:12 +02:00
currently stuck at factorio crash
This commit is contained in:
parent
ed66822afa
commit
fcd52cf91d
22
Upgrade.lua
22
Upgrade.lua
@ -35,6 +35,7 @@ function upgrade.attempt(natives, setNewSurface, gameSurfaces)
|
|||||||
natives.state = constants.AI_STATE_AGGRESSIVE
|
natives.state = constants.AI_STATE_AGGRESSIVE
|
||||||
|
|
||||||
natives.safeEntities = {}
|
natives.safeEntities = {}
|
||||||
|
natives.vengenceQueue = {}
|
||||||
|
|
||||||
natives.aiPointsScaler = settings.global["rampant-aiPointsScaler"].value
|
natives.aiPointsScaler = settings.global["rampant-aiPointsScaler"].value
|
||||||
natives.aiNocturnalMode = settings.global["rampant-permanentNocturnal"].value
|
natives.aiNocturnalMode = settings.global["rampant-permanentNocturnal"].value
|
||||||
@ -150,15 +151,30 @@ function upgrade.attempt(natives, setNewSurface, gameSurfaces)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
natives.remainingSquads = 0
|
|
||||||
natives.groupNumberToSquad = {}
|
natives.groupNumberToSquad = {}
|
||||||
game.forces.enemy.kill_all_units()
|
game.forces.enemy.kill_all_units()
|
||||||
natives.squads = nil
|
natives.squads = nil
|
||||||
natives.pendingAttack = nil
|
natives.pendingAttack = nil
|
||||||
natives.building = nil
|
natives.building = nil
|
||||||
end
|
end
|
||||||
if (global.version < 112) then
|
if (global.version < 113) then
|
||||||
global.version = 112
|
global.version = 113
|
||||||
|
|
||||||
|
natives.baseId = 0
|
||||||
|
|
||||||
|
local newBases = {}
|
||||||
|
for i=1,#natives.bases do
|
||||||
|
local base = natives.bases
|
||||||
|
base.id = natives.baseId
|
||||||
|
newBases[base.id] = base
|
||||||
|
natives.baseId = natives.baseId + 1
|
||||||
|
end
|
||||||
|
natives.bases = newBases
|
||||||
|
global.pendingChunks = nil
|
||||||
|
|
||||||
|
natives.vengenceQueue = {}
|
||||||
|
|
||||||
|
game.forces.enemy.ai_controllable = true
|
||||||
|
|
||||||
if not setNewSurface then
|
if not setNewSurface then
|
||||||
game.get_surface(natives.activeSurface).print("Rampant - Version 0.18.12")
|
game.get_surface(natives.activeSurface).print("Rampant - Version 0.18.12")
|
||||||
|
@ -1,10 +1,22 @@
|
|||||||
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
||||||
Version: 0.18.12
|
Version: 0.18.12
|
||||||
Date: 16. 4 2020
|
Date: 16. 4 2020
|
||||||
|
Improvements:
|
||||||
|
- Swapped to ai command completed for unit movements
|
||||||
|
- When squads reach a movement threshold for being in the same spots to much they switch to kamikaze mode
|
||||||
|
- Added effect when spawners build to destroy build site
|
||||||
|
- Integrated vanilla AI into Rampant for pollution management
|
||||||
Tweaks:
|
Tweaks:
|
||||||
- Changed ai credits per rocket launched to 5000
|
- Changed ai credits per rocket launched to 5000
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
- fixed add movement penalty not using squad chunk
|
- fixed add movement penalty not using squad chunk
|
||||||
|
- fixed landfill and waterfill getting registered properly
|
||||||
|
Optimizations:
|
||||||
|
- Cleaned up regroup squads
|
||||||
|
- Cleaned up invalid group detection
|
||||||
|
- Minimized use of group.members
|
||||||
|
- Changed how settlers remove entities around build sites
|
||||||
|
- Split map processing and unit group creation
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
||||||
Version: 0.18.11
|
Version: 0.18.11
|
||||||
|
288
control.lua
288
control.lua
@ -22,9 +22,9 @@ local upgrade = require("Upgrade")
|
|||||||
local config = require("config")
|
local config = require("config")
|
||||||
local aiPredicates = require("libs/AIPredicates")
|
local aiPredicates = require("libs/AIPredicates")
|
||||||
|
|
||||||
|
|
||||||
-- constants
|
-- constants
|
||||||
|
|
||||||
|
local DIVISOR_DEATH_TRAIL_TABLE = constants.DIVISOR_DEATH_TRAIL_TABLE
|
||||||
local TRIPLE_CHUNK_SIZE = constants.TRIPLE_CHUNK_SIZE
|
local TRIPLE_CHUNK_SIZE = constants.TRIPLE_CHUNK_SIZE
|
||||||
local INTERVAL_LOGIC = constants.INTERVAL_LOGIC
|
local INTERVAL_LOGIC = constants.INTERVAL_LOGIC
|
||||||
local INTERVAL_PLAYER_PROCESS = constants.INTERVAL_PLAYER_PROCESS
|
local INTERVAL_PLAYER_PROCESS = constants.INTERVAL_PLAYER_PROCESS
|
||||||
@ -32,8 +32,9 @@ local INTERVAL_MAP_PROCESS = constants.INTERVAL_MAP_PROCESS
|
|||||||
local INTERVAL_SCAN = constants.INTERVAL_SCAN
|
local INTERVAL_SCAN = constants.INTERVAL_SCAN
|
||||||
local INTERVAL_SQUAD = constants.INTERVAL_SQUAD
|
local INTERVAL_SQUAD = constants.INTERVAL_SQUAD
|
||||||
local INTERVAL_RESQUAD = constants.INTERVAL_RESQUAD
|
local INTERVAL_RESQUAD = constants.INTERVAL_RESQUAD
|
||||||
local INTERVAL_BUILDERS = constants.INTERVAL_BUILDERS
|
-- local INTERVAL_BUILDERS = constants.INTERVAL_BUILDERS
|
||||||
local INTERVAL_TEMPERAMENT = constants.INTERVAL_TEMPERAMENT
|
local INTERVAL_TEMPERAMENT = constants.INTERVAL_TEMPERAMENT
|
||||||
|
local INTERVAL_SPAWNER = constants.INTERVAL_SPAWNER
|
||||||
|
|
||||||
local HIVE_BUILDINGS = constants.HIVE_BUILDINGS
|
local HIVE_BUILDINGS = constants.HIVE_BUILDINGS
|
||||||
|
|
||||||
@ -52,6 +53,7 @@ local RETREAT_GRAB_RADIUS = constants.RETREAT_GRAB_RADIUS
|
|||||||
|
|
||||||
local RETREAT_SPAWNER_GRAB_RADIUS = constants.RETREAT_SPAWNER_GRAB_RADIUS
|
local RETREAT_SPAWNER_GRAB_RADIUS = constants.RETREAT_SPAWNER_GRAB_RADIUS
|
||||||
|
|
||||||
|
local DEFINES_BEHAVIOR_RESULT_FAIL = defines.behavior_result.fail
|
||||||
local DEFINES_COMMAND_GROUP = defines.command.group
|
local DEFINES_COMMAND_GROUP = defines.command.group
|
||||||
local DEFINES_COMMAND_WANDER = defines.command.wander
|
local DEFINES_COMMAND_WANDER = defines.command.wander
|
||||||
local DEFINES_COMMAND_BUILD_BASE = defines.command.build_base
|
local DEFINES_COMMAND_BUILD_BASE = defines.command.build_base
|
||||||
@ -91,6 +93,9 @@ local positionToChunkXY = mapUtils.positionToChunkXY
|
|||||||
|
|
||||||
local temperamentPlanner = aiPlanning.temperamentPlanner
|
local temperamentPlanner = aiPlanning.temperamentPlanner
|
||||||
|
|
||||||
|
local processVengence = mapProcessor.processVengence
|
||||||
|
local processSpawners = mapProcessor.processSpawners
|
||||||
|
|
||||||
local getPlayerBaseGenerator = chunkPropertyUtils.getPlayerBaseGenerator
|
local getPlayerBaseGenerator = chunkPropertyUtils.getPlayerBaseGenerator
|
||||||
|
|
||||||
local getChunkByPosition = mapUtils.getChunkByPosition
|
local getChunkByPosition = mapUtils.getChunkByPosition
|
||||||
@ -122,6 +127,10 @@ local findNearbyBase = baseUtils.findNearbyBase
|
|||||||
|
|
||||||
local processActiveNests = mapProcessor.processActiveNests
|
local processActiveNests = mapProcessor.processActiveNests
|
||||||
|
|
||||||
|
local removeSquadFromChunk = chunkPropertyUtils.removeSquadFromChunk
|
||||||
|
local addDeathGenerator = chunkPropertyUtils.addDeathGenerator
|
||||||
|
local getDeathGenerator = chunkPropertyUtils.getDeathGenerator
|
||||||
|
|
||||||
local retreatUnits = squadDefense.retreatUnits
|
local retreatUnits = squadDefense.retreatUnits
|
||||||
|
|
||||||
local accountPlayerEntity = chunkUtils.accountPlayerEntity
|
local accountPlayerEntity = chunkUtils.accountPlayerEntity
|
||||||
@ -137,16 +146,18 @@ local cleanSquads = unitGroupUtils.cleanSquads
|
|||||||
local upgradeEntity = baseUtils.upgradeEntity
|
local upgradeEntity = baseUtils.upgradeEntity
|
||||||
local rebuildNativeTables = baseUtils.rebuildNativeTables
|
local rebuildNativeTables = baseUtils.rebuildNativeTables
|
||||||
|
|
||||||
|
local mMin = math.min
|
||||||
local mRandom = math.random
|
local mRandom = math.random
|
||||||
|
|
||||||
local tRemove = table.remove
|
local tRemove = table.remove
|
||||||
|
|
||||||
|
local sFind = string.find
|
||||||
|
|
||||||
-- local references to global
|
-- local references to global
|
||||||
|
|
||||||
local gameSurfaces -- used for manage which surfaces have been visited
|
local gameSurfaces -- used for manage which surfaces have been visited
|
||||||
local map -- manages the chunks that make up the game world
|
local map -- manages the chunks that make up the game world
|
||||||
local natives -- manages the enemy units, structures, and ai
|
local natives -- manages the enemy units, structures, and ai
|
||||||
local pendingChunks -- chunks that have yet to be processed by the mod
|
|
||||||
|
|
||||||
-- hook functions
|
-- hook functions
|
||||||
|
|
||||||
@ -175,17 +186,17 @@ end
|
|||||||
local function onLoad()
|
local function onLoad()
|
||||||
map = global.map
|
map = global.map
|
||||||
natives = global.natives
|
natives = global.natives
|
||||||
pendingChunks = global.pendingChunks
|
|
||||||
gameSurfaces = global.gameSurfaces
|
gameSurfaces = global.gameSurfaces
|
||||||
|
|
||||||
hookEvents()
|
hookEvents()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onChunkGenerated(event)
|
local function onChunkGenerated(event)
|
||||||
|
print("1", game.tick)
|
||||||
-- queue generated chunk for delayed processing, queuing is required because some mods (RSO) mess with chunk as they
|
-- queue generated chunk for delayed processing, queuing is required because some mods (RSO) mess with chunk as they
|
||||||
-- are generated, which messes up the scoring.
|
-- are generated, which messes up the scoring.
|
||||||
if (event.surface.name == natives.activeSurface) then
|
if (event.surface.name == natives.activeSurface) then
|
||||||
pendingChunks[#pendingChunks+1] = event
|
map.pendingChunks[event] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -201,6 +212,7 @@ local function rebuildMap()
|
|||||||
map.processIndex = 1
|
map.processIndex = 1
|
||||||
map.scanIndex = 1
|
map.scanIndex = 1
|
||||||
|
|
||||||
|
map.pendingChunks = {}
|
||||||
map.chunkToBase = {}
|
map.chunkToBase = {}
|
||||||
map.chunkToNests = {}
|
map.chunkToNests = {}
|
||||||
map.chunkToTurrets = {}
|
map.chunkToTurrets = {}
|
||||||
@ -215,7 +227,6 @@ local function rebuildMap()
|
|||||||
|
|
||||||
map.chunkToRetreats = {}
|
map.chunkToRetreats = {}
|
||||||
map.chunkToRallys = {}
|
map.chunkToRallys = {}
|
||||||
map.chunkToSettler = {}
|
|
||||||
|
|
||||||
map.chunkToPassable = {}
|
map.chunkToPassable = {}
|
||||||
map.chunkToPathRating = {}
|
map.chunkToPathRating = {}
|
||||||
@ -229,6 +240,11 @@ local function rebuildMap()
|
|||||||
|
|
||||||
map.squadIterator = nil
|
map.squadIterator = nil
|
||||||
map.regroupIterator = nil
|
map.regroupIterator = nil
|
||||||
|
map.deployVengenceIterator = nil
|
||||||
|
map.recycleBaseIterator = nil
|
||||||
|
map.processActiveSpawnerIterator = nil
|
||||||
|
map.processActiveRaidSpawnerIterator = nil
|
||||||
|
map.processMigrationIterator = nil
|
||||||
|
|
||||||
-- preallocating memory to be used in code, making it fast by reducing garbage generated.
|
-- preallocating memory to be used in code, making it fast by reducing garbage generated.
|
||||||
map.neighbors = {
|
map.neighbors = {
|
||||||
@ -306,6 +322,10 @@ local function rebuildMap()
|
|||||||
"turret"
|
"turret"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
map.createBuildCloudQuery = {
|
||||||
|
name = "build-clear-cloud-rampant",
|
||||||
|
position = map.position
|
||||||
|
}
|
||||||
|
|
||||||
map.activePlayerForces = {"player"}
|
map.activePlayerForces = {"player"}
|
||||||
|
|
||||||
@ -434,6 +454,13 @@ local function rebuildMap()
|
|||||||
use_group_distraction = false
|
use_group_distraction = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
map.mergeGroupCommand = {
|
||||||
|
type = DEFINES_COMMAND_GROUP,
|
||||||
|
group = nil,
|
||||||
|
distraction = DEFINES_DISTRACTION_NONE,
|
||||||
|
use_group_distraction = false
|
||||||
|
}
|
||||||
|
|
||||||
map.fleeCommand = {
|
map.fleeCommand = {
|
||||||
type = DEFINES_COMMAND_FLEE,
|
type = DEFINES_COMMAND_FLEE,
|
||||||
from = nil,
|
from = nil,
|
||||||
@ -507,14 +534,10 @@ local function onModSettingsChange(event)
|
|||||||
upgrade.compareTable(natives, "newEnemies", settings.startup["rampant-newEnemies"].value)
|
upgrade.compareTable(natives, "newEnemies", settings.startup["rampant-newEnemies"].value)
|
||||||
upgrade.compareTable(natives, "enemySeed", settings.startup["rampant-enemySeed"].value)
|
upgrade.compareTable(natives, "enemySeed", settings.startup["rampant-enemySeed"].value)
|
||||||
|
|
||||||
upgrade.compareTable(natives, "disableVanillaAI", settings.global["rampant-disableVanillaAI"].value)
|
|
||||||
|
|
||||||
natives.enabledMigration = natives.expansion and settings.global["rampant-enableMigration"].value
|
natives.enabledMigration = natives.expansion and settings.global["rampant-enableMigration"].value
|
||||||
|
|
||||||
upgrade.compareTable(natives, "ENEMY_VARIATIONS", settings.startup["rampant-newEnemyVariations"].value)
|
upgrade.compareTable(natives, "ENEMY_VARIATIONS", settings.startup["rampant-newEnemyVariations"].value)
|
||||||
|
|
||||||
game.forces.enemy.ai_controllable = not natives.disableVanillaAI
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -548,10 +571,6 @@ local function prepWorld(rebuild, surfaceName)
|
|||||||
map.natives = natives
|
map.natives = natives
|
||||||
natives.map = map
|
natives.map = map
|
||||||
|
|
||||||
-- clear pending chunks, will be added when loop runs below
|
|
||||||
global.pendingChunks = {}
|
|
||||||
pendingChunks = global.pendingChunks
|
|
||||||
|
|
||||||
-- queue all current chunks that wont be generated during play
|
-- queue all current chunks that wont be generated during play
|
||||||
local surface = game.get_surface(natives.activeSurface)
|
local surface = game.get_surface(natives.activeSurface)
|
||||||
local tick = game.tick
|
local tick = game.tick
|
||||||
@ -569,7 +588,7 @@ local function prepWorld(rebuild, surfaceName)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
processPendingChunks(map, surface, pendingChunks, tick, rebuild)
|
processPendingChunks(map, surface, tick, rebuild, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -578,6 +597,7 @@ local function onConfigChanged()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onBuild(event)
|
local function onBuild(event)
|
||||||
|
print("2", game.tick)
|
||||||
local entity = event.created_entity or event.entity
|
local entity = event.created_entity or event.entity
|
||||||
if (entity.surface.name == natives.activeSurface) then
|
if (entity.surface.name == natives.activeSurface) then
|
||||||
if (entity.type == "resource") and (entity.force.name == "neutral") then
|
if (entity.type == "resource") and (entity.force.name == "neutral") then
|
||||||
@ -594,6 +614,7 @@ local function onBuild(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onMine(event)
|
local function onMine(event)
|
||||||
|
print("3", game.tick)
|
||||||
local entity = event.entity
|
local entity = event.entity
|
||||||
local surface = entity.surface
|
local surface = entity.surface
|
||||||
if (surface.name == natives.activeSurface) then
|
if (surface.name == natives.activeSurface) then
|
||||||
@ -608,6 +629,7 @@ local function onMine(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onDeath(event)
|
local function onDeath(event)
|
||||||
|
print("4", game.tick)
|
||||||
local entity = event.entity
|
local entity = event.entity
|
||||||
if entity.valid then
|
if entity.valid then
|
||||||
local surface = entity.surface
|
local surface = entity.surface
|
||||||
@ -634,14 +656,15 @@ local function onDeath(event)
|
|||||||
|
|
||||||
natives.lostEnemyUnits = natives.lostEnemyUnits + 1
|
natives.lostEnemyUnits = natives.lostEnemyUnits + 1
|
||||||
|
|
||||||
retreatUnits(chunk,
|
-- retreatUnits(chunk,
|
||||||
entityPosition,
|
-- entityPosition,
|
||||||
entity.unit_group,
|
-- entity.unit_group,
|
||||||
map,
|
-- map,
|
||||||
surface,
|
-- surface,
|
||||||
tick,
|
-- tick,
|
||||||
(artilleryBlast and RETREAT_SPAWNER_GRAB_RADIUS) or RETREAT_GRAB_RADIUS,
|
-- (artilleryBlast and RETREAT_SPAWNER_GRAB_RADIUS) or RETREAT_GRAB_RADIUS-- ,
|
||||||
artilleryBlast)
|
-- -- artilleryBlast
|
||||||
|
-- )
|
||||||
|
|
||||||
if (mRandom() < natives.rallyThreshold) and not surface.peaceful_mode then
|
if (mRandom() < natives.rallyThreshold) and not surface.peaceful_mode then
|
||||||
rallyUnits(chunk, map, surface, tick)
|
rallyUnits(chunk, map, surface, tick)
|
||||||
@ -653,19 +676,20 @@ local function onDeath(event)
|
|||||||
|
|
||||||
natives.points = natives.points + (((entityType == "unit-spawner") and RECOVER_NEST_COST) or RECOVER_WORM_COST)
|
natives.points = natives.points + (((entityType == "unit-spawner") and RECOVER_NEST_COST) or RECOVER_WORM_COST)
|
||||||
|
|
||||||
if (chunk ~= -1) then
|
unregisterEnemyBaseStructure(map, entity)
|
||||||
unregisterEnemyBaseStructure(map, entity)
|
|
||||||
|
|
||||||
|
if (chunk ~= -1) then
|
||||||
rallyUnits(chunk, map, surface, tick)
|
rallyUnits(chunk, map, surface, tick)
|
||||||
|
|
||||||
retreatUnits(chunk,
|
-- retreatUnits(chunk,
|
||||||
entityPosition,
|
-- entityPosition,
|
||||||
nil,
|
-- nil,
|
||||||
map,
|
-- map,
|
||||||
surface,
|
-- surface,
|
||||||
tick,
|
-- tick,
|
||||||
RETREAT_SPAWNER_GRAB_RADIUS,
|
-- RETREAT_SPAWNER_GRAB_RADIUS-- ,
|
||||||
(cause and ((cause.type == "artillery-wagon") or (cause.type == "artillery-turret"))))
|
-- -- (cause and ((cause.type == "artillery-wagon") or (cause.type == "artillery-turret")))
|
||||||
|
-- )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -751,6 +775,7 @@ local function onDeath(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onEnemyBaseBuild(event)
|
local function onEnemyBaseBuild(event)
|
||||||
|
print("5", game.tick)
|
||||||
local entity = event.entity
|
local entity = event.entity
|
||||||
if entity.valid then
|
if entity.valid then
|
||||||
local surface = entity.surface
|
local surface = entity.surface
|
||||||
@ -782,36 +807,35 @@ local function onEnemyBaseBuild(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onSurfaceTileChange(event)
|
local function onSurfaceTileChange(event)
|
||||||
|
print("6", game.tick)
|
||||||
local surfaceIndex = event.surface_index or (event.robot and event.robot.surface and event.robot.surface.index)
|
local surfaceIndex = event.surface_index or (event.robot and event.robot.surface and event.robot.surface.index)
|
||||||
local surfaceName = game.surfaces[surfaceIndex].name
|
local surface = game.get_surface(natives.activeSurface)
|
||||||
if (surfaceName == natives.activeSurface) and
|
if (surface.index == surfaceIndex) then
|
||||||
((event.item.name == "landfill") or (event.item.name == "waterfill")) and
|
|
||||||
event.item
|
|
||||||
then
|
|
||||||
local surface = game.get_surface(natives.activeSurface)
|
|
||||||
local chunks = {}
|
local chunks = {}
|
||||||
local tiles = event.tiles
|
local tiles = event.tiles
|
||||||
for i=1,#tiles do
|
if (event.tile.name == "landfill") or sFind(event.tile.name, "water") then
|
||||||
local position = tiles[i].position
|
for i=1,#tiles do
|
||||||
local chunk = getChunkByPosition(map, position)
|
local position = tiles[i].position
|
||||||
|
local chunk = getChunkByPosition(map, position)
|
||||||
|
|
||||||
if (chunk ~= -1) then
|
if (chunk ~= -1) then
|
||||||
map.chunkToPassScan[chunk] = true
|
map.chunkToPassScan[chunk] = true
|
||||||
else
|
else
|
||||||
local x,y = positionToChunkXY(position)
|
local x,y = positionToChunkXY(position)
|
||||||
local addMe = true
|
local addMe = true
|
||||||
for ci=1,#chunks do
|
for ci=1,#chunks do
|
||||||
local c = chunks[ci]
|
local c = chunks[ci]
|
||||||
if (c.x == x) and (c.y == y) then
|
if (c.x == x) and (c.y == y) then
|
||||||
addMe = false
|
addMe = false
|
||||||
break
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if addMe then
|
||||||
|
local chunkXY = {x=x,y=y}
|
||||||
|
chunks[#chunks+1] = chunkXY
|
||||||
|
onChunkGenerated({area = { left_top = chunkXY },
|
||||||
|
surface = surface})
|
||||||
end
|
end
|
||||||
end
|
|
||||||
if addMe then
|
|
||||||
local chunkXY = {x=x,y=y}
|
|
||||||
chunks[#chunks+1] = chunkXY
|
|
||||||
onChunkGenerated({area = { left_top = chunkXY },
|
|
||||||
surface = surface})
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -819,6 +843,7 @@ local function onSurfaceTileChange(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onResourceDepleted(event)
|
local function onResourceDepleted(event)
|
||||||
|
print("7", game.tick)
|
||||||
local entity = event.entity
|
local entity = event.entity
|
||||||
if (entity.surface.name == natives.activeSurface) then
|
if (entity.surface.name == natives.activeSurface) then
|
||||||
unregisterResource(entity, map)
|
unregisterResource(entity, map)
|
||||||
@ -826,7 +851,7 @@ local function onResourceDepleted(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onRobotCliff(event)
|
local function onRobotCliff(event)
|
||||||
|
print("8", game.tick)
|
||||||
local surface = event.robot.surface
|
local surface = event.robot.surface
|
||||||
if (surface.name == natives.activeSurface) and (event.item.name == "cliff-explosives") then
|
if (surface.name == natives.activeSurface) and (event.item.name == "cliff-explosives") then
|
||||||
entityForPassScan(map, event.cliff)
|
entityForPassScan(map, event.cliff)
|
||||||
@ -834,6 +859,7 @@ local function onRobotCliff(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onUsedCapsule(event)
|
local function onUsedCapsule(event)
|
||||||
|
print("9", game.tick)
|
||||||
local surface = game.players[event.player_index].surface
|
local surface = game.players[event.player_index].surface
|
||||||
if (surface.name == natives.activeSurface) and (event.item.name == "cliff-explosives") then
|
if (surface.name == natives.activeSurface) and (event.item.name == "cliff-explosives") then
|
||||||
map.position2Top.x = event.position.x-0.75
|
map.position2Top.x = event.position.x-0.75
|
||||||
@ -848,6 +874,7 @@ local function onUsedCapsule(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onRocketLaunch(event)
|
local function onRocketLaunch(event)
|
||||||
|
print("10", game.tick)
|
||||||
local entity = event.rocket_silo or event.rocket
|
local entity = event.rocket_silo or event.rocket
|
||||||
if entity and entity.valid and (entity.surface.name == natives.activeSurface) then
|
if entity and entity.valid and (entity.surface.name == natives.activeSurface) then
|
||||||
natives.rocketLaunched = natives.rocketLaunched + 1
|
natives.rocketLaunched = natives.rocketLaunched + 1
|
||||||
@ -856,6 +883,7 @@ local function onRocketLaunch(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onTriggerEntityCreated(event)
|
local function onTriggerEntityCreated(event)
|
||||||
|
print("11", game.tick)
|
||||||
local entity = event.entity
|
local entity = event.entity
|
||||||
if entity.valid and (entity.surface.name == natives.activeSurface) and (entity.name == "drain-trigger-rampant") then
|
if entity.valid and (entity.surface.name == natives.activeSurface) and (entity.name == "drain-trigger-rampant") then
|
||||||
local chunk = getChunkByPosition(map, entity.position)
|
local chunk = getChunkByPosition(map, entity.position)
|
||||||
@ -868,13 +896,11 @@ end
|
|||||||
|
|
||||||
local function onInit()
|
local function onInit()
|
||||||
global.map = {}
|
global.map = {}
|
||||||
global.pendingChunks = {}
|
|
||||||
global.natives = {}
|
global.natives = {}
|
||||||
global.gameSurfaces = {}
|
global.gameSurfaces = {}
|
||||||
|
|
||||||
map = global.map
|
map = global.map
|
||||||
natives = global.natives
|
natives = global.natives
|
||||||
pendingChunks = global.pendingChunks
|
|
||||||
gameSurfaces = global.gameSurfaces
|
gameSurfaces = global.gameSurfaces
|
||||||
|
|
||||||
prepWorld(false, "nauvis")
|
prepWorld(false, "nauvis")
|
||||||
@ -882,6 +908,7 @@ local function onInit()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onEntitySpawned(event)
|
local function onEntitySpawned(event)
|
||||||
|
print("12", game.tick)
|
||||||
local entity = event.entity
|
local entity = event.entity
|
||||||
if natives.newEnemies and entity.valid then
|
if natives.newEnemies and entity.valid then
|
||||||
local surface = entity.surface
|
local surface = entity.surface
|
||||||
@ -921,41 +948,76 @@ local function onEntitySpawned(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onUnitGroupCreated(event)
|
local function onUnitGroupCreated(event)
|
||||||
|
print("13", game.tick)
|
||||||
local group = event.group
|
local group = event.group
|
||||||
if (group.surface.name == natives.activeSurface) and (group.force.name == "enemy") then
|
local surface = group.surface
|
||||||
|
if (surface.name == natives.activeSurface) and (group.force.name == "enemy") then
|
||||||
if not group.is_script_driven then
|
if not group.is_script_driven then
|
||||||
squad = createSquad(nil,
|
if not natives.aiNocturnalMode then
|
||||||
nil,
|
squad = createSquad(nil,
|
||||||
group,
|
nil,
|
||||||
mRandom() < 0.75 and canMigrate(natives, game.get_surface(natives.activeSurface)))
|
group,
|
||||||
natives.groupNumberToSquad[group.group_number] = squad
|
mRandom() < 0.25 and canMigrate(natives, group.surface))
|
||||||
|
natives.groupNumberToSquad[group.group_number] = squad
|
||||||
|
elseif not (surface.darkness > 0.65) then
|
||||||
|
group.destroy()
|
||||||
|
else
|
||||||
|
squad = createSquad(nil,
|
||||||
|
nil,
|
||||||
|
group,
|
||||||
|
mRandom() < 0.25 and canMigrate(natives, group.surface))
|
||||||
|
natives.groupNumberToSquad[group.group_number] = squad
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onCommandComplete(event)
|
local function onCommandComplete(event)
|
||||||
-- local msg
|
print("14", game.tick)
|
||||||
-- if (event.result == defines.behavior_result.in_progress) then
|
|
||||||
-- msg = "progress"
|
|
||||||
-- elseif (event.result == defines.behavior_result.fail) then
|
|
||||||
-- msg = "fail"
|
|
||||||
-- elseif (event.result == defines.behavior_result.success) then
|
|
||||||
-- msg = "success"
|
|
||||||
-- elseif (event.result == defines.behavior_result.deleted) then
|
|
||||||
-- msg = "deleted"
|
|
||||||
-- end
|
|
||||||
|
|
||||||
local unitNumber = event.unit_number
|
local unitNumber = event.unit_number
|
||||||
local squad = natives.groupNumberToSquad[unitNumber]
|
local squad = natives.groupNumberToSquad[unitNumber]
|
||||||
if squad then
|
if squad then
|
||||||
|
-- local result = event.result
|
||||||
|
-- local msg
|
||||||
|
-- if (result == defines.behavior_result.in_progress) then
|
||||||
|
-- msg = "progress"
|
||||||
|
-- elseif (result == defines.behavior_result.fail) then
|
||||||
|
-- msg = "fail"
|
||||||
|
-- elseif (result == defines.behavior_result.success) then
|
||||||
|
-- msg = "success"
|
||||||
|
-- elseif (result == defines.behavior_result.deleted) then
|
||||||
|
-- msg = "deleted"
|
||||||
|
-- end
|
||||||
|
-- print(msg)
|
||||||
|
|
||||||
local group = squad.group
|
local group = squad.group
|
||||||
if group and group.valid and (group.surface.name == natives.activeSurface) then
|
if group and group.valid and (group.surface.name == natives.activeSurface) then
|
||||||
squadDispatch(map, group.surface, squad, unitNumber)
|
|
||||||
|
if (event.result == DEFINES_BEHAVIOR_RESULT_FAIL) then
|
||||||
|
print("count", #group.members)
|
||||||
|
if (#group.members == 0) then
|
||||||
|
print("dropping")
|
||||||
|
local deathGen = getDeathGenerator(map, squad.chunk)
|
||||||
|
local penalties = squad.penalties
|
||||||
|
for xc=1,mMin(#squad.penalties,5) do
|
||||||
|
addDeathGenerator(map,
|
||||||
|
penalties[xc].c,
|
||||||
|
deathGen * DIVISOR_DEATH_TRAIL_TABLE[xc])
|
||||||
|
end
|
||||||
|
removeSquadFromChunk(map, squad)
|
||||||
|
group.destroy()
|
||||||
|
else
|
||||||
|
squadDispatch(map, group.surface, squad, unitNumber)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
squadDispatch(map, group.surface, squad, unitNumber)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onGroupFinishedGathering(event)
|
local function onGroupFinishedGathering(event)
|
||||||
|
print("15", game.tick)
|
||||||
local group = event.group
|
local group = event.group
|
||||||
if group.valid then
|
if group.valid then
|
||||||
local unitNumber = group.group_number
|
local unitNumber = group.group_number
|
||||||
@ -967,10 +1029,12 @@ local function onGroupFinishedGathering(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onForceCreated(event)
|
local function onForceCreated(event)
|
||||||
|
print("16", game.tick)
|
||||||
map.activePlayerForces[#map.activePlayerForces+1] = event.force.name
|
map.activePlayerForces[#map.activePlayerForces+1] = event.force.name
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onForceMerged(event)
|
local function onForceMerged(event)
|
||||||
|
print("17", game.tick)
|
||||||
for i=#map.activePlayerForces,1,-1 do
|
for i=#map.activePlayerForces,1,-1 do
|
||||||
if (map.activePlayerForces[i] == event.source_name) then
|
if (map.activePlayerForces[i] == event.source_name) then
|
||||||
tRemove(map.activePlayerForces, i)
|
tRemove(map.activePlayerForces, i)
|
||||||
@ -980,6 +1044,7 @@ local function onForceMerged(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onSurfaceRenamed(event)
|
local function onSurfaceRenamed(event)
|
||||||
|
print("18", game.tick)
|
||||||
if event.old_name == natives.activeSurface then
|
if event.old_name == natives.activeSurface then
|
||||||
natives.activeSurface = event.new_name
|
natives.activeSurface = event.new_name
|
||||||
end
|
end
|
||||||
@ -990,6 +1055,7 @@ local function onSurfaceRenamed(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onSurfaceCleared(event)
|
local function onSurfaceCleared(event)
|
||||||
|
print("19", game.tick)
|
||||||
local surface = game.get_surface(event.surface_index)
|
local surface = game.get_surface(event.surface_index)
|
||||||
if surface and surface.valid and (surface.name == natives.activeSurface) then
|
if surface and surface.valid and (surface.name == natives.activeSurface) then
|
||||||
prepWorld(true, natives.activeSurface)
|
prepWorld(true, natives.activeSurface)
|
||||||
@ -997,6 +1063,7 @@ local function onSurfaceCleared(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onPlayerChangedSurface(event)
|
local function onPlayerChangedSurface(event)
|
||||||
|
print("20", game.tick)
|
||||||
local player = game.players[event.player_index]
|
local player = game.players[event.player_index]
|
||||||
local surface
|
local surface
|
||||||
if player and player.valid and not settings.get_player_settings(player)["rampant-suppress-surface-change-warnings"].value
|
if player and player.valid and not settings.get_player_settings(player)["rampant-suppress-surface-change-warnings"].value
|
||||||
@ -1020,6 +1087,7 @@ local function onPlayerChangedSurface(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onSurfaceDeleted(event)
|
local function onSurfaceDeleted(event)
|
||||||
|
print("21", game.tick)
|
||||||
local surface = game.get_surface(event.surface_index)
|
local surface = game.get_surface(event.surface_index)
|
||||||
if surface and surface.valid then
|
if surface and surface.valid then
|
||||||
if (surface.name == natives.activeSurface) then
|
if (surface.name == natives.activeSurface) then
|
||||||
@ -1035,68 +1103,106 @@ end
|
|||||||
|
|
||||||
script.on_nth_tick(INTERVAL_PLAYER_PROCESS,
|
script.on_nth_tick(INTERVAL_PLAYER_PROCESS,
|
||||||
function (event)
|
function (event)
|
||||||
|
print("22", game.tick)
|
||||||
|
local profiler = game.create_profiler()
|
||||||
local gameRef = game
|
local gameRef = game
|
||||||
|
|
||||||
processPlayers(gameRef.connected_players,
|
processPlayers(gameRef.connected_players,
|
||||||
map,
|
map,
|
||||||
gameRef.get_surface(natives.activeSurface),
|
gameRef.get_surface(natives.activeSurface),
|
||||||
event.tick)
|
event.tick)
|
||||||
|
game.print({"", "player", profiler})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
script.on_nth_tick(INTERVAL_MAP_PROCESS,
|
script.on_nth_tick(INTERVAL_MAP_PROCESS,
|
||||||
function (event)
|
function (event)
|
||||||
|
print("23", game.tick)
|
||||||
|
local profiler = game.create_profiler()
|
||||||
local gameRef = game
|
local gameRef = game
|
||||||
|
|
||||||
processMap(map,
|
-- processMap(map,
|
||||||
gameRef.get_surface(natives.activeSurface),
|
-- gameRef.get_surface(natives.activeSurface),
|
||||||
event.tick)
|
-- event.tick)
|
||||||
|
game.print({"", "map", profiler})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
script.on_nth_tick(INTERVAL_SCAN,
|
script.on_nth_tick(INTERVAL_SCAN,
|
||||||
function (event)
|
function (event)
|
||||||
|
print("24", game.tick)
|
||||||
|
local profiler = game.create_profiler()
|
||||||
local tick = event.tick
|
local tick = event.tick
|
||||||
local gameRef = game
|
local gameRef = game
|
||||||
local surface = gameRef.get_surface(natives.activeSurface)
|
local surface = gameRef.get_surface(natives.activeSurface)
|
||||||
|
|
||||||
processPendingChunks(map, surface, pendingChunks, tick)
|
processPendingChunks(map, surface, tick)
|
||||||
|
|
||||||
scanMap(map, surface, tick)
|
scanMap(map, surface, tick)
|
||||||
|
|
||||||
processScanChunks(map, surface)
|
processScanChunks(map, surface)
|
||||||
|
game.print({"", "scan", profiler})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
script.on_nth_tick(INTERVAL_LOGIC,
|
script.on_nth_tick(INTERVAL_LOGIC,
|
||||||
function (event)
|
function (event)
|
||||||
|
print("25", game.tick)
|
||||||
|
local profiler = game.create_profiler()
|
||||||
local tick = event.tick
|
local tick = event.tick
|
||||||
|
|
||||||
planning(natives,
|
planning(natives,
|
||||||
game.forces.enemy.evolution_factor,
|
game.forces.enemy.evolution_factor,
|
||||||
tick)
|
tick)
|
||||||
|
|
||||||
map.squadIterator = cleanSquads(natives, map.squadIterator)
|
cleanSquads(natives, map.squadIterator)
|
||||||
|
|
||||||
if natives.newEnemies then
|
if natives.newEnemies then
|
||||||
recycleBases(natives, tick)
|
recycleBases(natives, tick)
|
||||||
end
|
end
|
||||||
|
game.print({"", "logic", profiler})
|
||||||
|
end)
|
||||||
|
|
||||||
|
script.on_nth_tick(INTERVAL_SPAWNER,
|
||||||
|
function (event)
|
||||||
|
print("26", game.tick)
|
||||||
|
local profiler = game.create_profiler()
|
||||||
|
processSpawners(map,
|
||||||
|
game.get_surface(natives.activeSurface),
|
||||||
|
event.tick)
|
||||||
|
game.print({"", "spawners", profiler})
|
||||||
|
end)
|
||||||
|
|
||||||
|
script.on_nth_tick(INTERVAL_SQUAD,
|
||||||
|
function (event)
|
||||||
|
print("27", game.tick)
|
||||||
|
local profiler = game.create_profiler()
|
||||||
|
processVengence(map,
|
||||||
|
game.get_surface(natives.activeSurface),
|
||||||
|
event.tick)
|
||||||
|
game.print({"", "vengence", profiler})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
script.on_nth_tick(INTERVAL_TEMPERAMENT,
|
script.on_nth_tick(INTERVAL_TEMPERAMENT,
|
||||||
function (event)
|
function (event)
|
||||||
|
print("28", game.tick)
|
||||||
|
local profiler = game.create_profiler()
|
||||||
temperamentPlanner(natives)
|
temperamentPlanner(natives)
|
||||||
|
game.print({"", "temperament", profiler})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
script.on_nth_tick(INTERVAL_RESQUAD,
|
script.on_nth_tick(INTERVAL_RESQUAD,
|
||||||
function ()
|
function ()
|
||||||
|
print("29", game.tick)
|
||||||
|
local profiler = game.create_profiler()
|
||||||
map.regroupIterator = regroupSquads(natives, map.regroupIterator)
|
map.regroupIterator = regroupSquads(natives, map.regroupIterator)
|
||||||
|
game.print({"", "regroup", profiler})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
script.on_event(defines.events.on_tick,
|
script.on_event(defines.events.on_tick,
|
||||||
function (event)
|
function (event)
|
||||||
processActiveNests(map,
|
print("30", game.tick)
|
||||||
game.get_surface(natives.activeSurface),
|
local profiler = game.create_profiler()
|
||||||
event.tick)
|
-- processActiveNests(map,
|
||||||
|
-- game.get_surface(natives.activeSurface),
|
||||||
|
-- event.tick)
|
||||||
|
game.print({"", "processActiveNests", profiler})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
script.on_event(defines.events.on_surface_cleared, onSurfaceCleared)
|
script.on_event(defines.events.on_surface_cleared, onSurfaceCleared)
|
||||||
|
@ -5,6 +5,6 @@
|
|||||||
"title" : "Rampant",
|
"title" : "Rampant",
|
||||||
"author" : "Veden",
|
"author" : "Veden",
|
||||||
"homepage" : "https://forums.factorio.com/viewtopic.php?f=94&t=31445",
|
"homepage" : "https://forums.factorio.com/viewtopic.php?f=94&t=31445",
|
||||||
"description" : "Improves the enemies tactics by using potential fields/pheromones allowing probing of defenses, retreats, reinforcements, counterattacking, breaching, raids, rallying death cry, and player hunting. Uses blockable biter projectiles. Adds new Enemies (disabled by default). Can completely replace the vanilla AI. Difficulty setting in mod options menu.",
|
"description" : "Improves the enemies tactics by using potential fields/pheromones allowing probing of defenses, retreats, reinforcements, counterattacking, breaching, raids, rallying death cry, and player hunting. Uses blockable biter projectiles. Adds new Enemies (disabled by default). Difficulty setting in mod options menu.",
|
||||||
"dependencies" : ["base >= 0.18.22", "? bobenemies", "? Natural_Evolution_Enemies >= 0.17.0", "? Clockwork", "? Orbital Ion Cannon", "? RampantArsenal", "? RampantResources", "? ArmouredBiters"]
|
"dependencies" : ["base >= 0.18.22", "? bobenemies", "? Natural_Evolution_Enemies >= 0.17.0", "? Clockwork", "? Orbital Ion Cannon", "? RampantArsenal", "? RampantResources", "? ArmouredBiters"]
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ local AI_MAX_SQUAD_COUNT = constants.AI_MAX_SQUAD_COUNT
|
|||||||
local AI_VENGENCE_SQUAD_COST = constants.AI_VENGENCE_SQUAD_COST
|
local AI_VENGENCE_SQUAD_COST = constants.AI_VENGENCE_SQUAD_COST
|
||||||
local AI_STATE_AGGRESSIVE = constants.AI_STATE_AGGRESSIVE
|
local AI_STATE_AGGRESSIVE = constants.AI_STATE_AGGRESSIVE
|
||||||
|
|
||||||
local INTERVAL_RALLY = constants.INTERVAL_RALLY
|
local COOLDOWN_RALLY = constants.COOLDOWN_RALLY
|
||||||
|
|
||||||
local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS
|
local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS
|
||||||
|
|
||||||
@ -52,16 +52,12 @@ local randomTickEvent = mathUtils.randomTickEvent
|
|||||||
|
|
||||||
local mRandom = math.random
|
local mRandom = math.random
|
||||||
|
|
||||||
local createSpawnerProxies = baseUtils.createSpawnerProxies
|
|
||||||
|
|
||||||
local positionFromDirectionAndChunk = mapUtils.positionFromDirectionAndChunk
|
local positionFromDirectionAndChunk = mapUtils.positionFromDirectionAndChunk
|
||||||
|
|
||||||
local getPassable = chunkPropertyUtils.getPassable
|
local getPassable = chunkPropertyUtils.getPassable
|
||||||
local getNestCount = chunkPropertyUtils.getNestCount
|
local getNestCount = chunkPropertyUtils.getNestCount
|
||||||
local getChunkSettlerTick = chunkPropertyUtils.getChunkSettlerTick
|
|
||||||
local getRaidNestActiveness = chunkPropertyUtils.getRaidNestActiveness
|
local getRaidNestActiveness = chunkPropertyUtils.getRaidNestActiveness
|
||||||
local getNestActiveness = chunkPropertyUtils.getNestActiveness
|
local getNestActiveness = chunkPropertyUtils.getNestActiveness
|
||||||
local setChunkSettlerTick = chunkPropertyUtils.setChunkSettlerTick
|
|
||||||
local getRallyTick = chunkPropertyUtils.getRallyTick
|
local getRallyTick = chunkPropertyUtils.getRallyTick
|
||||||
local setRallyTick = chunkPropertyUtils.setRallyTick
|
local setRallyTick = chunkPropertyUtils.setRallyTick
|
||||||
|
|
||||||
@ -121,68 +117,76 @@ local function validUnitGroupLocation(map, neighborChunk)
|
|||||||
(getNestCount(map, neighborChunk) == 0)
|
(getNestCount(map, neighborChunk) == 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function visitPattern(o, cX, cY, distance)
|
||||||
|
local startX
|
||||||
|
local endX
|
||||||
|
local stepX
|
||||||
|
local startY
|
||||||
|
local endY
|
||||||
|
local stepY
|
||||||
|
if (o == 0) then
|
||||||
|
startX = cX - RALLY_CRY_DISTANCE
|
||||||
|
endX = cX + RALLY_CRY_DISTANCE
|
||||||
|
stepX = 32
|
||||||
|
startY = cY - RALLY_CRY_DISTANCE
|
||||||
|
endY = cY + RALLY_CRY_DISTANCE
|
||||||
|
stepY = 32
|
||||||
|
elseif (o == 1) then
|
||||||
|
startX = cX + RALLY_CRY_DISTANCE
|
||||||
|
endX = cX - RALLY_CRY_DISTANCE
|
||||||
|
stepX = -32
|
||||||
|
startY = cY + RALLY_CRY_DISTANCE
|
||||||
|
endY = cY - RALLY_CRY_DISTANCE
|
||||||
|
stepY = -32
|
||||||
|
elseif (o == 2) then
|
||||||
|
startX = cX - RALLY_CRY_DISTANCE
|
||||||
|
endX = cX + RALLY_CRY_DISTANCE
|
||||||
|
stepX = 32
|
||||||
|
startY = cY + RALLY_CRY_DISTANCE
|
||||||
|
endY = cY - RALLY_CRY_DISTANCE
|
||||||
|
stepY = -32
|
||||||
|
elseif (o == 3) then
|
||||||
|
startX = cX + RALLY_CRY_DISTANCE
|
||||||
|
endX = cX - RALLY_CRY_DISTANCE
|
||||||
|
stepX = -32
|
||||||
|
startY = cY - RALLY_CRY_DISTANCE
|
||||||
|
endY = cY + RALLY_CRY_DISTANCE
|
||||||
|
stepY = 32
|
||||||
|
end
|
||||||
|
return startX, endX, stepX, startY, endY, stepY
|
||||||
|
end
|
||||||
|
|
||||||
function aiAttackWave.rallyUnits(chunk, map, surface, tick)
|
function aiAttackWave.rallyUnits(chunk, map, surface, tick)
|
||||||
if ((tick - getRallyTick(map, chunk) > INTERVAL_RALLY) and (map.natives.points >= AI_VENGENCE_SQUAD_COST)) then
|
if ((tick - getRallyTick(map, chunk) > COOLDOWN_RALLY) and (map.natives.points >= AI_VENGENCE_SQUAD_COST)) then
|
||||||
setRallyTick(map, chunk, tick)
|
setRallyTick(map, chunk, tick)
|
||||||
local cX = chunk.x
|
local cX = chunk.x
|
||||||
local cY = chunk.y
|
local cY = chunk.y
|
||||||
for x=cX - RALLY_CRY_DISTANCE, cX + RALLY_CRY_DISTANCE, 32 do
|
local startX, endX, stepX, startY, endY, stepY = visitPattern(tick % 4, cX, cY, RALLY_CRY_DISTANCE)
|
||||||
for y=cY - RALLY_CRY_DISTANCE, cY + RALLY_CRY_DISTANCE, 32 do
|
local vengenceQueue = map.natives.vengenceQueue
|
||||||
|
for x=startX, endX, stepX do
|
||||||
|
for y=startY, endY, stepY do
|
||||||
if (x ~= cX) and (y ~= cY) then
|
if (x ~= cX) and (y ~= cY) then
|
||||||
local rallyChunk = getChunkByXY(map, x, y)
|
local rallyChunk = getChunkByXY(map, x, y)
|
||||||
if (rallyChunk ~= -1) and (getNestCount(map, rallyChunk) > 0) then
|
if (rallyChunk ~= -1) and (getNestCount(map, rallyChunk) > 0) then
|
||||||
if not aiAttackWave.formVengenceSquad(map, surface, rallyChunk) then
|
local count = vengenceQueue[rallyChunk]
|
||||||
return false
|
if not count then
|
||||||
|
count = 0
|
||||||
|
vengenceQueue[rallyChunk] = count
|
||||||
end
|
end
|
||||||
|
vengenceQueue[rallyChunk] = count + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function aiAttackWave.formAttackWave(chunk, map, surface, tick)
|
|
||||||
if (map.natives.points >= AI_SQUAD_COST) then
|
|
||||||
local cX = chunk.x
|
|
||||||
local cY = chunk.y
|
|
||||||
for x=cX - RALLY_CRY_DISTANCE, cX + RALLY_CRY_DISTANCE, 32 do
|
|
||||||
for y=cY - RALLY_CRY_DISTANCE, cY + RALLY_CRY_DISTANCE, 32 do
|
|
||||||
if (x ~= cX) and (y ~= cY) then
|
|
||||||
local rallyChunk = getChunkByXY(map, x, y)
|
|
||||||
if (rallyChunk ~= -1) and (getNestCount(map, rallyChunk) > 0) then
|
|
||||||
if not aiAttackWave.formSquads(map, surface, rallyChunk, tick) then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local function noNearbySettlers(map, chunk, tick)
|
|
||||||
local cX = chunk.x
|
|
||||||
local cY = chunk.y
|
|
||||||
for x=cX - SETTLER_DISTANCE, cX + SETTLER_DISTANCE, 32 do
|
|
||||||
for y=cY - SETTLER_DISTANCE, cY + SETTLER_DISTANCE, 32 do
|
|
||||||
if (x ~= cX) and (y ~= cY) then
|
|
||||||
local c = getChunkByXY(map, x, y)
|
|
||||||
if (c ~= -1) and ((tick - getChunkSettlerTick(map, c)) < 0) then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
function aiAttackWave.formSettlers(map, surface, chunk, tick)
|
function aiAttackWave.formSettlers(map, surface, chunk, tick)
|
||||||
local natives = map.natives
|
|
||||||
if (mRandom() < natives.formSquadThreshold) and (natives.remainingSquads > 0) then
|
|
||||||
|
|
||||||
|
local natives = map.natives
|
||||||
|
if (mRandom() < natives.formSquadThreshold) and ((natives.points - AI_SETTLER_COST) > 0) then
|
||||||
local squadPath, squadDirection
|
local squadPath, squadDirection
|
||||||
if (natives.state == AI_STATE_SIEGE) then
|
if (natives.state == AI_STATE_SIEGE) then
|
||||||
squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y),
|
squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y),
|
||||||
@ -197,7 +201,7 @@ function aiAttackWave.formSettlers(map, surface, chunk, tick)
|
|||||||
map)
|
map)
|
||||||
end
|
end
|
||||||
|
|
||||||
if (squadPath ~= -1) and noNearbySettlers(map, chunk, tick) then
|
if (squadPath ~= -1) then
|
||||||
local squadPosition = surface.find_non_colliding_position("chunk-scanner-squad-rampant",
|
local squadPosition = surface.find_non_colliding_position("chunk-scanner-squad-rampant",
|
||||||
positionFromDirectionAndChunk(squadDirection,
|
positionFromDirectionAndChunk(squadDirection,
|
||||||
chunk,
|
chunk,
|
||||||
@ -214,14 +218,12 @@ function aiAttackWave.formSettlers(map, surface, chunk, tick)
|
|||||||
10,
|
10,
|
||||||
natives.expansionMaxDistance)
|
natives.expansionMaxDistance)
|
||||||
|
|
||||||
|
|
||||||
local scaledWaveSize = settlerWaveScaling(natives)
|
local scaledWaveSize = settlerWaveScaling(natives)
|
||||||
map.formGroupCommand.group = squad.group
|
map.formGroupCommand.group = squad.group
|
||||||
map.formCommand.unit_count = scaledWaveSize
|
map.formCommand.unit_count = scaledWaveSize
|
||||||
local foundUnits = surface.set_multi_command(map.formCommand)
|
local foundUnits = surface.set_multi_command(map.formCommand)
|
||||||
if (foundUnits > 0) then
|
if (foundUnits > 0) then
|
||||||
createSpawnerProxies(map, surface, chunk, foundUnits)
|
|
||||||
setChunkSettlerTick(map, squadPath, tick + natives.settlerCooldown)
|
|
||||||
natives.remainingSquads = natives.remainingSquads - 1
|
|
||||||
natives.points = natives.points - AI_SETTLER_COST
|
natives.points = natives.points - AI_SETTLER_COST
|
||||||
natives.groupNumberToSquad[squad.groupNumber] = squad
|
natives.groupNumberToSquad[squad.groupNumber] = squad
|
||||||
else
|
else
|
||||||
@ -232,13 +234,11 @@ function aiAttackWave.formSettlers(map, surface, chunk, tick)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return ((natives.points - AI_SETTLER_COST) > 0) and (natives.remainingSquads > 0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function aiAttackWave.formVengenceSquad(map, surface, chunk)
|
function aiAttackWave.formVengenceSquad(map, surface, chunk)
|
||||||
local natives = map.natives
|
local natives = map.natives
|
||||||
if (mRandom() < natives.formSquadThreshold) then
|
if (mRandom() < natives.formSquadThreshold) and ((natives.points - AI_VENGENCE_SQUAD_COST) > 0) then
|
||||||
local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y),
|
local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y),
|
||||||
validUnitGroupLocation,
|
validUnitGroupLocation,
|
||||||
scoreUnitGroupLocation,
|
scoreUnitGroupLocation,
|
||||||
@ -262,7 +262,6 @@ function aiAttackWave.formVengenceSquad(map, surface, chunk)
|
|||||||
map.formCommand.unit_count = scaledWaveSize
|
map.formCommand.unit_count = scaledWaveSize
|
||||||
local foundUnits = surface.set_multi_command(map.formCommand)
|
local foundUnits = surface.set_multi_command(map.formCommand)
|
||||||
if (foundUnits > 0) then
|
if (foundUnits > 0) then
|
||||||
createSpawnerProxies(map, surface, chunk, foundUnits)
|
|
||||||
natives.groupNumberToSquad[squad.groupNumber] = squad
|
natives.groupNumberToSquad[squad.groupNumber] = squad
|
||||||
natives.points = natives.points - AI_VENGENCE_SQUAD_COST
|
natives.points = natives.points - AI_VENGENCE_SQUAD_COST
|
||||||
else
|
else
|
||||||
@ -273,15 +272,13 @@ function aiAttackWave.formVengenceSquad(map, surface, chunk)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return (natives.points - AI_VENGENCE_SQUAD_COST) > 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function aiAttackWave.formSquads(map, surface, chunk, tick)
|
function aiAttackWave.formSquads(map, surface, chunk, tick)
|
||||||
local natives = map.natives
|
local natives = map.natives
|
||||||
if attackWaveValidCandidate(chunk, natives, map) and
|
if attackWaveValidCandidate(chunk, natives, map) and
|
||||||
(mRandom() < natives.formSquadThreshold) and
|
(mRandom() < natives.formSquadThreshold) and
|
||||||
(natives.remainingSquads > 0)
|
((natives.points - AI_SQUAD_COST) > 0)
|
||||||
then
|
then
|
||||||
local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y),
|
local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y),
|
||||||
validUnitGroupLocation,
|
validUnitGroupLocation,
|
||||||
@ -308,13 +305,11 @@ function aiAttackWave.formSquads(map, surface, chunk, tick)
|
|||||||
if (foundUnits > 0) then
|
if (foundUnits > 0) then
|
||||||
createSpawnerProxies(map, surface, chunk, foundUnits)
|
createSpawnerProxies(map, surface, chunk, foundUnits)
|
||||||
natives.points = natives.points - AI_SQUAD_COST
|
natives.points = natives.points - AI_SQUAD_COST
|
||||||
natives.remainingSquads = natives.remainingSquads - 1
|
|
||||||
natives.groupNumberToSquad[squad.groupNumber] = squad
|
natives.groupNumberToSquad[squad.groupNumber] = squad
|
||||||
if tick and (natives.state == AI_STATE_AGGRESSIVE) then
|
if tick and (natives.state == AI_STATE_AGGRESSIVE) then
|
||||||
natives.canAttackTick = randomTickEvent(tick,
|
natives.canAttackTick = randomTickEvent(tick,
|
||||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if (squad.group.valid) then
|
if (squad.group.valid) then
|
||||||
@ -324,8 +319,6 @@ function aiAttackWave.formSquads(map, surface, chunk, tick)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return ((natives.points - AI_SQUAD_COST) > 0) and (natives.remainingSquads > 0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ function aiPlanning.planning(natives, evolution_factor, tick)
|
|||||||
local attackWaveMaxSize = natives.attackWaveMaxSize
|
local attackWaveMaxSize = natives.attackWaveMaxSize
|
||||||
natives.retreatThreshold = linearInterpolation(evolution_factor, RETREAT_MOVEMENT_PHEROMONE_LEVEL_MIN, RETREAT_MOVEMENT_PHEROMONE_LEVEL_MAX)
|
natives.retreatThreshold = linearInterpolation(evolution_factor, RETREAT_MOVEMENT_PHEROMONE_LEVEL_MIN, RETREAT_MOVEMENT_PHEROMONE_LEVEL_MAX)
|
||||||
natives.rallyThreshold = BASE_RALLY_CHANCE + (evolution_factor * BONUS_RALLY_CHANCE)
|
natives.rallyThreshold = BASE_RALLY_CHANCE + (evolution_factor * BONUS_RALLY_CHANCE)
|
||||||
natives.formSquadThreshold = mMax((0.25 * evolution_factor), 0.10)
|
natives.formSquadThreshold = mMax((0.20 * evolution_factor), 0.05)
|
||||||
|
|
||||||
natives.attackWaveSize = attackWaveMaxSize * (evolution_factor ^ 1.15)
|
natives.attackWaveSize = attackWaveMaxSize * (evolution_factor ^ 1.15)
|
||||||
natives.attackWaveDeviation = (natives.attackWaveSize * 0.333)
|
natives.attackWaveDeviation = (natives.attackWaveSize * 0.333)
|
||||||
|
@ -19,8 +19,10 @@ local AI_STATE_ONSLAUGHT = constants.AI_STATE_ONSLAUGHT
|
|||||||
|
|
||||||
-- module code
|
-- module code
|
||||||
|
|
||||||
function aiPredicates.canAttack(natives, surface)
|
function aiPredicates.canAttack(natives, surface, tick)
|
||||||
local goodAI = ((natives.state == AI_STATE_AGGRESSIVE) or (natives.state == AI_STATE_RAIDING) or (natives.state == AI_STATE_ONSLAUGHT))
|
local goodAI = (((natives.state == AI_STATE_AGGRESSIVE) and (natives.canAttackTick > tick)) or
|
||||||
|
(natives.state == AI_STATE_RAIDING) or
|
||||||
|
(natives.state == AI_STATE_ONSLAUGHT))
|
||||||
local notPeaceful = not surface.peaceful_mode
|
local notPeaceful = not surface.peaceful_mode
|
||||||
local noctural = (not natives.aiNocturnalMode) or (natives.aiNocturnalMode and surface.darkness > 0.65)
|
local noctural = (not natives.aiNocturnalMode) or (natives.aiNocturnalMode and surface.darkness > 0.65)
|
||||||
return goodAI and notPeaceful and noctural
|
return goodAI and notPeaceful and noctural
|
||||||
|
@ -76,6 +76,8 @@ local setChunkBase = chunkPropertyUtils.setChunkBase
|
|||||||
|
|
||||||
local getResourceGenerator = chunkPropertyUtils.getResourceGenerator
|
local getResourceGenerator = chunkPropertyUtils.getResourceGenerator
|
||||||
|
|
||||||
|
local next = next
|
||||||
|
|
||||||
local tRemove = table.remove
|
local tRemove = table.remove
|
||||||
|
|
||||||
local mRandom = math.random
|
local mRandom = math.random
|
||||||
@ -95,50 +97,6 @@ local function evoToTier(natives, evolutionFactor)
|
|||||||
return v
|
return v
|
||||||
end
|
end
|
||||||
|
|
||||||
function baseUtils.createSpawnerProxies(map, surface, chunk, foundUnits)
|
|
||||||
local query = map.placeSpawnerProxyQuery
|
|
||||||
if (foundUnits >= 60) then
|
|
||||||
query.name = "spawner-proxy-2-rampant"
|
|
||||||
elseif (foundUnits >= 120) then
|
|
||||||
query.name = "spawner-proxy-3-rampant"
|
|
||||||
else
|
|
||||||
query.name = "spawner-proxy-1-rampant"
|
|
||||||
end
|
|
||||||
local position3 = map.position3
|
|
||||||
local chunkX = chunk.x + 5
|
|
||||||
local chunkY = chunk.y + 5
|
|
||||||
position3.x = chunkX
|
|
||||||
position3.y = chunkY
|
|
||||||
local entity = surface.create_entity(query)
|
|
||||||
entity.destructible = false
|
|
||||||
position3.x = chunkX+CHUNK_SIZE
|
|
||||||
position3.y = chunkY
|
|
||||||
entity = surface.create_entity(query)
|
|
||||||
entity.destructible = false
|
|
||||||
position3.x = chunkX-CHUNK_SIZE
|
|
||||||
position3.y = chunkY
|
|
||||||
entity = surface.create_entity(query)
|
|
||||||
entity.destructible = false
|
|
||||||
position3.x = chunkX
|
|
||||||
position3.y = chunkY-CHUNK_SIZE
|
|
||||||
entity = surface.create_entity(query)
|
|
||||||
entity.destructible = false
|
|
||||||
position3.x = chunkX
|
|
||||||
position3.y = chunkY+CHUNK_SIZE
|
|
||||||
entity = surface.create_entity(query)
|
|
||||||
entity.destructible = false
|
|
||||||
end
|
|
||||||
|
|
||||||
function baseUtils.createSpawnerProxy(map, surface, chunk)
|
|
||||||
local query = map.placeSpawnerProxyQuery
|
|
||||||
query.name = "spawner-proxy-1-rampant"
|
|
||||||
local position3 = map.position3
|
|
||||||
position3.x = chunk.x + 5
|
|
||||||
position3.y = chunk.y + 5
|
|
||||||
local entity = surface.create_entity(query)
|
|
||||||
entity.destructible = false
|
|
||||||
end
|
|
||||||
|
|
||||||
function baseUtils.findNearbyBase(map, chunk)
|
function baseUtils.findNearbyBase(map, chunk)
|
||||||
local x = chunk.x
|
local x = chunk.x
|
||||||
local y = chunk.y
|
local y = chunk.y
|
||||||
@ -150,8 +108,7 @@ function baseUtils.findNearbyBase(map, chunk)
|
|||||||
|
|
||||||
local bases = map.natives.bases
|
local bases = map.natives.bases
|
||||||
local closet = MAGIC_MAXIMUM_NUMBER
|
local closet = MAGIC_MAXIMUM_NUMBER
|
||||||
for i=1, #bases do
|
for _, base in pairs(bases) do
|
||||||
local base = bases[i]
|
|
||||||
local distance = euclideanDistancePoints(base.x, base.y, x, y)
|
local distance = euclideanDistancePoints(base.x, base.y, x, y)
|
||||||
if (distance <= base.distanceThreshold) and (distance < closet) then
|
if (distance <= base.distanceThreshold) and (distance < closet) then
|
||||||
closet = distance
|
closet = distance
|
||||||
@ -283,7 +240,8 @@ local function findEntityUpgrade(baseAlignment, currentEvo, evoIndex, originalEn
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function findBaseInitialAlignment(natives, evoIndex)
|
local function findBaseInitialAlignment(natives, evoIndex)
|
||||||
local evoTop = gaussianRandomRange(evoIndex, evoIndex * 0.3, 0, evoIndex)
|
local dev = evoIndex * 0.3
|
||||||
|
local evoTop = gaussianRandomRange(evoIndex - dev, dev, 0, evoIndex)
|
||||||
|
|
||||||
local result
|
local result
|
||||||
if mRandom() < 0.05 then
|
if mRandom() < 0.05 then
|
||||||
@ -298,21 +256,23 @@ end
|
|||||||
function baseUtils.recycleBases(natives, tick)
|
function baseUtils.recycleBases(natives, tick)
|
||||||
local baseIndex = natives.baseIndex
|
local baseIndex = natives.baseIndex
|
||||||
local bases = natives.bases
|
local bases = natives.bases
|
||||||
|
local id, base = next(bases, natives.map.recycleBaseIterator)
|
||||||
local endIndex = mMin(baseIndex+BASE_QUEUE_SIZE, #bases)
|
for i=1,2 do
|
||||||
for index = endIndex, baseIndex, -1 do
|
if not id then
|
||||||
local base = bases[index]
|
natives.map.recycleBaseIterator = nil
|
||||||
|
return
|
||||||
if ((tick - base.tick) > BASE_COLLECTION_THRESHOLD) then
|
else
|
||||||
tRemove(bases, index)
|
if ((tick - base.tick) > BASE_COLLECTION_THRESHOLD) then
|
||||||
|
local nextId
|
||||||
|
nextId, base = next(bases, id)
|
||||||
|
bases[id] = nil
|
||||||
|
id = nextId
|
||||||
|
else
|
||||||
|
id, base = next(bases, id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
natives.map.recycleBaseIterator = id
|
||||||
if (endIndex == #bases) then
|
|
||||||
natives.baseIndex = 1
|
|
||||||
else
|
|
||||||
natives.baseIndex = endIndex + 1
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -495,12 +455,14 @@ function baseUtils.createBase(natives, chunk, tick, rebuilding)
|
|||||||
temperamentTick = 0,
|
temperamentTick = 0,
|
||||||
createdTick = tick,
|
createdTick = tick,
|
||||||
temperament = 0,
|
temperament = 0,
|
||||||
points = 0
|
points = 0,
|
||||||
|
id = natives.baseId
|
||||||
}
|
}
|
||||||
|
natives.baseId = natives.baseId + 1
|
||||||
|
|
||||||
setChunkBase(natives.map, chunk, base)
|
setChunkBase(natives.map, chunk, base)
|
||||||
|
|
||||||
natives.bases[#natives.bases+1] = base
|
natives.bases[base.id] = base
|
||||||
|
|
||||||
return base
|
return base
|
||||||
end
|
end
|
||||||
@ -653,8 +615,7 @@ function baseUtils.rebuildNativeTables(natives, surface, rg)
|
|||||||
|
|
||||||
local evoIndex = evoToTier(natives, natives.evolutionLevel)
|
local evoIndex = evoToTier(natives, natives.evolutionLevel)
|
||||||
|
|
||||||
for i=1,#natives.bases do
|
for id,base in pairs(natives.bases) do
|
||||||
local base = natives.bases[i]
|
|
||||||
for x=1,#base.alignment do
|
for x=1,#base.alignment do
|
||||||
local alignment = base.alignment[x]
|
local alignment = base.alignment[x]
|
||||||
if not natives.buildingEvolveLookup[alignment] then
|
if not natives.buildingEvolveLookup[alignment] then
|
||||||
|
@ -27,6 +27,8 @@ local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
|
|||||||
local tSort = table.sort
|
local tSort = table.sort
|
||||||
|
|
||||||
local abs = math.abs
|
local abs = math.abs
|
||||||
|
local next = next
|
||||||
|
local table_size = table_size
|
||||||
|
|
||||||
local tRemove = table.remove
|
local tRemove = table.remove
|
||||||
|
|
||||||
@ -49,49 +51,67 @@ local function sorter(a, b)
|
|||||||
return (aDistance < bDistance)
|
return (aDistance < bDistance)
|
||||||
end
|
end
|
||||||
|
|
||||||
function chunkProcessor.processPendingChunks(map, surface, pendingStack, tick, rebuilding)
|
function chunkProcessor.processPendingChunks(map, surface, tick, rebuilding, flush)
|
||||||
|
local profiler = game.create_profiler()
|
||||||
local processQueue = map.processQueue
|
local processQueue = map.processQueue
|
||||||
|
local pendingChunks = map.pendingChunks
|
||||||
|
|
||||||
local area = map.area
|
local area = map.area
|
||||||
|
|
||||||
local topOffset = area[1]
|
local topOffset = area[1]
|
||||||
local bottomOffset = area[2]
|
local bottomOffset = area[2]
|
||||||
|
|
||||||
for i=#pendingStack, 1, -1 do
|
local event = next(pendingChunks, map.chunkProcessorIterator)
|
||||||
local event = pendingStack[i]
|
local endCount = 5
|
||||||
pendingStack[i] = nil
|
if flush then
|
||||||
|
endCount = table_size(pendingChunks)
|
||||||
local topLeft = event.area.left_top
|
end
|
||||||
local x = topLeft.x
|
for i=1,endCount do
|
||||||
local y = topLeft.y
|
if not event then
|
||||||
|
map.chunkProcessorIterator = nil
|
||||||
topOffset[1] = x
|
if (table_size(pendingChunks) == 0) then
|
||||||
topOffset[2] = y
|
-- this is needed as the next command remembers the max length a table has been
|
||||||
bottomOffset[1] = x + CHUNK_SIZE
|
map.pendingChunks = {}
|
||||||
bottomOffset[2] = y + CHUNK_SIZE
|
end
|
||||||
|
break
|
||||||
if map[x] and map[x][y] then
|
|
||||||
mapScanChunk(map[x][y], surface, map)
|
|
||||||
else
|
else
|
||||||
if map[x] == nil then
|
local topLeft = event.area.left_top
|
||||||
map[x] = {}
|
local x = topLeft.x
|
||||||
end
|
local y = topLeft.y
|
||||||
|
|
||||||
local chunk = createChunk(x, y)
|
topOffset[1] = x
|
||||||
|
topOffset[2] = y
|
||||||
chunk = initialScan(chunk, surface, map, tick, rebuilding)
|
bottomOffset[1] = x + CHUNK_SIZE
|
||||||
|
bottomOffset[2] = y + CHUNK_SIZE
|
||||||
if (chunk ~= -1) then
|
|
||||||
map[x][y] = chunk
|
if map[x] and map[x][y] then
|
||||||
processQueue[#processQueue+1] = chunk
|
mapScanChunk(map[x][y], surface, map)
|
||||||
|
else
|
||||||
|
if map[x] == nil then
|
||||||
|
map[x] = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local chunk = createChunk(x, y)
|
||||||
|
|
||||||
|
chunk = initialScan(chunk, surface, map, tick, rebuilding)
|
||||||
|
|
||||||
|
if (chunk ~= -1) then
|
||||||
|
map[x][y] = chunk
|
||||||
|
processQueue[#processQueue+1] = chunk
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
local newEvent,_ = next(pendingChunks, event)
|
||||||
|
pendingChunks[event] = nil
|
||||||
|
event = newEvent
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
map.chunkProcessorIterator = event
|
||||||
|
|
||||||
if (#processQueue > map.nextChunkSort) or
|
if (#processQueue > map.nextChunkSort) or
|
||||||
(((tick - map.nextChunkSortTick) > MAX_TICKS_BEFORE_SORT_CHUNKS) and ((map.nextChunkSort - 75) ~= #processQueue))
|
(((tick - map.nextChunkSortTick) > MAX_TICKS_BEFORE_SORT_CHUNKS) and
|
||||||
|
((map.nextChunkSort - 150) < #processQueue))
|
||||||
then
|
then
|
||||||
map.nextChunkSort = #processQueue + 75
|
map.nextChunkSort = #processQueue + 150
|
||||||
map.nextChunkSortTick = tick
|
map.nextChunkSortTick = tick
|
||||||
tSort(processQueue, sorter)
|
tSort(processQueue, sorter)
|
||||||
end
|
end
|
||||||
|
@ -79,23 +79,14 @@ end
|
|||||||
function chunkPropertyUtils.setNestCount(map, chunk, count)
|
function chunkPropertyUtils.setNestCount(map, chunk, count)
|
||||||
if (count <= 0) then
|
if (count <= 0) then
|
||||||
map.chunkToNests[chunk] = nil
|
map.chunkToNests[chunk] = nil
|
||||||
|
if (map.processMigrationIterator == chunk) then
|
||||||
|
map.processMigrationIterator = nil
|
||||||
|
end
|
||||||
else
|
else
|
||||||
map.chunkToNests[chunk] = count
|
map.chunkToNests[chunk] = count
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function chunkPropertyUtils.getChunkSettlerTick(map, chunk)
|
|
||||||
return map.chunkToSettler[chunk] or 0
|
|
||||||
end
|
|
||||||
|
|
||||||
function chunkPropertyUtils.setChunkSettlerTick(map, chunk, tick)
|
|
||||||
if (tick <= 0) then
|
|
||||||
map.chunkToSettler[chunk] = nil
|
|
||||||
else
|
|
||||||
map.chunkToSettler[chunk] = tick
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function chunkPropertyUtils.getNestCount(map, chunk)
|
function chunkPropertyUtils.getNestCount(map, chunk)
|
||||||
return map.chunkToNests[chunk] or 0
|
return map.chunkToNests[chunk] or 0
|
||||||
end
|
end
|
||||||
@ -163,6 +154,9 @@ function chunkPropertyUtils.setRaidNestActiveness(map, chunk, value)
|
|||||||
if (map.chunkToActiveRaidNest[chunk] ~= nil) then
|
if (map.chunkToActiveRaidNest[chunk] ~= nil) then
|
||||||
map.natives.activeRaidNests = map.natives.activeRaidNests - 1
|
map.natives.activeRaidNests = map.natives.activeRaidNests - 1
|
||||||
end
|
end
|
||||||
|
if (map.processActiveRaidSpawnerIterator == chunk) then
|
||||||
|
map.processActiveRaidSpawnerIterator = nil
|
||||||
|
end
|
||||||
map.chunkToActiveRaidNest[chunk] = nil
|
map.chunkToActiveRaidNest[chunk] = nil
|
||||||
else
|
else
|
||||||
if (map.chunkToActiveRaidNest[chunk] == nil) then
|
if (map.chunkToActiveRaidNest[chunk] == nil) then
|
||||||
@ -193,6 +187,9 @@ function chunkPropertyUtils.setNestActiveness(map, chunk, value)
|
|||||||
if (map.chunkToActiveNest[chunk] ~= nil) then
|
if (map.chunkToActiveNest[chunk] ~= nil) then
|
||||||
map.natives.activeNests = map.natives.activeNests - 1
|
map.natives.activeNests = map.natives.activeNests - 1
|
||||||
end
|
end
|
||||||
|
if (map.processActiveSpawnerIterator == chunk) then
|
||||||
|
map.processActiveSpawnerIterator = nil
|
||||||
|
end
|
||||||
map.chunkToActiveNest[chunk] = nil
|
map.chunkToActiveNest[chunk] = nil
|
||||||
else
|
else
|
||||||
if (map.chunkToActiveNest[chunk] == nil) then
|
if (map.chunkToActiveNest[chunk] == nil) then
|
||||||
|
@ -58,15 +58,15 @@ constants.CHUNK_PASS_THRESHOLD = 0.25
|
|||||||
constants.INTERVAL_PLAYER_PROCESS = (settings.startup["rampant-liteMode"].value and 124) or 62
|
constants.INTERVAL_PLAYER_PROCESS = (settings.startup["rampant-liteMode"].value and 124) or 62
|
||||||
constants.INTERVAL_MAP_PROCESS = (settings.startup["rampant-liteMode"].value and 8) or 5
|
constants.INTERVAL_MAP_PROCESS = (settings.startup["rampant-liteMode"].value and 8) or 5
|
||||||
constants.INTERVAL_SCAN = (settings.startup["rampant-liteMode"].value and 42) or 21
|
constants.INTERVAL_SCAN = (settings.startup["rampant-liteMode"].value and 42) or 21
|
||||||
constants.INTERVAL_CHUNK = 17
|
|
||||||
constants.INTERVAL_LOGIC = 60
|
constants.INTERVAL_LOGIC = 60
|
||||||
constants.INTERVAL_TEMPERAMENT = 121
|
constants.INTERVAL_TEMPERAMENT = 121
|
||||||
constants.INTERVAL_SQUAD = 41
|
constants.INTERVAL_SQUAD = 17
|
||||||
constants.INTERVAL_RESQUAD = 101
|
constants.INTERVAL_RESQUAD = 101
|
||||||
|
constants.INTERVAL_SPAWNER = 31
|
||||||
constants.INTERVAL_BUILDERS = 300
|
constants.INTERVAL_BUILDERS = 300
|
||||||
constants.INTERVAL_SPAWNER = constants.TICKS_A_SECOND * 10
|
|
||||||
constants.INTERVAL_RALLY = constants.TICKS_A_SECOND * 10
|
constants.COOLDOWN_RALLY = constants.TICKS_A_SECOND * 10
|
||||||
constants.INTERVAL_RETREAT = constants.TICKS_A_SECOND * 10
|
constants.COOLDOWN_RETREAT = constants.TICKS_A_SECOND * 10
|
||||||
|
|
||||||
constants.RESOURCE_NORMALIZER = 1 / 1024
|
constants.RESOURCE_NORMALIZER = 1 / 1024
|
||||||
|
|
||||||
|
@ -36,15 +36,12 @@ local AI_VENGENCE_SQUAD_COST = constants.AI_VENGENCE_SQUAD_COST
|
|||||||
local AI_SETTLER_COST = constants.AI_SETTLER_COST
|
local AI_SETTLER_COST = constants.AI_SETTLER_COST
|
||||||
local AI_STATE_AGGRESSIVE = constants.AI_STATE_AGGRESSIVE
|
local AI_STATE_AGGRESSIVE = constants.AI_STATE_AGGRESSIVE
|
||||||
|
|
||||||
local processNestActiveness = chunkPropertyUtils.processNestActiveness
|
|
||||||
|
|
||||||
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
|
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
|
||||||
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
|
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
|
||||||
local BASE_PHEROMONE = constants.BASE_PHEROMONE
|
local BASE_PHEROMONE = constants.BASE_PHEROMONE
|
||||||
|
|
||||||
local INTERVAL_RALLY = constants.INTERVAL_RALLY
|
local COOLDOWN_RALLY = constants.COOLDOWN_RALLY
|
||||||
local INTERVAL_RETREAT = constants.INTERVAL_RETREAT
|
local COOLDOWN_RETREAT = constants.COOLDOWN_RETREAT
|
||||||
local INTERVAL_SPAWNER = constants.INTERVAL_SPAWNER
|
|
||||||
|
|
||||||
local BASE_PROCESS_INTERVAL = constants.BASE_PROCESS_INTERVAL
|
local BASE_PROCESS_INTERVAL = constants.BASE_PROCESS_INTERVAL
|
||||||
|
|
||||||
@ -52,15 +49,17 @@ local AI_MAX_SQUADS_PER_CYCLE = constants.AI_MAX_SQUADS_PER_CYCLE
|
|||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
-- local scents = pheromoneUtils.scents
|
|
||||||
local processPheromone = pheromoneUtils.processPheromone
|
local processPheromone = pheromoneUtils.processPheromone
|
||||||
local commitPheromone = pheromoneUtils.commitPheromone
|
local commitPheromone = pheromoneUtils.commitPheromone
|
||||||
local playerScent = pheromoneUtils.playerScent
|
local playerScent = pheromoneUtils.playerScent
|
||||||
|
|
||||||
|
local processBase = baseUtils.processBase
|
||||||
|
|
||||||
|
local processNestActiveness = chunkPropertyUtils.processNestActiveness
|
||||||
|
|
||||||
local formSquads = aiAttackWave.formSquads
|
local formSquads = aiAttackWave.formSquads
|
||||||
local formAttackWave = aiAttackWave.formAttackWave
|
|
||||||
local formSettlers = aiAttackWave.formSettlers
|
|
||||||
local formVengenceSquad = aiAttackWave.formVengenceSquad
|
local formVengenceSquad = aiAttackWave.formVengenceSquad
|
||||||
|
local formSettlers = aiAttackWave.formSettlers
|
||||||
|
|
||||||
local getChunkByPosition = mapUtils.getChunkByPosition
|
local getChunkByPosition = mapUtils.getChunkByPosition
|
||||||
local getChunkByXY = mapUtils.getChunkByXY
|
local getChunkByXY = mapUtils.getChunkByXY
|
||||||
@ -89,11 +88,9 @@ local canMigrate = aiPredicates.canMigrate
|
|||||||
|
|
||||||
local findNearbySquad = unitGroupUtils.findNearbySquad
|
local findNearbySquad = unitGroupUtils.findNearbySquad
|
||||||
|
|
||||||
local processBase = baseUtils.processBase
|
|
||||||
|
|
||||||
local mMin = math.min
|
local mMin = math.min
|
||||||
-- local mMax = math.max
|
|
||||||
|
|
||||||
|
local next = next
|
||||||
local mRandom = math.random
|
local mRandom = math.random
|
||||||
|
|
||||||
-- module code
|
-- module code
|
||||||
@ -109,47 +106,21 @@ function mapProcessor.processMap(map, surface, tick)
|
|||||||
local roll = map.processRoll
|
local roll = map.processRoll
|
||||||
local index = map.processIndex
|
local index = map.processIndex
|
||||||
|
|
||||||
local chunkToBase = map.chunkToBase
|
|
||||||
|
|
||||||
local natives = map.natives
|
|
||||||
|
|
||||||
if (index == 1) then
|
if (index == 1) then
|
||||||
roll = mRandom()
|
roll = mRandom()
|
||||||
map.processRoll = roll
|
map.processRoll = roll
|
||||||
natives.remainingSquads = AI_MAX_SQUADS_PER_CYCLE
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local newEnemies = natives.newEnemies
|
|
||||||
local scentStaging = map.scentStaging
|
local scentStaging = map.scentStaging
|
||||||
|
|
||||||
local squads = canAttack(natives, surface) and (roll <= 0.45) and (natives.points >= AI_SQUAD_COST)
|
|
||||||
if squads and (natives.state == AI_STATE_AGGRESSIVE) and (tick < natives.canAttackTick) then
|
|
||||||
squads = false
|
|
||||||
end
|
|
||||||
local settlers = canMigrate(natives, surface) and (roll <= 0.45) and (natives.points >= AI_SETTLER_COST)
|
|
||||||
|
|
||||||
local processQueue = map.processQueue
|
local processQueue = map.processQueue
|
||||||
local endIndex = mMin(index + PROCESS_QUEUE_SIZE, #processQueue)
|
local endIndex = mMin(index + PROCESS_QUEUE_SIZE, #processQueue)
|
||||||
local i = 1
|
local i = 1
|
||||||
|
|
||||||
for x=index,endIndex do
|
for x=index,endIndex do
|
||||||
local chunk = processQueue[x]
|
local chunk = processQueue[x]
|
||||||
|
|
||||||
if (chunk[CHUNK_TICK] ~= tick) then
|
if (chunk[CHUNK_TICK] ~= tick) then
|
||||||
processPheromone(map, chunk, scentStaging[i])
|
processPheromone(map, chunk, scentStaging[i])
|
||||||
|
|
||||||
if settlers and (getNestCount(map, chunk) > 0) then
|
|
||||||
settlers = formSettlers(map, surface, chunk, tick)
|
|
||||||
end
|
|
||||||
if squads then
|
|
||||||
squads = formAttackWave(chunk, map, surface, tick)
|
|
||||||
end
|
|
||||||
|
|
||||||
if newEnemies then
|
|
||||||
local base = chunkToBase[chunk]
|
|
||||||
if base and ((tick - base.tick) > BASE_PROCESS_INTERVAL) then
|
|
||||||
processBase(chunk, surface, natives, tick, base)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
@ -170,12 +141,11 @@ function mapProcessor.processMap(map, surface, tick)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function queueNestSpawners(map, chunk, tick)
|
local function queueNestSpawners(map, chunk, tick)
|
||||||
local limitPerActiveChunkTick = map.natives.activeNests * DURATION_ACTIVE_NEST_DIVIDER
|
local limitPerActiveChunkTick = map.natives.activeNests * DURATION_ACTIVE_NEST_DIVIDER
|
||||||
|
|
||||||
local processActiveNest = map.processActiveNest
|
local processActiveNest = map.processActiveNest
|
||||||
|
|
||||||
if ((getNestActiveness(map, chunk) > 0) and (getNestActiveTick(map, chunk) == 0)) then
|
if ((getNestActiveness(map, chunk) > 0) and (getNestActiveTick(map, chunk) == 0)) then
|
||||||
local nextTick = tick + DURATION_ACTIVE_NEST
|
local nextTick = tick + DURATION_ACTIVE_NEST
|
||||||
local slot = processActiveNest[nextTick]
|
local slot = processActiveNest[nextTick]
|
||||||
@ -223,8 +193,6 @@ function mapProcessor.processPlayers(players, map, surface, tick)
|
|||||||
|
|
||||||
local scentStaging = map.scentStaging
|
local scentStaging = map.scentStaging
|
||||||
|
|
||||||
local squads = allowingAttacks and (0.11 <= roll) and (roll <= 0.20) and (natives.points >= AI_SQUAD_COST)
|
|
||||||
|
|
||||||
-- not looping everyone because the cost is high enough already in multiplayer
|
-- not looping everyone because the cost is high enough already in multiplayer
|
||||||
if (#players > 0) then
|
if (#players > 0) then
|
||||||
local player = players[mRandom(#players)]
|
local player = players[mRandom(#players)]
|
||||||
@ -233,9 +201,10 @@ function mapProcessor.processPlayers(players, map, surface, tick)
|
|||||||
|
|
||||||
if (playerChunk ~= -1) then
|
if (playerChunk ~= -1) then
|
||||||
local i = 1
|
local i = 1
|
||||||
local vengence = (allowingAttacks and
|
local vengence = allowingAttacks and
|
||||||
(natives.points >= AI_VENGENCE_SQUAD_COST) and
|
(natives.points >= AI_VENGENCE_SQUAD_COST) and
|
||||||
((getEnemyStructureCount(map, playerChunk) > 0) or (playerChunk[MOVEMENT_PHEROMONE] < -natives.retreatThreshold)))
|
((getEnemyStructureCount(map, playerChunk) > 0) or
|
||||||
|
(playerChunk[MOVEMENT_PHEROMONE] < -natives.retreatThreshold))
|
||||||
|
|
||||||
for x=playerChunk.x - PROCESS_PLAYER_BOUND, playerChunk.x + PROCESS_PLAYER_BOUND, 32 do
|
for x=playerChunk.x - PROCESS_PLAYER_BOUND, playerChunk.x + PROCESS_PLAYER_BOUND, 32 do
|
||||||
for y=playerChunk.y - PROCESS_PLAYER_BOUND, playerChunk.y + PROCESS_PLAYER_BOUND, 32 do
|
for y=playerChunk.y - PROCESS_PLAYER_BOUND, playerChunk.y + PROCESS_PLAYER_BOUND, 32 do
|
||||||
@ -246,9 +215,14 @@ function mapProcessor.processPlayers(players, map, surface, tick)
|
|||||||
|
|
||||||
processNestActiveness(map, chunk, natives, surface)
|
processNestActiveness(map, chunk, natives, surface)
|
||||||
queueNestSpawners(map, chunk, tick)
|
queueNestSpawners(map, chunk, tick)
|
||||||
|
|
||||||
if vengence and (getNestCount(map, chunk) > 0) then
|
if vengence and (getNestCount(map, chunk) > 0) then
|
||||||
vengence = formVengenceSquad(map, surface, chunk)
|
local count = natives.vengenceQueue[chunk]
|
||||||
|
if not count then
|
||||||
|
count = 0
|
||||||
|
natives.vengenceQueue[chunk] = count
|
||||||
|
end
|
||||||
|
natives.vengenceQueue[chunk] = count + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
i = i + 1
|
i = i + 1
|
||||||
@ -293,8 +267,6 @@ function mapProcessor.scanMap(map, surface, tick)
|
|||||||
|
|
||||||
local retreats = map.chunkToRetreats
|
local retreats = map.chunkToRetreats
|
||||||
local rallys = map.chunkToRallys
|
local rallys = map.chunkToRallys
|
||||||
-- local spawners = map.chunkToSpawner
|
|
||||||
local settlers = map.chunkToSettler
|
|
||||||
local drained = map.chunkToDrained
|
local drained = map.chunkToDrained
|
||||||
|
|
||||||
local processQueue = map.processQueue
|
local processQueue = map.processQueue
|
||||||
@ -314,20 +286,15 @@ function mapProcessor.scanMap(map, surface, tick)
|
|||||||
offset[2] = chunk.y + CHUNK_SIZE
|
offset[2] = chunk.y + CHUNK_SIZE
|
||||||
|
|
||||||
local retreatTick = retreats[chunk]
|
local retreatTick = retreats[chunk]
|
||||||
if retreatTick and ((tick - retreatTick) > INTERVAL_RETREAT) then
|
if retreatTick and ((tick - retreatTick) > COOLDOWN_RETREAT) then
|
||||||
retreats[chunk] = nil
|
retreats[chunk] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local rallyTick = rallys[chunk]
|
local rallyTick = rallys[chunk]
|
||||||
if rallyTick and ((tick - rallyTick) > INTERVAL_RALLY) then
|
if rallyTick and ((tick - rallyTick) > COOLDOWN_RALLY) then
|
||||||
rallys[chunk] = nil
|
rallys[chunk] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local settlerTick = settlers[chunk]
|
|
||||||
if settlerTick and ((tick - settlerTick) > 0) then
|
|
||||||
settlers[chunk] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local drainTick = drained[chunk]
|
local drainTick = drained[chunk]
|
||||||
if drainTick and ((tick - drainTick) > 0) then
|
if drainTick and ((tick - drainTick) > 0) then
|
||||||
drained[chunk] = nil
|
drained[chunk] = nil
|
||||||
@ -362,11 +329,11 @@ function mapProcessor.processActiveNests(map, surface, tick)
|
|||||||
local processActiveNest = map.processActiveNest
|
local processActiveNest = map.processActiveNest
|
||||||
local slot = processActiveNest[tick]
|
local slot = processActiveNest[tick]
|
||||||
if slot then
|
if slot then
|
||||||
|
local natives = map.natives
|
||||||
for i=1,#slot do
|
for i=1,#slot do
|
||||||
local chunk = slot[i]
|
local chunk = slot[i]
|
||||||
if (getNestActiveness(map, chunk) > 0) then
|
if (getNestActiveness(map, chunk) > 0) then
|
||||||
createSpawnerProxy(map, surface, chunk)
|
processNestActiveness(map, chunk, natives, surface)
|
||||||
-- setNestActiveTick(map, chunk, tick)
|
|
||||||
local nextTick = tick + DURATION_ACTIVE_NEST
|
local nextTick = tick + DURATION_ACTIVE_NEST
|
||||||
local nextSlot = processActiveNest[nextTick]
|
local nextSlot = processActiveNest[nextTick]
|
||||||
if not nextSlot then
|
if not nextSlot then
|
||||||
@ -382,7 +349,75 @@ function mapProcessor.processActiveNests(map, surface, tick)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function mapProcessor.processVengence(map, surface, tick)
|
||||||
|
local natives = map.natives
|
||||||
|
local ss = natives.vengenceQueue
|
||||||
|
-- local generated = 0
|
||||||
|
local chunk, count = next(ss, map.deployVengenceIterator)
|
||||||
|
-- for i=1,3 do
|
||||||
|
if not chunk then
|
||||||
|
map.deployVengenceIterator = nil
|
||||||
|
-- break
|
||||||
|
else
|
||||||
|
-- generated = generated + 1
|
||||||
|
formVengenceSquad(map, surface, chunk)
|
||||||
|
local nextChunk
|
||||||
|
nextChunk, count = next(ss, chunk)
|
||||||
|
ss[chunk] = nil
|
||||||
|
chunk = nextChunk
|
||||||
|
end
|
||||||
|
-- end
|
||||||
|
map.deployVengenceIterator = chunk
|
||||||
|
end
|
||||||
|
|
||||||
|
local function processSpawners(map, surface, tick, natives, iteration, iterator, chunks)
|
||||||
|
|
||||||
|
local bases = map.chunkToBase
|
||||||
|
local chunk, count = next(chunks, map[iterator])
|
||||||
|
for i=1,iteration do
|
||||||
|
if not chunk then
|
||||||
|
map[iterator] = nil
|
||||||
|
return
|
||||||
|
else
|
||||||
|
if canMigrate(natives, surface) then
|
||||||
|
formSettlers(map, surface, chunk, tick)
|
||||||
|
elseif (canAttack(natives, surface, tick)) then
|
||||||
|
formSquads(map, surface, chunk, tick)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if (natives.newEnemies) then
|
||||||
|
local base = bases[chunk]
|
||||||
|
if base and ((tick - base.tick) > BASE_PROCESS_INTERVAL) then
|
||||||
|
processBase(chunk, surface, natives, tick, base)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
chunk, count = next(chunks, chunk)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
map[iterator] = chunk
|
||||||
|
end
|
||||||
|
|
||||||
|
function mapProcessor.processSpawners(map, surface, tick)
|
||||||
|
local chunks
|
||||||
|
local natives = map.natives
|
||||||
|
|
||||||
|
if (natives.state ~= AI_STATE_PEACEFUL) then
|
||||||
|
if (natives.state == AI_STATE_MIGRATING) or
|
||||||
|
((natives.state == AI_STATE_SIEGE) and natives.temperament <= 0.5)
|
||||||
|
then
|
||||||
|
processSpawners(map, surface, tick, natives, 2, "processMigrationIterator", map.chunkToNests)
|
||||||
|
else
|
||||||
|
if (natives.state ~= AI_STATE_AGGRESSIVE) then
|
||||||
|
processSpawners(map, surface, tick, natives, 1, "processActiveSpawnerIterator", map.chunkToActiveNest)
|
||||||
|
processSpawners(map, surface, tick, natives, 1, "processActiveRaidSpawnerIterator", map.chunkToActiveRaidNest)
|
||||||
|
else
|
||||||
|
processSpawners(map, surface, tick, natives, 2, "processActiveSpawnerIterator", map.chunkToActiveNest)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
mapProcessorG = mapProcessor
|
mapProcessorG = mapProcessor
|
||||||
return mapProcessor
|
return mapProcessor
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,25 +31,25 @@ local distortPosition = mathUtils.distortPosition
|
|||||||
|
|
||||||
function movementUtils.findMovementPosition(surface, position)
|
function movementUtils.findMovementPosition(surface, position)
|
||||||
local pos = position
|
local pos = position
|
||||||
if not surface.can_place_entity({name="chunk-scanner-squad-movement-rampant", position=pos}) then
|
-- if not surface.can_place_entity({name="chunk-scanner-squad-movement-rampant", position=pos}) then
|
||||||
pos = surface.find_non_colliding_position("chunk-scanner-squad-movement-rampant", pos, 15, 2, true)
|
pos = surface.find_non_colliding_position("chunk-scanner-squad-movement-rampant", pos, 10, 2, false)
|
||||||
end
|
-- end
|
||||||
return pos
|
return pos
|
||||||
end
|
end
|
||||||
|
|
||||||
function movementUtils.findMovementPositionEntity(entityName, surface, position)
|
function movementUtils.findMovementPositionEntity(entityName, surface, position)
|
||||||
local pos = position
|
local pos = position
|
||||||
if not surface.can_place_entity({name=entityName, position=pos}) then
|
-- if not surface.can_place_entity({name=entityName, position=pos}) then
|
||||||
pos = surface.find_non_colliding_position(entityName, pos, 5, 4, true)
|
pos = surface.find_non_colliding_position(entityName, pos, 5, 4, true)
|
||||||
end
|
-- end
|
||||||
return pos
|
return pos
|
||||||
end
|
end
|
||||||
|
|
||||||
function movementUtils.findMovementPositionDistort(surface, position)
|
function movementUtils.findMovementPositionDistort(surface, position)
|
||||||
local pos = position
|
local pos = position
|
||||||
if not surface.can_place_entity({name="chunk-scanner-squad-movement-rampant", position=pos}) then
|
-- if not surface.can_place_entity({name="chunk-scanner-squad-movement-rampant", position=pos}) then
|
||||||
pos = surface.find_non_colliding_position("chunk-scanner-squad-movement-rampant", pos, 15, 2, true)
|
pos = surface.find_non_colliding_position("chunk-scanner-squad-movement-rampant", pos, 10, 2, false)
|
||||||
end
|
-- end
|
||||||
return distortPosition(pos, 8)
|
return distortPosition(pos, 8)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -176,7 +176,6 @@ function movementUtils.scoreNeighborsForSettling(map, chunk, neighborDirectionCh
|
|||||||
neighborDirectionChunks = getNeighborChunks(map, highestChunk.x, highestChunk.y)
|
neighborDirectionChunks = getNeighborChunks(map, highestChunk.x, highestChunk.y)
|
||||||
for x=1,8 do
|
for x=1,8 do
|
||||||
local neighborChunk = neighborDirectionChunks[x]
|
local neighborChunk = neighborDirectionChunks[x]
|
||||||
|
|
||||||
if ((neighborChunk ~= -1) and (neighborChunk ~= chunk) and
|
if ((neighborChunk ~= -1) and (neighborChunk ~= chunk) and
|
||||||
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then
|
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then
|
||||||
local score = scoreFunction(squad, neighborChunk)
|
local score = scoreFunction(squad, neighborChunk)
|
||||||
|
@ -104,7 +104,7 @@ function pheromoneUtils.processPheromone(map, chunk, staging)
|
|||||||
local baseTotal = 0
|
local baseTotal = 0
|
||||||
local playerTotal = 0
|
local playerTotal = 0
|
||||||
local resourceTotal = 0
|
local resourceTotal = 0
|
||||||
|
|
||||||
local neighborCount = 0
|
local neighborCount = 0
|
||||||
|
|
||||||
local neighbor
|
local neighbor
|
||||||
@ -113,151 +113,175 @@ function pheromoneUtils.processPheromone(map, chunk, staging)
|
|||||||
local chunkPass = getPassable(map, chunk)
|
local chunkPass = getPassable(map, chunk)
|
||||||
|
|
||||||
if (chunkPass == CHUNK_ALL_DIRECTIONS) then
|
if (chunkPass == CHUNK_ALL_DIRECTIONS) then
|
||||||
neighbor = tempNeighbors[2]
|
neighbor = tempNeighbors[2]
|
||||||
neighborPass = getPassable(map, neighbor)
|
if (neighbor ~= -1) then
|
||||||
if ((neighbor ~= -1) and
|
neighborPass = getPassable(map, neighbor)
|
||||||
((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH))) then
|
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH)) then
|
||||||
neighborCount = neighborCount + 1
|
neighborCount = neighborCount + 1
|
||||||
movementTotal = movementTotal + (neighbor[MOVEMENT_PHEROMONE] - chunkMovement)
|
-- movementTotal = movementTotal + (neighbor[MOVEMENT_PHEROMONE] - chunkMovement)
|
||||||
baseTotal = baseTotal + (neighbor[BASE_PHEROMONE] - chunkBase)
|
-- baseTotal = baseTotal + (neighbor[BASE_PHEROMONE] - chunkBase)
|
||||||
playerTotal = playerTotal + (neighbor[PLAYER_PHEROMONE] - chunkPlayer)
|
-- playerTotal = playerTotal + (neighbor[PLAYER_PHEROMONE] - chunkPlayer)
|
||||||
resourceTotal = resourceTotal + (neighbor[RESOURCE_PHEROMONE] - chunkResource)
|
-- resourceTotal = resourceTotal + (neighbor[RESOURCE_PHEROMONE] - chunkResource)
|
||||||
|
movementTotal = movementTotal + neighbor[MOVEMENT_PHEROMONE]
|
||||||
|
baseTotal = baseTotal + neighbor[BASE_PHEROMONE]
|
||||||
|
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE]
|
||||||
|
resourceTotal = resourceTotal + neighbor[RESOURCE_PHEROMONE]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
neighbor = tempNeighbors[7]
|
neighbor = tempNeighbors[7]
|
||||||
neighborPass = getPassable(map, neighbor)
|
if (neighbor ~= -1) then
|
||||||
if ((neighbor ~= -1) and
|
neighborPass = getPassable(map, neighbor)
|
||||||
((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH))) then
|
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH)) then
|
||||||
neighborCount = neighborCount + 1
|
neighborCount = neighborCount + 1
|
||||||
movementTotal = movementTotal + (neighbor[MOVEMENT_PHEROMONE] - chunkMovement)
|
movementTotal = movementTotal + neighbor[MOVEMENT_PHEROMONE]
|
||||||
baseTotal = baseTotal + (neighbor[BASE_PHEROMONE] - chunkBase)
|
baseTotal = baseTotal + neighbor[BASE_PHEROMONE]
|
||||||
playerTotal = playerTotal + (neighbor[PLAYER_PHEROMONE] - chunkPlayer)
|
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE]
|
||||||
resourceTotal = resourceTotal + (neighbor[RESOURCE_PHEROMONE] - chunkResource)
|
resourceTotal = resourceTotal + neighbor[RESOURCE_PHEROMONE]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
neighbor = tempNeighbors[4]
|
neighbor = tempNeighbors[4]
|
||||||
neighborPass = getPassable(map, neighbor)
|
if (neighbor ~= -1) then
|
||||||
if ((neighbor ~= -1) and
|
neighborPass = getPassable(map, neighbor)
|
||||||
((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST))) then
|
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST)) then
|
||||||
neighborCount = neighborCount + 1
|
neighborCount = neighborCount + 1
|
||||||
movementTotal = movementTotal + (neighbor[MOVEMENT_PHEROMONE] - chunkMovement)
|
movementTotal = movementTotal + neighbor[MOVEMENT_PHEROMONE]
|
||||||
baseTotal = baseTotal + (neighbor[BASE_PHEROMONE] - chunkBase)
|
baseTotal = baseTotal + neighbor[BASE_PHEROMONE]
|
||||||
playerTotal = playerTotal + (neighbor[PLAYER_PHEROMONE] - chunkPlayer)
|
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE]
|
||||||
resourceTotal = resourceTotal + (neighbor[RESOURCE_PHEROMONE] - chunkResource)
|
resourceTotal = resourceTotal + neighbor[RESOURCE_PHEROMONE]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
neighbor = tempNeighbors[5]
|
neighbor = tempNeighbors[5]
|
||||||
neighborPass = getPassable(map, neighbor)
|
if (neighbor ~= -1) then
|
||||||
if ((neighbor ~= -1) and
|
neighborPass = getPassable(map, neighbor)
|
||||||
((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST))) then
|
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST)) then
|
||||||
neighborCount = neighborCount + 1
|
neighborCount = neighborCount + 1
|
||||||
movementTotal = movementTotal + (neighbor[MOVEMENT_PHEROMONE] - chunkMovement)
|
movementTotal = movementTotal + neighbor[MOVEMENT_PHEROMONE]
|
||||||
baseTotal = baseTotal + (neighbor[BASE_PHEROMONE] - chunkBase)
|
baseTotal = baseTotal + neighbor[BASE_PHEROMONE]
|
||||||
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE] - chunkPlayer
|
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE]
|
||||||
resourceTotal = resourceTotal + (neighbor[RESOURCE_PHEROMONE] - chunkResource)
|
resourceTotal = resourceTotal + neighbor[RESOURCE_PHEROMONE]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
neighbor = tempNeighbors[1]
|
neighbor = tempNeighbors[1]
|
||||||
neighborPass = getPassable(map, neighbor)
|
if (neighbor ~= -1) then
|
||||||
if (neighbor ~= -1) and (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
neighborPass = getPassable(map, neighbor)
|
||||||
neighborCount = neighborCount + 1
|
if (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
||||||
movementTotal = movementTotal + (neighbor[MOVEMENT_PHEROMONE] - chunkMovement)
|
neighborCount = neighborCount + 1
|
||||||
baseTotal = baseTotal + (neighbor[BASE_PHEROMONE] - chunkBase)
|
movementTotal = movementTotal + neighbor[MOVEMENT_PHEROMONE]
|
||||||
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE] - chunkPlayer
|
baseTotal = baseTotal + neighbor[BASE_PHEROMONE]
|
||||||
resourceTotal = resourceTotal + (neighbor[RESOURCE_PHEROMONE] - chunkResource)
|
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE]
|
||||||
|
resourceTotal = resourceTotal + neighbor[RESOURCE_PHEROMONE]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
neighbor = tempNeighbors[3]
|
neighbor = tempNeighbors[3]
|
||||||
neighborPass = getPassable(map, neighbor)
|
if (neighbor ~= -1) then
|
||||||
if (neighbor ~= -1) and (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
neighborPass = getPassable(map, neighbor)
|
||||||
neighborCount = neighborCount + 1
|
if (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
||||||
movementTotal = movementTotal + (neighbor[MOVEMENT_PHEROMONE] - chunkMovement)
|
neighborCount = neighborCount + 1
|
||||||
baseTotal = baseTotal + (neighbor[BASE_PHEROMONE] - chunkBase)
|
movementTotal = movementTotal + neighbor[MOVEMENT_PHEROMONE]
|
||||||
playerTotal = playerTotal + (neighbor[PLAYER_PHEROMONE] - chunkPlayer)
|
baseTotal = baseTotal + neighbor[BASE_PHEROMONE]
|
||||||
resourceTotal = resourceTotal + (neighbor[RESOURCE_PHEROMONE] - chunkResource)
|
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE]
|
||||||
|
resourceTotal = resourceTotal + neighbor[RESOURCE_PHEROMONE]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
neighbor = tempNeighbors[6]
|
neighbor = tempNeighbors[6]
|
||||||
neighborPass = getPassable(map, neighbor)
|
if (neighbor ~= -1) then
|
||||||
if (neighbor ~= -1) and (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
neighborPass = getPassable(map, neighbor)
|
||||||
neighborCount = neighborCount + 1
|
if (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
||||||
movementTotal = movementTotal + (neighbor[MOVEMENT_PHEROMONE] - chunkMovement)
|
neighborCount = neighborCount + 1
|
||||||
baseTotal = baseTotal + (neighbor[BASE_PHEROMONE] - chunkBase)
|
movementTotal = movementTotal + neighbor[MOVEMENT_PHEROMONE]
|
||||||
playerTotal = playerTotal + (neighbor[PLAYER_PHEROMONE] - chunkPlayer)
|
baseTotal = baseTotal + neighbor[BASE_PHEROMONE]
|
||||||
resourceTotal = resourceTotal + (neighbor[RESOURCE_PHEROMONE] - chunkResource)
|
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE]
|
||||||
|
resourceTotal = resourceTotal + neighbor[RESOURCE_PHEROMONE]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
neighbor = tempNeighbors[8]
|
neighbor = tempNeighbors[8]
|
||||||
neighborPass = getPassable(map, neighbor)
|
if (neighbor ~= -1) then
|
||||||
if (neighbor ~= -1) and (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
neighborPass = getPassable(map, neighbor)
|
||||||
neighborCount = neighborCount + 1
|
if (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
||||||
movementTotal = movementTotal + (neighbor[MOVEMENT_PHEROMONE] - chunkMovement)
|
neighborCount = neighborCount + 1
|
||||||
baseTotal = baseTotal + (neighbor[BASE_PHEROMONE] - chunkBase)
|
movementTotal = movementTotal + neighbor[MOVEMENT_PHEROMONE]
|
||||||
playerTotal = playerTotal + (neighbor[PLAYER_PHEROMONE] - chunkPlayer)
|
baseTotal = baseTotal + neighbor[BASE_PHEROMONE]
|
||||||
resourceTotal = resourceTotal + (neighbor[RESOURCE_PHEROMONE] - chunkResource)
|
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE]
|
||||||
|
resourceTotal = resourceTotal + neighbor[RESOURCE_PHEROMONE]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif (chunkPass == CHUNK_EAST_WEST) then
|
elseif (chunkPass == CHUNK_EAST_WEST) then
|
||||||
|
|
||||||
neighbor = tempNeighbors[4]
|
neighbor = tempNeighbors[4]
|
||||||
neighborPass = getPassable(map, neighbor)
|
if (neighbor ~= -1) then
|
||||||
if ((neighbor ~= -1) and
|
neighborPass = getPassable(map, neighbor)
|
||||||
((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST))) then
|
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST)) then
|
||||||
neighborCount = neighborCount + 1
|
neighborCount = neighborCount + 1
|
||||||
movementTotal = movementTotal + (neighbor[MOVEMENT_PHEROMONE] - chunkMovement)
|
movementTotal = movementTotal + neighbor[MOVEMENT_PHEROMONE]
|
||||||
baseTotal = baseTotal + (neighbor[BASE_PHEROMONE] - chunkBase)
|
baseTotal = baseTotal + neighbor[BASE_PHEROMONE]
|
||||||
playerTotal = playerTotal + (neighbor[PLAYER_PHEROMONE] - chunkPlayer)
|
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE]
|
||||||
resourceTotal = resourceTotal + (neighbor[RESOURCE_PHEROMONE] - chunkResource)
|
resourceTotal = resourceTotal + neighbor[RESOURCE_PHEROMONE]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
neighbor = tempNeighbors[5]
|
neighbor = tempNeighbors[5]
|
||||||
neighborPass = getPassable(map, neighbor)
|
if (neighbor ~= -1) then
|
||||||
if ((neighbor ~= -1) and
|
neighborPass = getPassable(map, neighbor)
|
||||||
((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST))) then
|
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST)) then
|
||||||
neighborCount = neighborCount + 1
|
neighborCount = neighborCount + 1
|
||||||
movementTotal = movementTotal + (neighbor[MOVEMENT_PHEROMONE] - chunkMovement)
|
movementTotal = movementTotal + neighbor[MOVEMENT_PHEROMONE]
|
||||||
baseTotal = baseTotal + (neighbor[BASE_PHEROMONE] - chunkBase)
|
baseTotal = baseTotal + neighbor[BASE_PHEROMONE]
|
||||||
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE] - chunkPlayer
|
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE]
|
||||||
resourceTotal = resourceTotal + (neighbor[RESOURCE_PHEROMONE] - chunkResource)
|
resourceTotal = resourceTotal + neighbor[RESOURCE_PHEROMONE]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif (chunkPass == CHUNK_NORTH_SOUTH) then
|
elseif (chunkPass == CHUNK_NORTH_SOUTH) then
|
||||||
|
|
||||||
neighbor = tempNeighbors[2]
|
neighbor = tempNeighbors[2]
|
||||||
neighborPass = getPassable(map, neighbor)
|
if (neighbor ~= -1) then
|
||||||
if ((neighbor ~= -1) and
|
neighborPass = getPassable(map, neighbor)
|
||||||
((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH))) then
|
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH)) then
|
||||||
neighborCount = neighborCount + 1
|
neighborCount = neighborCount + 1
|
||||||
movementTotal = movementTotal + (neighbor[MOVEMENT_PHEROMONE] - chunkMovement)
|
movementTotal = movementTotal + neighbor[MOVEMENT_PHEROMONE]
|
||||||
baseTotal = baseTotal + (neighbor[BASE_PHEROMONE] - chunkBase)
|
baseTotal = baseTotal + neighbor[BASE_PHEROMONE]
|
||||||
playerTotal = playerTotal + (neighbor[PLAYER_PHEROMONE] - chunkPlayer)
|
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE]
|
||||||
resourceTotal = resourceTotal + (neighbor[RESOURCE_PHEROMONE] - chunkResource)
|
resourceTotal = resourceTotal + neighbor[RESOURCE_PHEROMONE]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
neighbor = tempNeighbors[7]
|
neighbor = tempNeighbors[7]
|
||||||
neighborPass = getPassable(map, neighbor)
|
if (neighbor ~= -1) then
|
||||||
if ((neighbor ~= -1) and
|
neighborPass = getPassable(map, neighbor)
|
||||||
((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH))) then
|
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH)) then
|
||||||
neighborCount = neighborCount + 1
|
neighborCount = neighborCount + 1
|
||||||
movementTotal = movementTotal + (neighbor[MOVEMENT_PHEROMONE] - chunkMovement)
|
movementTotal = movementTotal + neighbor[MOVEMENT_PHEROMONE]
|
||||||
baseTotal = baseTotal + (neighbor[BASE_PHEROMONE] - chunkBase)
|
baseTotal = baseTotal + neighbor[BASE_PHEROMONE]
|
||||||
playerTotal = playerTotal + (neighbor[PLAYER_PHEROMONE] - chunkPlayer)
|
playerTotal = playerTotal + neighbor[PLAYER_PHEROMONE]
|
||||||
resourceTotal = resourceTotal + (neighbor[RESOURCE_PHEROMONE] - chunkResource)
|
resourceTotal = resourceTotal + neighbor[RESOURCE_PHEROMONE]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local neighborDiv = 0
|
local neighborDiv = 0
|
||||||
if neighborCount ~= 0 then
|
if neighborCount ~= 0 then
|
||||||
neighborDiv = NEIGHBOR_DIVIDER[neighborCount]
|
neighborDiv = NEIGHBOR_DIVIDER[neighborCount]
|
||||||
|
chunkMovement = chunkMovement + (neighborDiv * (movementTotal - (chunkMovement * neighborCount)))
|
||||||
|
chunkBase = chunkBase + (neighborDiv * (baseTotal - (chunkBase * neighborCount)))
|
||||||
|
chunkPlayer = chunkPlayer + (neighborDiv * (playerTotal - (chunkPlayer * neighborCount)))
|
||||||
|
chunkResource = chunkResource + (neighborDiv * (resourceTotal - (chunkResource * neighborCount)))
|
||||||
end
|
end
|
||||||
|
|
||||||
staging[MOVEMENT_PHEROMONE] = (chunkMovement + (neighborDiv * movementTotal)) * MOVEMENT_PHEROMONE_PERSISTANCE * chunkPathRating
|
staging[MOVEMENT_PHEROMONE] = chunkMovement * MOVEMENT_PHEROMONE_PERSISTANCE * chunkPathRating
|
||||||
staging[BASE_PHEROMONE] = (chunkBase + (neighborDiv * baseTotal)) * BASE_PHEROMONE_PERSISTANCE * chunkPathRating
|
staging[BASE_PHEROMONE] = chunkBase * BASE_PHEROMONE_PERSISTANCE * chunkPathRating
|
||||||
staging[PLAYER_PHEROMONE] = (chunkPlayer + (neighborDiv * playerTotal)) * PLAYER_PHEROMONE_PERSISTANCE * chunkPathRating
|
staging[PLAYER_PHEROMONE] = chunkPlayer * PLAYER_PHEROMONE_PERSISTANCE * chunkPathRating
|
||||||
if clear then
|
if clear then
|
||||||
staging[RESOURCE_PHEROMONE] = (chunkResource + (neighborDiv * resourceTotal)) * RESOURCE_PHEROMONE_PERSISTANCE * chunkPathRating
|
staging[RESOURCE_PHEROMONE] = chunkResource * RESOURCE_PHEROMONE_PERSISTANCE * chunkPathRating
|
||||||
else
|
else
|
||||||
staging[RESOURCE_PHEROMONE] = (chunkResource + (neighborDiv * resourceTotal)) * 0.01
|
staging[RESOURCE_PHEROMONE] = chunkResource * 0.01
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -76,7 +76,6 @@ local positionFromDirectionAndChunk = mapUtils.positionFromDirectionAndChunk
|
|||||||
local positionFromDirectionAndFlat = mapUtils.positionFromDirectionAndFlat
|
local positionFromDirectionAndFlat = mapUtils.positionFromDirectionAndFlat
|
||||||
|
|
||||||
local createSquad = unitGroupUtils.createSquad
|
local createSquad = unitGroupUtils.createSquad
|
||||||
local membersToSquad = unitGroupUtils.membersToSquad
|
|
||||||
|
|
||||||
local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
|
local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
|
||||||
|
|
||||||
@ -108,14 +107,14 @@ local function scoreAttackLocation(natives, squad, neighborChunk)
|
|||||||
if (movementPheromone >= 0) then
|
if (movementPheromone >= 0) then
|
||||||
damage = movementPheromone + (neighborChunk[BASE_PHEROMONE]) + (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
|
damage = movementPheromone + (neighborChunk[BASE_PHEROMONE]) + (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
|
||||||
else
|
else
|
||||||
damage = (neighborChunk[BASE_PHEROMONE] * (1 - (movementPheromone / -natives.retreatThreshold))) + (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
|
damage = (neighborChunk[BASE_PHEROMONE] * (1 - (movementPheromone / -natives.retreatThreshold))) + (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER) + (getPlayerBaseGenerator(natives.map, neighborChunk) * PLAYER_PHEROMONE_MULTIPLER)
|
||||||
end
|
end
|
||||||
|
|
||||||
return damage -- - lookupMovementPenalty(squad, neighborChunk)
|
return damage -- - lookupMovementPenalty(squad, neighborChunk)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function scoreAttackKamikazeLocation(natives, squad, neighborChunk)
|
local function scoreAttackKamikazeLocation(natives, squad, neighborChunk)
|
||||||
local damage = neighborChunk[BASE_PHEROMONE] + (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
|
local damage = neighborChunk[BASE_PHEROMONE] + (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER) + (getPlayerBaseGenerator(natives.map, neighborChunk) * PLAYER_PHEROMONE_MULTIPLER)
|
||||||
return damage -- - lookupMovementPenalty(squad, neighborChunk)
|
return damage -- - lookupMovementPenalty(squad, neighborChunk)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -140,7 +139,6 @@ local function settleMove(map, squad, surface)
|
|||||||
groupPosition.y,
|
groupPosition.y,
|
||||||
squad.originPosition.x,
|
squad.originPosition.x,
|
||||||
squad.originPosition.y)
|
squad.originPosition.y)
|
||||||
|
|
||||||
local cmd
|
local cmd
|
||||||
local position
|
local position
|
||||||
local position2
|
local position2
|
||||||
@ -165,18 +163,7 @@ local function settleMove(map, squad, surface)
|
|||||||
|
|
||||||
squad.status = SQUAD_BUILDING
|
squad.status = SQUAD_BUILDING
|
||||||
|
|
||||||
map.buildPositionTop.x = position.x - BASE_CLEAN_DISTANCE
|
surface.create_entity(map.createBuildCloudQuery)
|
||||||
map.buildPositionTop.y = position.y - BASE_CLEAN_DISTANCE
|
|
||||||
map.buildPositionBottom.x = position.x + BASE_CLEAN_DISTANCE
|
|
||||||
map.buildPositionBottom.y = position.y + BASE_CLEAN_DISTANCE
|
|
||||||
|
|
||||||
local entities = surface.find_entities_filtered(map.filteredEntitiesClearBuildingQuery)
|
|
||||||
for i=1,#entities do
|
|
||||||
local entity = entities[i]
|
|
||||||
if entity.valid and (entity.type ~= "cliff") then
|
|
||||||
entity.die()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
group.set_command(cmd)
|
group.set_command(cmd)
|
||||||
else
|
else
|
||||||
@ -186,70 +173,52 @@ local function settleMove(map, squad, surface)
|
|||||||
scoreFunction,
|
scoreFunction,
|
||||||
squad)
|
squad)
|
||||||
|
|
||||||
|
|
||||||
if (attackChunk == -1) then
|
if (attackChunk == -1) then
|
||||||
cmd = map.wonderCommand
|
cmd = map.wonderCommand
|
||||||
group.set_command(cmd)
|
group.set_command(cmd)
|
||||||
return
|
return
|
||||||
else
|
elseif (attackDirection ~= 0) then
|
||||||
positionFromDirectionAndFlat(attackDirection, groupPosition, targetPosition)
|
|
||||||
position = findMovementPosition(surface, targetPosition)
|
|
||||||
|
|
||||||
local attackPlayerThreshold = natives.attackPlayerThreshold
|
local attackPlayerThreshold = natives.attackPlayerThreshold
|
||||||
|
|
||||||
if not position then
|
if (nextAttackChunk ~= -1) then
|
||||||
|
attackChunk = nextAttackChunk
|
||||||
|
positionFromDirectionAndFlat(attackDirection, groupPosition, targetPosition)
|
||||||
|
positionFromDirectionAndFlat(nextAttackDirection, targetPosition, targetPosition2)
|
||||||
|
position = findMovementPosition(surface, targetPosition2)
|
||||||
|
else
|
||||||
|
positionFromDirectionAndFlat(attackDirection, groupPosition, targetPosition)
|
||||||
|
position = findMovementPosition(surface, targetPosition)
|
||||||
|
end
|
||||||
|
|
||||||
|
if position then
|
||||||
|
targetPosition.x = position.x
|
||||||
|
targetPosition.y = position.y
|
||||||
|
else
|
||||||
cmd = map.wonderCommand
|
cmd = map.wonderCommand
|
||||||
group.set_command(cmd)
|
group.set_command(cmd)
|
||||||
return
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if (getPlayerBaseGenerator(map, attackChunk) ~= 0) or
|
||||||
|
(attackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold)
|
||||||
|
then
|
||||||
|
cmd = map.attackCommand
|
||||||
|
|
||||||
|
if not squad.rabid then
|
||||||
|
squad.frenzy = true
|
||||||
|
squad.frenzyPosition.x = groupPosition.x
|
||||||
|
squad.frenzyPosition.y = groupPosition.y
|
||||||
|
end
|
||||||
else
|
else
|
||||||
targetPosition.x = position.x
|
cmd = map.moveCommand
|
||||||
targetPosition.y = position.y
|
if squad.rabid or squad.kamikaze then
|
||||||
|
cmd.distraction = DEFINES_DISTRACTION_NONE
|
||||||
if (getPlayerBaseGenerator(map, attackChunk) ~= 0) or
|
|
||||||
(attackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold)
|
|
||||||
then
|
|
||||||
cmd = map.attackCommand
|
|
||||||
|
|
||||||
if not squad.rabid then
|
|
||||||
squad.frenzy = true
|
|
||||||
squad.frenzyPosition.x = groupPosition.x
|
|
||||||
squad.frenzyPosition.y = groupPosition.y
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
cmd = map.moveCommand
|
cmd.distraction = DEFINES_DISTRACTION_BY_ENEMY
|
||||||
if squad.rabid or squad.kamikaze then
|
|
||||||
cmd.distraction = DEFINES_DISTRACTION_NONE
|
|
||||||
else
|
|
||||||
cmd.distraction = DEFINES_DISTRACTION_BY_ENEMY
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
else
|
||||||
if (nextAttackChunk ~= -1) then
|
|
||||||
positionFromDirectionAndFlat(nextAttackDirection, targetPosition, targetPosition2)
|
|
||||||
|
|
||||||
position2 = findMovementPosition(surface, targetPosition2)
|
|
||||||
|
|
||||||
if position2 then
|
|
||||||
targetPosition.x = position2.x
|
|
||||||
targetPosition.y = position2.y
|
|
||||||
|
|
||||||
if ((cmd ~= map.attackCommand) and
|
|
||||||
((getPlayerBaseGenerator(map, nextAttackChunk) ~= 0) or
|
|
||||||
(nextAttackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold)))
|
|
||||||
then
|
|
||||||
cmd = map.attackCommand
|
|
||||||
|
|
||||||
if not squad.rabid then
|
|
||||||
squad.frenzy = true
|
|
||||||
squad.frenzyPosition.x = groupPosition.x
|
|
||||||
squad.frenzyPosition.y = groupPosition.y
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if (attackDirection == 0) then
|
|
||||||
cmd = map.settleCommand
|
cmd = map.settleCommand
|
||||||
if squad.kamikaze then
|
if squad.kamikaze then
|
||||||
cmd.distraction = DEFINES_DISTRACTION_NONE
|
cmd.distraction = DEFINES_DISTRACTION_NONE
|
||||||
@ -259,32 +228,21 @@ local function settleMove(map, squad, surface)
|
|||||||
|
|
||||||
squad.status = SQUAD_BUILDING
|
squad.status = SQUAD_BUILDING
|
||||||
|
|
||||||
map.buildPositionTop.x = targetPosition.x - BASE_CLEAN_DISTANCE
|
surface.create_entity(map.createBuildCloudQuery)
|
||||||
map.buildPositionTop.y = targetPosition.y - BASE_CLEAN_DISTANCE
|
|
||||||
map.buildPositionBottom.x = targetPosition.x + BASE_CLEAN_DISTANCE
|
|
||||||
map.buildPositionBottom.y = targetPosition.y + BASE_CLEAN_DISTANCE
|
|
||||||
|
|
||||||
local entities = surface.find_entities_filtered(map.filteredEntitiesClearBuildingQuery)
|
|
||||||
for i=1,#entities do
|
|
||||||
local entity = entities[i]
|
|
||||||
if entity.valid and (entity.type ~= "cliff") then
|
|
||||||
entity.die()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
group.set_command(cmd)
|
|
||||||
else
|
|
||||||
group.set_command(cmd)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
group.set_command(cmd)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function attackMove(map, squad, surface)
|
local function attackMove(map, squad, surface)
|
||||||
|
|
||||||
local targetPosition = map.position
|
local targetPosition = map.position
|
||||||
local targetPosition2 = map.position2
|
local targetPosition2 = map.position2
|
||||||
|
|
||||||
local group = squad.group
|
local group = squad.group
|
||||||
|
|
||||||
|
local position
|
||||||
local groupPosition = group.position
|
local groupPosition = group.position
|
||||||
local x, y = positionToChunkXY(groupPosition)
|
local x, y = positionToChunkXY(groupPosition)
|
||||||
local chunk = getChunkByXY(map, x, y)
|
local chunk = getChunkByXY(map, x, y)
|
||||||
@ -305,68 +263,45 @@ local function attackMove(map, squad, surface)
|
|||||||
cmd = map.wonderCommand
|
cmd = map.wonderCommand
|
||||||
group.set_command(cmd)
|
group.set_command(cmd)
|
||||||
return
|
return
|
||||||
|
elseif (nextAttackChunk ~= -1) then
|
||||||
|
attackChunk = nextAttackChunk
|
||||||
|
positionFromDirectionAndFlat(attackDirection, groupPosition, targetPosition)
|
||||||
|
positionFromDirectionAndFlat(nextAttackDirection, targetPosition, targetPosition2)
|
||||||
|
position = findMovementPosition(surface, targetPosition2)
|
||||||
else
|
else
|
||||||
positionFromDirectionAndFlat(attackDirection, groupPosition, targetPosition)
|
positionFromDirectionAndFlat(attackDirection, groupPosition, targetPosition)
|
||||||
|
position = findMovementPosition(surface, targetPosition)
|
||||||
local attackPlayerThreshold = map.natives.attackPlayerThreshold
|
|
||||||
local position = findMovementPosition(surface, targetPosition)
|
|
||||||
|
|
||||||
if not position then
|
|
||||||
cmd = map.wonderCommand
|
|
||||||
group.set_command(cmd)
|
|
||||||
return
|
|
||||||
else
|
|
||||||
targetPosition.x = position.x
|
|
||||||
targetPosition.y = position.y
|
|
||||||
|
|
||||||
if (getPlayerBaseGenerator(map, attackChunk) ~= 0) and
|
|
||||||
(attackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold)
|
|
||||||
then
|
|
||||||
cmd = map.attackCommand
|
|
||||||
|
|
||||||
if not squad.rabid then
|
|
||||||
squad.frenzy = true
|
|
||||||
squad.frenzyPosition.x = groupPosition.x
|
|
||||||
squad.frenzyPosition.y = groupPosition.y
|
|
||||||
end
|
|
||||||
else
|
|
||||||
cmd = map.moveCommand
|
|
||||||
if squad.rabid or squad.frenzy then
|
|
||||||
cmd.distraction = DEFINES_DISTRACTION_BY_ANYTHING
|
|
||||||
else
|
|
||||||
cmd.distraction = DEFINES_DISTRACTION_BY_ENEMY
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local position2
|
|
||||||
|
|
||||||
if (nextAttackChunk ~= -1) then
|
|
||||||
positionFromDirectionAndFlat(nextAttackDirection, targetPosition, targetPosition2)
|
|
||||||
|
|
||||||
position2 = findMovementPosition(surface, targetPosition2)
|
|
||||||
|
|
||||||
if position2 then
|
|
||||||
targetPosition.x = position2.x
|
|
||||||
targetPosition.y = position2.y
|
|
||||||
|
|
||||||
if (cmd ~= map.attackCommand) and
|
|
||||||
((getPlayerBaseGenerator(map, nextAttackChunk) ~= 0) or
|
|
||||||
(nextAttackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold))
|
|
||||||
then
|
|
||||||
cmd = map.attackCommand
|
|
||||||
|
|
||||||
if not squad.rabid then
|
|
||||||
squad.frenzy = true
|
|
||||||
squad.frenzyPosition.x = groupPosition.x
|
|
||||||
squad.frenzyPosition.y = groupPosition.y
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
group.set_command(cmd)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not position then
|
||||||
|
cmd = map.wonderCommand
|
||||||
|
group.set_command(cmd)
|
||||||
|
return
|
||||||
|
else
|
||||||
|
targetPosition.x = position.x
|
||||||
|
targetPosition.y = position.y
|
||||||
|
end
|
||||||
|
|
||||||
|
if (getPlayerBaseGenerator(map, attackChunk) ~= 0) and
|
||||||
|
(attackChunk[PLAYER_PHEROMONE] >= map.natives.attackPlayerThreshold)
|
||||||
|
then
|
||||||
|
cmd = map.attackCommand
|
||||||
|
|
||||||
|
if not squad.rabid then
|
||||||
|
squad.frenzy = true
|
||||||
|
squad.frenzyPosition.x = groupPosition.x
|
||||||
|
squad.frenzyPosition.y = groupPosition.y
|
||||||
|
end
|
||||||
|
else
|
||||||
|
cmd = map.moveCommand
|
||||||
|
if squad.rabid or squad.frenzy then
|
||||||
|
cmd.distraction = DEFINES_DISTRACTION_BY_ANYTHING
|
||||||
|
else
|
||||||
|
cmd.distraction = DEFINES_DISTRACTION_BY_ENEMY
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
group.set_command(cmd)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function buildMove(map, squad, surface)
|
local function buildMove(map, squad, surface)
|
||||||
@ -385,53 +320,36 @@ local function buildMove(map, squad, surface)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function squadAttack.squadDispatch(map, surface, squad)
|
function squadAttack.squadDispatch(map, surface, squad)
|
||||||
|
-- local profiler = game.create_profiler()
|
||||||
local group = squad.group
|
local group = squad.group
|
||||||
if group and group.valid then
|
if group and group.valid then
|
||||||
local memberCount = #group.members
|
local status = squad.status
|
||||||
if (memberCount == 0) then
|
if (status == SQUAD_RAIDING) then
|
||||||
removeSquadFromChunk(map, squad)
|
attackMove(map, squad, surface)
|
||||||
local deathGen = getDeathGenerator(map, squad.chunk)
|
elseif (status == SQUAD_SETTLING) then
|
||||||
local penalties = squad.penalties
|
settleMove(map, squad, surface)
|
||||||
for xc=1,mMin(#squad.penalties,5) do
|
elseif (status == SQUAD_RETREATING) then
|
||||||
addDeathGenerator(map,
|
if squad.settlers then
|
||||||
penalties[xc].c,
|
squad.status = SQUAD_SETTLING
|
||||||
deathGen * DIVISOR_DEATH_TRAIL_TABLE[xc])
|
|
||||||
end
|
|
||||||
group.destroy()
|
|
||||||
elseif (memberCount > AI_MAX_BITER_GROUP_SIZE) then
|
|
||||||
local members = group.members
|
|
||||||
unitGroupUtils.recycleBiters(natives, members)
|
|
||||||
removeSquadFromChunk(map, squad)
|
|
||||||
group.destroy()
|
|
||||||
else
|
|
||||||
local status = squad.status
|
|
||||||
|
|
||||||
if (status == SQUAD_RAIDING) then
|
|
||||||
attackMove(map, squad, surface)
|
|
||||||
elseif (status == SQUAD_SETTLING) then
|
|
||||||
settleMove(map, squad, surface)
|
settleMove(map, squad, surface)
|
||||||
elseif (status == SQUAD_RETREATING) then
|
else
|
||||||
if squad.settlers then
|
squad.status = SQUAD_RAIDING
|
||||||
squad.status = SQUAD_SETTLING
|
attackMove(map, squad, surface)
|
||||||
settleMove(map, squad, surface)
|
end
|
||||||
else
|
elseif (status == SQUAD_BUILDING) then
|
||||||
squad.status = SQUAD_RAIDING
|
removeSquadFromChunk(map, squad)
|
||||||
attackMove(map, squad, surface)
|
buildMove(map, squad, surface)
|
||||||
end
|
elseif (status == SQUAD_GUARDING) then
|
||||||
elseif (status == SQUAD_BUILDING) then
|
if squad.settlers then
|
||||||
removeSquadFromChunk(map, squad)
|
squad.status = SQUAD_SETTLING
|
||||||
buildMove(map, squad, surface)
|
settleMove(map, squad, surface)
|
||||||
elseif (status == SQUAD_GUARDING) then
|
else
|
||||||
if squad.settlers then
|
squad.status = SQUAD_RAIDING
|
||||||
squad.status = SQUAD_SETTLING
|
attackMove(map, squad, surface)
|
||||||
settleMove(map, squad, surface)
|
|
||||||
else
|
|
||||||
squad.status = SQUAD_RAIDING
|
|
||||||
attackMove(map, squad, surface)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- game.print({"", "--dispatch4 ", profiler})
|
||||||
end
|
end
|
||||||
|
|
||||||
squadAttackG = squadAttack
|
squadAttackG = squadAttack
|
||||||
|
@ -21,7 +21,7 @@ local PLAYER_PHEROMONE_MULTIPLER = constants.PLAYER_PHEROMONE_MULTIPLER
|
|||||||
|
|
||||||
local SQUAD_RETREATING = constants.SQUAD_RETREATING
|
local SQUAD_RETREATING = constants.SQUAD_RETREATING
|
||||||
|
|
||||||
local INTERVAL_RETREAT = constants.INTERVAL_RETREAT
|
local COOLDOWN_RETREAT = constants.COOLDOWN_RETREAT
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
@ -54,23 +54,24 @@ local function scoreRetreatLocation(map, neighborChunk)
|
|||||||
-(getPlayerBaseGenerator(map, neighborChunk) * 1000))
|
-(getPlayerBaseGenerator(map, neighborChunk) * 1000))
|
||||||
end
|
end
|
||||||
|
|
||||||
function aiDefense.retreatUnits(chunk, position, group, map, surface, tick, radius, artilleryBlast)
|
function aiDefense.retreatUnits(chunk, position, group, map, surface, tick, radius)
|
||||||
if (tick - getRetreatTick(map, chunk) > INTERVAL_RETREAT) and
|
if (tick - getRetreatTick(map, chunk) > COOLDOWN_RETREAT) and (getEnemyStructureCount(map, chunk) == 0) then
|
||||||
((getEnemyStructureCount(map, chunk) == 0) or artilleryBlast)
|
|
||||||
then
|
|
||||||
local performRetreat = false
|
local performRetreat = false
|
||||||
local enemiesToSquad = nil
|
local enemiesToSquad = nil
|
||||||
|
|
||||||
local squad
|
local squad
|
||||||
|
local groupMembers
|
||||||
if group and group.valid then
|
if group and group.valid then
|
||||||
squad = map.natives.groupNumberToSquad[group.group_number]
|
squad = map.natives.groupNumberToSquad[group.group_number]
|
||||||
if not squad then
|
if not squad then
|
||||||
squad = createSquad(position, surface, group)
|
squad = createSquad(position, surface, group)
|
||||||
squad.kamikaze = mRandom() < calculateKamikazeThreshold(group.members, natives)
|
groupMembers = group.members
|
||||||
|
squad.kamikaze = mRandom() < calculateKamikazeThreshold(#groupMembers, natives)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not squad then
|
if not squad then
|
||||||
|
print("grabbing people", position.x, position.y)
|
||||||
enemiesToSquad = map.enemiesToSquad
|
enemiesToSquad = map.enemiesToSquad
|
||||||
local unitCount = 0
|
local unitCount = 0
|
||||||
local units = surface.find_enemy_units(position, radius)
|
local units = surface.find_enemy_units(position, radius)
|
||||||
@ -83,16 +84,16 @@ function aiDefense.retreatUnits(chunk, position, group, map, surface, tick, radi
|
|||||||
end
|
end
|
||||||
enemiesToSquad.len = unitCount
|
enemiesToSquad.len = unitCount
|
||||||
if (mRandom() < calculateKamikazeThreshold(unitCount, map.natives)) then
|
if (mRandom() < calculateKamikazeThreshold(unitCount, map.natives)) then
|
||||||
setRetreatTick(map, chunk, tick)
|
performRetreat = false
|
||||||
return
|
else
|
||||||
end
|
performRetreat = unitCount > 6
|
||||||
performRetreat = unitCount > 6
|
end
|
||||||
elseif squad.group and squad.group.valid and (squad.status ~= SQUAD_RETREATING) and not squad.kamikaze then
|
elseif squad.group and squad.group.valid and (squad.status ~= SQUAD_RETREATING) and not squad.kamikaze then
|
||||||
performRetreat = #squad.group.members > 6
|
performRetreat = #groupMembers > 6
|
||||||
end
|
end
|
||||||
|
|
||||||
|
setRetreatTick(map, chunk, tick)
|
||||||
if performRetreat then
|
if performRetreat then
|
||||||
setRetreatTick(map, chunk, tick)
|
|
||||||
local exitPath,exitDirection,nextExitPath,nextExitDirection = scoreNeighborsForRetreat(chunk,
|
local exitPath,exitDirection,nextExitPath,nextExitDirection = scoreNeighborsForRetreat(chunk,
|
||||||
getNeighborChunks(map,
|
getNeighborChunks(map,
|
||||||
chunk.x,
|
chunk.x,
|
||||||
@ -140,7 +141,7 @@ function aiDefense.retreatUnits(chunk, position, group, map, surface, tick, radi
|
|||||||
if enemiesToSquad then
|
if enemiesToSquad then
|
||||||
membersToSquad(cmd, enemiesToSquad.len, enemiesToSquad, artilleryBlast)
|
membersToSquad(cmd, enemiesToSquad.len, enemiesToSquad, artilleryBlast)
|
||||||
else
|
else
|
||||||
membersToSquad(cmd, #squad.group.members, squad.group.members, true)
|
membersToSquad(cmd, #groupMembers, groupMembers, true)
|
||||||
if squad.rabid then
|
if squad.rabid then
|
||||||
newSquad.rabid = true
|
newSquad.rabid = true
|
||||||
end
|
end
|
||||||
|
@ -15,6 +15,7 @@ local movementUtils = require("MovementUtils")
|
|||||||
|
|
||||||
local DEFINES_GROUP_FINISHED = defines.group_state.finished
|
local DEFINES_GROUP_FINISHED = defines.group_state.finished
|
||||||
|
|
||||||
|
local DIVISOR_DEATH_TRAIL_TABLE = constants.DIVISOR_DEATH_TRAIL_TABLE
|
||||||
local SQUAD_QUEUE_SIZE = constants.SQUAD_QUEUE_SIZE
|
local SQUAD_QUEUE_SIZE = constants.SQUAD_QUEUE_SIZE
|
||||||
|
|
||||||
local DEFINES_GROUP_STATE_ATTACKING_TARGET = defines.group_state.attacking_target
|
local DEFINES_GROUP_STATE_ATTACKING_TARGET = defines.group_state.attacking_target
|
||||||
@ -36,6 +37,11 @@ local mRandom = math.random
|
|||||||
|
|
||||||
local findMovementPosition = movementUtils.findMovementPosition
|
local findMovementPosition = movementUtils.findMovementPosition
|
||||||
local removeSquadFromChunk = chunkPropertyUtils.removeSquadFromChunk
|
local removeSquadFromChunk = chunkPropertyUtils.removeSquadFromChunk
|
||||||
|
local addDeathGenerator = chunkPropertyUtils.addDeathGenerator
|
||||||
|
local getDeathGenerator = chunkPropertyUtils.getDeathGenerator
|
||||||
|
|
||||||
|
local next = next
|
||||||
|
local table_size = table_size
|
||||||
|
|
||||||
local mLog = math.log10
|
local mLog = math.log10
|
||||||
|
|
||||||
@ -139,15 +145,21 @@ function unitGroupUtils.createSquad(position, surface, group, settlers)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function unitGroupUtils.cleanSquads(natives, iterator)
|
function unitGroupUtils.cleanSquads(natives, iterator)
|
||||||
|
local profiler = game.create_profiler()
|
||||||
local squads = natives.groupNumberToSquad
|
local squads = natives.groupNumberToSquad
|
||||||
local map = natives.map
|
local map = natives.map
|
||||||
|
|
||||||
local k, squad = next(squads, iterator)
|
local k, squad = next(squads, iterator)
|
||||||
local nextK
|
local nextK
|
||||||
for i=1,2 do
|
-- for i=1,2 do
|
||||||
if not k then
|
if not k then
|
||||||
return nil
|
if (table_size(squads) == 0) then
|
||||||
elseif not squad.group.valid then
|
-- this is needed as the next command remembers the max length a table has been
|
||||||
|
natives.groupNumberToSquad = {}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local group = squad.group
|
||||||
|
if not group.valid then
|
||||||
removeSquadFromChunk(map, squad)
|
removeSquadFromChunk(map, squad)
|
||||||
if (map.regroupIterator == k) then
|
if (map.regroupIterator == k) then
|
||||||
map.regroupIterator = nil
|
map.regroupIterator = nil
|
||||||
@ -155,9 +167,39 @@ function unitGroupUtils.cleanSquads(natives, iterator)
|
|||||||
nextK,squad = next(squads, k)
|
nextK,squad = next(squads, k)
|
||||||
squads[k] = nil
|
squads[k] = nil
|
||||||
k = nextK
|
k = nextK
|
||||||
|
-- else
|
||||||
|
-- game.print({"", "3b", profiler})
|
||||||
|
-- profiler.restart()
|
||||||
|
-- local members = group.members
|
||||||
|
-- local memberCount = #members
|
||||||
|
-- if (memberCount == 0) then
|
||||||
|
-- game.print({"", "4a", profiler})
|
||||||
|
-- profiler.restart()
|
||||||
|
-- local deathGen = getDeathGenerator(map, squad.chunk)
|
||||||
|
-- local penalties = squad.penalties
|
||||||
|
-- for xc=1,mMin(#squad.penalties,5) do
|
||||||
|
-- addDeathGenerator(map,
|
||||||
|
-- penalties[xc].c,
|
||||||
|
-- deathGen * DIVISOR_DEATH_TRAIL_TABLE[xc])
|
||||||
|
-- end
|
||||||
|
-- removeSquadFromChunk(map, squad)
|
||||||
|
-- group.destroy()
|
||||||
|
-- game.print({"", "4ea", profiler})
|
||||||
|
-- profiler.restart()
|
||||||
|
-- elseif (memberCount > AI_MAX_BITER_GROUP_SIZE) then
|
||||||
|
-- game.print({"", "4b", profiler})
|
||||||
|
-- profiler.restart()
|
||||||
|
-- unitGroupUtils.recycleBiters(natives, members)
|
||||||
|
-- removeSquadFromChunk(map, squad)
|
||||||
|
-- group.destroy()
|
||||||
|
-- game.print({"", "4eb", profiler})
|
||||||
|
-- profiler.restart()
|
||||||
|
-- end
|
||||||
|
-- game.print({"", "3be", profiler})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return k
|
-- end
|
||||||
|
map.squadIterator = k
|
||||||
end
|
end
|
||||||
|
|
||||||
function unitGroupUtils.membersToSquad(cmd, size, members, overwriteGroup)
|
function unitGroupUtils.membersToSquad(cmd, size, members, overwriteGroup)
|
||||||
@ -185,6 +227,7 @@ end
|
|||||||
function unitGroupUtils.regroupSquads(natives, iterator)
|
function unitGroupUtils.regroupSquads(natives, iterator)
|
||||||
local map = natives.map
|
local map = natives.map
|
||||||
local squads = natives.groupNumberToSquad
|
local squads = natives.groupNumberToSquad
|
||||||
|
local cmd = map.mergeGroupCommand
|
||||||
|
|
||||||
local k, squad = iterator, nil
|
local k, squad = iterator, nil
|
||||||
for i=1,SQUAD_QUEUE_SIZE do
|
for i=1,SQUAD_QUEUE_SIZE do
|
||||||
@ -194,42 +237,45 @@ function unitGroupUtils.regroupSquads(natives, iterator)
|
|||||||
else
|
else
|
||||||
local group = squad.group
|
local group = squad.group
|
||||||
if group and group.valid then
|
if group and group.valid then
|
||||||
|
cmd.group = group
|
||||||
local groupState = group.state
|
local groupState = group.state
|
||||||
if (groupState ~= DEFINES_GROUP_STATE_ATTACKING_TARGET) and
|
if (groupState ~= DEFINES_GROUP_STATE_ATTACKING_TARGET) and
|
||||||
(groupState ~= DEFINES_GROUP_STATE_ATTACKING_DISTRACTION)
|
(groupState ~= DEFINES_GROUP_STATE_ATTACKING_DISTRACTION)
|
||||||
then
|
then
|
||||||
local memberCount = #group.members
|
-- local memberCount = #group.members
|
||||||
if (memberCount < AI_SQUAD_MERGE_THRESHOLD) then
|
-- if (memberCount < AI_SQUAD_MERGE_THRESHOLD) then
|
||||||
local status = squad.status
|
local status = squad.status
|
||||||
local chunk = squad.chunk
|
local chunk = squad.chunk
|
||||||
|
|
||||||
if (chunk ~= -1) then
|
if (chunk ~= -1) then
|
||||||
for _,mergeSquad in pairs(getSquadsOnChunk(map, chunk)) do
|
for _,mergeSquad in pairs(getSquadsOnChunk(map, chunk)) do
|
||||||
if (mergeSquad ~= squad) then
|
if (mergeSquad ~= squad) then
|
||||||
local mergeGroup = mergeSquad.group
|
local mergeGroup = mergeSquad.group
|
||||||
if mergeGroup and mergeGroup.valid and (mergeSquad.status == status) then
|
if mergeGroup and mergeGroup.valid and (mergeSquad.status == status) then
|
||||||
local mergeGroupState = mergeGroup.state
|
local mergeGroupState = mergeGroup.state
|
||||||
if (mergeGroupState ~= DEFINES_GROUP_STATE_ATTACKING_TARGET) and
|
if (mergeGroupState ~= DEFINES_GROUP_STATE_ATTACKING_TARGET) and
|
||||||
(mergeGroupState ~= DEFINES_GROUP_STATE_ATTACKING_DISTRACTION)
|
(mergeGroupState ~= DEFINES_GROUP_STATE_ATTACKING_DISTRACTION)
|
||||||
then
|
then
|
||||||
local mergeMembers = mergeGroup.members
|
print("merging group")
|
||||||
local mergeCount = #mergeMembers
|
mergeGroup.set_command(cmd)
|
||||||
if ((mergeCount + memberCount) < AI_MAX_BITER_GROUP_SIZE) then
|
-- local mergeMembers = mergeGroup.members
|
||||||
for memberIndex=1, mergeCount do
|
-- local mergeCount = #mergeMembers
|
||||||
group.add_member(mergeMembers[memberIndex])
|
-- if ((mergeCount + memberCount) < AI_MAX_BITER_GROUP_SIZE) then
|
||||||
end
|
-- for memberIndex=1, mergeCount do
|
||||||
mergeGroup.destroy()
|
-- group.add_member(mergeMembers[memberIndex])
|
||||||
end
|
-- end
|
||||||
squad.status = SQUAD_GUARDING
|
-- mergeGroup.destroy()
|
||||||
memberCount = memberCount + mergeCount
|
-- end
|
||||||
if (memberCount > AI_SQUAD_MERGE_THRESHOLD) then
|
squad.status = SQUAD_GUARDING
|
||||||
break
|
-- memberCount = memberCount + mergeCount
|
||||||
end
|
-- if (memberCount > AI_SQUAD_MERGE_THRESHOLD) then
|
||||||
end
|
-- break
|
||||||
|
-- end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -18710,7 +18710,6 @@ rampant-enableNEUnits=World: Enable NE as a faction
|
|||||||
rampant-disallowFriendlyFire=Safety: Disallow Friendly Fire Splash Damage
|
rampant-disallowFriendlyFire=Safety: Disallow Friendly Fire Splash Damage
|
||||||
rampant-tierStart=World: Beginning enemy level
|
rampant-tierStart=World: Beginning enemy level
|
||||||
rampant-tierEnd=World: Ending enemy level
|
rampant-tierEnd=World: Ending enemy level
|
||||||
rampant-disableVanillaAI=AI: Disable Vanilla AI
|
|
||||||
rampant-enableMigration=AI: Enable Migration
|
rampant-enableMigration=AI: Enable Migration
|
||||||
rampant-liteMode=Optimization: Lite mode
|
rampant-liteMode=Optimization: Lite mode
|
||||||
|
|
||||||
@ -18806,7 +18805,6 @@ rampant-newEnemyVariations=This number corresponds to the number of variations p
|
|||||||
rampant-disallowFriendlyFire=Prevents enemy spitters and worms from damaging units or buildings from the same force through splash damage
|
rampant-disallowFriendlyFire=Prevents enemy spitters and worms from damaging units or buildings from the same force through splash damage
|
||||||
rampant-tierStart=This is the starting level of the enemy that will be used when generating the set of enemies for the specified number of tiers and increases linearly to the end tier for as many tiers selected. Roughly healthwise each tier is a follows (1-15,2-75,3-150,4-250,5-1000,6-2000,7-3500,8-7500,9-15000,10-30000). min 1, max 10
|
rampant-tierStart=This is the starting level of the enemy that will be used when generating the set of enemies for the specified number of tiers and increases linearly to the end tier for as many tiers selected. Roughly healthwise each tier is a follows (1-15,2-75,3-150,4-250,5-1000,6-2000,7-3500,8-7500,9-15000,10-30000). min 1, max 10
|
||||||
rampant-tierEnd=This is the ending tier level that is reached after increasing linearly from the start tier for as many tiers selected. Roughly healthwise each tier is a follows (1-15,2-75,3-150,4-250,5-1000,6-2000,7-3500,8-7500,9-15000,10-30000). min 1, max 10
|
rampant-tierEnd=This is the ending tier level that is reached after increasing linearly from the start tier for as many tiers selected. Roughly healthwise each tier is a follows (1-15,2-75,3-150,4-250,5-1000,6-2000,7-3500,8-7500,9-15000,10-30000). min 1, max 10
|
||||||
rampant-disableVanillaAI=This will turn off the vanilla attack waves and the vanilla biter expansion.
|
|
||||||
rampant-enableMigration=This will allow the ai to expand its worms and nests. Respects the map settings for biter expansion.
|
rampant-enableMigration=This will allow the ai to expand its worms and nests. Respects the map settings for biter expansion.
|
||||||
|
|
||||||
rampant-enableShrinkNestsAndWorms=Reduce the collision box size of nests and worms by 50%. May cause overlapping entities due to the collision box being smaller than the entity graphic.
|
rampant-enableShrinkNestsAndWorms=Reduce the collision box size of nests and worms by 50%. May cause overlapping entities due to the collision box being smaller than the entity graphic.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
local biterFunctions = require("prototypes/utils/BiterUtils")
|
local biterFunctions = require("prototypes/utils/BiterUtils")
|
||||||
local constants = require("libs/Constants")
|
local constants = require("libs/Constants")
|
||||||
|
local smokeUtils = require("prototypes/utils/SmokeUtils")
|
||||||
|
|
||||||
data:extend({
|
data:extend({
|
||||||
biterFunctions.makeBiter({
|
biterFunctions.makeBiter({
|
||||||
@ -83,3 +84,39 @@ for t=1,11 do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
smokeUtils.makeNewCloud(
|
||||||
|
{
|
||||||
|
name = "build-clear",
|
||||||
|
wind = false,
|
||||||
|
scale = 9,
|
||||||
|
duration = 540,
|
||||||
|
cooldown = 10,
|
||||||
|
tint = { r=0.7, g=0.2, b=0.7 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "area",
|
||||||
|
radius = 17,
|
||||||
|
force = "not-same",
|
||||||
|
action_delivery =
|
||||||
|
{
|
||||||
|
type = "instant",
|
||||||
|
target_effects =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
type = "damage",
|
||||||
|
damage = { amount = 8, type = "poison"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "damage",
|
||||||
|
damage = { amount = 8, type = "acid"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "damage",
|
||||||
|
damage = { amount = 8, type = "fire"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ -2,6 +2,145 @@ local smokeUtils = {}
|
|||||||
|
|
||||||
-- module code
|
-- module code
|
||||||
|
|
||||||
|
function smokeUtils.makeNewCloud(attributes, attack)
|
||||||
|
local name = attributes.name .. "-cloud-rampant"
|
||||||
|
|
||||||
|
data:extend({
|
||||||
|
{
|
||||||
|
type = "smoke-with-trigger",
|
||||||
|
name = "dummy-" .. name,
|
||||||
|
flags = {"not-on-map"},
|
||||||
|
show_when_smoke_off = true,
|
||||||
|
particle_count = 24,
|
||||||
|
particle_spread = { 3.6 * 1.05, 3.6 * 0.6 * 1.05 },
|
||||||
|
particle_distance_scale_factor = 0.5,
|
||||||
|
particle_scale_factor = { 1, 0.707 },
|
||||||
|
particle_duration_variation = 60 * 3,
|
||||||
|
wave_speed = { 0.5 / 80, 0.5 / 60 },
|
||||||
|
wave_distance = { 1, 0.5 },
|
||||||
|
spread_duration_variation = 300 - 20,
|
||||||
|
|
||||||
|
render_layer = "object",
|
||||||
|
|
||||||
|
affected_by_wind = attributes.wind,
|
||||||
|
cyclic = true,
|
||||||
|
duration = attributes.duration or 60 * 20 + 4 * 60,
|
||||||
|
fade_away_duration = 3 * 60,
|
||||||
|
spread_duration = (300 - 20) / 2 ,
|
||||||
|
color = attributes.tint or { r = 0.7, g = 0.9, b = 0.2 }, -- #035b6452
|
||||||
|
|
||||||
|
animation =
|
||||||
|
{
|
||||||
|
width = 152,
|
||||||
|
height = 120,
|
||||||
|
line_length = 5,
|
||||||
|
frame_count = 60,
|
||||||
|
shift = {-0.53125, -0.4375},
|
||||||
|
priority = "high",
|
||||||
|
animation_speed = 0.25,
|
||||||
|
scale = (attributes.scale and attributes.scale * 0.75) or 2.25,
|
||||||
|
filename = "__base__/graphics/entity/smoke/smoke.png",
|
||||||
|
flags = { "smoke" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "smoke-with-trigger",
|
||||||
|
name = name,
|
||||||
|
flags = {"not-on-map"},
|
||||||
|
show_when_smoke_off = true,
|
||||||
|
animation =
|
||||||
|
{
|
||||||
|
width = 152,
|
||||||
|
height = 120,
|
||||||
|
line_length = 5,
|
||||||
|
frame_count = 60,
|
||||||
|
shift = {-0.53125, -0.4375},
|
||||||
|
priority = "high",
|
||||||
|
animation_speed = 0.25,
|
||||||
|
filename = "__base__/graphics/entity/smoke/smoke.png",
|
||||||
|
flags = { "smoke" },
|
||||||
|
scale = attributes.scale or 3,
|
||||||
|
tint = attributes.tint or { r = 0.7, g = 0.9, b = 0.2 }
|
||||||
|
},
|
||||||
|
created_effect =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
type = "cluster",
|
||||||
|
cluster_count = (attributes.scale and attributes.scale * 0.5) and 10,
|
||||||
|
distance = (attributes.scale and attributes.scale * 0.8) and 4,
|
||||||
|
distance_deviation = 5,
|
||||||
|
action_delivery =
|
||||||
|
{
|
||||||
|
type = "instant",
|
||||||
|
target_effects =
|
||||||
|
{
|
||||||
|
type = "create-smoke",
|
||||||
|
show_in_tooltip = false,
|
||||||
|
entity_name = "dummy-" .. name,
|
||||||
|
initial_height = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "cluster",
|
||||||
|
cluster_count = (attributes.scale and attributes.scale * 0.65) and 11,
|
||||||
|
distance = (attributes.scale and attributes.scale * 1.8) and 8 * 1.1,
|
||||||
|
distance_deviation = 2,
|
||||||
|
action_delivery =
|
||||||
|
{
|
||||||
|
type = "instant",
|
||||||
|
target_effects =
|
||||||
|
{
|
||||||
|
type = "create-smoke",
|
||||||
|
show_in_tooltip = false,
|
||||||
|
entity_name = "dummy-" .. name,
|
||||||
|
initial_height = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
slow_down_factor = attributes.slowdown or 0,
|
||||||
|
affected_by_wind = attributes.wind,
|
||||||
|
cyclic = true,
|
||||||
|
render_layer = "higher-object-above",
|
||||||
|
duration = attributes.duration or 60 * 20,
|
||||||
|
fade_away_duration = attributes.outDuration or (attributes.duration and attributes.duration * 0.25) or 2 * 60,
|
||||||
|
spread_duration = attributes.inDuration or (attributes.duration and attributes.duration * 0.25) or 10,
|
||||||
|
action = attack or
|
||||||
|
{
|
||||||
|
type = "direct",
|
||||||
|
action_delivery =
|
||||||
|
{
|
||||||
|
type = "instant",
|
||||||
|
target_effects =
|
||||||
|
{
|
||||||
|
type = "nested-result",
|
||||||
|
action =
|
||||||
|
{
|
||||||
|
type = "area",
|
||||||
|
radius = 11,
|
||||||
|
entity_flags = {"breaths-air"},
|
||||||
|
action_delivery =
|
||||||
|
{
|
||||||
|
type = "instant",
|
||||||
|
target_effects =
|
||||||
|
{
|
||||||
|
type = "damage",
|
||||||
|
damage = { amount = 8, type = "poison"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
action_cooldown = attributes.cooldown or 30
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return name
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function smokeUtils.makeCloud(attributes, attack)
|
function smokeUtils.makeCloud(attributes, attack)
|
||||||
local name = attributes.name .. "-cloud-rampant"
|
local name = attributes.name .. "-cloud-rampant"
|
||||||
|
|
||||||
|
18
settings.lua
18
settings.lua
@ -393,15 +393,15 @@ data:extend({
|
|||||||
per_user = false
|
per_user = false
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
-- {
|
||||||
type = "bool-setting",
|
-- type = "bool-setting",
|
||||||
name = "rampant-disableVanillaAI",
|
-- name = "rampant-disableVanillaAI",
|
||||||
description = "rampant-disableVanillaAI",
|
-- description = "rampant-disableVanillaAI",
|
||||||
setting_type = 'runtime-global',
|
-- setting_type = 'runtime-global',
|
||||||
default_value = true,
|
-- default_value = true,
|
||||||
order = "m[total]-a[ai]",
|
-- order = "m[total]-a[ai]",
|
||||||
per_user = false
|
-- per_user = false
|
||||||
},
|
-- },
|
||||||
|
|
||||||
{
|
{
|
||||||
type = "bool-setting",
|
type = "bool-setting",
|
||||||
|
@ -219,9 +219,9 @@ function tests.attackOrigin()
|
|||||||
max_distance = 1000})
|
max_distance = 1000})
|
||||||
if (enemy ~= nil) and enemy.valid then
|
if (enemy ~= nil) and enemy.valid then
|
||||||
print(enemy, enemy.unit_number)
|
print(enemy, enemy.unit_number)
|
||||||
enemy.set_command({type=defines.command.attack_area,
|
enemy.set_command({type=defines.command.go_to_location,
|
||||||
destination={0,0},
|
destination={0,0},
|
||||||
radius=32})
|
radius=15})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user