mirror of
https://github.com/veden/Rampant.git
synced 2025-03-17 20:58:35 +02:00
working through runtime errors
This commit is contained in:
parent
7c47a495fd
commit
8063664616
361
Upgrade.lua
361
Upgrade.lua
@ -3,20 +3,326 @@ local upgrade = {}
|
||||
-- imports
|
||||
|
||||
local constants = require("libs/Constants")
|
||||
local mathUtils = require("libs/MathUtils")
|
||||
|
||||
-- constants
|
||||
|
||||
local INTERVAL_LOGIC = constants.INTERVAL_LOGIC
|
||||
local DEFINES_COMMAND_GROUP = defines.command.group
|
||||
local DEFINES_COMMAND_WANDER = defines.command.wander
|
||||
local DEFINES_COMMAND_BUILD_BASE = defines.command.build_base
|
||||
local DEFINES_COMMAND_ATTACK_AREA = defines.command.attack_area
|
||||
local DEFINES_COMMAND_GO_TO_LOCATION = defines.command.go_to_location
|
||||
local DEFINES_COMMMAD_COMPOUND = defines.command.compound
|
||||
local DEFINES_COMMAND_FLEE = defines.command.flee
|
||||
local DEFINES_COMMAND_STOP = defines.command.stop
|
||||
|
||||
local DEFINES_COMPOUND_COMMAND_RETURN_LAST = defines.compound_command.return_last
|
||||
|
||||
local DEFINES_DISTRACTION_NONE = defines.distraction.none
|
||||
local DEFINES_DISTRACTION_BY_ENEMY = defines.distraction.by_enemy
|
||||
local DEFINES_DISTRACTION_BY_ANYTHING = defines.distraction.by_anything
|
||||
|
||||
local CHUNK_SIZE = constants.CHUNK_SIZE
|
||||
local TRIPLE_CHUNK_SIZE = constants.TRIPLE_CHUNK_SIZE
|
||||
|
||||
-- imported functions
|
||||
|
||||
local roundToNearest = mathUtils.roundToNearest
|
||||
|
||||
-- module code
|
||||
|
||||
function upgrade.attempt(natives, setNewSurface, gameSurfaces)
|
||||
local function addCommandSet(queriesAndCommands)
|
||||
-- preallocating memory to be used in code, making it fast by reducing garbage generated.
|
||||
queriesAndCommands.neighbors = {
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
}
|
||||
queriesAndCommands.cardinalNeighbors = {
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
}
|
||||
queriesAndCommands.position = {
|
||||
x=0,
|
||||
y=0
|
||||
}
|
||||
queriesAndCommands.position2 = {
|
||||
x=0,
|
||||
y=0
|
||||
}
|
||||
queriesAndCommands.position3 = {
|
||||
x=0,
|
||||
y=0
|
||||
}
|
||||
|
||||
queriesAndCommands.chunkOverlapArray = {
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
}
|
||||
|
||||
queriesAndCommands.position2Top = {0, 0}
|
||||
queriesAndCommands.position2Bottom = {0, 0}
|
||||
--this is shared between two different queries
|
||||
queriesAndCommands.area = {
|
||||
{0, 0},
|
||||
{0, 0}
|
||||
}
|
||||
queriesAndCommands.area2 = {
|
||||
queriesAndCommands.position2Top,
|
||||
queriesAndCommands.position2Bottom
|
||||
}
|
||||
queriesAndCommands.buildPositionTop = {0, 0}
|
||||
queriesAndCommands.buildPositionBottom = {0, 0}
|
||||
queriesAndCommands.buildArea = {
|
||||
queriesAndCommands.buildPositionTop,
|
||||
queriesAndCommands.buildPositionBottom
|
||||
}
|
||||
queriesAndCommands.countResourcesQuery = {
|
||||
area=queriesAndCommands.area,
|
||||
type="resource"
|
||||
}
|
||||
queriesAndCommands.filteredEntitiesUnitQuery = {
|
||||
area=queriesAndCommands.area,
|
||||
force="enemy",
|
||||
type="unit"
|
||||
}
|
||||
queriesAndCommands.hasPlayerStructuresQuery = {
|
||||
area=queriesAndCommands.area,
|
||||
force={"enemy","neutral"},
|
||||
invert=true,
|
||||
limit=1
|
||||
}
|
||||
queriesAndCommands.filteredEntitiesEnemyStructureQuery = {
|
||||
area=queriesAndCommands.area,
|
||||
force="enemy",
|
||||
type={
|
||||
"turret",
|
||||
"unit-spawner"
|
||||
}
|
||||
}
|
||||
queriesAndCommands.filteredEntitiesPointQueryLimited = {
|
||||
position = queriesAndCommands.position,
|
||||
radius = 10,
|
||||
limit = 1,
|
||||
force = "enemy",
|
||||
type = {
|
||||
"unit-spawner",
|
||||
"turret"
|
||||
}
|
||||
}
|
||||
queriesAndCommands.createBuildCloudQuery = {
|
||||
name = "build-clear-cloud-rampant",
|
||||
position = queriesAndCommands.position
|
||||
}
|
||||
|
||||
queriesAndCommands.activePlayerForces = {"player"}
|
||||
|
||||
for _,force in pairs(game.forces) do
|
||||
local add = true
|
||||
|
||||
if (force.name ~= "neutral") and (force.name ~= "enemy") then
|
||||
for i=1,#queriesAndCommands.activePlayerForces do
|
||||
if (queriesAndCommands.activePlayerForces[i] == force.name) then
|
||||
add = false
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if add then
|
||||
queriesAndCommands.activePlayerForces[#queriesAndCommands.activePlayerForces+1] = force.name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
queriesAndCommands.filteredEntitiesPlayerQueryLowest = {
|
||||
area=queriesAndCommands.area,
|
||||
force=queriesAndCommands.activePlayerForces,
|
||||
collision_mask = "player-layer",
|
||||
type={
|
||||
"wall",
|
||||
"transport-belt"
|
||||
}
|
||||
}
|
||||
|
||||
queriesAndCommands.filteredEntitiesPlayerQueryLow = {
|
||||
area=queriesAndCommands.area,
|
||||
force=queriesAndCommands.activePlayerForces,
|
||||
collision_mask = "player-layer",
|
||||
type={
|
||||
"splitter",
|
||||
"pump",
|
||||
"offshore-pump",
|
||||
"lamp",
|
||||
"solar-panel",
|
||||
"programmable-speaker",
|
||||
"accumulator",
|
||||
"assembling-machine",
|
||||
"turret",
|
||||
"ammo-turret"
|
||||
}
|
||||
}
|
||||
|
||||
queriesAndCommands.filteredEntitiesPlayerQueryHigh = {
|
||||
area=queriesAndCommands.area,
|
||||
force=queriesAndCommands.activePlayerForces,
|
||||
collision_mask = "player-layer",
|
||||
type={
|
||||
"furnace",
|
||||
"lab",
|
||||
"roboport",
|
||||
"beacon",
|
||||
"radar",
|
||||
"electric-turret",
|
||||
"boiler",
|
||||
"generator",
|
||||
"fluid-turret",
|
||||
"mining-drill"
|
||||
}
|
||||
}
|
||||
|
||||
queriesAndCommands.filteredEntitiesPlayerQueryHighest = {
|
||||
area=queriesAndCommands.area,
|
||||
force=queriesAndCommands.activePlayerForces,
|
||||
collision_mask = "player-layer",
|
||||
type={
|
||||
"artillery-turret",
|
||||
"reactor",
|
||||
"rocket-silo"
|
||||
}
|
||||
}
|
||||
|
||||
queriesAndCommands.filteredEntitiesChunkNeutral = {
|
||||
area=queriesAndCommands.area,
|
||||
collision_mask = "player-layer",
|
||||
type={
|
||||
"tree",
|
||||
"simple-entity"
|
||||
}
|
||||
}
|
||||
|
||||
local sharedArea = {
|
||||
{0,0},
|
||||
{0,0}
|
||||
}
|
||||
queriesAndCommands.filteredEntitiesCliffQuery = {
|
||||
area=sharedArea,
|
||||
type="cliff",
|
||||
limit = 1
|
||||
}
|
||||
queriesAndCommands.filteredTilesPathQuery = {
|
||||
area=sharedArea,
|
||||
collision_mask="water-tile",
|
||||
limit = 1
|
||||
}
|
||||
queriesAndCommands.cliffQuery = {
|
||||
area=queriesAndCommands.area2,
|
||||
type="cliff"
|
||||
}
|
||||
queriesAndCommands.canPlaceQuery = {
|
||||
name="",
|
||||
position={0,0}
|
||||
}
|
||||
queriesAndCommands.filteredTilesQuery = {
|
||||
collision_mask="water-tile",
|
||||
area=queriesAndCommands.area
|
||||
}
|
||||
|
||||
queriesAndCommands.upgradeEntityQuery = {
|
||||
name = "",
|
||||
position = nil
|
||||
}
|
||||
|
||||
queriesAndCommands.attackCommand = {
|
||||
type = DEFINES_COMMAND_ATTACK_AREA,
|
||||
destination = queriesAndCommands.position,
|
||||
radius = CHUNK_SIZE * 1.5,
|
||||
distraction = DEFINES_DISTRACTION_BY_ANYTHING
|
||||
}
|
||||
|
||||
queriesAndCommands.moveCommand = {
|
||||
type = DEFINES_COMMAND_GO_TO_LOCATION,
|
||||
destination = queriesAndCommands.position,
|
||||
pathfind_flags = { cache = true },
|
||||
distraction = DEFINES_DISTRACTION_BY_ENEMY
|
||||
}
|
||||
|
||||
queriesAndCommands.settleCommand = {
|
||||
type = DEFINES_COMMAND_BUILD_BASE,
|
||||
destination = queriesAndCommands.position,
|
||||
distraction = DEFINES_DISTRACTION_BY_ENEMY,
|
||||
ignore_planner = true
|
||||
}
|
||||
|
||||
queriesAndCommands.wonderCommand = {
|
||||
type = DEFINES_COMMAND_WANDER,
|
||||
wander_in_group = false,
|
||||
radius = TRIPLE_CHUNK_SIZE*2,
|
||||
ticks_to_wait = 36000
|
||||
}
|
||||
|
||||
queriesAndCommands.stopCommand = {
|
||||
type = DEFINES_COMMAND_STOP
|
||||
}
|
||||
|
||||
queriesAndCommands.compoundSettleCommand = {
|
||||
type = DEFINES_COMMMAD_COMPOUND,
|
||||
structure_type = DEFINES_COMPOUND_COMMAND_RETURN_LAST,
|
||||
commands = {
|
||||
queriesAndCommands.wonder2Command,
|
||||
queriesAndCommands.settleCommand
|
||||
}
|
||||
}
|
||||
|
||||
queriesAndCommands.retreatCommand = {
|
||||
type = DEFINES_COMMAND_GROUP,
|
||||
group = nil,
|
||||
distraction = DEFINES_DISTRACTION_BY_ANYTHING,
|
||||
use_group_distraction = true
|
||||
}
|
||||
|
||||
queriesAndCommands.fleeCommand = {
|
||||
type = DEFINES_COMMAND_FLEE,
|
||||
from = nil,
|
||||
distraction = DEFINES_DISTRACTION_NONE
|
||||
}
|
||||
|
||||
queriesAndCommands.compoundRetreatGroupCommand = {
|
||||
type = DEFINES_COMMMAD_COMPOUND,
|
||||
structure_type = DEFINES_COMPOUND_COMMAND_RETURN_LAST,
|
||||
commands = {
|
||||
queriesAndCommands.stopCommand,
|
||||
queriesAndCommands.fleeCommand,
|
||||
queriesAndCommands.retreatCommand
|
||||
}
|
||||
}
|
||||
|
||||
queriesAndCommands.formGroupCommand = {
|
||||
type = DEFINES_COMMAND_GROUP,
|
||||
group = nil,
|
||||
distraction = DEFINES_DISTRACTION_BY_ANYTHING,
|
||||
use_group_distraction = false
|
||||
}
|
||||
|
||||
queriesAndCommands.formCommand = {
|
||||
command = queriesAndCommands.formGroupCommand,
|
||||
unit_count = 0,
|
||||
unit_search_distance = TRIPLE_CHUNK_SIZE
|
||||
}
|
||||
|
||||
queriesAndCommands.formRetreatCommand = {
|
||||
command = queriesAndCommands.compoundRetreatGroupCommand,
|
||||
unit_count = 1,
|
||||
unit_search_distance = CHUNK_SIZE
|
||||
}
|
||||
end
|
||||
|
||||
function upgrade.attempt(natives, queriesAndCommands)
|
||||
local starting = global.version
|
||||
if not global.version or global.version < 106 then
|
||||
global.version = 106
|
||||
@ -31,8 +337,8 @@ function upgrade.attempt(natives, setNewSurface, gameSurfaces)
|
||||
natives.aiNocturnalMode = settings.global["rampant-permanentNocturnal"].value
|
||||
|
||||
-- needs to be on inner logic tick loop interval
|
||||
natives.stateTick = roundToNearest(game.tick + INTERVAL_LOGIC, INTERVAL_LOGIC)
|
||||
natives.temperamentTick = roundToNearest(game.tick + INTERVAL_LOGIC, INTERVAL_LOGIC)
|
||||
-- natives.stateTick = roundToNearest(game.tick + INTERVAL_LOGIC, INTERVAL_LOGIC)
|
||||
-- natives.temperamentTick = roundToNearest(game.tick + INTERVAL_LOGIC, INTERVAL_LOGIC)
|
||||
|
||||
-- used to precompute some values per logic cycle
|
||||
natives.retreatThreshold = 0
|
||||
@ -108,39 +414,6 @@ function upgrade.attempt(natives, setNewSurface, gameSurfaces)
|
||||
if (global.version < 111) then
|
||||
global.version = 111
|
||||
|
||||
local gameSurfs
|
||||
if not gameSurfaces then
|
||||
gameSurfs = {}
|
||||
global.gameSurfaces = gameSurfs
|
||||
if natives.activeSurface == 1 then
|
||||
natives.activeSurface = "nauvis"
|
||||
end
|
||||
else
|
||||
gameSurfs = gameSurfaces
|
||||
end
|
||||
|
||||
for _,player in pairs(game.connected_players) do
|
||||
if player and player.valid and
|
||||
not settings.get_player_settings(player)["rampant-suppress-surface-change-warnings"].value
|
||||
then
|
||||
local surface = player.surface
|
||||
if (natives.activeSurface ~= surface.name) then
|
||||
local playerName = player.name
|
||||
local surfaceName = surface.name
|
||||
local playerSurfaces = gameSurfs[surfaceName]
|
||||
if not playerSurfaces then
|
||||
playerSurfaces = {}
|
||||
gameSurfs[surfaceName] = playerSurfaces
|
||||
player.print({"description.rampant-change-surface", surfaceName, natives.activeSurface})
|
||||
playerSurfaces[playerName] = true
|
||||
elseif not playerSurfaces[playerName] then
|
||||
player.print({"description.rampant-change-surface", surfaceName, natives.activeSurface})
|
||||
playerSurfaces[playerName] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
natives.groupNumberToSquad = {}
|
||||
game.forces.enemy.kill_all_units()
|
||||
natives.squads = nil
|
||||
@ -171,12 +444,12 @@ function upgrade.attempt(natives, setNewSurface, gameSurfaces)
|
||||
|
||||
game.forces.enemy.ai_controllable = true
|
||||
|
||||
if not setNewSurface then
|
||||
game.get_surface(natives.activeSurface).print("Rampant - Version 1.0.3")
|
||||
end
|
||||
addCommandSet(queriesAndCommands)
|
||||
|
||||
game.print("Rampant - Version 1.0.3")
|
||||
end
|
||||
|
||||
return starting ~= global.version, natives
|
||||
return starting ~= global.version
|
||||
end
|
||||
|
||||
function upgrade.compareTable(entities, option, new)
|
||||
|
1335
control.lua
1335
control.lua
File diff suppressed because it is too large
Load Diff
@ -71,9 +71,9 @@ local getDeathGenerator = chunkPropertyUtils.getDeathGenerator
|
||||
|
||||
-- module code
|
||||
|
||||
local function attackWaveValidCandidate(chunk, natives, map)
|
||||
local function attackWaveValidCandidate(chunk, native, map)
|
||||
local isValid = getNestActiveness(map, chunk)
|
||||
if natives.state == AI_STATE_RAIDING then
|
||||
if native.state == AI_STATE_RAIDING then
|
||||
isValid = isValid + getRaidNestActiveness(map, chunk)
|
||||
end
|
||||
return (isValid > 0)
|
||||
@ -155,12 +155,12 @@ local function visitPattern(o, cX, cY, distance)
|
||||
end
|
||||
|
||||
function aiAttackWave.rallyUnits(chunk, map, tick)
|
||||
if ((tick - getRallyTick(map, chunk) > COOLDOWN_RALLY) and (map.natives.points >= AI_VENGENCE_SQUAD_COST)) then
|
||||
if ((tick - getRallyTick(map, chunk) > COOLDOWN_RALLY) and (map.native.points >= AI_VENGENCE_SQUAD_COST)) then
|
||||
setRallyTick(map, chunk, tick)
|
||||
local cX = chunk.x
|
||||
local cY = chunk.y
|
||||
local startX, endX, stepX, startY, endY, stepY = visitPattern(tick % 4, cX, cY, RALLY_CRY_DISTANCE)
|
||||
local vengenceQueue = map.natives.vengenceQueue
|
||||
local vengenceQueue = map.native.vengenceQueue
|
||||
for x=startX, endX, stepX do
|
||||
for y=startY, endY, stepY do
|
||||
if (x ~= cX) and (y ~= cY) then
|
||||
@ -181,15 +181,15 @@ function aiAttackWave.rallyUnits(chunk, map, tick)
|
||||
end
|
||||
end
|
||||
|
||||
function aiAttackWave.formSettlers(map, surface, chunk)
|
||||
|
||||
local natives = map.natives
|
||||
if (natives.builderCount < natives.AI_MAX_BUILDER_COUNT) and
|
||||
(mRandom() < natives.formSquadThreshold) and
|
||||
((natives.points - AI_SETTLER_COST) > 0)
|
||||
function aiAttackWave.formSettlers(map, chunk)
|
||||
local native = map.native
|
||||
if (native.builderCount < native.AI_MAX_BUILDER_COUNT) and
|
||||
(mRandom() < native.formSquadThreshold) and
|
||||
((native.points - AI_SETTLER_COST) > 0)
|
||||
then
|
||||
local surface = map.surface
|
||||
local squadPath, squadDirection
|
||||
if (natives.state == AI_STATE_SIEGE) then
|
||||
if (native.state == AI_STATE_SIEGE) then
|
||||
squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y),
|
||||
validSiegeSettlerLocation,
|
||||
scoreSiegeSettlerLocation,
|
||||
@ -214,21 +214,21 @@ function aiAttackWave.formSettlers(map, surface, chunk)
|
||||
if squadPosition then
|
||||
local squad = createSquad(squadPosition, surface, nil, true)
|
||||
|
||||
squad.maxDistance = gaussianRandomRange(natives.expansionMaxDistance * 0.5,
|
||||
natives.expansionMaxDistanceDerivation,
|
||||
squad.maxDistance = gaussianRandomRange(native.expansionMaxDistance * 0.5,
|
||||
native.expansionMaxDistanceDerivation,
|
||||
10,
|
||||
natives.expansionMaxDistance)
|
||||
native.expansionMaxDistance)
|
||||
|
||||
|
||||
local scaledWaveSize = settlerWaveScaling(natives)
|
||||
local scaledWaveSize = settlerWaveScaling(native)
|
||||
map.formGroupCommand.group = squad.group
|
||||
map.formCommand.unit_count = scaledWaveSize
|
||||
local foundUnits = surface.set_multi_command(map.formCommand)
|
||||
if (foundUnits > 0) then
|
||||
squad.kamikaze = mRandom() < calculateKamikazeThreshold(foundUnits, natives)
|
||||
natives.builderCount = natives.builderCount + 1
|
||||
natives.points = natives.points - AI_SETTLER_COST
|
||||
natives.groupNumberToSquad[squad.groupNumber] = squad
|
||||
squad.kamikaze = mRandom() < calculateKamikazeThreshold(foundUnits, native)
|
||||
native.builderCount = native.builderCount + 1
|
||||
native.points = native.points - AI_SETTLER_COST
|
||||
native.groupNumberToSquad[squad.groupNumber] = squad
|
||||
else
|
||||
if (squad.group.valid) then
|
||||
squad.group.destroy()
|
||||
@ -239,12 +239,13 @@ function aiAttackWave.formSettlers(map, surface, chunk)
|
||||
end
|
||||
end
|
||||
|
||||
function aiAttackWave.formVengenceSquad(map, surface, chunk)
|
||||
local natives = map.natives
|
||||
if (natives.squadCount < natives.AI_MAX_SQUAD_COUNT) and
|
||||
(mRandom() < natives.formSquadThreshold) and
|
||||
((natives.points - AI_VENGENCE_SQUAD_COST) > 0)
|
||||
function aiAttackWave.formVengenceSquad(map, chunk)
|
||||
local native = map.native
|
||||
if (native.squadCount < native.AI_MAX_SQUAD_COUNT) and
|
||||
(mRandom() < native.formSquadThreshold) and
|
||||
((native.points - AI_VENGENCE_SQUAD_COST) > 0)
|
||||
then
|
||||
local surface = map.surface
|
||||
local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y),
|
||||
validUnitGroupLocation,
|
||||
scoreUnitGroupLocation,
|
||||
@ -263,15 +264,15 @@ function aiAttackWave.formVengenceSquad(map, surface, chunk)
|
||||
|
||||
squad.rabid = mRandom() < 0.03
|
||||
|
||||
local scaledWaveSize = attackWaveScaling(natives)
|
||||
local scaledWaveSize = attackWaveScaling(native)
|
||||
map.formGroupCommand.group = squad.group
|
||||
map.formCommand.unit_count = scaledWaveSize
|
||||
local foundUnits = surface.set_multi_command(map.formCommand)
|
||||
if (foundUnits > 0) then
|
||||
squad.kamikaze = mRandom() < calculateKamikazeThreshold(foundUnits, natives)
|
||||
natives.groupNumberToSquad[squad.groupNumber] = squad
|
||||
natives.squadCount = natives.squadCount + 1
|
||||
natives.points = natives.points - AI_VENGENCE_SQUAD_COST
|
||||
squad.kamikaze = mRandom() < calculateKamikazeThreshold(foundUnits, native)
|
||||
native.groupNumberToSquad[squad.groupNumber] = squad
|
||||
native.squadCount = native.squadCount + 1
|
||||
native.points = native.points - AI_VENGENCE_SQUAD_COST
|
||||
else
|
||||
if (squad.group.valid) then
|
||||
squad.group.destroy()
|
||||
@ -282,13 +283,14 @@ function aiAttackWave.formVengenceSquad(map, surface, chunk)
|
||||
end
|
||||
end
|
||||
|
||||
function aiAttackWave.formSquads(map, surface, chunk, tick)
|
||||
local natives = map.natives
|
||||
if (natives.squadCount < natives.AI_MAX_SQUAD_COUNT) and
|
||||
attackWaveValidCandidate(chunk, natives, map) and
|
||||
(mRandom() < natives.formSquadThreshold) and
|
||||
((natives.points - AI_SQUAD_COST) > 0)
|
||||
function aiAttackWave.formSquads(map, chunk, tick)
|
||||
local native = map.native
|
||||
if (native.squadCount < native.AI_MAX_SQUAD_COUNT) and
|
||||
attackWaveValidCandidate(chunk, native, map) and
|
||||
(mRandom() < native.formSquadThreshold) and
|
||||
((native.points - AI_SQUAD_COST) > 0)
|
||||
then
|
||||
local surface = native.surface
|
||||
local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y),
|
||||
validUnitGroupLocation,
|
||||
scoreUnitGroupLocation,
|
||||
@ -307,17 +309,17 @@ function aiAttackWave.formSquads(map, surface, chunk, tick)
|
||||
|
||||
squad.rabid = mRandom() < 0.03
|
||||
|
||||
local scaledWaveSize = attackWaveScaling(natives)
|
||||
local scaledWaveSize = attackWaveScaling(native)
|
||||
map.formGroupCommand.group = squad.group
|
||||
map.formCommand.unit_count = scaledWaveSize
|
||||
local foundUnits = surface.set_multi_command(map.formCommand)
|
||||
if (foundUnits > 0) then
|
||||
squad.kamikaze = mRandom() < calculateKamikazeThreshold(foundUnits, natives)
|
||||
natives.points = natives.points - AI_SQUAD_COST
|
||||
natives.squadCount = natives.squadCount + 1
|
||||
natives.groupNumberToSquad[squad.groupNumber] = squad
|
||||
if tick and (natives.state == AI_STATE_AGGRESSIVE) then
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
squad.kamikaze = mRandom() < calculateKamikazeThreshold(foundUnits, native)
|
||||
native.points = native.points - AI_SQUAD_COST
|
||||
native.squadCount = native.squadCount + 1
|
||||
native.groupNumberToSquad[squad.groupNumber] = squad
|
||||
if tick and (native.state == AI_STATE_AGGRESSIVE) then
|
||||
native.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
end
|
||||
|
@ -54,12 +54,13 @@ local mMin = math.min
|
||||
|
||||
-- module code
|
||||
|
||||
function aiPlanning.planning(natives, evolution_factor, tick)
|
||||
function aiPlanning.planning(natives, native, evolution_factor, tick)
|
||||
native.evolutionLevel = evolution_factor
|
||||
natives.evolutionLevel = evolution_factor
|
||||
|
||||
local maxPoints = mMax(AI_MAX_POINTS * evolution_factor, MINIMUM_AI_POINTS)
|
||||
|
||||
if not natives.ranIncompatibleMessage and natives.newEnemies and
|
||||
if not native.ranIncompatibleMessage and native.newEnemies and
|
||||
(game.active_mods["bobenemies"] or game.active_mods["Natural_Evolution_Enemies"]) then
|
||||
natives.ranIncompatibleMessage = true
|
||||
game.print({"description.rampant-bobs-nee-newEnemies"})
|
||||
@ -75,8 +76,8 @@ function aiPlanning.planning(natives, evolution_factor, tick)
|
||||
natives.formSquadThreshold = mMax((0.20 * evolution_factor), 0.05)
|
||||
|
||||
natives.attackWaveSize = attackWaveMaxSize * (evolution_factor ^ 1.4)
|
||||
natives.attackWaveDeviation = (natives.attackWaveSize * 0.333)
|
||||
natives.attackWaveUpperBound = natives.attackWaveSize + (natives.attackWaveSize * 0.35)
|
||||
natives.attackWaveDeviation = (native.attackWaveSize * 0.333)
|
||||
natives.attackWaveUpperBound = native.attackWaveSize + (native.attackWaveSize * 0.35)
|
||||
|
||||
if (natives.attackWaveSize < 1) then
|
||||
natives.attackWaveSize = 2
|
||||
@ -85,202 +86,202 @@ function aiPlanning.planning(natives, evolution_factor, tick)
|
||||
end
|
||||
|
||||
natives.settlerWaveSize = linearInterpolation(evolution_factor ^ 1.66667,
|
||||
natives.expansionMinSize,
|
||||
natives.expansionMaxSize)
|
||||
natives.settlerWaveDeviation = (natives.settlerWaveSize * 0.33)
|
||||
native.expansionMinSize,
|
||||
native.expansionMaxSize)
|
||||
natives.settlerWaveDeviation = (native.settlerWaveSize * 0.33)
|
||||
|
||||
natives.settlerCooldown = mFloor(linearInterpolation(evolution_factor ^ 1.66667,
|
||||
natives.expansionMaxTime,
|
||||
natives.expansionMinTime))
|
||||
native.expansionMaxTime,
|
||||
native.expansionMinTime))
|
||||
|
||||
natives.unitRefundAmount = AI_UNIT_REFUND * evolution_factor
|
||||
natives.kamikazeThreshold = NO_RETREAT_BASE_PERCENT + (evolution_factor * NO_RETREAT_EVOLUTION_BONUS_MAX)
|
||||
|
||||
local points = mFloor((AI_POINT_GENERATOR_AMOUNT * mRandom()) + (natives.activeNests * 0.25) +
|
||||
(((AI_POINT_GENERATOR_AMOUNT * 0.7) * (evolution_factor ^ 2.5)) * natives.aiPointsScaler))
|
||||
local points = mFloor((AI_POINT_GENERATOR_AMOUNT * mRandom()) + (native.activeNests * 0.25) +
|
||||
(((AI_POINT_GENERATOR_AMOUNT * 0.7) * (evolution_factor ^ 2.5)) * native.aiPointsScaler))
|
||||
|
||||
if (natives.state == AI_STATE_ONSLAUGHT) then
|
||||
if (native.state == AI_STATE_ONSLAUGHT) then
|
||||
points = points * 2
|
||||
end
|
||||
|
||||
natives.baseIncrement = points
|
||||
native.baseIncrement = points
|
||||
|
||||
local currentPoints = natives.points
|
||||
local currentPoints = native.points
|
||||
|
||||
if (currentPoints < maxPoints) then
|
||||
natives.points = currentPoints + points
|
||||
native.points = currentPoints + points
|
||||
end
|
||||
|
||||
if (currentPoints > maxOverflowPoints) then
|
||||
natives.points = maxOverflowPoints
|
||||
native.points = maxOverflowPoints
|
||||
end
|
||||
|
||||
if (natives.stateTick <= tick) then
|
||||
-- local roll = mRandom() * mMax(1 - evolution_factor, 0.15) * natives.aiAggressiveness
|
||||
if (native.stateTick <= tick) then
|
||||
-- local roll = mRandom() * mMax(1 - evolution_factor, 0.15) * native.aiAggressiveness
|
||||
|
||||
local roll = mRandom()
|
||||
if (natives.temperament < 0.05) then -- 0 - 0.05
|
||||
if (native.temperament < 0.05) then -- 0 - 0.05
|
||||
if natives.enabledMigration then
|
||||
natives.state = (natives.siegeAIToggle and AI_STATE_SIEGE) or AI_STATE_MIGRATING
|
||||
native.state = (natives.siegeAIToggle and AI_STATE_SIEGE) or AI_STATE_MIGRATING
|
||||
else
|
||||
if natives.raidAIToggle then
|
||||
if (roll < 0.85) then
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
native.state = AI_STATE_AGGRESSIVE
|
||||
native.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
else
|
||||
natives.state = AI_STATE_RAIDING
|
||||
native.state = AI_STATE_RAIDING
|
||||
end
|
||||
else
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
native.state = AI_STATE_AGGRESSIVE
|
||||
native.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
end
|
||||
end
|
||||
elseif (natives.temperament < 0.20) then -- 0.05 - 0.2
|
||||
elseif (native.temperament < 0.20) then -- 0.05 - 0.2
|
||||
if (natives.enabledMigration) then
|
||||
if (roll < 0.4) then
|
||||
natives.state = (natives.siegeAIToggle and AI_STATE_SIEGE) or AI_STATE_MIGRATING
|
||||
native.state = (natives.siegeAIToggle and AI_STATE_SIEGE) or AI_STATE_MIGRATING
|
||||
else
|
||||
natives.state = AI_STATE_MIGRATING
|
||||
native.state = AI_STATE_MIGRATING
|
||||
end
|
||||
else
|
||||
if natives.raidAIToggle then
|
||||
if (roll < 0.95) then
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
native.state = AI_STATE_AGGRESSIVE
|
||||
native.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
else
|
||||
natives.state = AI_STATE_RAIDING
|
||||
native.state = AI_STATE_RAIDING
|
||||
end
|
||||
else
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
native.state = AI_STATE_AGGRESSIVE
|
||||
native.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
end
|
||||
end
|
||||
elseif (natives.temperament < 0.4) then -- 0.2 - 0.4
|
||||
elseif (native.temperament < 0.4) then -- 0.2 - 0.4
|
||||
if (natives.enabledMigration) then
|
||||
if (roll < 0.2) then
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
native.state = AI_STATE_AGGRESSIVE
|
||||
native.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
elseif (roll < 0.8) then
|
||||
natives.state = AI_STATE_MIGRATING
|
||||
native.state = AI_STATE_MIGRATING
|
||||
else
|
||||
natives.state = AI_STATE_PEACEFUL
|
||||
native.state = AI_STATE_PEACEFUL
|
||||
end
|
||||
else
|
||||
if (roll < 0.6) then
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
native.state = AI_STATE_AGGRESSIVE
|
||||
native.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
else
|
||||
natives.state = AI_STATE_PEACEFUL
|
||||
native.state = AI_STATE_PEACEFUL
|
||||
end
|
||||
end
|
||||
elseif (natives.temperament < 0.6) then -- 0.4 - 0.6
|
||||
elseif (native.temperament < 0.6) then -- 0.4 - 0.6
|
||||
if (roll < 0.5) then
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
native.state = AI_STATE_AGGRESSIVE
|
||||
native.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
else
|
||||
natives.state = AI_STATE_PEACEFUL
|
||||
native.state = AI_STATE_PEACEFUL
|
||||
end
|
||||
elseif (natives.temperament < 0.8) then -- 0.6 - 0.8
|
||||
elseif (native.temperament < 0.8) then -- 0.6 - 0.8
|
||||
if (roll < 0.6) then
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
native.state = AI_STATE_AGGRESSIVE
|
||||
native.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
elseif (roll < 0.8) then
|
||||
natives.state = AI_STATE_ONSLAUGHT
|
||||
native.state = AI_STATE_ONSLAUGHT
|
||||
else
|
||||
natives.state = AI_STATE_PEACEFUL
|
||||
native.state = AI_STATE_PEACEFUL
|
||||
end
|
||||
else -- 0.8 - 1
|
||||
if (natives.enabledMigration and natives.raidAIToggle) then
|
||||
if (roll < 0.15) then
|
||||
natives.state = (natives.siegeAIToggle and AI_STATE_SIEGE) or AI_STATE_ONSLAUGHT
|
||||
native.state = (natives.siegeAIToggle and AI_STATE_SIEGE) or AI_STATE_ONSLAUGHT
|
||||
elseif (roll < 0.6) then
|
||||
natives.state = AI_STATE_ONSLAUGHT
|
||||
native.state = AI_STATE_ONSLAUGHT
|
||||
elseif (roll < 0.8) then
|
||||
natives.state = AI_STATE_RAIDING
|
||||
native.state = AI_STATE_RAIDING
|
||||
else
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
native.state = AI_STATE_AGGRESSIVE
|
||||
native.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
end
|
||||
elseif (natives.enabledMigration) then
|
||||
if (roll < 0.15) then
|
||||
natives.state = (natives.siegeAIToggle and AI_STATE_SIEGE) or AI_STATE_ONSLAUGHT
|
||||
native.state = (natives.siegeAIToggle and AI_STATE_SIEGE) or AI_STATE_ONSLAUGHT
|
||||
elseif (roll < 0.7) then
|
||||
natives.state = AI_STATE_ONSLAUGHT
|
||||
native.state = AI_STATE_ONSLAUGHT
|
||||
else
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
native.state = AI_STATE_AGGRESSIVE
|
||||
native.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
end
|
||||
elseif (natives.raidAIToggle) then
|
||||
if (roll < 0.4) then
|
||||
natives.state = AI_STATE_ONSLAUGHT
|
||||
native.state = AI_STATE_ONSLAUGHT
|
||||
elseif (roll < 0.7) then
|
||||
natives.state = AI_STATE_RAIDING
|
||||
native.state = AI_STATE_RAIDING
|
||||
else
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
native.state = AI_STATE_AGGRESSIVE
|
||||
native.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
end
|
||||
else
|
||||
if (roll < 0.6) then
|
||||
natives.state = AI_STATE_ONSLAUGHT
|
||||
native.state = AI_STATE_ONSLAUGHT
|
||||
else
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
native.state = AI_STATE_AGGRESSIVE
|
||||
native.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- print("changing state", natives.state)
|
||||
-- print("changing state", native.state)
|
||||
|
||||
natives.destroyPlayerBuildings = 0
|
||||
natives.lostEnemyUnits = 0
|
||||
natives.lostEnemyBuilding = 0
|
||||
natives.rocketLaunched = 0
|
||||
natives.builtEnemyBuilding = 0
|
||||
natives.ionCannonBlasts = 0
|
||||
natives.artilleryBlasts = 0
|
||||
native.destroyPlayerBuildings = 0
|
||||
native.lostEnemyUnits = 0
|
||||
native.lostEnemyBuilding = 0
|
||||
native.rocketLaunched = 0
|
||||
native.builtEnemyBuilding = 0
|
||||
native.ionCannonBlasts = 0
|
||||
native.artilleryBlasts = 0
|
||||
|
||||
natives.stateTick = randomTickEvent(tick, AI_MIN_STATE_DURATION, AI_MAX_STATE_DURATION)
|
||||
native.stateTick = randomTickEvent(tick, AI_MIN_STATE_DURATION, AI_MAX_STATE_DURATION)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
function aiPlanning.temperamentPlanner(natives)
|
||||
local destroyPlayerBuildings = natives.destroyPlayerBuildings
|
||||
local lostEnemyUnits = natives.lostEnemyUnits
|
||||
local lostEnemyBuilding = natives.lostEnemyBuilding
|
||||
local rocketLaunched = natives.rocketLaunched
|
||||
local builtEnemyBuilding = natives.builtEnemyBuilding
|
||||
local ionCannonBlasts = natives.ionCannonBlasts
|
||||
local artilleryBlasts = natives.artilleryBlasts
|
||||
local activeNests = natives.activeNests
|
||||
local activeRaidNests = natives.activeRaidNests
|
||||
function aiPlanning.temperamentPlanner(native)
|
||||
local destroyPlayerBuildings = native.destroyPlayerBuildings
|
||||
local lostEnemyUnits = native.lostEnemyUnits
|
||||
local lostEnemyBuilding = native.lostEnemyBuilding
|
||||
local rocketLaunched = native.rocketLaunched
|
||||
local builtEnemyBuilding = native.builtEnemyBuilding
|
||||
local ionCannonBlasts = native.ionCannonBlasts
|
||||
local artilleryBlasts = native.artilleryBlasts
|
||||
local activeNests = native.activeNests
|
||||
local activeRaidNests = native.activeRaidNests
|
||||
|
||||
local currentTemperament = natives.temperamentScore
|
||||
local currentTemperament = native.temperamentScore
|
||||
local delta = 0
|
||||
|
||||
if activeNests > 0 then
|
||||
@ -307,15 +308,15 @@ function aiPlanning.temperamentPlanner(natives)
|
||||
|
||||
if lostEnemyUnits > 0 then
|
||||
local multipler
|
||||
if natives.evolutionLevel < 0.3 then
|
||||
if native.evolutionLevel < 0.3 then
|
||||
multipler = 0.0005
|
||||
elseif natives.evolutionLevel < 0.5 then
|
||||
elseif native.evolutionLevel < 0.5 then
|
||||
multipler = 0.000385
|
||||
elseif natives.evolutionLevel < 0.7 then
|
||||
elseif native.evolutionLevel < 0.7 then
|
||||
multipler = 0.00025
|
||||
elseif natives.evolutionLevel < 0.9 then
|
||||
elseif native.evolutionLevel < 0.9 then
|
||||
multipler = 0.00012
|
||||
elseif natives.evolutionLevel < 0.9 then
|
||||
elseif native.evolutionLevel < 0.9 then
|
||||
multipler = 0.00006
|
||||
end
|
||||
local val = (multipler * lostEnemyUnits)
|
||||
@ -361,23 +362,23 @@ function aiPlanning.temperamentPlanner(natives)
|
||||
delta = delta + val
|
||||
end
|
||||
|
||||
print("temperament", natives.activeNests, natives.activeRaidNests, natives.destroyPlayerBuildings,
|
||||
natives.lostEnemyUnits,
|
||||
natives.lostEnemyBuilding, natives.rocketLaunched, natives.builtEnemyBuilding, natives.ionCannonBlasts,
|
||||
natives.artilleryBlasts)
|
||||
print("temperament", native.activeNests, native.activeRaidNests, native.destroyPlayerBuildings,
|
||||
native.lostEnemyUnits,
|
||||
native.lostEnemyBuilding, native.rocketLaunched, native.builtEnemyBuilding, native.ionCannonBlasts,
|
||||
native.artilleryBlasts)
|
||||
|
||||
-- natives.destroyPlayerBuildings = 0
|
||||
-- natives.lostEnemyUnits = 0
|
||||
-- natives.lostEnemyBuilding = 0
|
||||
-- natives.rocketLaunched = 0
|
||||
-- natives.builtEnemyBuilding = 0
|
||||
-- natives.ionCannonBlasts = 0
|
||||
-- natives.artilleryBlasts = 0
|
||||
-- native.destroyPlayerBuildings = 0
|
||||
-- native.lostEnemyUnits = 0
|
||||
-- native.lostEnemyBuilding = 0
|
||||
-- native.rocketLaunched = 0
|
||||
-- native.builtEnemyBuilding = 0
|
||||
-- native.ionCannonBlasts = 0
|
||||
-- native.artilleryBlasts = 0
|
||||
|
||||
natives.temperamentScore = mMin(10000, mMax(-10000, currentTemperament + delta))
|
||||
natives.temperament = ((natives.temperamentScore + 10000) * 0.00005)
|
||||
native.temperamentScore = mMin(10000, mMax(-10000, currentTemperament + delta))
|
||||
native.temperament = ((native.temperamentScore + 10000) * 0.00005)
|
||||
|
||||
print("tempResult", natives.temperament, natives.temperamentScore)
|
||||
print("tempResult", native.temperament, native.temperamentScore)
|
||||
print("--")
|
||||
end
|
||||
|
||||
|
@ -19,22 +19,24 @@ local AI_STATE_ONSLAUGHT = constants.AI_STATE_ONSLAUGHT
|
||||
|
||||
-- module code
|
||||
|
||||
function aiPredicates.canAttack(natives, surface, tick)
|
||||
local goodAI = (((natives.state == AI_STATE_AGGRESSIVE) and (natives.canAttackTick > tick)) or
|
||||
(natives.state == AI_STATE_RAIDING) or
|
||||
(natives.state == AI_STATE_ONSLAUGHT))
|
||||
function aiPredicates.canAttack(native, tick)
|
||||
local surface = native.surface
|
||||
local goodAI = (((native.state == AI_STATE_AGGRESSIVE) and (native.canAttackTick > tick)) or
|
||||
(native.state == AI_STATE_RAIDING) or
|
||||
(native.state == AI_STATE_ONSLAUGHT))
|
||||
local notPeaceful = not surface.peaceful_mode
|
||||
local noctural = (not natives.aiNocturnalMode) or (natives.aiNocturnalMode and surface.darkness > 0.65)
|
||||
local noctural = (not native.aiNocturnalMode) or (native.aiNocturnalMode and surface.darkness > 0.65)
|
||||
return goodAI and notPeaceful and noctural
|
||||
end
|
||||
|
||||
function aiPredicates.canMigrate(natives, surface)
|
||||
return ((natives.state == AI_STATE_MIGRATING) or
|
||||
(natives.state == AI_STATE_SIEGE))
|
||||
and natives.expansion
|
||||
function aiPredicates.canMigrate(native)
|
||||
local surface = native.surface
|
||||
return ((native.state == AI_STATE_MIGRATING) or
|
||||
(native.state == AI_STATE_SIEGE))
|
||||
and native.expansion
|
||||
and not surface.peaceful_mode
|
||||
and ((not natives.aiNocturnalMode) or
|
||||
(natives.aiNocturnalMode and surface.darkness > 0.65))
|
||||
and ((not native.aiNocturnalMode) or
|
||||
(native.aiNocturnalMode and surface.darkness > 0.65))
|
||||
end
|
||||
|
||||
aiPredicatesG = aiPredicates
|
||||
|
@ -72,10 +72,10 @@ local mRandom = math.random
|
||||
|
||||
-- module code
|
||||
|
||||
local function evoToTier(natives, evolutionFactor)
|
||||
local function evoToTier(native, evolutionFactor)
|
||||
local v
|
||||
for i=10,1,-1 do
|
||||
if natives.evoToTierMapping[i] <= evolutionFactor then
|
||||
if native.evoToTierMapping[i] <= evolutionFactor then
|
||||
v = i
|
||||
if mRandom() <= 0.65 then
|
||||
break
|
||||
@ -94,7 +94,7 @@ function baseUtils.findNearbyBase(map, chunk)
|
||||
return foundBase
|
||||
end
|
||||
|
||||
local bases = map.natives.bases
|
||||
local bases = map.native.bases
|
||||
local closest = MAGIC_MAXIMUM_NUMBER
|
||||
for _, base in pairs(bases) do
|
||||
local distance = euclideanDistancePoints(base.x, base.y, x, y)
|
||||
@ -107,9 +107,9 @@ function baseUtils.findNearbyBase(map, chunk)
|
||||
return foundBase
|
||||
end
|
||||
|
||||
local function findBaseMutation(natives, targetEvolution)
|
||||
local tier = evoToTier(natives, targetEvolution or natives.evolutionLevel)
|
||||
local alignments = natives.evolutionTableAlignment[tier]
|
||||
local function findBaseMutation(native, targetEvolution)
|
||||
local tier = evoToTier(native, targetEvolution or native.evolutionLevel)
|
||||
local alignments = native.evolutionTableAlignment[tier]
|
||||
|
||||
local roll = mRandom()
|
||||
for i=1,#alignments do
|
||||
@ -124,8 +124,8 @@ local function findBaseMutation(natives, targetEvolution)
|
||||
return alignments[#alignments]
|
||||
end
|
||||
|
||||
local function initialEntityUpgrade(baseAlignment, tier, maxTier, natives, useHiveType)
|
||||
local evolutionTable = natives.buildingEvolveLookup
|
||||
local function initialEntityUpgrade(baseAlignment, tier, maxTier, native, useHiveType)
|
||||
local evolutionTable = native.buildingEvolveLookup
|
||||
local entity
|
||||
|
||||
local useTier
|
||||
@ -172,9 +172,9 @@ local function initialEntityUpgrade(baseAlignment, tier, maxTier, natives, useHi
|
||||
return entity
|
||||
end
|
||||
|
||||
local function entityUpgrade(baseAlignment, tier, maxTier, originalEntity, natives)
|
||||
local buildingHiveTypeLookup = natives.buildingHiveTypeLookup
|
||||
local evolutionTable = natives.upgradeLookup
|
||||
local function entityUpgrade(baseAlignment, tier, maxTier, originalEntity, native)
|
||||
local buildingHiveTypeLookup = native.buildingHiveTypeLookup
|
||||
local evolutionTable = native.upgradeLookup
|
||||
local entity
|
||||
|
||||
local hiveType = buildingHiveTypeLookup[originalEntity.name]
|
||||
@ -203,66 +203,67 @@ local function entityUpgrade(baseAlignment, tier, maxTier, originalEntity, nativ
|
||||
return entity
|
||||
end
|
||||
|
||||
local function findEntityUpgrade(baseAlignment, currentEvo, evoIndex, originalEntity, natives, evolve)
|
||||
local function findEntityUpgrade(baseAlignment, currentEvo, evoIndex, originalEntity, native, evolve)
|
||||
|
||||
local adjCurrentEvo = mMax(
|
||||
((baseAlignment ~= natives.enemyAlignmentLookup[originalEntity.name]) and 0) or currentEvo,
|
||||
((baseAlignment ~= native.enemyAlignmentLookup[originalEntity.name]) and 0) or currentEvo,
|
||||
0
|
||||
)
|
||||
|
||||
local tier = evoToTier(natives, adjCurrentEvo)
|
||||
local maxTier = evoToTier(natives, evoIndex)
|
||||
local tier = evoToTier(native, adjCurrentEvo)
|
||||
local maxTier = evoToTier(native, evoIndex)
|
||||
|
||||
if (tier > maxTier) then
|
||||
return nil
|
||||
end
|
||||
|
||||
if evolve then
|
||||
local chunk = getChunkByPosition(natives.map, originalEntity.position)
|
||||
local makeHive = (chunk ~= -1) and (getResourceGenerator(natives.map, chunk) > 0) and (mRandom() < 0.2)
|
||||
return initialEntityUpgrade(baseAlignment, tier, maxTier, natives, (makeHive and "hive"))
|
||||
local chunk = getChunkByPosition(native.map, originalEntity.position)
|
||||
local makeHive = (chunk ~= -1) and (getResourceGenerator(native.map, chunk) > 0) and (mRandom() < 0.2)
|
||||
return initialEntityUpgrade(baseAlignment, tier, maxTier, native, (makeHive and "hive"))
|
||||
else
|
||||
return entityUpgrade(baseAlignment, tier, maxTier, originalEntity, natives)
|
||||
return entityUpgrade(baseAlignment, tier, maxTier, originalEntity, native)
|
||||
end
|
||||
end
|
||||
|
||||
local function findBaseInitialAlignment(natives, evoIndex)
|
||||
local function findBaseInitialAlignment(native, evoIndex)
|
||||
local dev = evoIndex * 0.3
|
||||
local evoTop = gaussianRandomRange(evoIndex - dev, dev, 0, evoIndex)
|
||||
|
||||
local result
|
||||
if mRandom() < 0.05 then
|
||||
result = {findBaseMutation(natives, evoTop), findBaseMutation(natives, evoTop)}
|
||||
result = {findBaseMutation(native, evoTop), findBaseMutation(native, evoTop)}
|
||||
else
|
||||
result = {findBaseMutation(natives, evoTop)}
|
||||
result = {findBaseMutation(native, evoTop)}
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function baseUtils.recycleBases(natives, tick)
|
||||
local bases = natives.bases
|
||||
local id, base = next(bases, natives.map.recycleBaseIterator)
|
||||
for _=1,2 do
|
||||
if not id then
|
||||
natives.map.recycleBaseIterator = nil
|
||||
return
|
||||
function baseUtils.recycleBases(native, tick)
|
||||
local bases = native.bases
|
||||
local id, base = next(bases, native.map.recycleBaseIterator)
|
||||
-- for _=1,2 do
|
||||
if not id then
|
||||
native.map.recycleBaseIterator = nil
|
||||
return
|
||||
else
|
||||
if ((tick - base.tick) > BASE_COLLECTION_THRESHOLD) then
|
||||
local nextId
|
||||
nextId = next(bases, id)
|
||||
bases[id] = nil
|
||||
id = nextId
|
||||
else
|
||||
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
|
||||
id = next(bases, id)
|
||||
end
|
||||
end
|
||||
natives.map.recycleBaseIterator = id
|
||||
-- end
|
||||
native.map.recycleBaseIterator = id
|
||||
end
|
||||
|
||||
|
||||
function baseUtils.upgradeEntity(entity, surface, baseAlignment, natives, disPos, evolve)
|
||||
function baseUtils.upgradeEntity(entity, baseAlignment, native, disPos, evolve)
|
||||
local surface = native.surface
|
||||
local position = entity.position
|
||||
local currentEvo = entity.prototype.build_base_evolution_requirement or 0
|
||||
|
||||
@ -272,19 +273,19 @@ function baseUtils.upgradeEntity(entity, surface, baseAlignment, natives, disPos
|
||||
end
|
||||
|
||||
local distance = mMin(1, euclideanDistancePoints(position.x, position.y, 0, 0) * BASE_DISTANCE_TO_EVO_INDEX)
|
||||
local evoIndex = mMax(distance, natives.evolutionLevel)
|
||||
local evoIndex = mMax(distance, native.evolutionLevel)
|
||||
|
||||
local spawnerName = findEntityUpgrade(baseAlignment[mRandom(#baseAlignment)],
|
||||
currentEvo,
|
||||
evoIndex,
|
||||
entity,
|
||||
natives,
|
||||
native,
|
||||
evolve)
|
||||
|
||||
if spawnerName then
|
||||
entity.destroy()
|
||||
local name = natives.buildingSpaceLookup[spawnerName] or spawnerName
|
||||
local query = natives.map.upgradeEntityQuery
|
||||
local name = native.buildingSpaceLookup[spawnerName] or spawnerName
|
||||
local query = native.map.upgradeEntityQuery
|
||||
query.name = name
|
||||
query.position = disPos or position
|
||||
|
||||
@ -308,37 +309,38 @@ function baseUtils.upgradeEntity(entity, surface, baseAlignment, natives, disPos
|
||||
return entity
|
||||
end
|
||||
|
||||
local function upgradeBase(natives, base)
|
||||
local function upgradeBase(native, base)
|
||||
local baseAlignment = base.alignment
|
||||
|
||||
local roll = mRandom()
|
||||
if baseAlignment[2] then
|
||||
if (roll < 0.05) then
|
||||
baseAlignment[2] = nil
|
||||
baseAlignment[1] = findBaseMutation(natives)
|
||||
baseAlignment[1] = findBaseMutation(native)
|
||||
elseif (roll < 0.25) then
|
||||
baseAlignment[1] = findBaseMutation(natives)
|
||||
baseAlignment[1] = findBaseMutation(native)
|
||||
else
|
||||
baseAlignment[2] = findBaseMutation(natives)
|
||||
baseAlignment[2] = findBaseMutation(native)
|
||||
end
|
||||
return true
|
||||
else
|
||||
if (roll < 0.85) then
|
||||
base.alignment[1] = findBaseMutation(natives)
|
||||
base.alignment[1] = findBaseMutation(native)
|
||||
else
|
||||
base.alignment[2] = findBaseMutation(natives)
|
||||
base.alignment[2] = findBaseMutation(native)
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function baseUtils.processBase(chunk, surface, natives, tick, base)
|
||||
function baseUtils.processBase(chunk, native, tick, base)
|
||||
if not base.alignment[1] then
|
||||
base.state = BASE_AI_STATE_DORMANT
|
||||
return
|
||||
end
|
||||
|
||||
local map = natives.map
|
||||
local surface = native.surface
|
||||
local map = native.map
|
||||
local point = map.position
|
||||
|
||||
point.x = chunk.x + (CHUNK_SIZE * mRandom())
|
||||
@ -346,28 +348,28 @@ function baseUtils.processBase(chunk, surface, natives, tick, base)
|
||||
|
||||
if (base.state == BASE_AI_STATE_ACTIVE) then
|
||||
local entity = surface.find_entities_filtered(map.filteredEntitiesPointQueryLimited)
|
||||
local cost = (natives.costLookup[entity.name] or MAGIC_MAXIMUM_NUMBER)
|
||||
local cost = (native.costLookup[entity.name] or MAGIC_MAXIMUM_NUMBER)
|
||||
if entity and (base.points >= cost) then
|
||||
local newEntity = baseUtils.upgradeEntity(entity,
|
||||
surface,
|
||||
base.alignment,
|
||||
natives)
|
||||
native)
|
||||
if newEntity then
|
||||
base.points = base.points - cost
|
||||
end
|
||||
end
|
||||
elseif (base.state == BASE_AI_STATE_MUTATE) then
|
||||
if (base.points >= BASE_UPGRADE) then
|
||||
if upgradeBase(natives, base) then
|
||||
if upgradeBase(native, base) then
|
||||
base.points = base.points - BASE_UPGRADE
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (base.state == BASE_AI_STATE_OVERDRIVE) then
|
||||
base.points = base.points + (natives.baseIncrement * 5)
|
||||
base.points = base.points + (native.baseIncrement * 5)
|
||||
elseif (base.state ~= BASE_AI_STATE_DORMANT) then
|
||||
base.points = base.points + natives.baseIncrement
|
||||
base.points = base.points + native.baseIncrement
|
||||
end
|
||||
|
||||
if (base.temperamentTick <= tick) then
|
||||
@ -378,8 +380,8 @@ function baseUtils.processBase(chunk, surface, natives, tick, base)
|
||||
end
|
||||
|
||||
if (base.stateTick <= tick) then
|
||||
local roll = mRandom() * mMax(1 - natives.evolutionLevel, 0.15)
|
||||
if (roll > natives.temperament) then
|
||||
local roll = mRandom() * mMax(1 - native.evolutionLevel, 0.15)
|
||||
if (roll > native.temperament) then
|
||||
base.state = BASE_AI_STATE_DORMANT
|
||||
else
|
||||
roll = mRandom()
|
||||
@ -403,7 +405,7 @@ function baseUtils.processBase(chunk, surface, natives, tick, base)
|
||||
base.tick = tick
|
||||
end
|
||||
|
||||
function baseUtils.createBase(natives, chunk, tick, rebuilding)
|
||||
function baseUtils.createBase(native, chunk, tick, rebuilding)
|
||||
local x = chunk.x
|
||||
local y = chunk.y
|
||||
local distance = euclideanDistancePoints(x, y, 0, 0)
|
||||
@ -411,16 +413,16 @@ function baseUtils.createBase(natives, chunk, tick, rebuilding)
|
||||
local meanLevel = mFloor(distance * 0.005)
|
||||
|
||||
local distanceIndex = mMin(1, distance * BASE_DISTANCE_TO_EVO_INDEX)
|
||||
local evoIndex = mMax(distanceIndex, natives.evolutionLevel)
|
||||
local evoIndex = mMax(distanceIndex, native.evolutionLevel)
|
||||
|
||||
local baseTick = tick
|
||||
|
||||
local alignment
|
||||
if (not rebuilding) and (mRandom() < natives.deadZoneFrequency) then
|
||||
if (not rebuilding) and (mRandom() < native.deadZoneFrequency) then
|
||||
alignment = {}
|
||||
baseTick = BASE_DEADZONE_TTL
|
||||
else
|
||||
alignment = findBaseInitialAlignment(natives, evoIndex) or {"neutral"}
|
||||
alignment = findBaseInitialAlignment(native, evoIndex) or {"neutral"}
|
||||
end
|
||||
|
||||
local baseLevel = gaussianRandomRange(meanLevel, meanLevel * 0.3, meanLevel * 0.50, meanLevel * 1.50)
|
||||
@ -442,34 +444,34 @@ function baseUtils.createBase(natives, chunk, tick, rebuilding)
|
||||
createdTick = tick,
|
||||
temperament = 0,
|
||||
points = 0,
|
||||
id = natives.baseId
|
||||
id = native.baseId
|
||||
}
|
||||
natives.baseId = natives.baseId + 1
|
||||
native.baseId = native.baseId + 1
|
||||
|
||||
setChunkBase(natives.map, chunk, base)
|
||||
setChunkBase(native.map, chunk, base)
|
||||
|
||||
natives.bases[base.id] = base
|
||||
native.bases[base.id] = base
|
||||
|
||||
return base
|
||||
end
|
||||
|
||||
function baseUtils.rebuildNativeTables(natives, rg)
|
||||
function baseUtils.rebuildNativeTables(native, rg)
|
||||
local alignmentSet = {}
|
||||
natives.evolutionTableAlignment = alignmentSet
|
||||
native.evolutionTableAlignment = alignmentSet
|
||||
local buildingSpaceLookup = {}
|
||||
natives.buildingSpaceLookup = buildingSpaceLookup
|
||||
native.buildingSpaceLookup = buildingSpaceLookup
|
||||
local enemyAlignmentLookup = {}
|
||||
natives.enemyAlignmentLookup = enemyAlignmentLookup
|
||||
native.enemyAlignmentLookup = enemyAlignmentLookup
|
||||
local evoToTierMapping = {}
|
||||
natives.evoToTierMapping = evoToTierMapping
|
||||
native.evoToTierMapping = evoToTierMapping
|
||||
local upgradeLookup = {}
|
||||
natives.upgradeLookup = upgradeLookup
|
||||
native.upgradeLookup = upgradeLookup
|
||||
local buildingEvolveLookup = {}
|
||||
natives.buildingEvolveLookup = buildingEvolveLookup
|
||||
native.buildingEvolveLookup = buildingEvolveLookup
|
||||
local costLookup = {}
|
||||
natives.costLookup = costLookup
|
||||
native.costLookup = costLookup
|
||||
local buildingHiveTypeLookup = {}
|
||||
natives.buildingHiveTypeLookup = buildingHiveTypeLookup
|
||||
native.buildingHiveTypeLookup = buildingHiveTypeLookup
|
||||
|
||||
for i=1,10 do
|
||||
evoToTierMapping[#evoToTierMapping+1] = (((i - 1) * 0.1) ^ 0.5) - 0.05
|
||||
@ -532,7 +534,7 @@ function baseUtils.rebuildNativeTables(natives, rg)
|
||||
end
|
||||
|
||||
local variationSet = {}
|
||||
for v=1,natives.ENEMY_VARIATIONS do
|
||||
for v=1,native.ENEMY_VARIATIONS do
|
||||
local entry = faction.type .. "-" .. building.name .. "-v" .. v .. "-t" .. t .. "-rampant"
|
||||
enemyAlignmentLookup[entry] = faction.type
|
||||
local proxyEntity = "entity-proxy-" .. building.type .. "-t" .. t .. "-rampant"
|
||||
@ -591,13 +593,13 @@ function baseUtils.rebuildNativeTables(natives, rg)
|
||||
end
|
||||
end
|
||||
|
||||
local evoIndex = evoToTier(natives, natives.evolutionLevel)
|
||||
local evoIndex = evoToTier(native, native.evolutionLevel)
|
||||
|
||||
for _,base in pairs(natives.bases) do
|
||||
for _,base in pairs(native.bases) do
|
||||
for x=1,#base.alignment do
|
||||
local alignment = base.alignment[x]
|
||||
if not natives.buildingEvolveLookup[alignment] then
|
||||
base.alignment = findBaseInitialAlignment(natives, evoIndex)
|
||||
if not native.buildingEvolveLookup[alignment] then
|
||||
base.alignment = findBaseInitialAlignment(native, evoIndex)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
@ -54,17 +54,18 @@ local function sorter(a, b)
|
||||
return (aDistance < bDistance)
|
||||
end
|
||||
|
||||
function chunkProcessor.processPendingChunks(map, surface, tick, rebuilding, flush)
|
||||
function chunkProcessor.processPendingChunks(map, tick, flush)
|
||||
local processQueue = map.processQueue
|
||||
local pendingChunks = map.pendingChunks
|
||||
|
||||
local area = map.area
|
||||
local surface = map.surface
|
||||
local area = map.queriesAndCommands.area
|
||||
|
||||
local topOffset = area[1]
|
||||
local bottomOffset = area[2]
|
||||
|
||||
local event = next(pendingChunks, map.chunkProcessorIterator)
|
||||
local endCount = 5
|
||||
local endCount = 2
|
||||
if flush then
|
||||
endCount = table_size(pendingChunks)
|
||||
end
|
||||
@ -98,7 +99,7 @@ function chunkProcessor.processPendingChunks(map, surface, tick, rebuilding, flu
|
||||
|
||||
local chunk = createChunk(x, y)
|
||||
|
||||
chunk = initialScan(chunk, surface, map, tick, rebuilding)
|
||||
chunk = initialScan(chunk, map, tick)
|
||||
|
||||
if (chunk ~= -1) then
|
||||
map[x][y] = chunk
|
||||
@ -123,8 +124,8 @@ function chunkProcessor.processPendingChunks(map, surface, tick, rebuilding, flu
|
||||
end
|
||||
end
|
||||
|
||||
function chunkProcessor.processScanChunks(map, surface)
|
||||
local area = map.area
|
||||
function chunkProcessor.processScanChunks(map)
|
||||
local area = map.queriesAndCommands.area
|
||||
|
||||
local topOffset = area[1]
|
||||
local bottomOffset = area[2]
|
||||
@ -144,7 +145,7 @@ function chunkProcessor.processScanChunks(map, surface)
|
||||
bottomOffset[1] = x + CHUNK_SIZE
|
||||
bottomOffset[2] = y + CHUNK_SIZE
|
||||
|
||||
chunk = chunkPassScan(chunk, surface, map)
|
||||
chunk = chunkPassScan(chunk, map)
|
||||
|
||||
if (chunk == -1) then
|
||||
map[x][y] = nil
|
||||
|
@ -152,7 +152,7 @@ end
|
||||
function chunkPropertyUtils.setRaidNestActiveness(map, chunk, value)
|
||||
if (value <= 0) then
|
||||
if (map.chunkToActiveRaidNest[chunk] ~= nil) then
|
||||
map.natives.activeRaidNests = map.natives.activeRaidNests - 1
|
||||
map.native.activeRaidNests = map.native.activeRaidNests - 1
|
||||
end
|
||||
if (map.processActiveRaidSpawnerIterator == chunk) then
|
||||
map.processActiveRaidSpawnerIterator = nil
|
||||
@ -160,7 +160,7 @@ function chunkPropertyUtils.setRaidNestActiveness(map, chunk, value)
|
||||
map.chunkToActiveRaidNest[chunk] = nil
|
||||
else
|
||||
if (map.chunkToActiveRaidNest[chunk] == nil) then
|
||||
map.natives.activeRaidNests = map.natives.activeRaidNests + 1
|
||||
map.native.activeRaidNests = map.native.activeRaidNests + 1
|
||||
end
|
||||
map.chunkToActiveRaidNest[chunk] = value
|
||||
end
|
||||
@ -185,7 +185,7 @@ end
|
||||
function chunkPropertyUtils.setNestActiveness(map, chunk, value)
|
||||
if (value <= 0) then
|
||||
if (map.chunkToActiveNest[chunk] ~= nil) then
|
||||
map.natives.activeNests = map.natives.activeNests - 1
|
||||
map.native.activeNests = map.native.activeNests - 1
|
||||
end
|
||||
if (map.processActiveSpawnerIterator == chunk) then
|
||||
map.processActiveSpawnerIterator = nil
|
||||
@ -193,7 +193,7 @@ function chunkPropertyUtils.setNestActiveness(map, chunk, value)
|
||||
map.chunkToActiveNest[chunk] = nil
|
||||
else
|
||||
if (map.chunkToActiveNest[chunk] == nil) then
|
||||
map.natives.activeNests = map.natives.activeNests + 1
|
||||
map.native.activeNests = map.native.activeNests + 1
|
||||
end
|
||||
map.chunkToActiveNest[chunk] = value
|
||||
end
|
||||
@ -324,12 +324,14 @@ function chunkPropertyUtils.addPlayerBaseGenerator(map, chunk, playerGenerator)
|
||||
map.chunkToPlayerBase[chunk] = (map.chunkToPlayerBase[chunk] or 0) + playerGenerator
|
||||
end
|
||||
|
||||
function chunkPropertyUtils.processNestActiveness(map, chunk, natives, surface)
|
||||
function chunkPropertyUtils.processNestActiveness(map, chunk)
|
||||
local nests = chunkPropertyUtils.getNestCount(map, chunk)
|
||||
if (nests > 0) then
|
||||
local native = map.native
|
||||
local surface = native.surface
|
||||
local activeness = chunkPropertyUtils.getNestActiveness(map, chunk)
|
||||
local raidActiveness = chunkPropertyUtils.getRaidNestActiveness(map, chunk)
|
||||
if natives.attackUsePlayer and (chunk[PLAYER_PHEROMONE] > natives.attackPlayerThreshold) then
|
||||
if native.attackUsePlayer and (chunk[PLAYER_PHEROMONE] > native.attackPlayerThreshold) then
|
||||
chunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20))
|
||||
elseif (chunk[BASE_PHEROMONE] > 0) then
|
||||
local position = map.position
|
||||
|
@ -89,7 +89,7 @@ local mFloor = math.floor
|
||||
|
||||
local function getEntityOverlapChunks(map, entity)
|
||||
local boundingBox = entity.prototype.collision_box or entity.prototype.selection_box;
|
||||
local overlapArray = map.chunkOverlapArray
|
||||
local overlapArray = map.queriesAndCommands.chunkOverlapArray
|
||||
|
||||
overlapArray[1] = -1 --LeftTop
|
||||
overlapArray[2] = -1 --RightTop
|
||||
@ -129,14 +129,16 @@ local function getEntityOverlapChunks(map, entity)
|
||||
return overlapArray
|
||||
end
|
||||
|
||||
local function scanPaths(chunk, surface, map)
|
||||
local function scanPaths(chunk, map)
|
||||
local surface = map.surface
|
||||
local pass = CHUNK_IMPASSABLE
|
||||
|
||||
local x = chunk.x
|
||||
local y = chunk.y
|
||||
|
||||
local filteredEntitiesCliffQuery = map.filteredEntitiesCliffQuery
|
||||
local filteredTilesPathQuery = map.filteredTilesPathQuery
|
||||
local queriesAndCommands = map.queriesAndCommands
|
||||
local filteredEntitiesCliffQuery = queriesAndCommands.filteredEntitiesCliffQuery
|
||||
local filteredTilesPathQuery = queriesAndCommands.filteredTilesPathQuery
|
||||
local count_entities_filtered = surface.count_entities_filtered
|
||||
local count_tiles_filtered = surface.count_tiles_filtered
|
||||
|
||||
@ -183,53 +185,57 @@ local function scanPaths(chunk, surface, map)
|
||||
return pass
|
||||
end
|
||||
|
||||
local function scorePlayerBuildings(surface, map)
|
||||
if surface.count_entities_filtered(map.hasPlayerStructuresQuery) > 0 then
|
||||
return (surface.count_entities_filtered(map.filteredEntitiesPlayerQueryLowest) * GENERATOR_PHEROMONE_LEVEL_1) +
|
||||
(surface.count_entities_filtered(map.filteredEntitiesPlayerQueryLow) * GENERATOR_PHEROMONE_LEVEL_3) +
|
||||
(surface.count_entities_filtered(map.filteredEntitiesPlayerQueryHigh) * GENERATOR_PHEROMONE_LEVEL_5) +
|
||||
(surface.count_entities_filtered(map.filteredEntitiesPlayerQueryHighest) * GENERATOR_PHEROMONE_LEVEL_6)
|
||||
local function scorePlayerBuildings(map)
|
||||
local surface = map.surface
|
||||
local queriesAndCommands = map.queriesAndCommands
|
||||
if surface.count_entities_filtered(queriesAndCommands.hasPlayerStructuresQuery) > 0 then
|
||||
return (surface.count_entities_filtered(queriesAndCommands.filteredEntitiesPlayerQueryLowest) * GENERATOR_PHEROMONE_LEVEL_1) +
|
||||
(surface.count_entities_filtered(queriesAndCommands.filteredEntitiesPlayerQueryLow) * GENERATOR_PHEROMONE_LEVEL_3) +
|
||||
(surface.count_entities_filtered(queriesAndCommands.filteredEntitiesPlayerQueryHigh) * GENERATOR_PHEROMONE_LEVEL_5) +
|
||||
(surface.count_entities_filtered(queriesAndCommands.filteredEntitiesPlayerQueryHighest) * GENERATOR_PHEROMONE_LEVEL_6)
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function chunkUtils.initialScan(chunk, surface, map, tick, rebuilding)
|
||||
local waterTiles = (1 - (surface.count_tiles_filtered(map.filteredTilesQuery) * 0.0009765625)) * 0.80
|
||||
local natives = map.natives
|
||||
local enemyBuildings = surface.find_entities_filtered(map.filteredEntitiesEnemyStructureQuery)
|
||||
function chunkUtils.initialScan(chunk, map, tick)
|
||||
local surface = map.surface
|
||||
local queriesAndCommands = map.queriesAndCommands
|
||||
local waterTiles = (1 - (surface.count_tiles_filtered(queriesAndCommands.filteredTilesQuery) * 0.0009765625)) * 0.80
|
||||
local native = map.native
|
||||
local enemyBuildings = surface.find_entities_filtered(queriesAndCommands.filteredEntitiesEnemyStructureQuery)
|
||||
|
||||
if (waterTiles >= CHUNK_PASS_THRESHOLD) or (#enemyBuildings > 0) then
|
||||
local neutralObjects = mMax(0,
|
||||
mMin(1 - (surface.count_entities_filtered(map.filteredEntitiesChunkNeutral) * 0.005),
|
||||
mMin(1 - (surface.count_entities_filtered(queriesAndCommands.filteredEntitiesChunkNeutral) * 0.005),
|
||||
1) * 0.20)
|
||||
local pass = scanPaths(chunk, surface, map)
|
||||
local pass = scanPaths(chunk, map)
|
||||
|
||||
local playerObjects = scorePlayerBuildings(surface, map)
|
||||
local playerObjects = scorePlayerBuildings(map)
|
||||
|
||||
if ((playerObjects > 0) or (#enemyBuildings > 0)) and (pass == CHUNK_IMPASSABLE) then
|
||||
pass = CHUNK_ALL_DIRECTIONS
|
||||
end
|
||||
|
||||
if (pass ~= CHUNK_IMPASSABLE) then
|
||||
local resources = surface.count_entities_filtered(map.countResourcesQuery) * RESOURCE_NORMALIZER
|
||||
local resources = surface.count_entities_filtered(queriesAndCommands.countResourcesQuery) * RESOURCE_NORMALIZER
|
||||
|
||||
local buildingHiveTypeLookup = natives.buildingHiveTypeLookup
|
||||
local buildingHiveTypeLookup = native.buildingHiveTypeLookup
|
||||
local counts = map.chunkScanCounts
|
||||
for i=1,#HIVE_BUILDINGS_TYPES do
|
||||
counts[HIVE_BUILDINGS_TYPES[i]] = 0
|
||||
end
|
||||
|
||||
if (#enemyBuildings > 0) then
|
||||
if natives.newEnemies then
|
||||
if native.newEnemies then
|
||||
local base = findNearbyBase(map, chunk)
|
||||
if base then
|
||||
setChunkBase(map, chunk, base)
|
||||
else
|
||||
base = createBase(natives, chunk, tick, rebuilding)
|
||||
base = createBase(native, chunk, tick)
|
||||
end
|
||||
local alignment = base.alignment
|
||||
|
||||
local unitList = surface.find_entities_filtered(map.filteredEntitiesUnitQuery)
|
||||
local unitList = surface.find_entities_filtered(queriesAndCommands.filteredEntitiesUnitQuery)
|
||||
for i=1,#unitList do
|
||||
local unit = unitList[i]
|
||||
if (unit.valid) then
|
||||
@ -240,7 +246,7 @@ function chunkUtils.initialScan(chunk, surface, map, tick, rebuilding)
|
||||
for i = 1, #enemyBuildings do
|
||||
local enemyBuilding = enemyBuildings[i]
|
||||
if not isRampant(enemyBuilding.name) then
|
||||
local newEntity = upgradeEntity(enemyBuilding, surface, alignment, natives, nil, true)
|
||||
local newEntity = upgradeEntity(enemyBuilding, surface, alignment, native, nil, true)
|
||||
if newEntity then
|
||||
local hiveType = buildingHiveTypeLookup[newEntity.name]
|
||||
counts[hiveType] = counts[hiveType] + 1
|
||||
@ -286,14 +292,16 @@ function chunkUtils.initialScan(chunk, surface, map, tick, rebuilding)
|
||||
return -1
|
||||
end
|
||||
|
||||
function chunkUtils.chunkPassScan(chunk, surface, map)
|
||||
local waterTiles = (1 - (surface.count_tiles_filtered(map.filteredTilesQuery) * 0.0009765625)) * 0.80
|
||||
function chunkUtils.chunkPassScan(chunk, map)
|
||||
local surface = map.surface
|
||||
local queriesAndCommands = map.queriesAndCommands
|
||||
local waterTiles = (1 - (surface.count_tiles_filtered(queriesAndCommands.filteredTilesQuery) * 0.0009765625)) * 0.80
|
||||
|
||||
if (waterTiles >= CHUNK_PASS_THRESHOLD) then
|
||||
local neutralObjects = mMax(0,
|
||||
mMin(1 - (surface.count_entities_filtered(map.filteredEntitiesChunkNeutral) * 0.005),
|
||||
mMin(1 - (surface.count_entities_filtered(queriesAndCommands.filteredEntitiesChunkNeutral) * 0.005),
|
||||
1) * 0.20)
|
||||
local pass = scanPaths(chunk, surface, map)
|
||||
local pass = scanPaths(chunk, map)
|
||||
|
||||
local playerObjects = getPlayerBaseGenerator(map, chunk)
|
||||
|
||||
@ -312,24 +320,27 @@ function chunkUtils.chunkPassScan(chunk, surface, map)
|
||||
return -1
|
||||
end
|
||||
|
||||
function chunkUtils.mapScanPlayerChunk(chunk, surface, map)
|
||||
local playerObjects = scorePlayerBuildings(surface, map)
|
||||
function chunkUtils.mapScanPlayerChunk(chunk, map)
|
||||
local playerObjects = scorePlayerBuildings(map)
|
||||
setPlayerBaseGenerator(map, chunk, playerObjects)
|
||||
end
|
||||
|
||||
function chunkUtils.mapScanResourceChunk(chunk, surface, map)
|
||||
local resources = surface.count_entities_filtered(map.countResourcesQuery) * RESOURCE_NORMALIZER
|
||||
function chunkUtils.mapScanResourceChunk(chunk, map)
|
||||
local surface = map.surface
|
||||
local queriesAndCommands = map.queriesAndCommands
|
||||
local resources = surface.count_entities_filtered(queriesAndCommands.countResourcesQuery) * RESOURCE_NORMALIZER
|
||||
setResourceGenerator(map, chunk, resources)
|
||||
local waterTiles = (1 - (surface.count_tiles_filtered(map.filteredTilesQuery) * 0.0009765625)) * 0.80
|
||||
local waterTiles = (1 - (surface.count_tiles_filtered(queriesAndCommands.filteredTilesQuery) * 0.0009765625)) * 0.80
|
||||
local neutralObjects = mMax(0,
|
||||
mMin(1 - (surface.count_entities_filtered(map.filteredEntitiesChunkNeutral) * 0.005),
|
||||
mMin(1 - (surface.count_entities_filtered(queriesAndCommands.filteredEntitiesChunkNeutral) * 0.005),
|
||||
1) * 0.20)
|
||||
setPathRating(map, chunk, waterTiles + neutralObjects)
|
||||
end
|
||||
|
||||
function chunkUtils.mapScanEnemyChunk(chunk, surface, map)
|
||||
local buildingHiveTypeLookup = map.natives.buildingHiveTypeLookup
|
||||
local buildings = surface.find_entities_filtered(map.filteredEntitiesEnemyStructureQuery)
|
||||
function chunkUtils.mapScanEnemyChunk(chunk, map)
|
||||
local buildingHiveTypeLookup = map.native.buildingHiveTypeLookup
|
||||
local queriesAndCommands = map.queriesAndCommands
|
||||
local buildings = map.surface.find_entities_filtered(queriesAndCommands.filteredEntitiesEnemyStructureQuery)
|
||||
local counts = map.chunkScanCounts
|
||||
for i=1,#HIVE_BUILDINGS_TYPES do
|
||||
counts[HIVE_BUILDINGS_TYPES[i]] = 0
|
||||
@ -407,42 +418,42 @@ function chunkUtils.colorXY(x, y, surface, color)
|
||||
end
|
||||
|
||||
|
||||
function chunkUtils.registerEnemyBaseStructure(map, entity, base, surface)
|
||||
function chunkUtils.registerEnemyBaseStructure(map, entity, base)
|
||||
local entityType = entity.type
|
||||
if ((entityType == "unit-spawner") or (entityType == "turret")) and (entity.force.name == "enemy") then
|
||||
local overlapArray = getEntityOverlapChunks(map, entity)
|
||||
|
||||
local natives = map.natives
|
||||
local native = map.native
|
||||
local getFunc
|
||||
local setFunc
|
||||
local hiveTypeLookup = natives.buildingHiveTypeLookup
|
||||
local hiveTypeLookup = native.buildingHiveTypeLookup
|
||||
local hiveType = hiveTypeLookup[entity.name]
|
||||
if (hiveType == "spitter-spawner") or (hiveType == "biter-spawner") then
|
||||
natives.builtEnemyBuilding = natives.builtEnemyBuilding + 1
|
||||
native.builtEnemyBuilding = native.builtEnemyBuilding + 1
|
||||
getFunc = getNestCount
|
||||
setFunc = setNestCount
|
||||
elseif (hiveType == "turret") then
|
||||
natives.builtEnemyBuilding = natives.builtEnemyBuilding + 1
|
||||
native.builtEnemyBuilding = native.builtEnemyBuilding + 1
|
||||
getFunc = getTurretCount
|
||||
setFunc = setTurretCount
|
||||
elseif (hiveType == "trap") then
|
||||
getFunc = getTrapCount
|
||||
setFunc = setTrapCount
|
||||
elseif (hiveType == "utility") then
|
||||
natives.builtEnemyBuilding = natives.builtEnemyBuilding + 1
|
||||
native.builtEnemyBuilding = native.builtEnemyBuilding + 1
|
||||
getFunc = getUtilityCount
|
||||
setFunc = setUtilityCount
|
||||
elseif (hiveType == "hive") then
|
||||
natives.builtEnemyBuilding = natives.builtEnemyBuilding + 1
|
||||
native.builtEnemyBuilding = native.builtEnemyBuilding + 1
|
||||
getFunc = getHiveCount
|
||||
setFunc = setHiveCount
|
||||
else
|
||||
if (entityType == "turret") then
|
||||
natives.builtEnemyBuilding = natives.builtEnemyBuilding + 1
|
||||
native.builtEnemyBuilding = native.builtEnemyBuilding + 1
|
||||
getFunc = getTurretCount
|
||||
setFunc = setTurretCount
|
||||
elseif (entityType == "unit-spawner") then
|
||||
natives.builtEnemyBuilding = natives.builtEnemyBuilding + 1
|
||||
native.builtEnemyBuilding = native.builtEnemyBuilding + 1
|
||||
getFunc = getNestCount
|
||||
setFunc = setNestCount
|
||||
end
|
||||
@ -453,7 +464,7 @@ function chunkUtils.registerEnemyBaseStructure(map, entity, base, surface)
|
||||
if (chunk ~= -1) then
|
||||
setFunc(map, chunk, getFunc(map, chunk) + 1)
|
||||
setChunkBase(map, chunk, base)
|
||||
processNestActiveness(map, chunk, natives, surface)
|
||||
processNestActiveness(map, chunk)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -466,38 +477,38 @@ function chunkUtils.unregisterEnemyBaseStructure(map, entity)
|
||||
if ((entityType == "unit-spawner") or (entityType == "turret")) and (entity.force.name == "enemy") then
|
||||
local overlapArray = getEntityOverlapChunks(map, entity)
|
||||
|
||||
local natives = map.natives
|
||||
local native = map.native
|
||||
local getFunc
|
||||
local setFunc
|
||||
local hiveTypeLookup = map.natives.buildingHiveTypeLookup
|
||||
local hiveTypeLookup = map.native.buildingHiveTypeLookup
|
||||
local hiveType = hiveTypeLookup[entity.name]
|
||||
if (hiveType == "spitter-spawner") or (hiveType == "biter-spawner") then
|
||||
natives.lostEnemyBuilding = natives.lostEnemyBuilding + 1
|
||||
native.lostEnemyBuilding = native.lostEnemyBuilding + 1
|
||||
getFunc = getNestCount
|
||||
setFunc = setNestCount
|
||||
elseif (hiveType == "turret") then
|
||||
natives.lostEnemyBuilding = natives.lostEnemyBuilding + 1
|
||||
native.lostEnemyBuilding = native.lostEnemyBuilding + 1
|
||||
getFunc = getTurretCount
|
||||
setFunc = setTurretCount
|
||||
elseif (hiveType == "trap") then
|
||||
getFunc = getTrapCount
|
||||
setFunc = setTrapCount
|
||||
elseif (hiveType == "utility") then
|
||||
natives.lostEnemyBuilding = natives.lostEnemyBuilding + 1
|
||||
native.lostEnemyBuilding = native.lostEnemyBuilding + 1
|
||||
getFunc = getUtilityCount
|
||||
setFunc = setUtilityCount
|
||||
elseif (hiveType == "hive") then
|
||||
natives.lostEnemyBuilding = natives.lostEnemyBuilding + 1
|
||||
native.lostEnemyBuilding = native.lostEnemyBuilding + 1
|
||||
getFunc = getHiveCount
|
||||
setFunc = setHiveCount
|
||||
else
|
||||
if (entityType == "turret") then
|
||||
natives.lostEnemyBuilding = natives.lostEnemyBuilding + 1
|
||||
native.lostEnemyBuilding = native.lostEnemyBuilding + 1
|
||||
getFunc = getTurretCount
|
||||
setFunc = setTurretCount
|
||||
elseif (entityType == "unit-spawner") then
|
||||
hiveType = "biter-spawner"
|
||||
natives.lostEnemyBuilding = natives.lostEnemyBuilding + 1
|
||||
native.lostEnemyBuilding = native.lostEnemyBuilding + 1
|
||||
getFunc = getNestCount
|
||||
setFunc = setNestCount
|
||||
end
|
||||
@ -527,19 +538,19 @@ function chunkUtils.unregisterEnemyBaseStructure(map, entity)
|
||||
end
|
||||
end
|
||||
|
||||
function chunkUtils.accountPlayerEntity(entity, natives, addObject, creditNatives)
|
||||
function chunkUtils.accountPlayerEntity(entity, native, addObject, creditNatives)
|
||||
if (BUILDING_PHEROMONES[entity.type] ~= nil) and (entity.force.name ~= "enemy") then
|
||||
local map = natives.map
|
||||
local map = native.map
|
||||
local entityValue = BUILDING_PHEROMONES[entity.type]
|
||||
|
||||
local overlapArray = getEntityOverlapChunks(map, entity)
|
||||
if not addObject then
|
||||
if creditNatives then
|
||||
natives.destroyPlayerBuildings = natives.destroyPlayerBuildings + 1
|
||||
if (natives.state == AI_STATE_ONSLAUGHT) then
|
||||
natives.points = natives.points + entityValue
|
||||
native.destroyPlayerBuildings = native.destroyPlayerBuildings + 1
|
||||
if (native.state == AI_STATE_ONSLAUGHT) then
|
||||
native.points = native.points + entityValue
|
||||
else
|
||||
natives.points = natives.points + (entityValue * 0.12)
|
||||
native.points = native.points + (entityValue * 0.12)
|
||||
end
|
||||
end
|
||||
entityValue = -entityValue
|
||||
|
@ -48,7 +48,7 @@ constants.SCAN_QUEUE_SIZE = 2
|
||||
constants.RESOURCE_QUEUE_SIZE = 7
|
||||
constants.ENEMY_QUEUE_SIZE = 7
|
||||
constants.PLAYER_QUEUE_SIZE = 7
|
||||
constants.CLEANUP_QUEUE_SIZE = 15
|
||||
constants.CLEANUP_QUEUE_SIZE = 8
|
||||
constants.ATTACK_QUEUE_SIZE = 18
|
||||
constants.BASE_QUEUE_SIZE = 1
|
||||
constants.PROCESS_STATIC_QUEUE_SIZE = 20
|
||||
@ -64,16 +64,16 @@ constants.CHUNK_PASS_THRESHOLD = 0.2
|
||||
-- constants.INTERVAL_MAP_PROCESS = 5
|
||||
-- constants.INTERVAL_MAP_STATIC_PROCESS = 11
|
||||
-- constants.INTERVAL_SCAN = 19
|
||||
constants.INTERVAL_CHUNK_PROCESS = 23
|
||||
constants.INTERVAL_LOGIC = 59
|
||||
constants.INTERVAL_TEMPERAMENT = 121
|
||||
constants.INTERVAL_SQUAD = 14
|
||||
constants.INTERVAL_NEST = 16
|
||||
constants.INTERVAL_PASS_SCAN = 29
|
||||
-- constants.INTERVAL_CHUNK_PROCESS = 23
|
||||
-- constants.INTERVAL_LOGIC = 59
|
||||
-- constants.INTERVAL_TEMPERAMENT = 121
|
||||
-- constants.INTERVAL_SQUAD = 14
|
||||
-- constants.INTERVAL_NEST = 16
|
||||
-- constants.INTERVAL_PASS_SCAN = 29
|
||||
-- constants.INTERVAL_RESQUAD = 101
|
||||
constants.INTERVAL_SPAWNER = 19
|
||||
constants.INTERVAL_VICTORY = 10
|
||||
constants.INTERVAL_CLEANUP = 34
|
||||
-- constants.INTERVAL_SPAWNER = 19
|
||||
-- constants.INTERVAL_VICTORY = 10
|
||||
-- constants.INTERVAL_CLEANUP = 34
|
||||
|
||||
constants.COOLDOWN_RALLY = constants.TICKS_A_SECOND * 10
|
||||
constants.COOLDOWN_RETREAT = constants.TICKS_A_SECOND * 10
|
||||
|
130
libs/Interop.lua
130
libs/Interop.lua
@ -3,91 +3,91 @@ if interopG then
|
||||
end
|
||||
local interop = {}
|
||||
|
||||
function interop.addAIPoints(value)
|
||||
global.natives.points = global.natives.points + value
|
||||
end
|
||||
-- function interop.addAIPoints(value)
|
||||
-- global.natives.points = global.natives.points + value
|
||||
-- end
|
||||
|
||||
function interop.getAIPoints()
|
||||
return global.natives.points
|
||||
end
|
||||
-- function interop.getAIPoints()
|
||||
-- return global.natives.points
|
||||
-- end
|
||||
|
||||
function interop.setNocturnalMode(flag)
|
||||
global.natives.aiNocturnalMode = flag
|
||||
end
|
||||
-- function interop.setNocturnalMode(flag)
|
||||
-- global.natives.aiNocturnalMode = flag
|
||||
-- end
|
||||
|
||||
function interop.getNocturnalMode()
|
||||
return global.natives.aiNocturnalMode
|
||||
end
|
||||
-- function interop.getNocturnalMode()
|
||||
-- return global.natives.aiNocturnalMode
|
||||
-- end
|
||||
|
||||
function interop.setPointsPerCycleScaling(scale)
|
||||
global.natives.aiPointsScaler = scale
|
||||
end
|
||||
-- function interop.setPointsPerCycleScaling(scale)
|
||||
-- global.natives.aiPointsScaler = scale
|
||||
-- end
|
||||
|
||||
function interop.getPointsPerCycleScaling()
|
||||
return global.natives.aiPointsScaler
|
||||
end
|
||||
-- function interop.getPointsPerCycleScaling()
|
||||
-- return global.natives.aiPointsScaler
|
||||
-- end
|
||||
|
||||
function interop.changeState(aiState)
|
||||
global.natives.state = aiState
|
||||
end
|
||||
-- function interop.changeState(aiState)
|
||||
-- global.natives.state = aiState
|
||||
-- end
|
||||
|
||||
function interop.getState()
|
||||
return global.natives.state
|
||||
end
|
||||
-- function interop.getState()
|
||||
-- return global.natives.state
|
||||
-- end
|
||||
|
||||
function interop.getNextStateTick()
|
||||
return global.natives.stateTick
|
||||
end
|
||||
-- function interop.getNextStateTick()
|
||||
-- return global.natives.stateTick
|
||||
-- end
|
||||
|
||||
function interop.getMaxWaveSize()
|
||||
return global.natives.attackWaveMaxSize
|
||||
end
|
||||
-- function interop.getMaxWaveSize()
|
||||
-- return global.natives.attackWaveMaxSize
|
||||
-- end
|
||||
|
||||
function interop.getThresholds()
|
||||
return global.natives.attackThresholdMin, global.natives.attackThresholdMax
|
||||
end
|
||||
-- function interop.getThresholds()
|
||||
-- return global.natives.attackThresholdMin, global.natives.attackThresholdMax
|
||||
-- end
|
||||
|
||||
function interop.changeMaxWaveSize(waveSize)
|
||||
global.natives.attackWaveMaxSize = waveSize
|
||||
end
|
||||
-- function interop.changeMaxWaveSize(waveSize)
|
||||
-- global.natives.attackWaveMaxSize = waveSize
|
||||
-- end
|
||||
|
||||
function interop.getSettlerCooldown()
|
||||
return global.natives.settlerCooldown
|
||||
end
|
||||
-- function interop.getSettlerCooldown()
|
||||
-- return global.natives.settlerCooldown
|
||||
-- end
|
||||
|
||||
function interop.getSettlerWaveSize()
|
||||
return global.natives.settlerWaveSize
|
||||
end
|
||||
-- function interop.getSettlerWaveSize()
|
||||
-- return global.natives.settlerWaveSize
|
||||
-- end
|
||||
|
||||
function interop.changeThreshold(min, max)
|
||||
global.natives.attackThresholdMin = min
|
||||
global.natives.attackThresholdMax = max
|
||||
global.natives.attackThresholdRange = max - min
|
||||
end
|
||||
-- function interop.changeThreshold(min, max)
|
||||
-- global.natives.attackThresholdMin = min
|
||||
-- global.natives.attackThresholdMax = max
|
||||
-- global.natives.attackThresholdRange = max - min
|
||||
-- end
|
||||
|
||||
function interop.changePlayerThreshold(value)
|
||||
global.natives.attackPlayerThreshold = value
|
||||
end
|
||||
-- function interop.changePlayerThreshold(value)
|
||||
-- global.natives.attackPlayerThreshold = value
|
||||
-- end
|
||||
|
||||
function interop.getPlayerThreshold()
|
||||
return global.natives.attackPlayerThreshold
|
||||
end
|
||||
-- function interop.getPlayerThreshold()
|
||||
-- return global.natives.attackPlayerThreshold
|
||||
-- end
|
||||
|
||||
function interop.changeAttackUsePollution(bool)
|
||||
global.natives.attackUsePollution = bool
|
||||
end
|
||||
-- function interop.changeAttackUsePollution(bool)
|
||||
-- global.natives.attackUsePollution = bool
|
||||
-- end
|
||||
|
||||
function interop.changeAttackUsePlayer(bool)
|
||||
global.natives.attackUsePlayer = bool
|
||||
end
|
||||
-- function interop.changeAttackUsePlayer(bool)
|
||||
-- global.natives.attackUsePlayer = bool
|
||||
-- end
|
||||
|
||||
function interop.getAttackUsePollution()
|
||||
return global.natives.attackUsePollution
|
||||
end
|
||||
-- function interop.getAttackUsePollution()
|
||||
-- return global.natives.attackUsePollution
|
||||
-- end
|
||||
|
||||
function interop.getAttackUsePlayer()
|
||||
return global.natives.attackUsePlayer
|
||||
end
|
||||
-- function interop.getAttackUsePlayer()
|
||||
-- return global.natives.attackUsePlayer
|
||||
-- end
|
||||
|
||||
-- function interop.registerUnitGroup(unitGroup, isSettler)
|
||||
-- local squad = unitGroupUtils.createSquad(unitGroup.position, unitGroup.surface, unitGroup, isSettler)
|
||||
|
@ -178,7 +178,7 @@ end
|
||||
|
||||
local function queueNestSpawners(map, chunk, tick)
|
||||
local limitPerActiveChunkTick =
|
||||
(map.natives.activeNests + map.natives.activeRaidNests) * DURATION_ACTIVE_NEST_DIVIDER
|
||||
(map.native.activeNests + map.native.activeRaidNests) * DURATION_ACTIVE_NEST_DIVIDER
|
||||
|
||||
local processActiveNest = map.processActiveNest
|
||||
|
||||
@ -220,24 +220,24 @@ end
|
||||
vs
|
||||
the slower passive version processing the entire map in multiple passes.
|
||||
--]]
|
||||
function mapProcessor.processPlayers(players, map, surface, tick)
|
||||
function mapProcessor.processPlayers(players, map, tick)
|
||||
-- put down player pheromone for player hunters
|
||||
-- randomize player order to ensure a single player isn't singled out
|
||||
local natives = map.natives
|
||||
local native = map.native
|
||||
|
||||
local allowingAttacks = canAttack(natives, surface, tick)
|
||||
local allowingAttacks = canAttack(native, tick)
|
||||
|
||||
-- not looping everyone because the cost is high enough already in multiplayer
|
||||
if (#players > 0) then
|
||||
local player = players[mRandom(#players)]
|
||||
if validPlayer(player, natives) then
|
||||
if validPlayer(player, native) then
|
||||
local playerChunk = getChunkByPosition(map, player.character.position)
|
||||
|
||||
if (playerChunk ~= -1) then
|
||||
local vengence = allowingAttacks and
|
||||
(natives.points >= AI_VENGENCE_SQUAD_COST) and
|
||||
(native.points >= AI_VENGENCE_SQUAD_COST) and
|
||||
((getEnemyStructureCount(map, playerChunk) > 0) or
|
||||
(-getDeathGenerator(map, playerChunk) < -natives.retreatThreshold))
|
||||
(-getDeathGenerator(map, playerChunk) < -native.retreatThreshold))
|
||||
|
||||
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
|
||||
@ -248,16 +248,16 @@ function mapProcessor.processPlayers(players, map, surface, tick)
|
||||
processPheromone(map, chunk, true)
|
||||
|
||||
if (getNestCount(map, chunk) > 0) then
|
||||
processNestActiveness(map, chunk, natives, surface)
|
||||
processNestActiveness(map, chunk)
|
||||
queueNestSpawners(map, chunk, tick)
|
||||
|
||||
if vengence then
|
||||
local count = natives.vengenceQueue[chunk]
|
||||
local count = native.vengenceQueue[chunk]
|
||||
if not count then
|
||||
count = 0
|
||||
natives.vengenceQueue[chunk] = count
|
||||
native.vengenceQueue[chunk] = count
|
||||
end
|
||||
natives.vengenceQueue[chunk] = count + 1
|
||||
native.vengenceQueue[chunk] = count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -269,7 +269,7 @@ function mapProcessor.processPlayers(players, map, surface, tick)
|
||||
|
||||
for i=1,#players do
|
||||
local player = players[i]
|
||||
if validPlayer(player, natives) then
|
||||
if validPlayer(player, native) then
|
||||
local playerChunk = getChunkByPosition(map, player.character.position)
|
||||
|
||||
if (playerChunk ~= -1) then
|
||||
@ -323,7 +323,7 @@ end
|
||||
--[[
|
||||
Passive scan to find entities that have been generated outside the factorio event system
|
||||
--]]
|
||||
function mapProcessor.scanPlayerMap(map, surface, tick)
|
||||
function mapProcessor.scanPlayerMap(map, tick)
|
||||
if (map.nextProcessMap == tick) or (map.nextPlayerScan == tick) or
|
||||
(map.nextEnemyScan == tick) or (map.nextChunkProcess == tick)
|
||||
then
|
||||
@ -351,7 +351,7 @@ function mapProcessor.scanPlayerMap(map, surface, tick)
|
||||
offset[1] = chunk.x + CHUNK_SIZE
|
||||
offset[2] = chunk.y + CHUNK_SIZE
|
||||
|
||||
mapScanPlayerChunk(chunk, surface, map)
|
||||
mapScanPlayerChunk(chunk, map)
|
||||
end
|
||||
|
||||
if (endIndex == processQueueLength) then
|
||||
@ -361,7 +361,7 @@ function mapProcessor.scanPlayerMap(map, surface, tick)
|
||||
end
|
||||
end
|
||||
|
||||
function mapProcessor.scanEnemyMap(map, surface, tick)
|
||||
function mapProcessor.scanEnemyMap(map, tick)
|
||||
if (map.nextProcessMap == tick) or (map.nextPlayerScan == tick) or (map.nextChunkProcess == tick) then
|
||||
return
|
||||
end
|
||||
@ -388,7 +388,7 @@ function mapProcessor.scanEnemyMap(map, surface, tick)
|
||||
offset[1] = chunk.x + CHUNK_SIZE
|
||||
offset[2] = chunk.y + CHUNK_SIZE
|
||||
|
||||
mapScanEnemyChunk(chunk, surface, map)
|
||||
mapScanEnemyChunk(chunk, map)
|
||||
end
|
||||
|
||||
if (endIndex == processQueueLength) then
|
||||
@ -398,7 +398,7 @@ function mapProcessor.scanEnemyMap(map, surface, tick)
|
||||
end
|
||||
end
|
||||
|
||||
function mapProcessor.scanResourceMap(map, surface, tick)
|
||||
function mapProcessor.scanResourceMap(map, tick)
|
||||
if (map.nextProcessMap == tick) or (map.nextPlayerScan == tick) or
|
||||
(map.nextEnemyScan == tick) or (map.nextChunkProcess == tick)
|
||||
then
|
||||
@ -426,7 +426,7 @@ function mapProcessor.scanResourceMap(map, surface, tick)
|
||||
offset[1] = chunk.x + CHUNK_SIZE
|
||||
offset[2] = chunk.y + CHUNK_SIZE
|
||||
|
||||
mapScanResourceChunk(chunk, surface, map)
|
||||
mapScanResourceChunk(chunk, map)
|
||||
end
|
||||
|
||||
if (endIndex == processQueueLength) then
|
||||
@ -436,15 +436,14 @@ function mapProcessor.scanResourceMap(map, surface, tick)
|
||||
end
|
||||
end
|
||||
|
||||
function mapProcessor.processActiveNests(map, surface, tick)
|
||||
function mapProcessor.processActiveNests(map, tick)
|
||||
local processActiveNest = map.processActiveNest
|
||||
local slot = processActiveNest[tick]
|
||||
if slot then
|
||||
local natives = map.natives
|
||||
for i=1,#slot do
|
||||
local chunk = slot[i]
|
||||
if (getNestActiveness(map, chunk) > 0) or (getRaidNestActiveness(map, chunk) > 0) then
|
||||
processNestActiveness(map, chunk, natives, surface)
|
||||
processNestActiveness(map, chunk)
|
||||
local nextTick = tick + DURATION_ACTIVE_NEST
|
||||
local nextSlot = processActiveNest[nextTick]
|
||||
if not nextSlot then
|
||||
@ -460,17 +459,17 @@ function mapProcessor.processActiveNests(map, surface, tick)
|
||||
end
|
||||
end
|
||||
|
||||
function mapProcessor.processVengence(map, surface)
|
||||
local natives = map.natives
|
||||
local ss = natives.vengenceQueue
|
||||
function mapProcessor.processVengence(map)
|
||||
local native = map.native
|
||||
local ss = native.vengenceQueue
|
||||
local chunk = next(ss, map.deployVengenceIterator)
|
||||
if not chunk then
|
||||
map.deployVengenceIterator = nil
|
||||
if (tableSize(ss) == 0) then
|
||||
natives.vengenceQueue = {}
|
||||
native.vengenceQueue = {}
|
||||
end
|
||||
else
|
||||
formVengenceSquad(map, surface, chunk)
|
||||
formVengenceSquad(map, chunk)
|
||||
local nextChunk
|
||||
nextChunk = next(ss, chunk)
|
||||
ss[chunk] = nil
|
||||
@ -479,73 +478,75 @@ function mapProcessor.processVengence(map, surface)
|
||||
map.deployVengenceIterator = chunk
|
||||
end
|
||||
|
||||
function mapProcessor.processNests(map, surface, tick)
|
||||
local natives = map.natives
|
||||
function mapProcessor.processNests(map, tick)
|
||||
local native = map.native
|
||||
local bases = map.chunkToBase
|
||||
local chunks = map.chunkToNests
|
||||
local chunk = next(chunks, map.processNestIterator)
|
||||
for _=1,5 do
|
||||
if not chunk then
|
||||
map.processNestIterator = nil
|
||||
return
|
||||
else
|
||||
processNestActiveness(map, chunk, natives, surface)
|
||||
queueNestSpawners(map, chunk, tick)
|
||||
if not chunk then
|
||||
map.processNestIterator = nil
|
||||
return
|
||||
else
|
||||
processNestActiveness(map, chunk)
|
||||
queueNestSpawners(map, chunk, tick)
|
||||
|
||||
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
|
||||
if native.newEnemies then
|
||||
local base = bases[chunk]
|
||||
if base and ((tick - base.tick) > BASE_PROCESS_INTERVAL) then
|
||||
processBase(chunk, native, tick, base)
|
||||
end
|
||||
|
||||
chunk = next(chunks, chunk)
|
||||
end
|
||||
|
||||
chunk = next(chunks, chunk)
|
||||
end
|
||||
map.processNestIterator = chunk
|
||||
end
|
||||
|
||||
local function processSpawners(map, surface, tick, natives, iteration, iterator, chunks)
|
||||
|
||||
local function processSpawners(map, tick, iterator, chunks)
|
||||
local native = map.native
|
||||
local chunk = next(chunks, map[iterator])
|
||||
local migrate = canMigrate(natives, surface)
|
||||
local attack = canAttack(natives, surface, tick)
|
||||
for _=1,iteration do
|
||||
if not chunk then
|
||||
map[iterator] = nil
|
||||
return
|
||||
else
|
||||
if migrate then
|
||||
formSettlers(map, surface, chunk)
|
||||
elseif attack then
|
||||
formSquads(map, surface, chunk, tick)
|
||||
end
|
||||
chunk = next(chunks, chunk)
|
||||
local migrate = canMigrate(native)
|
||||
local attack = canAttack(native, tick)
|
||||
if not chunk then
|
||||
map[iterator] = nil
|
||||
return
|
||||
else
|
||||
if migrate then
|
||||
formSettlers(map, chunk)
|
||||
elseif attack then
|
||||
formSquads(map, chunk, tick)
|
||||
end
|
||||
chunk = next(chunks, chunk)
|
||||
end
|
||||
map[iterator] = chunk
|
||||
end
|
||||
|
||||
function mapProcessor.processSpawners(map, surface, tick)
|
||||
local natives = map.natives
|
||||
function mapProcessor.processSpawners(map, tick)
|
||||
local native = map.native
|
||||
|
||||
if (natives.state ~= AI_STATE_PEACEFUL) then
|
||||
if (natives.state == AI_STATE_MIGRATING) or
|
||||
((natives.state == AI_STATE_SIEGE) and natives.temperament <= 0.5)
|
||||
if (native.state ~= AI_STATE_PEACEFUL) then
|
||||
if (native.state == AI_STATE_MIGRATING) or
|
||||
((native.state == AI_STATE_SIEGE) and native.temperament <= 0.5)
|
||||
then
|
||||
processSpawners(map, surface, tick, natives, 2, "processMigrationIterator", map.chunkToNests)
|
||||
processSpawners(map,
|
||||
tick,
|
||||
"processMigrationIterator",
|
||||
map.chunkToNests)
|
||||
else
|
||||
if (natives.state ~= AI_STATE_AGGRESSIVE) then
|
||||
processSpawners(map, surface, tick, natives, 1, "processActiveSpawnerIterator", map.chunkToActiveNest)
|
||||
if (native.state ~= AI_STATE_AGGRESSIVE) then
|
||||
processSpawners(map,
|
||||
tick,
|
||||
"processActiveSpawnerIterator",
|
||||
map.chunkToActiveNest)
|
||||
processSpawners(map,
|
||||
surface,
|
||||
tick,
|
||||
natives,
|
||||
1,
|
||||
"processActiveRaidSpawnerIterator",
|
||||
map.chunkToActiveRaidNest)
|
||||
else
|
||||
processSpawners(map, surface, tick, natives, 2, "processActiveSpawnerIterator", map.chunkToActiveNest)
|
||||
processSpawners(map,
|
||||
tick,
|
||||
"processActiveSpawnerIterator",
|
||||
map.chunkToActiveNest)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -98,7 +98,7 @@ local function scoreAttackKamikazeLocation(_, neighborChunk)
|
||||
return damage
|
||||
end
|
||||
|
||||
local function settleMove(map, squad, surface)
|
||||
local function settleMove(map, squad)
|
||||
local targetPosition = map.position
|
||||
local targetPosition2 = map.position2
|
||||
local group = squad.group
|
||||
@ -107,8 +107,8 @@ local function settleMove(map, squad, surface)
|
||||
local x, y = positionToChunkXY(groupPosition)
|
||||
local chunk = getChunkByXY(map, x, y)
|
||||
local scoreFunction = scoreResourceLocation
|
||||
local natives = map.natives
|
||||
if (natives.state == AI_STATE_SIEGE) then
|
||||
local native = map.native
|
||||
if (native.state == AI_STATE_SIEGE) then
|
||||
if squad.kamikaze then
|
||||
scoreFunction = scoreSiegeLocationKamikaze
|
||||
else
|
||||
@ -126,6 +126,7 @@ local function settleMove(map, squad, surface)
|
||||
squad.originPosition.y)
|
||||
local cmd
|
||||
local position
|
||||
local surface = map.surface
|
||||
|
||||
if (distance >= squad.maxDistance) or ((getResourceGenerator(map, chunk) ~= 0) and (getNestCount(map, chunk) == 0))
|
||||
then
|
||||
@ -162,7 +163,7 @@ local function settleMove(map, squad, surface)
|
||||
group.set_command(cmd)
|
||||
return
|
||||
elseif (attackDirection ~= 0) then
|
||||
local attackPlayerThreshold = natives.attackPlayerThreshold
|
||||
local attackPlayerThreshold = native.attackPlayerThreshold
|
||||
|
||||
if (nextAttackChunk ~= -1) then
|
||||
attackChunk = nextAttackChunk
|
||||
@ -224,13 +225,14 @@ local function settleMove(map, squad, surface)
|
||||
end
|
||||
end
|
||||
|
||||
local function attackMove(map, squad, surface)
|
||||
local function attackMove(map, squad)
|
||||
|
||||
local targetPosition = map.position
|
||||
local targetPosition2 = map.position2
|
||||
|
||||
local group = squad.group
|
||||
|
||||
local surface = map.surface
|
||||
local position
|
||||
local groupPosition = group.position
|
||||
local x, y = positionToChunkXY(groupPosition)
|
||||
@ -279,7 +281,7 @@ local function attackMove(map, squad, surface)
|
||||
end
|
||||
|
||||
if (getPlayerBaseGenerator(map, attackChunk) ~= 0) and
|
||||
(attackChunk[PLAYER_PHEROMONE] >= map.natives.attackPlayerThreshold)
|
||||
(attackChunk[PLAYER_PHEROMONE] >= map.native.attackPlayerThreshold)
|
||||
then
|
||||
cmd = map.attackCommand
|
||||
|
||||
@ -300,10 +302,10 @@ local function attackMove(map, squad, surface)
|
||||
group.set_command(cmd)
|
||||
end
|
||||
|
||||
local function buildMove(map, squad, surface)
|
||||
local function buildMove(map, squad)
|
||||
local group = squad.group
|
||||
local position = map.position
|
||||
local groupPosition = findMovementPosition(surface, group.position)
|
||||
local groupPosition = findMovementPosition(map.surface, group.position)
|
||||
|
||||
if not groupPosition then
|
||||
groupPosition = group.position
|
||||
@ -315,15 +317,16 @@ local function buildMove(map, squad, surface)
|
||||
group.set_command(map.compoundSettleCommand)
|
||||
end
|
||||
|
||||
function squadAttack.cleanSquads(natives, iterator)
|
||||
local squads = natives.groupNumberToSquad
|
||||
local map = natives.map
|
||||
function squadAttack.cleanSquads(natives, native)
|
||||
local squads = native.groupNumberToSquad
|
||||
local map = native.map
|
||||
local iterator = map.squadIterator
|
||||
|
||||
local k, squad = next(squads, iterator)
|
||||
if not k then
|
||||
if (table_size(squads) == 0) then
|
||||
-- this is needed as the next command remembers the max length a table has been
|
||||
natives.groupNumberToSquad = {}
|
||||
native.groupNumberToSquad = {}
|
||||
end
|
||||
else
|
||||
local group = squad.group
|
||||
@ -349,32 +352,32 @@ function squadAttack.cleanSquads(natives, iterator)
|
||||
map.squadIterator = k
|
||||
end
|
||||
|
||||
function squadAttack.squadDispatch(map, surface, squad)
|
||||
function squadAttack.squadDispatch(map, squad)
|
||||
local group = squad.group
|
||||
if group and group.valid then
|
||||
local status = squad.status
|
||||
if (status == SQUAD_RAIDING) then
|
||||
attackMove(map, squad, surface)
|
||||
attackMove(map, squad)
|
||||
elseif (status == SQUAD_SETTLING) then
|
||||
settleMove(map, squad, surface)
|
||||
settleMove(map, squad)
|
||||
elseif (status == SQUAD_RETREATING) then
|
||||
if squad.settlers then
|
||||
squad.status = SQUAD_SETTLING
|
||||
settleMove(map, squad, surface)
|
||||
settleMove(map, squad)
|
||||
else
|
||||
squad.status = SQUAD_RAIDING
|
||||
attackMove(map, squad, surface)
|
||||
attackMove(map, squad)
|
||||
end
|
||||
elseif (status == SQUAD_BUILDING) then
|
||||
removeSquadFromChunk(map, squad)
|
||||
buildMove(map, squad, surface)
|
||||
buildMove(map, squad)
|
||||
elseif (status == SQUAD_GUARDING) then
|
||||
if squad.settlers then
|
||||
squad.status = SQUAD_SETTLING
|
||||
settleMove(map, squad, surface)
|
||||
settleMove(map, squad)
|
||||
else
|
||||
squad.status = SQUAD_RAIDING
|
||||
attackMove(map, squad, surface)
|
||||
attackMove(map, squad)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -48,7 +48,7 @@ local function scoreRetreatLocation(map, neighborChunk)
|
||||
-(getPlayerBaseGenerator(map, neighborChunk) * 1000))
|
||||
end
|
||||
|
||||
function aiDefense.retreatUnits(chunk, cause, map, surface, tick, radius)
|
||||
function aiDefense.retreatUnits(chunk, cause, map, tick, radius)
|
||||
if (tick - getRetreatTick(map, chunk) > COOLDOWN_RETREAT) and (getEnemyStructureCount(map, chunk) == 0) then
|
||||
|
||||
setRetreatTick(map, chunk, tick)
|
||||
@ -64,6 +64,7 @@ function aiDefense.retreatUnits(chunk, cause, map, surface, tick, radius)
|
||||
local retreatPosition
|
||||
position.x = chunk.x + 16
|
||||
position.y = chunk.y + 16
|
||||
local surface = map.surface
|
||||
if (exitPath == -1) then
|
||||
return
|
||||
elseif (nextExitPath ~= -1) then
|
||||
@ -85,10 +86,10 @@ function aiDefense.retreatUnits(chunk, cause, map, surface, tick, radius)
|
||||
|
||||
local newSquad = findNearbyRetreatingSquad(map, exitPath)
|
||||
local created = false
|
||||
local natives = map.natives
|
||||
local native = map.native
|
||||
|
||||
if not newSquad then
|
||||
if (natives.squadCount < natives.AI_MAX_SQUAD_COUNT) then
|
||||
if (native.squadCount < native.AI_MAX_SQUAD_COUNT) then
|
||||
created = true
|
||||
newSquad = createSquad(position, surface)
|
||||
else
|
||||
@ -111,8 +112,8 @@ function aiDefense.retreatUnits(chunk, cause, map, surface, tick, radius)
|
||||
end
|
||||
|
||||
if created then
|
||||
natives.groupNumberToSquad[newSquad.groupNumber] = newSquad
|
||||
natives.squadCount = natives.squadCount + 1
|
||||
native.groupNumberToSquad[newSquad.groupNumber] = newSquad
|
||||
native.squadCount = native.squadCount + 1
|
||||
end
|
||||
|
||||
newSquad.status = SQUAD_RETREATING
|
||||
|
Loading…
x
Reference in New Issue
Block a user