1
0
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:
Aaron Veden 2021-02-19 21:41:30 -08:00
parent 7c47a495fd
commit 8063664616
No known key found for this signature in database
GPG Key ID: FF5990B1C6DD3F84
14 changed files with 1312 additions and 1370 deletions

View File

@ -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)

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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