1
0
mirror of https://github.com/veden/Rampant.git synced 2025-09-16 09:16:43 +02:00

FACTO-249: Moved universe global into all library files

This commit is contained in:
Aaron Veden
2023-03-11 12:53:06 -08:00
parent 749f6cbb90
commit e189001880
20 changed files with 1551 additions and 1479 deletions

View File

@@ -52,6 +52,7 @@ Version: 3.2.0
- Fixed bases being able to mutate to the same factions - Fixed bases being able to mutate to the same factions
- Fixed players disconnecting on multiplayer could leave residual player pheromone that never dissipated - Fixed players disconnecting on multiplayer could leave residual player pheromone that never dissipated
- Fixed /rampantSetAIState command could error if not provide correct parameters or didn't display a message if parameters were missing - Fixed /rampantSetAIState command could error if not provide correct parameters or didn't display a message if parameters were missing
- Fixed the pheromone processing could skip the inner most chunks or the outer most chunks of a map
Optimizations: Optimizations:
- Moved most constants out of global - Moved most constants out of global
- Removed new enemy variations setting - Removed new enemy variations setting

File diff suppressed because it is too large Load Diff

View File

@@ -21,6 +21,10 @@ local aiAttackWave = {}
-- imports -- imports
local Universe
--
local constants = require("Constants") local constants = require("Constants")
local mapUtils = require("MapUtils") local mapUtils = require("MapUtils")
local chunkPropertyUtils = require("ChunkPropertyUtils") local chunkPropertyUtils = require("ChunkPropertyUtils")
@@ -80,29 +84,29 @@ local mCeil = math.ceil
-- module code -- module code
local function settlerWaveScaling(universe) local function settlerWaveScaling()
return mCeil(gaussianRandomRangeRG(universe.settlerWaveSize, return mCeil(gaussianRandomRangeRG(Universe.settlerWaveSize,
universe.settlerWaveDeviation, Universe.settlerWaveDeviation,
universe.expansionMinSize, Universe.expansionMinSize,
universe.expansionMaxSize, Universe.expansionMaxSize,
universe.random)) Universe.random))
end end
local function attackWaveScaling(universe) local function attackWaveScaling()
return mCeil(gaussianRandomRangeRG(universe.attackWaveSize, return mCeil(gaussianRandomRangeRG(Universe.attackWaveSize,
universe.attackWaveDeviation, Universe.attackWaveDeviation,
1, 1,
universe.attackWaveUpperBound, Universe.attackWaveUpperBound,
universe.random)) Universe.random))
end end
local function attackWaveValidCandidate(chunk, map, base) local function attackWaveValidCandidate(chunk, base)
local isValid = getNestActiveness(map, chunk) local isValid = getNestActiveness(chunk)
if (base.stateAI == BASE_AI_STATE_RAIDING) or if (base.stateAI == BASE_AI_STATE_RAIDING) or
(base.stateAI == BASE_AI_STATE_SIEGE) or (base.stateAI == BASE_AI_STATE_SIEGE) or
(base.stateAI == BASE_AI_STATE_ONSLAUGHT) (base.stateAI == BASE_AI_STATE_ONSLAUGHT)
then then
isValid = isValid + getRaidNestActiveness(map, chunk) isValid = isValid + getRaidNestActiveness(chunk)
end end
return (isValid > 0) return (isValid > 0)
end end
@@ -121,19 +125,19 @@ end
local function validSiegeSettlerLocation(map, neighborChunk) local function validSiegeSettlerLocation(map, neighborChunk)
return (getPassable(map, neighborChunk) == CHUNK_ALL_DIRECTIONS) and return (getPassable(map, neighborChunk) == CHUNK_ALL_DIRECTIONS) and
(getNestCount(map, neighborChunk) == 0) (getNestCount(neighborChunk) == 0)
end end
local function validSettlerLocation(map, chunk, neighborChunk) local function validSettlerLocation(map, chunk, neighborChunk)
local chunkResource = chunk[RESOURCE_PHEROMONE] local chunkResource = chunk[RESOURCE_PHEROMONE]
return (getPassable(map, neighborChunk) == CHUNK_ALL_DIRECTIONS) and return (getPassable(map, neighborChunk) == CHUNK_ALL_DIRECTIONS) and
(getNestCount(map, neighborChunk) == 0) and (getNestCount(neighborChunk) == 0) and
(neighborChunk[RESOURCE_PHEROMONE] >= chunkResource) (neighborChunk[RESOURCE_PHEROMONE] >= chunkResource)
end end
local function validUnitGroupLocation(map, neighborChunk) local function validUnitGroupLocation(map, neighborChunk)
return getPassable(map, neighborChunk) == CHUNK_ALL_DIRECTIONS and return getPassable(map, neighborChunk) == CHUNK_ALL_DIRECTIONS and
(getNestCount(map, neighborChunk) == 0) (getNestCount(neighborChunk) == 0)
end end
local function visitPattern(o, cX, cY, distance) local function visitPattern(o, cX, cY, distance)
@@ -176,17 +180,17 @@ local function visitPattern(o, cX, cY, distance)
end end
function aiAttackWave.rallyUnits(chunk, map, tick, base) function aiAttackWave.rallyUnits(chunk, map, tick, base)
if ((tick - getRallyTick(map, chunk) > COOLDOWN_RALLY) and (base.unitPoints >= AI_VENGENCE_SQUAD_COST)) then if ((tick - getRallyTick(chunk) > COOLDOWN_RALLY) and (base.unitPoints >= AI_VENGENCE_SQUAD_COST)) then
setRallyTick(map, chunk, tick) setRallyTick(map, chunk, tick)
local cX = chunk.x local cX = chunk.x
local cY = chunk.y local cY = chunk.y
local startX, endX, stepX, startY, endY, stepY = visitPattern(tick % 4, cX, cY, RALLY_CRY_DISTANCE) local startX, endX, stepX, startY, endY, stepY = visitPattern(tick % 4, cX, cY, RALLY_CRY_DISTANCE)
local vengenceQueue = map.universe.vengenceQueue local vengenceQueue = Universe.vengenceQueue
for x=startX, endX, stepX do for x=startX, endX, stepX do
for y=startY, endY, stepY do for y=startY, endY, stepY do
if (x ~= cX) and (y ~= cY) then if (x ~= cX) and (y ~= cY) then
local rallyChunk = getChunkByXY(map, x, y) local rallyChunk = getChunkByXY(map, x, y)
if (rallyChunk ~= -1) and (getNestCount(map, rallyChunk) > 0) then if (rallyChunk ~= -1) and (getNestCount(rallyChunk) > 0) then
local pack = vengenceQueue[rallyChunk.id] local pack = vengenceQueue[rallyChunk.id]
if not pack then if not pack then
pack = { pack = {
@@ -207,11 +211,10 @@ function aiAttackWave.rallyUnits(chunk, map, tick, base)
end end
function aiAttackWave.formSettlers(map, chunk, base) function aiAttackWave.formSettlers(map, chunk, base)
local universe = map.universe if (Universe.builderCount < Universe.AI_MAX_BUILDER_COUNT)
if (universe.builderCount < universe.AI_MAX_BUILDER_COUNT)
and (base.sentExpansionGroups < base.maxExpansionGroups) and (base.sentExpansionGroups < base.maxExpansionGroups)
and ((base.unitPoints - AI_SETTLER_COST) > 0) and ((base.unitPoints - AI_SETTLER_COST) > 0)
and (map.random() < universe.formSquadThreshold) and (Universe.random() < Universe.formSquadThreshold)
then then
local surface = map.surface local surface = map.surface
local squadPath, squadDirection local squadPath, squadDirection
@@ -239,23 +242,23 @@ function aiAttackWave.formSettlers(map, chunk, base)
if squadPosition then if squadPosition then
local squad = createSquad(squadPosition, map, nil, true, base) local squad = createSquad(squadPosition, map, nil, true, base)
local scaledWaveSize = settlerWaveScaling(universe) local scaledWaveSize = settlerWaveScaling()
universe.formGroupCommand.group = squad.group Universe.formGroupCommand.group = squad.group
universe.formCommand.unit_count = scaledWaveSize Universe.formCommand.unit_count = scaledWaveSize
local foundUnits = surface.set_multi_command(universe.formCommand) local foundUnits = surface.set_multi_command(Universe.formCommand)
if (foundUnits > 0) then if (foundUnits > 0) then
base.sentExpansionGroups = base.sentExpansionGroups + 1 base.sentExpansionGroups = base.sentExpansionGroups + 1
squad.base = base squad.base = base
local kamikazeThreshold = calculateKamikazeSettlerThreshold(foundUnits, universe) local kamikazeThreshold = calculateKamikazeSettlerThreshold(foundUnits)
if base.stateAI == BASE_AI_STATE_SIEGE then if base.stateAI == BASE_AI_STATE_SIEGE then
kamikazeThreshold = kamikazeThreshold * 2.5 kamikazeThreshold = kamikazeThreshold * 2.5
end end
squad.kamikaze = map.random() < kamikazeThreshold squad.kamikaze = Universe.random() < kamikazeThreshold
universe.builderCount = universe.builderCount + 1 Universe.builderCount = Universe.builderCount + 1
modifyBaseUnitPoints(base, -AI_SETTLER_COST, "Settler", squadPosition.x, squadPosition.y) modifyBaseUnitPoints(base, -AI_SETTLER_COST, "Settler", squadPosition.x, squadPosition.y)
universe.groupNumberToSquad[squad.groupNumber] = squad Universe.groupNumberToSquad[squad.groupNumber] = squad
else else
if (squad.group.valid) then if (squad.group.valid) then
squad.group.destroy() squad.group.destroy()
@@ -267,10 +270,9 @@ function aiAttackWave.formSettlers(map, chunk, base)
end end
function aiAttackWave.formVengenceSquad(map, chunk, base) function aiAttackWave.formVengenceSquad(map, chunk, base)
local universe = map.universe if (Universe.squadCount < Universe.AI_MAX_SQUAD_COUNT)
if (universe.squadCount < universe.AI_MAX_SQUAD_COUNT)
and ((base.unitPoints - AI_VENGENCE_SQUAD_COST) > 0) and ((base.unitPoints - AI_VENGENCE_SQUAD_COST) > 0)
and (map.random() < universe.formSquadThreshold) and (Universe.random() < Universe.formSquadThreshold)
then then
if (chunk[BASE_PHEROMONE] < 0.0001) or (chunk[PLAYER_PHEROMONE] < 0.0001) then if (chunk[BASE_PHEROMONE] < 0.0001) or (chunk[PLAYER_PHEROMONE] < 0.0001) then
return return
@@ -292,17 +294,17 @@ function aiAttackWave.formVengenceSquad(map, chunk, base)
if squadPosition then if squadPosition then
local squad = createSquad(squadPosition, map, nil, false, base) local squad = createSquad(squadPosition, map, nil, false, base)
squad.rabid = map.random() < 0.03 squad.rabid = Universe.random() < 0.03
local scaledWaveSize = attackWaveScaling(universe) local scaledWaveSize = attackWaveScaling()
universe.formGroupCommand.group = squad.group Universe.formGroupCommand.group = squad.group
universe.formCommand.unit_count = scaledWaveSize Universe.formCommand.unit_count = scaledWaveSize
local foundUnits = surface.set_multi_command(universe.formCommand) local foundUnits = surface.set_multi_command(Universe.formCommand)
if (foundUnits > 0) then if (foundUnits > 0) then
squad.base = base squad.base = base
squad.kamikaze = map.random() < calculateKamikazeSquadThreshold(foundUnits, universe) squad.kamikaze = Universe.random() < calculateKamikazeSquadThreshold(foundUnits)
universe.groupNumberToSquad[squad.groupNumber] = squad Universe.groupNumberToSquad[squad.groupNumber] = squad
universe.squadCount = universe.squadCount + 1 Universe.squadCount = Universe.squadCount + 1
modifyBaseUnitPoints(base, -AI_VENGENCE_SQUAD_COST, "Vengence", squadPosition.x, squadPosition.y) modifyBaseUnitPoints(base, -AI_VENGENCE_SQUAD_COST, "Vengence", squadPosition.x, squadPosition.y)
else else
if (squad.group.valid) then if (squad.group.valid) then
@@ -315,11 +317,10 @@ function aiAttackWave.formVengenceSquad(map, chunk, base)
end end
function aiAttackWave.formVengenceSettler(map, chunk, base) function aiAttackWave.formVengenceSettler(map, chunk, base)
local universe = map.universe if (Universe.builderCount < Universe.AI_MAX_BUILDER_COUNT)
if (universe.builderCount < universe.AI_MAX_BUILDER_COUNT)
and (base.sentExpansionGroups < base.maxExpansionGroups) and (base.sentExpansionGroups < base.maxExpansionGroups)
and ((base.unitPoints - AI_VENGENCE_SQUAD_COST) > 0) and ((base.unitPoints - AI_VENGENCE_SQUAD_COST) > 0)
and (map.random() < universe.formSquadThreshold) and (Universe.random() < Universe.formSquadThreshold)
then then
local surface = map.surface local surface = map.surface
local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y), local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y),
@@ -337,19 +338,19 @@ function aiAttackWave.formVengenceSettler(map, chunk, base)
if squadPosition then if squadPosition then
local squad = createSquad(squadPosition, map, nil, true, base) local squad = createSquad(squadPosition, map, nil, true, base)
squad.rabid = map.random() < 0.03 squad.rabid = Universe.random() < 0.03
local scaledWaveSize = settlerWaveScaling(universe) local scaledWaveSize = settlerWaveScaling()
universe.formGroupCommand.group = squad.group Universe.formGroupCommand.group = squad.group
universe.formCommand.unit_count = scaledWaveSize Universe.formCommand.unit_count = scaledWaveSize
local foundUnits = surface.set_multi_command(universe.formCommand) local foundUnits = surface.set_multi_command(Universe.formCommand)
if (foundUnits > 0) then if (foundUnits > 0) then
base.sentExpansionGroups = base.sentExpansionGroups + 1 base.sentExpansionGroups = base.sentExpansionGroups + 1
squad.base = base squad.base = base
squad.kamikaze = map.random() < calculateKamikazeSettlerThreshold(foundUnits, universe) squad.kamikaze = Universe.random() < calculateKamikazeSettlerThreshold(foundUnits)
universe.groupNumberToSquad[squad.groupNumber] = squad Universe.groupNumberToSquad[squad.groupNumber] = squad
universe.builderCount = universe.builderCount + 1 Universe.builderCount = Universe.builderCount + 1
modifyBaseUnitPoints(base, -AI_VENGENCE_SQUAD_COST, "Vengence Settlers", squadPosition.x, squadPosition.y) modifyBaseUnitPoints(base, -AI_VENGENCE_SQUAD_COST, "Vengence Settlers", squadPosition.x, squadPosition.y)
else else
if (squad.group.valid) then if (squad.group.valid) then
@@ -362,11 +363,10 @@ function aiAttackWave.formVengenceSettler(map, chunk, base)
end end
function aiAttackWave.formSquads(map, chunk, base) function aiAttackWave.formSquads(map, chunk, base)
local universe = map.universe if (Universe.squadCount < Universe.AI_MAX_SQUAD_COUNT)
if (universe.squadCount < universe.AI_MAX_SQUAD_COUNT) and attackWaveValidCandidate(chunk, base)
and attackWaveValidCandidate(chunk, map, base)
and ((base.unitPoints - AI_SQUAD_COST) > 0) and ((base.unitPoints - AI_SQUAD_COST) > 0)
and (map.random() < universe.formSquadThreshold) and (Universe.random() < Universe.formSquadThreshold)
then then
if (chunk[BASE_PHEROMONE] < 0.0001) or (chunk[PLAYER_PHEROMONE] < 0.0001) then if (chunk[BASE_PHEROMONE] < 0.0001) or (chunk[PLAYER_PHEROMONE] < 0.0001) then
return return
@@ -388,17 +388,17 @@ function aiAttackWave.formSquads(map, chunk, base)
if squadPosition then if squadPosition then
local squad = createSquad(squadPosition, map, nil, false, base) local squad = createSquad(squadPosition, map, nil, false, base)
squad.rabid = map.random() < 0.03 squad.rabid = Universe.random() < 0.03
local scaledWaveSize = attackWaveScaling(universe) local scaledWaveSize = attackWaveScaling()
universe.formGroupCommand.group = squad.group Universe.formGroupCommand.group = squad.group
universe.formCommand.unit_count = scaledWaveSize Universe.formCommand.unit_count = scaledWaveSize
local foundUnits = surface.set_multi_command(universe.formCommand) local foundUnits = surface.set_multi_command(Universe.formCommand)
if (foundUnits > 0) then if (foundUnits > 0) then
squad.base = base squad.base = base
squad.kamikaze = map.random() < calculateKamikazeSquadThreshold(foundUnits, universe) squad.kamikaze = Universe.random() < calculateKamikazeSquadThreshold(foundUnits)
universe.squadCount = universe.squadCount + 1 Universe.squadCount = Universe.squadCount + 1
universe.groupNumberToSquad[squad.groupNumber] = squad Universe.groupNumberToSquad[squad.groupNumber] = squad
if (base.stateAI == BASE_AI_STATE_AGGRESSIVE) then if (base.stateAI == BASE_AI_STATE_AGGRESSIVE) then
base.sentAggressiveGroups = base.sentAggressiveGroups + 1 base.sentAggressiveGroups = base.sentAggressiveGroups + 1
end end
@@ -413,6 +413,9 @@ function aiAttackWave.formSquads(map, chunk, base)
end end
end end
function aiAttackWave.init(universe)
Universe = universe
end
aiAttackWaveG = aiAttackWave aiAttackWaveG = aiAttackWave
return aiAttackWave return aiAttackWave

View File

@@ -19,6 +19,10 @@ if aiPlanningG then
end end
local aiPlanning = {} local aiPlanning = {}
--
local universe
-- imports -- imports
local constants = require("Constants") local constants = require("Constants")
@@ -100,7 +104,7 @@ local function getTimeStringFromTick(tick)
return days .. "d " .. hours .. "h " .. minutes .. "m " .. seconds .. "s" return days .. "d " .. hours .. "h " .. minutes .. "m " .. seconds .. "s"
end end
function aiPlanning.planning(universe, evolutionLevel) function aiPlanning.planning(evolutionLevel)
universe.evolutionLevel = evolutionLevel universe.evolutionLevel = evolutionLevel
local maxPoints = mMax(AI_MAX_POINTS * evolutionLevel, MINIMUM_AI_POINTS) local maxPoints = mMax(AI_MAX_POINTS * evolutionLevel, MINIMUM_AI_POINTS)
universe.maxPoints = maxPoints universe.maxPoints = maxPoints
@@ -140,7 +144,7 @@ function aiPlanning.planning(universe, evolutionLevel)
universe.kamikazeThreshold = NO_RETREAT_BASE_PERCENT + (evolutionLevel * NO_RETREAT_EVOLUTION_BONUS_MAX) universe.kamikazeThreshold = NO_RETREAT_BASE_PERCENT + (evolutionLevel * NO_RETREAT_EVOLUTION_BONUS_MAX)
end end
local function processBase(universe, base, tick) local function processBase(base, tick)
base.maxAggressiveGroups = mCeil(base.activeNests / ACTIVE_NESTS_PER_AGGRESSIVE_GROUPS) base.maxAggressiveGroups = mCeil(base.activeNests / ACTIVE_NESTS_PER_AGGRESSIVE_GROUPS)
base.maxExpansionGroups = mCeil((base.activeNests + base.activeRaidNests) / ALL_NESTS_PER_EXPANSION_GROUPS) base.maxExpansionGroups = mCeil((base.activeNests + base.activeRaidNests) / ALL_NESTS_PER_EXPANSION_GROUPS)
@@ -204,7 +208,7 @@ local function processBase(universe, base, tick)
deathThreshold = universe.adaptationModifier * deathThreshold deathThreshold = universe.adaptationModifier * deathThreshold
if ((base.deathEvents > deathThreshold) and (universe.random() > 0.95)) then if ((base.deathEvents > deathThreshold) and (universe.random() > 0.95)) then
if (base.mutations < universe.MAX_BASE_MUTATIONS) then if (base.mutations < universe.MAX_BASE_MUTATIONS) then
if upgradeBaseBasedOnDamage(universe, base) then if upgradeBaseBasedOnDamage(base) then
base.mutations = base.mutations + 1 base.mutations = base.mutations + 1
end end
elseif (base.mutations == universe.MAX_BASE_MUTATIONS) then elseif (base.mutations == universe.MAX_BASE_MUTATIONS) then
@@ -345,8 +349,6 @@ local function temperamentPlanner(base, evolutionLevel)
delta = delta + val delta = delta + val
end end
local universe = base.universe
delta = delta * universe.temperamentRateModifier delta = delta * universe.temperamentRateModifier
base.temperamentScore = mMin(TEMPERAMENT_RANGE_MAX, mMax(TEMPERAMENT_RANGE_MIN, currentTemperament + delta)) base.temperamentScore = mMin(TEMPERAMENT_RANGE_MAX, mMax(TEMPERAMENT_RANGE_MIN, currentTemperament + delta))
base.temperament = ((base.temperamentScore + TEMPERAMENT_RANGE_MAX) * TEMPERAMENT_DIVIDER) base.temperament = ((base.temperamentScore + TEMPERAMENT_RANGE_MAX) * TEMPERAMENT_DIVIDER)
@@ -370,7 +372,7 @@ local function temperamentPlanner(base, evolutionLevel)
end end
end end
local function processState(universe, base, tick) local function processState(base, tick)
if (base.stateAITick > tick) or not universe.awake then if (base.stateAITick > tick) or not universe.awake then
if (not universe.awake) and (tick >= universe.initialPeaceTime) then if (not universe.awake) and (tick >= universe.initialPeaceTime) then
@@ -562,7 +564,7 @@ local function processState(universe, base, tick)
end end
function aiPlanning.processBaseAIs(universe, tick) function aiPlanning.processBaseAIs(tick)
local baseId = universe.processBaseAIIterator local baseId = universe.processBaseAIIterator
local base local base
if not baseId then if not baseId then
@@ -579,10 +581,14 @@ function aiPlanning.processBaseAIs(universe, tick)
return return
end end
temperamentPlanner(base, universe.evolutionLevel) temperamentPlanner(base, universe.evolutionLevel)
processState(universe, base, tick) processState(base, tick)
processBase(universe, base, tick) processBase(base, tick)
end end
end end
function aiPlanning.init(universeGlobal)
universe = universeGlobal
end
aiPlanningG = aiPlanning aiPlanningG = aiPlanning
return aiPlanning return aiPlanning

View File

@@ -19,6 +19,10 @@ if (aiPredicatesG) then
end end
local aiPredicates = {} local aiPredicates = {}
--
local universe
-- imports -- imports
local constants = require("Constants") local constants = require("Constants")
@@ -36,7 +40,6 @@ local BASE_AI_STATE_ONSLAUGHT = constants.BASE_AI_STATE_ONSLAUGHT
-- module code -- module code
function aiPredicates.canAttack(map, base) function aiPredicates.canAttack(map, base)
local universe = map.universe
local isAggressive = ((base.stateAI == BASE_AI_STATE_AGGRESSIVE) local isAggressive = ((base.stateAI == BASE_AI_STATE_AGGRESSIVE)
and (base.sentAggressiveGroups < base.maxAggressiveGroups)) and (base.sentAggressiveGroups < base.maxAggressiveGroups))
local isRaiding = (base.stateAI == BASE_AI_STATE_RAIDING) local isRaiding = (base.stateAI == BASE_AI_STATE_RAIDING)
@@ -65,7 +68,6 @@ function aiPredicates.canMigrate(map, base)
if badAIState then if badAIState then
return false return false
end end
local universe = map.universe
if not universe.expansion then if not universe.expansion then
return false return false
end end
@@ -81,5 +83,9 @@ function aiPredicates.canMigrate(map, base)
return true return true
end end
function aiPredicates.init(universeGlobal)
universe = universeGlobal
end
aiPredicatesG = aiPredicates aiPredicatesG = aiPredicates
return aiPredicates return aiPredicates

View File

@@ -14,10 +14,14 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
if baseUtilsG then if BaseUtilsG then
return baseUtilsG return BaseUtilsG
end end
local baseUtils = {} local BaseUtils = {}
--
local Universe
-- imports -- imports
@@ -83,13 +87,13 @@ local next = next
-- module code -- module code
local function evoToTier(universe, evolutionFactor, maxSkips) local function evoToTier(evolutionFactor, maxSkips)
local v local v
local skipsRemaining = maxSkips local skipsRemaining = maxSkips
for i=TIERS,1,-1 do for i=TIERS,1,-1 do
if EVO_TO_TIER_MAPPING[i] <= evolutionFactor then if EVO_TO_TIER_MAPPING[i] <= evolutionFactor then
v = i v = i
if (skipsRemaining == 0) or (universe.random() <= 0.75) then if (skipsRemaining == 0) or (Universe.random() <= 0.75) then
break break
end end
skipsRemaining = skipsRemaining - 1 skipsRemaining = skipsRemaining - 1
@@ -98,8 +102,8 @@ local function evoToTier(universe, evolutionFactor, maxSkips)
return v return v
end end
local function findBaseMutation(universe, targetEvolution, excludeFactions) local function findBaseMutation(targetEvolution, excludeFactions)
local tier = evoToTier(universe, targetEvolution or universe.evolutionLevel, 2) local tier = evoToTier(targetEvolution or Universe.evolutionLevel, 2)
local availableAlignments local availableAlignments
local alignments = EVOLUTION_TABLE_ALIGNMENT[tier] local alignments = EVOLUTION_TABLE_ALIGNMENT[tier]
@@ -114,7 +118,7 @@ local function findBaseMutation(universe, targetEvolution, excludeFactions)
availableAlignments = alignments availableAlignments = alignments
end end
local roll = universe.random() local roll = Universe.random()
for i=1,#availableAlignments do for i=1,#availableAlignments do
local alignment = availableAlignments[i] local alignment = availableAlignments[i]
@@ -132,7 +136,7 @@ local function initialEntityUpgrade(baseAlignment, tier, maxTier, map, useHiveTy
local useTier local useTier
local tierRoll = map.random() local tierRoll = Universe.random()
if (tierRoll < 0.4) then if (tierRoll < 0.4) then
useTier = maxTier useTier = maxTier
elseif (tierRoll < 0.7) then elseif (tierRoll < 0.7) then
@@ -154,7 +158,7 @@ local function initialEntityUpgrade(baseAlignment, tier, maxTier, map, useHiveTy
for ui=1,#upgrades do for ui=1,#upgrades do
local upgrade = upgrades[ui] local upgrade = upgrades[ui]
if upgrade[3] == useHiveType then if upgrade[3] == useHiveType then
entity = upgrade[2][map.random(#upgrade[2])] entity = upgrade[2][Universe.random(#upgrade[2])]
break break
end end
end end
@@ -163,7 +167,7 @@ local function initialEntityUpgrade(baseAlignment, tier, maxTier, map, useHiveTy
for ui=1,#upgrades do for ui=1,#upgrades do
local upgrade = upgrades[ui] local upgrade = upgrades[ui]
if upgrade[3] == entityType then if upgrade[3] == entityType then
entity = upgrade[2][map.random(#upgrade[2])] entity = upgrade[2][Universe.random(#upgrade[2])]
end end
end end
if not entity then if not entity then
@@ -173,7 +177,7 @@ local function initialEntityUpgrade(baseAlignment, tier, maxTier, map, useHiveTy
for ui=1,#upgrades do for ui=1,#upgrades do
local upgrade = upgrades[ui] local upgrade = upgrades[ui]
if upgrade[3] == mappedType then if upgrade[3] == mappedType then
return upgrade[2][map.random(#upgrade[2])] return upgrade[2][Universe.random(#upgrade[2])]
end end
end end
end end
@@ -197,15 +201,15 @@ local function entityUpgrade(baseAlignment, tier, maxTier, originalEntity, map)
for i=1, #mapTypes do for i=1, #mapTypes do
local upgrade = factionLookup[mapTypes[i]] local upgrade = factionLookup[mapTypes[i]]
if upgrade and (#upgrade > 0) then if upgrade and (#upgrade > 0) then
entity = upgrade[map.random(#upgrade)] entity = upgrade[Universe.random(#upgrade)]
if map.random() < 0.55 then if Universe.random() < 0.55 then
return entity return entity
end end
end end
end end
elseif (#upgrades > 0) then elseif (#upgrades > 0) then
entity = upgrades[map.random(#upgrades)] entity = upgrades[Universe.random(#upgrades)]
if map.random() < 0.55 then if Universe.random() < 0.55 then
return entity return entity
end end
end end
@@ -213,15 +217,14 @@ local function entityUpgrade(baseAlignment, tier, maxTier, originalEntity, map)
return entity return entity
end end
function baseUtils.findEntityUpgrade(baseAlignment, currentEvo, evoIndex, originalEntity, map, evolve) function BaseUtils.findEntityUpgrade(baseAlignment, currentEvo, evoIndex, originalEntity, map, evolve)
local universe = map.universe
local adjCurrentEvo = mMax( local adjCurrentEvo = mMax(
((baseAlignment ~= ENEMY_ALIGNMENT_LOOKUP[originalEntity.name]) and 0) or currentEvo, ((baseAlignment ~= ENEMY_ALIGNMENT_LOOKUP[originalEntity.name]) and 0) or currentEvo,
0 0
) )
local tier = evoToTier(universe, adjCurrentEvo, 5) local tier = evoToTier(adjCurrentEvo, 5)
local maxTier = evoToTier(universe, evoIndex, 4) local maxTier = evoToTier(evoIndex, 4)
if (tier > maxTier) then if (tier > maxTier) then
maxTier = tier maxTier = tier
@@ -232,13 +235,13 @@ function baseUtils.findEntityUpgrade(baseAlignment, currentEvo, evoIndex, origin
local entityName = originalEntity.name local entityName = originalEntity.name
local entityType = BUILDING_HIVE_TYPE_LOOKUP[entityName] local entityType = BUILDING_HIVE_TYPE_LOOKUP[entityName]
if not entityType then if not entityType then
if map.random() < 0.5 then if Universe.random() < 0.5 then
entityType = "biter-spawner" entityType = "biter-spawner"
else else
entityType = "spitter-spawner" entityType = "spitter-spawner"
end end
end end
local roll = map.random() local roll = Universe.random()
local makeHive = (chunk ~= -1) and local makeHive = (chunk ~= -1) and
( (
(entityType == "biter-spawner") or (entityType == "spitter-spawner") (entityType == "biter-spawner") or (entityType == "spitter-spawner")
@@ -262,23 +265,23 @@ function baseUtils.findEntityUpgrade(baseAlignment, currentEvo, evoIndex, origin
end end
-- local -- local
function baseUtils.findBaseInitialAlignment(universe, evoIndex, excludeFactions) function BaseUtils.findBaseInitialAlignment(evoIndex, excludeFactions)
local dev = evoIndex * 0.15 local dev = evoIndex * 0.15
local evoTop = gaussianRandomRangeRG(evoIndex - (evoIndex * 0.075), dev, 0, evoIndex, universe.random) local evoTop = gaussianRandomRangeRG(evoIndex - (evoIndex * 0.075), dev, 0, evoIndex, Universe.random)
local result local result
if universe.random() < 0.05 then if Universe.random() < 0.05 then
result = {findBaseMutation(universe, evoTop, excludeFactions), findBaseMutation(universe, evoTop, excludeFactions)} result = {findBaseMutation(evoTop, excludeFactions), findBaseMutation(evoTop, excludeFactions)}
else else
result = {findBaseMutation(universe, evoTop, excludeFactions)} result = {findBaseMutation(evoTop, excludeFactions)}
end end
return result return result
end end
function baseUtils.recycleBases(universe) function BaseUtils.recycleBases()
local bases = universe.bases local bases = Universe.bases
local id = universe.recycleBaseIterator local id = Universe.recycleBaseIterator
local base local base
if not id then if not id then
id, base = next(bases, nil) id, base = next(bases, nil)
@@ -286,24 +289,24 @@ function baseUtils.recycleBases(universe)
base = bases[id] base = bases[id]
end end
if not id then if not id then
universe.recycleBaseIterator = nil Universe.recycleBaseIterator = nil
else else
universe.recycleBaseIterator = next(bases, id) Universe.recycleBaseIterator = next(bases, id)
local map = base.map local map = base.map
if (base.chunkCount == 0) or not map.surface.valid then if (base.chunkCount == 0) or not map.surface.valid then
bases[id] = nil bases[id] = nil
if universe.processBaseAIIterator == id then if Universe.processBaseAIIterator == id then
universe.processBaseAIIterator = nil Universe.processBaseAIIterator = nil
end end
if map.surface.valid then if map.surface.valid then
map.universe.bases[id] = nil Universe.bases[id] = nil
end end
end end
end end
end end
function baseUtils.queueUpgrade(entity, base, disPos, evolve, register, timeDelay) function BaseUtils.queueUpgrade(entity, base, disPos, evolve, register, timeDelay)
base.universe.pendingUpgrades[entity.unit_number] = { Universe.pendingUpgrades[entity.unit_number] = {
["position"] = disPos, ["position"] = disPos,
["register"] = register, ["register"] = register,
["evolve"] = evolve, ["evolve"] = evolve,
@@ -313,7 +316,7 @@ function baseUtils.queueUpgrade(entity, base, disPos, evolve, register, timeDela
} }
end end
local function pickMutationFromDamageType(universe, damageType, roll, base) local function pickMutationFromDamageType(damageType, roll, base)
local baseAlignment = base.alignment local baseAlignment = base.alignment
local damageFactions = FACTIONS_BY_DAMAGE_TYPE[damageType] local damageFactions = FACTIONS_BY_DAMAGE_TYPE[damageType]
@@ -321,7 +324,7 @@ local function pickMutationFromDamageType(universe, damageType, roll, base)
local mutated = false local mutated = false
if damageFactions and (#damageFactions > 0) then if damageFactions and (#damageFactions > 0) then
mutation = damageFactions[universe.random(#damageFactions)] mutation = damageFactions[Universe.random(#damageFactions)]
if not isMember(mutation, base.alignmentHistory) then if not isMember(mutation, base.alignmentHistory) then
if baseAlignment[2] then if baseAlignment[2] then
if (baseAlignment[1] ~= mutation) and (baseAlignment[2] ~= mutation) then if (baseAlignment[1] ~= mutation) and (baseAlignment[2] ~= mutation) then
@@ -349,7 +352,7 @@ local function pickMutationFromDamageType(universe, damageType, roll, base)
end end
end end
else else
mutation = findBaseMutation(universe) mutation = findBaseMutation()
if not isMember(mutation, base.alignmentHistory) then if not isMember(mutation, base.alignmentHistory) then
if baseAlignment[2] then if baseAlignment[2] then
if (baseAlignment[1] ~= mutation) and (baseAlignment[2] ~= mutation) then if (baseAlignment[1] ~= mutation) and (baseAlignment[2] ~= mutation) then
@@ -377,7 +380,7 @@ local function pickMutationFromDamageType(universe, damageType, roll, base)
end end
end end
end end
if mutated and universe.printBaseAdaptation then if mutated and Universe.printBaseAdaptation then
if baseAlignment[2] then if baseAlignment[2] then
game.print({"description.rampant--adaptation2DebugMessage", game.print({"description.rampant--adaptation2DebugMessage",
base.id, base.id,
@@ -388,7 +391,7 @@ local function pickMutationFromDamageType(universe, damageType, roll, base)
base.x, base.x,
base.y, base.y,
base.mutations, base.mutations,
universe.MAX_BASE_MUTATIONS}) Universe.MAX_BASE_MUTATIONS})
else else
game.print({"description.rampant--adaptation1DebugMessage", game.print({"description.rampant--adaptation1DebugMessage",
base.id, base.id,
@@ -398,18 +401,18 @@ local function pickMutationFromDamageType(universe, damageType, roll, base)
base.x, base.x,
base.y, base.y,
base.mutations, base.mutations,
universe.MAX_BASE_MUTATIONS}) Universe.MAX_BASE_MUTATIONS})
end end
end end
local alignmentCount = table_size(base.alignmentHistory) local alignmentCount = table_size(base.alignmentHistory)
while (alignmentCount > universe.MAX_BASE_ALIGNMENT_HISTORY) do while (alignmentCount > Universe.MAX_BASE_ALIGNMENT_HISTORY) do
tableRemove(base.alignmentHistory, 1) tableRemove(base.alignmentHistory, 1)
alignmentCount = alignmentCount - 1 alignmentCount = alignmentCount - 1
end end
return mutated return mutated
end end
function baseUtils.upgradeBaseBasedOnDamage(universe, base) function BaseUtils.upgradeBaseBasedOnDamage(base)
local total = 0 local total = 0
@@ -420,7 +423,7 @@ function baseUtils.upgradeBaseBasedOnDamage(universe, base)
base.damagedBy["RandomMutation"] = mutationAmount base.damagedBy["RandomMutation"] = mutationAmount
total = total + mutationAmount total = total + mutationAmount
local pickedDamage local pickedDamage
local roll = universe.random() local roll = Universe.random()
for damageTypeName,amount in pairs(base.damagedBy) do for damageTypeName,amount in pairs(base.damagedBy) do
base.damagedBy[damageTypeName] = amount / total base.damagedBy[damageTypeName] = amount / total
end end
@@ -432,68 +435,66 @@ function baseUtils.upgradeBaseBasedOnDamage(universe, base)
end end
end end
return pickMutationFromDamageType(universe, pickedDamage, roll, base) return pickMutationFromDamageType(pickedDamage, roll, base)
end end
function baseUtils.processBaseMutation(chunk, map, base) function BaseUtils.processBaseMutation(chunk, map, base)
if not base.alignment[1] or if not base.alignment[1] or
(base.stateGeneration ~= BASE_GENERATION_STATE_ACTIVE) or (base.stateGeneration ~= BASE_GENERATION_STATE_ACTIVE) or
(map.random() >= 0.30) (Universe.random() >= 0.30)
then then
return return
end end
if (base.points >= MINIMUM_BUILDING_COST) then if (base.points >= MINIMUM_BUILDING_COST) then
local surface = map.surface local surface = map.surface
local universe = map.universe setPositionXYInQuery(Universe.pbFilteredEntitiesPointQueryLimited,
setPositionXYInQuery(universe.pbFilteredEntitiesPointQueryLimited, chunk.x + (CHUNK_SIZE * Universe.random()),
chunk.x + (CHUNK_SIZE * map.random()), chunk.y + (CHUNK_SIZE * Universe.random()))
chunk.y + (CHUNK_SIZE * map.random()))
local entities = surface.find_entities_filtered(universe.pbFilteredEntitiesPointQueryLimited) local entities = surface.find_entities_filtered(Universe.pbFilteredEntitiesPointQueryLimited)
if #entities ~= 0 then if #entities ~= 0 then
local entity = entities[1] local entity = entities[1]
local cost = (COST_LOOKUP[entity.name] or MAGIC_MAXIMUM_NUMBER) local cost = (COST_LOOKUP[entity.name] or MAGIC_MAXIMUM_NUMBER)
if (base.points >= cost) then if (base.points >= cost) then
local position = entity.position local position = entity.position
baseUtils.modifyBaseSpecialPoints(base, -cost, "Scheduling Entity upgrade", position.x, position.y) BaseUtils.modifyBaseSpecialPoints(base, -cost, "Scheduling Entity upgrade", position.x, position.y)
baseUtils.queueUpgrade(entity, base, nil, false, true) BaseUtils.queueUpgrade(entity, base, nil, false, true)
end end
end end
end end
end end
function baseUtils.createBase(map, chunk, tick) function BaseUtils.createBase(map, chunk, tick)
local x = chunk.x local x = chunk.x
local y = chunk.y local y = chunk.y
local distance = euclideanDistancePoints(x, y, 0, 0) local distance = euclideanDistancePoints(x, y, 0, 0)
local meanLevel = mFloor(distance * 0.005) local meanLevel = mFloor(distance * 0.005)
local universe = map.universe
local distanceIndex = mMin(1, distance * BASE_DISTANCE_TO_EVO_INDEX) local distanceIndex = mMin(1, distance * BASE_DISTANCE_TO_EVO_INDEX)
local evoIndex = mMax(distanceIndex, universe.evolutionLevel) local evoIndex = mMax(distanceIndex, Universe.evolutionLevel)
local alignment = local alignment =
(universe.NEW_ENEMIES and baseUtils.findBaseInitialAlignment(universe, evoIndex)) (Universe.NEW_ENEMIES and BaseUtils.findBaseInitialAlignment(evoIndex))
or {"neutral"} or {"neutral"}
local baseLevel = gaussianRandomRangeRG(meanLevel, local baseLevel = gaussianRandomRangeRG(meanLevel,
meanLevel * 0.3, meanLevel * 0.3,
meanLevel * 0.50, meanLevel * 0.50,
meanLevel * 1.50, meanLevel * 1.50,
universe.random) Universe.random)
local baseDistanceThreshold = gaussianRandomRangeRG(BASE_DISTANCE_THRESHOLD, local baseDistanceThreshold = gaussianRandomRangeRG(BASE_DISTANCE_THRESHOLD,
BASE_DISTANCE_THRESHOLD * 0.2, BASE_DISTANCE_THRESHOLD * 0.2,
BASE_DISTANCE_THRESHOLD * 0.75, BASE_DISTANCE_THRESHOLD * 0.75,
BASE_DISTANCE_THRESHOLD * 1.50, BASE_DISTANCE_THRESHOLD * 1.50,
universe.random) Universe.random)
local distanceThreshold = (baseLevel * BASE_DISTANCE_LEVEL_BONUS) + baseDistanceThreshold local distanceThreshold = (baseLevel * BASE_DISTANCE_LEVEL_BONUS) + baseDistanceThreshold
local base = { local base = {
x = x, x = x,
y = y, y = y,
distanceThreshold = distanceThreshold * universe.baseDistanceModifier, distanceThreshold = distanceThreshold * Universe.baseDistanceModifier,
tick = tick, tick = tick,
alignment = alignment, alignment = alignment,
alignmentHistory = {}, alignmentHistory = {},
@@ -526,19 +527,18 @@ function baseUtils.createBase(map, chunk, tick)
resourceChunkCount = 0, resourceChunkCount = 0,
temperament = 0.5, temperament = 0.5,
temperamentScore = 0, temperamentScore = 0,
universe = universe,
map = map, map = map,
id = universe.baseId id = Universe.baseId
} }
universe.baseId = universe.baseId + 1 Universe.baseId = Universe.baseId + 1
map.bases[base.id] = base map.bases[base.id] = base
universe.bases[base.id] = base Universe.bases[base.id] = base
return base return base
end end
function baseUtils.modifyBaseUnitPoints(base, points, tag, x, y) function BaseUtils.modifyBaseUnitPoints(base, points, tag, x, y)
if points > 0 and base.stateAI == BASE_AI_STATE_PEACEFUL then if points > 0 and base.stateAI == BASE_AI_STATE_PEACEFUL then
return return
@@ -550,17 +550,16 @@ function baseUtils.modifyBaseUnitPoints(base, points, tag, x, y)
base.unitPoints = base.unitPoints + points base.unitPoints = base.unitPoints + points
local universe = base.universe
local overflowMessage = "" local overflowMessage = ""
if base.unitPoints > universe.maxOverflowPoints then if base.unitPoints > Universe.maxOverflowPoints then
base.unitPoints = universe.maxOverflowPoints base.unitPoints = Universe.maxOverflowPoints
overflowMessage = " [Point cap reached]" overflowMessage = " [Point cap reached]"
end end
local printPointChange = "" local printPointChange = ""
if points > 0 and universe.aiPointsPrintGainsToChat then if points > 0 and Universe.aiPointsPrintGainsToChat then
printPointChange = "+" .. string.format("%.2f", points) printPointChange = "+" .. string.format("%.2f", points)
elseif points < 0 and universe.aiPointsPrintSpendingToChat then elseif points < 0 and Universe.aiPointsPrintSpendingToChat then
printPointChange = string.format("%.2f", points) printPointChange = string.format("%.2f", points)
end end
@@ -573,7 +572,7 @@ function baseUtils.modifyBaseUnitPoints(base, points, tag, x, y)
end end
end end
function baseUtils.modifyBaseSpecialPoints(base, points, tag, x, y) function BaseUtils.modifyBaseSpecialPoints(base, points, tag, x, y)
if points > 0 and base.stateAI == BASE_AI_STATE_PEACEFUL then if points > 0 and base.stateAI == BASE_AI_STATE_PEACEFUL then
return return
@@ -585,17 +584,16 @@ function baseUtils.modifyBaseSpecialPoints(base, points, tag, x, y)
base.points = base.points + points base.points = base.points + points
local universe = base.universe
local overflowMessage = "" local overflowMessage = ""
if base.points > universe.maxOverflowPoints then if base.points > Universe.maxOverflowPoints then
base.points = universe.maxOverflowPoints base.points = Universe.maxOverflowPoints
overflowMessage = " [Point cap reached]" overflowMessage = " [Point cap reached]"
end end
local printPointChange = "" local printPointChange = ""
if points > 0 and universe.aiPointsPrintGainsToChat then if points > 0 and Universe.aiPointsPrintGainsToChat then
printPointChange = "+" .. string.format("%.2f", points) printPointChange = "+" .. string.format("%.2f", points)
elseif points < 0 and universe.aiPointsPrintSpendingToChat then elseif points < 0 and Universe.aiPointsPrintSpendingToChat then
printPointChange = string.format("%.2f", points) printPointChange = string.format("%.2f", points)
end end
@@ -608,5 +606,9 @@ function baseUtils.modifyBaseSpecialPoints(base, points, tag, x, y)
end end
end end
baseUtilsG = baseUtils function BaseUtils.init(universe)
return baseUtils Universe = universe
end
BaseUtilsG = BaseUtils
return BaseUtils

View File

@@ -14,41 +14,45 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
if (chunkProcessorG) then if (ChunkProcessorG) then
return chunkProcessorG return ChunkProcessorG
end end
local chunkProcessor = {} local ChunkProcessor = {}
--
local Universe
-- imports -- imports
local chunkUtils = require("ChunkUtils") local ChunkUtils = require("ChunkUtils")
local queryUtils = require("QueryUtils") local QueryUtils = require("QueryUtils")
local mapUtils = require("MapUtils") local MapUtils = require("MapUtils")
local mathUtils = require("MathUtils") local MathUtils = require("MathUtils")
local constants = require("Constants") local Constants = require("Constants")
local baseUtils = require("BaseUtils") local BaseUtils = require("BaseUtils")
-- constants -- Constants
local PROXY_ENTITY_LOOKUP = constants.PROXY_ENTITY_LOOKUP local PROXY_ENTITY_LOOKUP = Constants.PROXY_ENTITY_LOOKUP
local BASE_DISTANCE_TO_EVO_INDEX = constants.BASE_DISTANCE_TO_EVO_INDEX local BASE_DISTANCE_TO_EVO_INDEX = Constants.BASE_DISTANCE_TO_EVO_INDEX
local BUILDING_SPACE_LOOKUP = constants.BUILDING_SPACE_LOOKUP local BUILDING_SPACE_LOOKUP = Constants.BUILDING_SPACE_LOOKUP
-- imported functions -- imported functions
local findInsertionPoint = mapUtils.findInsertionPoint local findInsertionPoint = MapUtils.findInsertionPoint
local removeChunkFromMap = mapUtils.removeChunkFromMap local removeChunkFromMap = MapUtils.removeChunkFromMap
local setPositionInQuery = queryUtils.setPositionInQuery local setPositionInQuery = QueryUtils.setPositionInQuery
local registerEnemyBaseStructure = chunkUtils.registerEnemyBaseStructure local registerEnemyBaseStructure = ChunkUtils.registerEnemyBaseStructure
local unregisterEnemyBaseStructure = chunkUtils.unregisterEnemyBaseStructure local unregisterEnemyBaseStructure = ChunkUtils.unregisterEnemyBaseStructure
local euclideanDistancePoints = mathUtils.euclideanDistancePoints local euclideanDistancePoints = MathUtils.euclideanDistancePoints
local findEntityUpgrade = baseUtils.findEntityUpgrade local findEntityUpgrade = BaseUtils.findEntityUpgrade
local createChunk = chunkUtils.createChunk local createChunk = ChunkUtils.createChunk
local initialScan = chunkUtils.initialScan local initialScan = ChunkUtils.initialScan
local chunkPassScan = chunkUtils.chunkPassScan local chunkPassScan = ChunkUtils.chunkPassScan
local mMin = math.min local mMin = math.min
local mMax = math.max local mMax = math.max
@@ -59,9 +63,9 @@ local tInsert = table.insert
-- module code -- module code
function chunkProcessor.processPendingChunks(universe, tick, flush) function ChunkProcessor.processPendingChunks(tick, flush)
local pendingChunks = universe.pendingChunks local pendingChunks = Universe.pendingChunks
local eventId = universe.chunkProcessorIterator local eventId = Universe.chunkProcessorIterator
local event local event
if not eventId then if not eventId then
@@ -76,22 +80,22 @@ function chunkProcessor.processPendingChunks(universe, tick, flush)
end end
for _=1,endCount do for _=1,endCount do
if not eventId then if not eventId then
universe.chunkProcessorIterator = nil Universe.chunkProcessorIterator = nil
if (table_size(pendingChunks) == 0) then if (table_size(pendingChunks) == 0) then
-- this is needed as the next command remembers the max length a table has been -- this is needed as the next command remembers the max length a table has been
universe.pendingChunks = {} Universe.pendingChunks = {}
end end
break break
else else
if not flush and (event.tick > tick) then if not flush and (event.tick > tick) then
universe.chunkProcessorIterator = eventId Universe.chunkProcessorIterator = eventId
return return
end end
local newEventId, newEvent = next(pendingChunks, eventId) local newEventId, newEvent = next(pendingChunks, eventId)
pendingChunks[eventId] = nil pendingChunks[eventId] = nil
local map = event.map local map = event.map
if not map.surface.valid then if not map.surface.valid then
universe.chunkProcessorIterator = newEventId Universe.chunkProcessorIterator = newEventId
return return
end end
@@ -112,7 +116,7 @@ function chunkProcessor.processPendingChunks(universe, tick, flush)
else else
local initialChunk = createChunk(map, x, y) local initialChunk = createChunk(map, x, y)
map[x][y] = initialChunk map[x][y] = initialChunk
universe.chunkIdToChunk[initialChunk.id] = initialChunk Universe.chunkIdToChunk[initialChunk.id] = initialChunk
local chunk = initialScan(initialChunk, map, tick) local chunk = initialScan(initialChunk, map, tick)
if (chunk ~= -1) then if (chunk ~= -1) then
tInsert( tInsert(
@@ -122,7 +126,7 @@ function chunkProcessor.processPendingChunks(universe, tick, flush)
) )
else else
map[x][y] = nil map[x][y] = nil
universe.chunkIdToChunk[initialChunk.id] = nil Universe.chunkIdToChunk[initialChunk.id] = nil
end end
end end
@@ -130,30 +134,30 @@ function chunkProcessor.processPendingChunks(universe, tick, flush)
event = newEvent event = newEvent
end end
end end
universe.chunkProcessorIterator = eventId Universe.chunkProcessorIterator = eventId
end end
function chunkProcessor.processPendingUpgrades(universe, tick) function ChunkProcessor.processPendingUpgrades(tick)
local entityId = universe.pendingUpgradeIterator local entityId = Universe.pendingUpgradeIterator
local entityData local entityData
if not entityId then if not entityId then
entityId, entityData = next(universe.pendingUpgrades, nil) entityId, entityData = next(Universe.pendingUpgrades, nil)
else else
entityData = universe.pendingUpgrades[entityId] entityData = Universe.pendingUpgrades[entityId]
end end
if not entityId then if not entityId then
universe.pendingUpgradeIterator = nil Universe.pendingUpgradeIterator = nil
if table_size(universe.pendingUpgrades) == 0 then if table_size(Universe.pendingUpgrades) == 0 then
universe.pendingUpgrades = {} Universe.pendingUpgrades = {}
end end
else else
local entity = entityData.entity local entity = entityData.entity
if entity.valid then if entity.valid then
universe.pendingUpgradeIterator = next(universe.pendingUpgrades, entityId) Universe.pendingUpgradeIterator = next(Universe.pendingUpgrades, entityId)
if entityData.delayTLL and tick < entityData.delayTLL then if entityData.delayTLL and tick < entityData.delayTLL then
return return
end end
universe.pendingUpgrades[entityId] = nil Universe.pendingUpgrades[entityId] = nil
local base = entityData.base local base = entityData.base
local map = base.map local map = base.map
local baseAlignment = base.alignment local baseAlignment = base.alignment
@@ -173,7 +177,7 @@ function chunkProcessor.processPendingUpgrades(universe, tick)
local currentEvo = entity.prototype.build_base_evolution_requirement or 0 local currentEvo = entity.prototype.build_base_evolution_requirement or 0
local distance = mMin(1, euclideanDistancePoints(position.x, position.y, 0, 0) * BASE_DISTANCE_TO_EVO_INDEX) local distance = mMin(1, euclideanDistancePoints(position.x, position.y, 0, 0) * BASE_DISTANCE_TO_EVO_INDEX)
local evoIndex = mMax(distance, universe.evolutionLevel) local evoIndex = mMax(distance, Universe.evolutionLevel)
local name = findEntityUpgrade(pickedBaseAlignment, local name = findEntityUpgrade(pickedBaseAlignment,
currentEvo, currentEvo,
@@ -191,7 +195,7 @@ function chunkProcessor.processPendingUpgrades(universe, tick)
end end
local surface = entity.surface local surface = entity.surface
local query = universe.ppuUpgradeEntityQuery local query = Universe.ppuUpgradeEntityQuery
query.name = name query.name = name
unregisterEnemyBaseStructure(map, entity, nil, true) unregisterEnemyBaseStructure(map, entity, nil, true)
@@ -211,7 +215,7 @@ function chunkProcessor.processPendingUpgrades(universe, tick)
if entityData.register then if entityData.register then
registerEnemyBaseStructure(map, createdEntity, base, true) registerEnemyBaseStructure(map, createdEntity, base, true)
end end
if not entityData.evolve and universe.printBaseUpgrades then if not entityData.evolve and Universe.printBaseUpgrades then
surface.print("["..base.id.."]:"..surface.name.." Upgrading ".. entityName .. " to " .. name .. " [gps=".. position.x ..",".. position.y .."]") surface.print("["..base.id.."]:"..surface.name.." Upgrading ".. entityName .. " to " .. name .. " [gps=".. position.x ..",".. position.y .."]")
end end
if remote.interfaces["kr-creep"] then if remote.interfaces["kr-creep"] then
@@ -219,31 +223,31 @@ function chunkProcessor.processPendingUpgrades(universe, tick)
end end
end end
else else
universe.pendingUpgradeIterator = next(universe.pendingUpgrades, entityId) Universe.pendingUpgradeIterator = next(Universe.pendingUpgrades, entityId)
universe.pendingUpgrades[entityId] = nil Universe.pendingUpgrades[entityId] = nil
end end
end end
end end
function chunkProcessor.processScanChunks(universe) function ChunkProcessor.processScanChunks()
local chunkId = universe.chunkToPassScanIterator local chunkId = Universe.chunkToPassScanIterator
local chunkPack local chunkPack
if not chunkId then if not chunkId then
chunkId, chunkPack = next(universe.chunkToPassScan, nil) chunkId, chunkPack = next(Universe.chunkToPassScan, nil)
else else
chunkPack = universe.chunkToPassScan[chunkId] chunkPack = Universe.chunkToPassScan[chunkId]
end end
if not chunkId then if not chunkId then
universe.chunkToPassScanIterator = nil Universe.chunkToPassScanIterator = nil
if (table_size(universe.chunkToPassScan) == 0) then if (table_size(Universe.chunkToPassScan) == 0) then
-- this is needed as the next command remembers the max length a table has been -- this is needed as the next command remembers the max length a table has been
universe.chunkToPassScan = {} Universe.chunkToPassScan = {}
end end
else else
universe.chunkToPassScanIterator = next(universe.chunkToPassScan, chunkId) Universe.chunkToPassScanIterator = next(Universe.chunkToPassScan, chunkId)
universe.chunkToPassScan[chunkId] = nil Universe.chunkToPassScan[chunkId] = nil
local map = chunkPack.map local map = chunkPack.map
if not map.surface.valid then if not map.surface.valid then
return return
@@ -256,5 +260,9 @@ function chunkProcessor.processScanChunks(universe)
end end
end end
chunkProcessorG = chunkProcessor function ChunkProcessor.init(universe)
return chunkProcessor Universe = universe
end
ChunkProcessorG = ChunkProcessor
return ChunkProcessor

View File

@@ -14,56 +14,63 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
if chunkPropertyUtilsG then if ChunkPropertyUtilsG then
return chunkPropertyUtilsG return ChunkPropertyUtilsG
end end
local chunkPropertyUtils = {} local ChunkPropertyUtils = {}
local constants = require("Constants") --
local mathUtils = require("MathUtils")
-- constants local Universe
local PLAYER_GENERATOR_PERSISTANCE = constants.PLAYER_GENERATOR_PERSISTANCE --
local PLAYER_PHEROMONE_GENERATOR_AMOUNT = constants.PLAYER_PHEROMONE_GENERATOR_AMOUNT
local COOLDOWN_DRAIN = constants.COOLDOWN_DRAIN local Constants = require("Constants")
local MathUtils = require("MathUtils")
local RAIDING_MINIMUM_BASE_THRESHOLD = constants.RAIDING_MINIMUM_BASE_THRESHOLD -- Constants
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE local PLAYER_GENERATOR_PERSISTANCE = Constants.PLAYER_GENERATOR_PERSISTANCE
local BASE_PHEROMONE = constants.BASE_PHEROMONE local PLAYER_PHEROMONE_GENERATOR_AMOUNT = Constants.PLAYER_PHEROMONE_GENERATOR_AMOUNT
local MOVEMENT_GENERATOR_PERSISTANCE = constants.MOVEMENT_GENERATOR_PERSISTANCE local COOLDOWN_DRAIN = Constants.COOLDOWN_DRAIN
local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS
local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER local RAIDING_MINIMUM_BASE_THRESHOLD = Constants.RAIDING_MINIMUM_BASE_THRESHOLD
local PLAYER_PHEROMONE = Constants.PLAYER_PHEROMONE
local BASE_PHEROMONE = Constants.BASE_PHEROMONE
local MOVEMENT_GENERATOR_PERSISTANCE = Constants.MOVEMENT_GENERATOR_PERSISTANCE
local CHUNK_ALL_DIRECTIONS = Constants.CHUNK_ALL_DIRECTIONS
local MAGIC_MAXIMUM_NUMBER = Constants.MAGIC_MAXIMUM_NUMBER
-- imported functions -- imported functions
local manhattenDistancePoints = mathUtils.manhattenDistancePoints local manhattenDistancePoints = MathUtils.manhattenDistancePoints
local tableSize = table_size
local mMin = math.min local mMin = math.min
-- module code -- module code
function chunkPropertyUtils.getTurretCount(map, chunk) function ChunkPropertyUtils.getTurretCount(map, chunk)
return map.chunkToTurrets[chunk.id] or 0 return map.chunkToTurrets[chunk.id] or 0
end end
function chunkPropertyUtils.getTrapCount(map, chunk) function ChunkPropertyUtils.getTrapCount(map, chunk)
return map.chunkToTraps[chunk.id] or 0 return map.chunkToTraps[chunk.id] or 0
end end
function chunkPropertyUtils.getUtilityCount(map, chunk) function ChunkPropertyUtils.getUtilityCount(map, chunk)
return map.chunkToUtilities[chunk.id] or 0 return map.chunkToUtilities[chunk.id] or 0
end end
function chunkPropertyUtils.getHiveCount(map, chunk) function ChunkPropertyUtils.getHiveCount(map, chunk)
return map.chunkToHives[chunk.id] or 0 return map.chunkToHives[chunk.id] or 0
end end
function chunkPropertyUtils.addTurretCount(map, chunk, unitNumber) function ChunkPropertyUtils.addTurretCount(map, chunk, unitNumber)
map.activeSurface = true map.activeSurface = true
if not map.chunkToTurretIds[chunk.id] then if not map.chunkToTurretIds[chunk.id] then
map.chunkToTurretIds[chunk.id] = {} map.chunkToTurretIds[chunk.id] = {}
@@ -76,7 +83,7 @@ function chunkPropertyUtils.addTurretCount(map, chunk, unitNumber)
return false return false
end end
function chunkPropertyUtils.removeTurretCount(map, chunk, unitNumber) function ChunkPropertyUtils.removeTurretCount(map, chunk, unitNumber)
if map.chunkToTurretIds[chunk.id] and map.chunkToTurretIds[chunk.id][unitNumber] then if map.chunkToTurretIds[chunk.id] and map.chunkToTurretIds[chunk.id][unitNumber] then
map.chunkToTurretIds[chunk.id][unitNumber] = nil map.chunkToTurretIds[chunk.id][unitNumber] = nil
map.chunkToTurrets[chunk.id] = map.chunkToTurrets[chunk.id] - 1 map.chunkToTurrets[chunk.id] = map.chunkToTurrets[chunk.id] - 1
@@ -89,7 +96,7 @@ function chunkPropertyUtils.removeTurretCount(map, chunk, unitNumber)
return false return false
end end
function chunkPropertyUtils.addTrapCount(map, chunk, unitNumber) function ChunkPropertyUtils.addTrapCount(map, chunk, unitNumber)
map.activeSurface = true map.activeSurface = true
if not map.chunkToTrapIds[chunk.id] then if not map.chunkToTrapIds[chunk.id] then
map.chunkToTrapIds[chunk.id] = {} map.chunkToTrapIds[chunk.id] = {}
@@ -102,7 +109,7 @@ function chunkPropertyUtils.addTrapCount(map, chunk, unitNumber)
return false return false
end end
function chunkPropertyUtils.removeTrapCount(map, chunk, unitNumber) function ChunkPropertyUtils.removeTrapCount(map, chunk, unitNumber)
if map.chunkToTrapIds[chunk.id] and map.chunkToTrapIds[chunk.id][unitNumber] then if map.chunkToTrapIds[chunk.id] and map.chunkToTrapIds[chunk.id][unitNumber] then
map.chunkToTrapIds[chunk.id][unitNumber] = nil map.chunkToTrapIds[chunk.id][unitNumber] = nil
map.chunkToTraps[chunk.id] = map.chunkToTraps[chunk.id] - 1 map.chunkToTraps[chunk.id] = map.chunkToTraps[chunk.id] - 1
@@ -115,7 +122,7 @@ function chunkPropertyUtils.removeTrapCount(map, chunk, unitNumber)
return false return false
end end
function chunkPropertyUtils.addUtilitiesCount(map, chunk, unitNumber) function ChunkPropertyUtils.addUtilitiesCount(map, chunk, unitNumber)
map.activeSurface = true map.activeSurface = true
if not map.chunkToUtilityIds[chunk.id] then if not map.chunkToUtilityIds[chunk.id] then
map.chunkToUtilityIds[chunk.id] = {} map.chunkToUtilityIds[chunk.id] = {}
@@ -128,7 +135,7 @@ function chunkPropertyUtils.addUtilitiesCount(map, chunk, unitNumber)
return false return false
end end
function chunkPropertyUtils.removeUtilitiesCount(map, chunk, unitNumber) function ChunkPropertyUtils.removeUtilitiesCount(map, chunk, unitNumber)
if map.chunkToUtilityIds[chunk.id] and map.chunkToUtilityIds[chunk.id][unitNumber] then if map.chunkToUtilityIds[chunk.id] and map.chunkToUtilityIds[chunk.id][unitNumber] then
map.chunkToUtilityIds[chunk.id][unitNumber] = nil map.chunkToUtilityIds[chunk.id][unitNumber] = nil
map.chunkToUtilities[chunk.id] = map.chunkToUtilities[chunk.id] - 1 map.chunkToUtilities[chunk.id] = map.chunkToUtilities[chunk.id] - 1
@@ -141,7 +148,7 @@ function chunkPropertyUtils.removeUtilitiesCount(map, chunk, unitNumber)
return false return false
end end
function chunkPropertyUtils.addHiveCount(map, chunk, unitNumber) function ChunkPropertyUtils.addHiveCount(map, chunk, unitNumber)
map.activeSurface = true map.activeSurface = true
if not map.chunkToHiveIds[chunk.id] then if not map.chunkToHiveIds[chunk.id] then
map.chunkToHiveIds[chunk.id] = {} map.chunkToHiveIds[chunk.id] = {}
@@ -154,7 +161,7 @@ function chunkPropertyUtils.addHiveCount(map, chunk, unitNumber)
return false return false
end end
function chunkPropertyUtils.removeHiveCount(map, chunk, unitNumber) function ChunkPropertyUtils.removeHiveCount(map, chunk, unitNumber)
if map.chunkToHiveIds[chunk.id] and map.chunkToHiveIds[chunk.id][unitNumber] then if map.chunkToHiveIds[chunk.id] and map.chunkToHiveIds[chunk.id][unitNumber] then
map.chunkToHiveIds[chunk.id][unitNumber] = nil map.chunkToHiveIds[chunk.id][unitNumber] = nil
map.chunkToHives[chunk.id] = map.chunkToHives[chunk.id] - 1 map.chunkToHives[chunk.id] = map.chunkToHives[chunk.id] - 1
@@ -167,7 +174,7 @@ function chunkPropertyUtils.removeHiveCount(map, chunk, unitNumber)
return false return false
end end
function chunkPropertyUtils.addNestCount(map, chunk, unitNumber) function ChunkPropertyUtils.addNestCount(map, chunk, unitNumber)
map.activeSurface = true map.activeSurface = true
local chunkId = chunk.id local chunkId = chunk.id
if not map.chunkToNestIds[chunkId] then if not map.chunkToNestIds[chunkId] then
@@ -175,7 +182,7 @@ function chunkPropertyUtils.addNestCount(map, chunk, unitNumber)
end end
if not map.chunkToNestIds[chunkId][unitNumber] then if not map.chunkToNestIds[chunkId][unitNumber] then
map.chunkToNestIds[chunkId][unitNumber] = true map.chunkToNestIds[chunkId][unitNumber] = true
local cToN = map.universe.chunkToNests local cToN = Universe.chunkToNests
local pack = cToN[chunkId] local pack = cToN[chunkId]
if not pack then if not pack then
cToN[chunkId] = { cToN[chunkId] = {
@@ -189,20 +196,20 @@ function chunkPropertyUtils.addNestCount(map, chunk, unitNumber)
return false return false
end end
function chunkPropertyUtils.removeNestCount(map, chunk, unitNumber) function ChunkPropertyUtils.removeNestCount(map, chunk, unitNumber)
local chunkId = chunk.id local chunkId = chunk.id
if map.chunkToNestIds[chunkId] and map.chunkToNestIds[chunkId][unitNumber] then if map.chunkToNestIds[chunkId] and map.chunkToNestIds[chunkId][unitNumber] then
map.chunkToNestIds[chunkId][unitNumber] = nil map.chunkToNestIds[chunkId][unitNumber] = nil
local cToN = map.universe.chunkToNests local cToN = Universe.chunkToNests
cToN[chunkId].v = cToN[chunkId].v - 1 cToN[chunkId].v = cToN[chunkId].v - 1
if cToN[chunkId].v == 0 then if cToN[chunkId].v == 0 then
map.chunkToNestIds[chunkId] = nil map.chunkToNestIds[chunkId] = nil
cToN[chunkId] = nil cToN[chunkId] = nil
if (map.universe.processMigrationIterator == chunkId) then if (Universe.processMigrationIterator == chunkId) then
map.universe.processMigrationIterator = nil Universe.processMigrationIterator = nil
end end
if (map.universe.processNestIterator == chunkId) then if (Universe.processNestIterator == chunkId) then
map.universe.processNestIterator = nil Universe.processNestIterator = nil
end end
end end
return true return true
@@ -210,49 +217,49 @@ function chunkPropertyUtils.removeNestCount(map, chunk, unitNumber)
return false return false
end end
function chunkPropertyUtils.getNestCount(map, chunk) function ChunkPropertyUtils.getNestCount(chunk)
local nestPack = map.universe.chunkToNests[chunk.id] local nestPack = Universe.chunkToNests[chunk.id]
if not nestPack then if not nestPack then
return 0 return 0
end end
return nestPack.v return nestPack.v
end end
function chunkPropertyUtils.addBaseResourceChunk(base, chunk) function ChunkPropertyUtils.addBaseResourceChunk(base, chunk)
if chunkPropertyUtils.getResourceGenerator(base.map, chunk) > 0 then if ChunkPropertyUtils.getResourceGenerator(base.map, chunk) > 0 then
base.resourceChunkCount = base.resourceChunkCount + 1 base.resourceChunkCount = base.resourceChunkCount + 1
base.resourceChunks[chunk.id] = true base.resourceChunks[chunk.id] = true
end end
end end
function chunkPropertyUtils.removeBaseResourceChunk(base, chunk) function ChunkPropertyUtils.removeBaseResourceChunk(base, chunk)
if base.resourceChunks[chunk.id] then if base.resourceChunks[chunk.id] then
base.resourceChunkCount = base.resourceChunkCount - 1 base.resourceChunkCount = base.resourceChunkCount - 1
base.resourceChunks[chunk.id] = nil base.resourceChunks[chunk.id] = nil
end end
end end
function chunkPropertyUtils.getChunkBase(map, chunk) function ChunkPropertyUtils.getChunkBase(map, chunk)
return map.chunkToBase[chunk.id] return map.chunkToBase[chunk.id]
end end
function chunkPropertyUtils.removeChunkBase(map, chunk, base) function ChunkPropertyUtils.removeChunkBase(map, chunk, base)
if map.chunkToBase[chunk.id] then if map.chunkToBase[chunk.id] then
base.chunkCount = base.chunkCount - 1 base.chunkCount = base.chunkCount - 1
map.chunkToBase[chunk.id] = nil map.chunkToBase[chunk.id] = nil
end end
end end
function chunkPropertyUtils.setChunkBase(map, chunk, base) function ChunkPropertyUtils.setChunkBase(map, chunk, base)
if not map.chunkToBase[chunk.id] then if not map.chunkToBase[chunk.id] then
base.chunkCount = base.chunkCount + 1 base.chunkCount = base.chunkCount + 1
map.chunkToBase[chunk.id] = base map.chunkToBase[chunk.id] = base
end end
end end
function chunkPropertyUtils.getEnemyStructureCount(map, chunk) function ChunkPropertyUtils.getEnemyStructureCount(map, chunk)
local nests = 0 local nests = 0
local nestPack = map.universe.chunkToNests[chunk.id] local nestPack = Universe.chunkToNests[chunk.id]
if nestPack then if nestPack then
nests = nestPack.v nests = nestPack.v
end end
@@ -260,13 +267,13 @@ function chunkPropertyUtils.getEnemyStructureCount(map, chunk)
(map.chunkToUtilities[chunk.id] or 0) + (map.chunkToHives[chunk.id] or 0) (map.chunkToUtilities[chunk.id] or 0) + (map.chunkToHives[chunk.id] or 0)
end end
function chunkPropertyUtils.setDrainPylons(map, entity1, entity2) function ChunkPropertyUtils.setDrainPylons(map, entity1, entity2)
local pair = {entity1, entity2} local pair = {entity1, entity2}
map.drainPylons[entity1.unit_number] = pair map.drainPylons[entity1.unit_number] = pair
map.drainPylons[entity2.unit_number] = pair map.drainPylons[entity2.unit_number] = pair
end end
function chunkPropertyUtils.removeDrainPylons(map, unitNumber) function ChunkPropertyUtils.removeDrainPylons(map, unitNumber)
local pair = map.drainPylons[unitNumber] local pair = map.drainPylons[unitNumber]
if pair then if pair then
local target = pair[1] local target = pair[1]
@@ -287,74 +294,74 @@ function chunkPropertyUtils.removeDrainPylons(map, unitNumber)
end end
end end
function chunkPropertyUtils.getDrainPylonPair(map, unitNumber) function ChunkPropertyUtils.getDrainPylonPair(map, unitNumber)
return map.drainPylons[unitNumber] return map.drainPylons[unitNumber]
end end
function chunkPropertyUtils.isDrained(map, chunk, tick) function ChunkPropertyUtils.isDrained(chunk, tick)
local pack = map.universe.chunkToDrained[chunk.id] local pack = Universe.chunkToDrained[chunk.id]
if not pack then if not pack then
return false return false
end end
return (tick - pack.tick) < COOLDOWN_DRAIN return (tick - pack.tick) < COOLDOWN_DRAIN
end end
function chunkPropertyUtils.setDrainedTick(map, chunk, tick) function ChunkPropertyUtils.setDrainedTick(map, chunk, tick)
local chunkId = chunk.id local chunkId = chunk.id
local pack = map.universe.chunkToDrained[chunkId] local pack = Universe.chunkToDrained[chunkId]
if not pack then if not pack then
pack = { pack = {
map = map, map = map,
tick = 0 tick = 0
} }
map.universe.chunkToDrained[chunkId] = pack Universe.chunkToDrained[chunkId] = pack
end end
pack.tick = tick pack.tick = tick
end end
function chunkPropertyUtils.getRetreatTick(map, chunk) function ChunkPropertyUtils.getRetreatTick(chunk)
local pack = map.universe.chunkToRetreats[chunk.id] local pack = Universe.chunkToRetreats[chunk.id]
if not pack then if not pack then
return 0 return 0
end end
return pack.tick return pack.tick
end end
function chunkPropertyUtils.getRallyTick(map, chunk) function ChunkPropertyUtils.getRallyTick(chunk)
local pack = map.universe.chunkToRallys[chunk.id] local pack = Universe.chunkToRallys[chunk.id]
if not pack then if not pack then
return 0 return 0
end end
return pack.tick return pack.tick
end end
function chunkPropertyUtils.setRallyTick(map, chunk, tick) function ChunkPropertyUtils.setRallyTick(map, chunk, tick)
local chunkId = chunk.id local chunkId = chunk.id
local pack = map.universe.chunkToRallys[chunkId] local pack = Universe.chunkToRallys[chunkId]
if not pack then if not pack then
pack = { pack = {
map = map, map = map,
tick = tick tick = tick
} }
map.universe.chunkToRallys[chunkId] = pack Universe.chunkToRallys[chunkId] = pack
end end
pack.tick = tick pack.tick = tick
end end
function chunkPropertyUtils.setRetreatTick(map, chunk, tick) function ChunkPropertyUtils.setRetreatTick(map, chunk, tick)
local chunkId = chunk.id local chunkId = chunk.id
local pack = map.universe.chunkToRetreats[chunkId] local pack = Universe.chunkToRetreats[chunkId]
if not pack then if not pack then
pack = { pack = {
map = map, map = map,
tick = tick tick = tick
} }
map.universe.chunkToRetreats[chunkId] = pack Universe.chunkToRetreats[chunkId] = pack
end end
pack.tick = tick pack.tick = tick
end end
function chunkPropertyUtils.setResourceGenerator(map, chunk, resourceGenerator) function ChunkPropertyUtils.setResourceGenerator(map, chunk, resourceGenerator)
if (resourceGenerator <= 0) then if (resourceGenerator <= 0) then
map.chunkToResource[chunk.id] = nil map.chunkToResource[chunk.id] = nil
else else
@@ -362,80 +369,78 @@ function chunkPropertyUtils.setResourceGenerator(map, chunk, resourceGenerator)
end end
end end
function chunkPropertyUtils.getResourceGenerator(map, chunk) function ChunkPropertyUtils.getResourceGenerator(map, chunk)
return map.chunkToResource[chunk.id] or 0 return map.chunkToResource[chunk.id] or 0
end end
function chunkPropertyUtils.addResourceGenerator(map, chunk, delta) function ChunkPropertyUtils.addResourceGenerator(map, chunk, delta)
map.chunkToResource[chunk.id] = (map.chunkToResource[chunk.id] or 0) + delta map.chunkToResource[chunk.id] = (map.chunkToResource[chunk.id] or 0) + delta
end end
function chunkPropertyUtils.getPassable(map, chunk) function ChunkPropertyUtils.getPassable(map, chunk)
return map.chunkToPassable[chunk.id] or CHUNK_ALL_DIRECTIONS return map.chunkToPassable[chunk.id] or CHUNK_ALL_DIRECTIONS
end end
function chunkPropertyUtils.getRaidNestActiveness(map, chunk) function ChunkPropertyUtils.getRaidNestActiveness(chunk)
local activeness = map.universe.chunkToActiveRaidNest[chunk.id] local activeness = Universe.chunkToActiveRaidNest[chunk.id]
if not activeness then if not activeness then
return 0 return 0
end end
return activeness.v or 0 return activeness.v or 0
end end
function chunkPropertyUtils.setRaidNestActiveness(map, chunk, value, base) function ChunkPropertyUtils.setRaidNestActiveness(map, chunk, value, base)
local universe = map.universe
if (value <= 0) then if (value <= 0) then
if universe.chunkToActiveRaidNest[chunk.id] then if Universe.chunkToActiveRaidNest[chunk.id] then
base.activeRaidNests = base.activeRaidNests - 1 base.activeRaidNests = base.activeRaidNests - 1
end end
if (universe.processActiveRaidSpawnerIterator == chunk.id) then if (Universe.processActiveRaidSpawnerIterator == chunk.id) then
universe.processActiveRaidSpawnerIterator = nil Universe.processActiveRaidSpawnerIterator = nil
end end
universe.chunkToActiveRaidNest[chunk.id] = nil Universe.chunkToActiveRaidNest[chunk.id] = nil
else else
if not universe.chunkToActiveRaidNest[chunk.id] then if not Universe.chunkToActiveRaidNest[chunk.id] then
base.activeRaidNests = base.activeRaidNests + 1 base.activeRaidNests = base.activeRaidNests + 1
universe.chunkToActiveRaidNest[chunk.id] = { Universe.chunkToActiveRaidNest[chunk.id] = {
map = map, map = map,
v = 0 v = 0
} }
end end
universe.chunkToActiveRaidNest[chunk.id].v = value Universe.chunkToActiveRaidNest[chunk.id].v = value
end end
end end
function chunkPropertyUtils.getNestActiveness(map, chunk) function ChunkPropertyUtils.getNestActiveness(chunk)
local activeness = map.universe.chunkToActiveNest[chunk.id] local activeness = Universe.chunkToActiveNest[chunk.id]
if not activeness then if not activeness then
return 0 return 0
end end
return activeness.v or 0 return activeness.v or 0
end end
function chunkPropertyUtils.setNestActiveness(map, chunk, value, base) function ChunkPropertyUtils.setNestActiveness(map, chunk, value, base)
local universe = map.universe
if (value <= 0) then if (value <= 0) then
if universe.chunkToActiveNest[chunk.id] then if Universe.chunkToActiveNest[chunk.id] then
base.activeNests = base.activeNests - 1 base.activeNests = base.activeNests - 1
end end
if (universe.processActiveSpawnerIterator == chunk.id) then if (Universe.processActiveSpawnerIterator == chunk.id) then
universe.processActiveSpawnerIterator = nil Universe.processActiveSpawnerIterator = nil
end end
universe.chunkToActiveNest[chunk.id] = nil Universe.chunkToActiveNest[chunk.id] = nil
else else
if not universe.chunkToActiveNest[chunk.id] then if not Universe.chunkToActiveNest[chunk.id] then
base.activeNests = base.activeNests + 1 base.activeNests = base.activeNests + 1
universe.chunkToActiveNest[chunk.id] = { Universe.chunkToActiveNest[chunk.id] = {
map = map, map = map,
v = 0 v = 0
} }
end end
universe.chunkToActiveNest[chunk.id].v = value Universe.chunkToActiveNest[chunk.id].v = value
end end
end end
function chunkPropertyUtils.setPassable(map, chunk, value) function ChunkPropertyUtils.setPassable(map, chunk, value)
if (value == CHUNK_ALL_DIRECTIONS) then if (value == CHUNK_ALL_DIRECTIONS) then
map.chunkToPassable[chunk.id] = nil map.chunkToPassable[chunk.id] = nil
else else
@@ -443,11 +448,11 @@ function chunkPropertyUtils.setPassable(map, chunk, value)
end end
end end
function chunkPropertyUtils.getPathRating(map, chunk) function ChunkPropertyUtils.getPathRating(map, chunk)
return map.chunkToPathRating[chunk.id] or 1 return map.chunkToPathRating[chunk.id] or 1
end end
function chunkPropertyUtils.setPathRating(map, chunk, value) function ChunkPropertyUtils.setPathRating(map, chunk, value)
if (value == 1) then if (value == 1) then
map.chunkToPathRating[chunk.id] = nil map.chunkToPathRating[chunk.id] = nil
else else
@@ -455,11 +460,11 @@ function chunkPropertyUtils.setPathRating(map, chunk, value)
end end
end end
function chunkPropertyUtils.getDeathGeneratorRating(map, chunk) function ChunkPropertyUtils.getDeathGeneratorRating(map, chunk)
return 1 + (map.chunkToDeathGenerator[chunk.id] or 0) return 1 + (map.chunkToDeathGenerator[chunk.id] or 0)
end end
function chunkPropertyUtils.getCombinedDeathGeneratorRating(map, chunk) function ChunkPropertyUtils.getCombinedDeathGeneratorRating(map, chunk)
local amount = 1 + ((map.chunkToDeathGenerator[chunk.id] or 0) + (map.chunkToPermanentDeathGenerator[chunk.id] or 0)) local amount = 1 + ((map.chunkToDeathGenerator[chunk.id] or 0) + (map.chunkToPermanentDeathGenerator[chunk.id] or 0))
if (amount > 1) then if (amount > 1) then
return 1 return 1
@@ -470,15 +475,15 @@ function chunkPropertyUtils.getCombinedDeathGeneratorRating(map, chunk)
end end
end end
function chunkPropertyUtils.getDeathGenerator(map, chunk) function ChunkPropertyUtils.getDeathGenerator(map, chunk)
return map.chunkToDeathGenerator[chunk.id] or 0 return map.chunkToDeathGenerator[chunk.id] or 0
end end
function chunkPropertyUtils.getPermanentDeathGeneratorRating(map, chunk) function ChunkPropertyUtils.getPermanentDeathGeneratorRating(map, chunk)
return 1 + (map.chunkToPermanentDeathGenerator[chunk.id] or 0) return 1 + (map.chunkToPermanentDeathGenerator[chunk.id] or 0)
end end
function chunkPropertyUtils.getCombinedDeathGenerator(map, chunk) function ChunkPropertyUtils.getCombinedDeathGenerator(map, chunk)
local amount = (map.chunkToDeathGenerator[chunk.id] or 0) + (map.chunkToPermanentDeathGenerator[chunk.id] or 0) local amount = (map.chunkToDeathGenerator[chunk.id] or 0) + (map.chunkToPermanentDeathGenerator[chunk.id] or 0)
if (amount > 1) then if (amount > 1) then
return 1 return 1
@@ -489,7 +494,7 @@ function chunkPropertyUtils.getCombinedDeathGenerator(map, chunk)
end end
end end
function chunkPropertyUtils.addPermanentDeathGenerator(map, chunk, amount) function ChunkPropertyUtils.addPermanentDeathGenerator(map, chunk, amount)
local adjustedAmount = (amount * 0.25) + (map.chunkToPermanentDeathGenerator[chunk.id] or 0) local adjustedAmount = (amount * 0.25) + (map.chunkToPermanentDeathGenerator[chunk.id] or 0)
if (adjustedAmount > 0.75) then if (adjustedAmount > 0.75) then
map.chunkToPermanentDeathGenerator[chunk.id] = 0.75 map.chunkToPermanentDeathGenerator[chunk.id] = 0.75
@@ -500,7 +505,7 @@ function chunkPropertyUtils.addPermanentDeathGenerator(map, chunk, amount)
end end
end end
function chunkPropertyUtils.addDeathGenerator(map, chunk, value) function ChunkPropertyUtils.addDeathGenerator(map, chunk, value)
local currentAmount = (map.chunkToDeathGenerator[chunk.id] or 0) + value local currentAmount = (map.chunkToDeathGenerator[chunk.id] or 0) + value
if (currentAmount > 1) then if (currentAmount > 1) then
map.chunkToDeathGenerator[chunk.id] = 1 map.chunkToDeathGenerator[chunk.id] = 1
@@ -511,7 +516,7 @@ function chunkPropertyUtils.addDeathGenerator(map, chunk, value)
end end
end end
function chunkPropertyUtils.setDeathGenerator(map, chunk, value) function ChunkPropertyUtils.setDeathGenerator(map, chunk, value)
if (value > 1) then if (value > 1) then
map.chunkToDeathGenerator[chunk.id] = 1 map.chunkToDeathGenerator[chunk.id] = 1
elseif (value < -1) then elseif (value < -1) then
@@ -521,8 +526,8 @@ function chunkPropertyUtils.setDeathGenerator(map, chunk, value)
end end
end end
function chunkPropertyUtils.addVictoryGenerator(map, chunk, value) function ChunkPropertyUtils.addVictoryGenerator(map, chunk, value)
local cToV = map.universe.chunkToVictory local cToV = Universe.chunkToVictory
local chunkId = chunk.id local chunkId = chunk.id
if not cToV[chunkId] then if not cToV[chunkId] then
cToV[chunkId] = { cToV[chunkId] = {
@@ -533,7 +538,7 @@ function chunkPropertyUtils.addVictoryGenerator(map, chunk, value)
cToV[chunkId].v = cToV[chunkId].v + value cToV[chunkId].v = cToV[chunkId].v + value
end end
function chunkPropertyUtils.decayDeathGenerator(map, chunk) function ChunkPropertyUtils.decayDeathGenerator(map, chunk)
local gen = map.chunkToDeathGenerator[chunk.id] local gen = map.chunkToDeathGenerator[chunk.id]
if gen then if gen then
local v = gen * MOVEMENT_GENERATOR_PERSISTANCE local v = gen * MOVEMENT_GENERATOR_PERSISTANCE
@@ -545,7 +550,7 @@ function chunkPropertyUtils.decayDeathGenerator(map, chunk)
end end
end end
function chunkPropertyUtils.decayPlayerGenerator(map, chunk) function ChunkPropertyUtils.decayPlayerGenerator(map, chunk)
local gen = map.chunkToPlayerGenerator[chunk.id] local gen = map.chunkToPlayerGenerator[chunk.id]
if gen then if gen then
local v = gen * PLAYER_GENERATOR_PERSISTANCE local v = gen * PLAYER_GENERATOR_PERSISTANCE
@@ -557,7 +562,7 @@ function chunkPropertyUtils.decayPlayerGenerator(map, chunk)
end end
end end
function chunkPropertyUtils.addPlayerGenerator(map, chunk, playerMaxGenerator) function ChunkPropertyUtils.addPlayerGenerator(map, chunk, playerMaxGenerator)
local value = map.chunkToPlayerGenerator[chunk.id] local value = map.chunkToPlayerGenerator[chunk.id]
if value then if value then
map.chunkToPlayerGenerator[chunk.id] = mMin( map.chunkToPlayerGenerator[chunk.id] = mMin(
@@ -569,19 +574,19 @@ function chunkPropertyUtils.addPlayerGenerator(map, chunk, playerMaxGenerator)
end end
end end
function chunkPropertyUtils.getPlayerGenerator(map, chunk) function ChunkPropertyUtils.getPlayerGenerator(map, chunk)
return map.chunkToPlayerGenerator[chunk.id] or 0 return map.chunkToPlayerGenerator[chunk.id] or 0
end end
function chunkPropertyUtils.getPlayerBaseGenerator(map, chunk) function ChunkPropertyUtils.getPlayerBaseGenerator(map, chunk)
return map.chunkToPlayerBase[chunk.id] or 0 return map.chunkToPlayerBase[chunk.id] or 0
end end
function chunkPropertyUtils.addSquadToChunk(map, chunk, squad) function ChunkPropertyUtils.addSquadToChunk(map, chunk, squad)
local chunkToSquad = map.chunkToSquad local chunkToSquad = map.chunkToSquad
if (chunk ~= -1) and ((squad.chunk == -1) or (squad.chunk.id ~= chunk.id)) then if (chunk ~= -1) and ((squad.chunk == -1) or (squad.chunk.id ~= chunk.id)) then
chunkPropertyUtils.removeSquadFromChunk(map, squad) ChunkPropertyUtils.removeSquadFromChunk(map, squad)
local squads = chunkToSquad[chunk.id] local squads = chunkToSquad[chunk.id]
if not squads then if not squads then
squads = {} squads = {}
@@ -592,25 +597,25 @@ function chunkPropertyUtils.addSquadToChunk(map, chunk, squad)
end end
end end
function chunkPropertyUtils.removeSquadFromChunk(map, squad) function ChunkPropertyUtils.removeSquadFromChunk(map, squad)
local chunkToSquad = map.chunkToSquad local chunkToSquad = map.chunkToSquad
local chunk = squad.chunk local chunk = squad.chunk
if (chunk ~= -1) then if (chunk ~= -1) then
local squads = chunkToSquad[chunk.id] local squads = chunkToSquad[chunk.id]
if squads then if squads then
squads[squad.groupNumber] = nil squads[squad.groupNumber] = nil
if (table_size(squads) == 0) then if (tableSize(squads) == 0) then
chunkToSquad[chunk.id] = nil chunkToSquad[chunk.id] = nil
end end
end end
end end
end end
function chunkPropertyUtils.getSquadsOnChunk(map, chunk) function ChunkPropertyUtils.getSquadsOnChunk(map, chunk)
return map.chunkToSquad[chunk.id] or map.emptySquadsOnChunk return map.chunkToSquad[chunk.id] or map.emptySquadsOnChunk
end end
function chunkPropertyUtils.setPlayerBaseGenerator(map, chunk, playerGenerator) function ChunkPropertyUtils.setPlayerBaseGenerator(map, chunk, playerGenerator)
if (playerGenerator <= 0) then if (playerGenerator <= 0) then
map.chunkToPlayerBase[chunk.id] = nil map.chunkToPlayerBase[chunk.id] = nil
return 0 return 0
@@ -620,7 +625,7 @@ function chunkPropertyUtils.setPlayerBaseGenerator(map, chunk, playerGenerator)
end end
end end
function chunkPropertyUtils.addPlayerBaseGenerator(map, chunk, playerGenerator) function ChunkPropertyUtils.addPlayerBaseGenerator(map, chunk, playerGenerator)
local amount = (map.chunkToPlayerBase[chunk.id] or 0) + playerGenerator local amount = (map.chunkToPlayerBase[chunk.id] or 0) + playerGenerator
if amount <= 0 then if amount <= 0 then
map.chunkToPlayerBase[chunk.id] = nil map.chunkToPlayerBase[chunk.id] = nil
@@ -631,11 +636,11 @@ function chunkPropertyUtils.addPlayerBaseGenerator(map, chunk, playerGenerator)
end end
end end
function chunkPropertyUtils.findNearbyBase(map, chunk) function ChunkPropertyUtils.findNearbyBase(map, chunk)
local x = chunk.x local x = chunk.x
local y = chunk.y local y = chunk.y
local foundBase = chunkPropertyUtils.getChunkBase(map, chunk) local foundBase = ChunkPropertyUtils.getChunkBase(map, chunk)
if foundBase then if foundBase then
return foundBase return foundBase
end end
@@ -652,7 +657,7 @@ function chunkPropertyUtils.findNearbyBase(map, chunk)
return foundBase return foundBase
end end
function chunkPropertyUtils.findNearbyBaseByPosition(map, x, y) function ChunkPropertyUtils.findNearbyBaseByPosition(map, x, y)
local foundBase local foundBase
local closest = MAGIC_MAXIMUM_NUMBER local closest = MAGIC_MAXIMUM_NUMBER
@@ -667,47 +672,46 @@ function chunkPropertyUtils.findNearbyBaseByPosition(map, x, y)
return foundBase return foundBase
end end
function chunkPropertyUtils.processNestActiveness(map, chunk) function ChunkPropertyUtils.processNestActiveness(map, chunk)
local nests = chunkPropertyUtils.getNestCount(map, chunk) local nests = ChunkPropertyUtils.getNestCount(chunk)
local base = chunkPropertyUtils.findNearbyBase(map, chunk) local base = ChunkPropertyUtils.findNearbyBase(map, chunk)
if (nests > 0) then if (nests > 0) then
local surface = map.surface local surface = map.surface
local activeness = chunkPropertyUtils.getNestActiveness(map, chunk) local activeness = ChunkPropertyUtils.getNestActiveness(chunk)
local universe = map.universe local raidActiveness = ChunkPropertyUtils.getRaidNestActiveness(chunk)
local raidActiveness = chunkPropertyUtils.getRaidNestActiveness(map, chunk) if Universe.attackUsePlayer and (chunk[PLAYER_PHEROMONE] > Universe.attackPlayerThreshold) then
if universe.attackUsePlayer and (chunk[PLAYER_PHEROMONE] > universe.attackPlayerThreshold) then ChunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base)
chunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base)
elseif (chunk[BASE_PHEROMONE] > 0) then elseif (chunk[BASE_PHEROMONE] > 0) then
if (surface.get_pollution(chunk) > 0) then if (surface.get_pollution(chunk) > 0) then
chunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base) ChunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base)
else else
local x = chunk.x local x = chunk.x
local y = chunk.y local y = chunk.y
local position = {x=0,y=0} local position = {x=0,y=0}
local pollutionThreshold = universe.pollutionDiffuseMinimum local pollutionThreshold = Universe.pollutionDiffuseMinimum
position.x = x + 32 position.x = x + 32
position.y = y position.y = y
if (surface.get_pollution(position) > pollutionThreshold) then if (surface.get_pollution(position) > pollutionThreshold) then
chunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base) ChunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base)
else else
position.x = x - 32 position.x = x - 32
if (surface.get_pollution(position) > pollutionThreshold) then if (surface.get_pollution(position) > pollutionThreshold) then
chunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base) ChunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base)
else else
position.x = x position.x = x
position.y = y - 32 position.y = y - 32
if (surface.get_pollution(position) > pollutionThreshold) then if (surface.get_pollution(position) > pollutionThreshold) then
chunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base) ChunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base)
else else
position.y = y + 32 position.y = y + 32
if (surface.get_pollution(position) > pollutionThreshold) then if (surface.get_pollution(position) > pollutionThreshold) then
chunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base) ChunkPropertyUtils.setNestActiveness(map, chunk, mMin(activeness + 5, 20), base)
else else
chunkPropertyUtils.setNestActiveness(map, chunk, activeness - 2, base) ChunkPropertyUtils.setNestActiveness(map, chunk, activeness - 2, base)
if (chunk[BASE_PHEROMONE] > RAIDING_MINIMUM_BASE_THRESHOLD) then if (chunk[BASE_PHEROMONE] > RAIDING_MINIMUM_BASE_THRESHOLD) then
chunkPropertyUtils.setRaidNestActiveness(map, chunk, mMin(raidActiveness + 3, 20), base) ChunkPropertyUtils.setRaidNestActiveness(map, chunk, mMin(raidActiveness + 3, 20), base)
else else
chunkPropertyUtils.setRaidNestActiveness(map, chunk, raidActiveness - 1, base) ChunkPropertyUtils.setRaidNestActiveness(map, chunk, raidActiveness - 1, base)
end end
end end
end end
@@ -715,15 +719,18 @@ function chunkPropertyUtils.processNestActiveness(map, chunk)
end end
end end
else else
chunkPropertyUtils.setNestActiveness(map, chunk, activeness - 5, base) ChunkPropertyUtils.setNestActiveness(map, chunk, activeness - 5, base)
chunkPropertyUtils.setRaidNestActiveness(map, chunk, raidActiveness - 5, base) ChunkPropertyUtils.setRaidNestActiveness(map, chunk, raidActiveness - 5, base)
end end
elseif base then elseif base then
chunkPropertyUtils.setNestActiveness(map, chunk, 0, base) ChunkPropertyUtils.setNestActiveness(map, chunk, 0, base)
chunkPropertyUtils.setRaidNestActiveness(map, chunk, 0, base) ChunkPropertyUtils.setRaidNestActiveness(map, chunk, 0, base)
end end
end end
function ChunkPropertyUtils.init(universe)
Universe = universe
end
chunkPropertyUtilsG = chunkPropertyUtils ChunkPropertyUtilsG = ChunkPropertyUtils
return chunkPropertyUtils return ChunkPropertyUtils

View File

@@ -14,104 +14,109 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
if chunkUtilsG then if ChunkUtilsG then
return chunkUtilsG return ChunkUtilsG
end end
local chunkUtils = {} local ChunkUtils = {}
--
local Universe
local ChunkOverlapArray
-- imports -- imports
local baseUtils = require("BaseUtils") local BaseUtils = require("BaseUtils")
local constants = require("Constants") local Constants = require("Constants")
local mapUtils = require("MapUtils") local MapUtils = require("MapUtils")
local chunkPropertyUtils = require("ChunkPropertyUtils") local ChunkPropertyUtils = require("ChunkPropertyUtils")
local mathUtils = require("MathUtils") local MathUtils = require("MathUtils")
local queryUtils = require("QueryUtils") local QueryUtils = require("QueryUtils")
-- constants -- Constants
local VANILLA_ENTITY_TYPE_LOOKUP = constants.VANILLA_ENTITY_TYPE_LOOKUP local VANILLA_ENTITY_TYPE_LOOKUP = Constants.VANILLA_ENTITY_TYPE_LOOKUP
local BUILDING_HIVE_TYPE_LOOKUP = constants.BUILDING_HIVE_TYPE_LOOKUP local BUILDING_HIVE_TYPE_LOOKUP = Constants.BUILDING_HIVE_TYPE_LOOKUP
local HIVE_BUILDINGS_TYPES = constants.HIVE_BUILDINGS_TYPES local HIVE_BUILDINGS_TYPES = Constants.HIVE_BUILDINGS_TYPES
local DEFINES_WIRE_TYPE_RED = defines.wire_type.red local DEFINES_WIRE_TYPE_RED = defines.wire_type.red
local DEFINES_WIRE_TYPE_GREEN = defines.wire_type.green local DEFINES_WIRE_TYPE_GREEN = defines.wire_type.green
local BASE_AI_STATE_ONSLAUGHT = constants.BASE_AI_STATE_ONSLAUGHT local BASE_AI_STATE_ONSLAUGHT = Constants.BASE_AI_STATE_ONSLAUGHT
local BASE_PHEROMONE = constants.BASE_PHEROMONE local BASE_PHEROMONE = Constants.BASE_PHEROMONE
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE local PLAYER_PHEROMONE = Constants.PLAYER_PHEROMONE
local RESOURCE_PHEROMONE = constants.RESOURCE_PHEROMONE local RESOURCE_PHEROMONE = Constants.RESOURCE_PHEROMONE
local ENEMY_PHEROMONE = constants.ENEMY_PHEROMONE local ENEMY_PHEROMONE = Constants.ENEMY_PHEROMONE
local BUILDING_PHEROMONES = constants.BUILDING_PHEROMONES local BUILDING_PHEROMONES = Constants.BUILDING_PHEROMONES
local CHUNK_SIZE = constants.CHUNK_SIZE local CHUNK_SIZE = Constants.CHUNK_SIZE
local CHUNK_SIZE_DIVIDER = constants.CHUNK_SIZE_DIVIDER local CHUNK_SIZE_DIVIDER = Constants.CHUNK_SIZE_DIVIDER
local CHUNK_NORTH_SOUTH = constants.CHUNK_NORTH_SOUTH local CHUNK_NORTH_SOUTH = Constants.CHUNK_NORTH_SOUTH
local CHUNK_EAST_WEST = constants.CHUNK_EAST_WEST local CHUNK_EAST_WEST = Constants.CHUNK_EAST_WEST
local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS local CHUNK_ALL_DIRECTIONS = Constants.CHUNK_ALL_DIRECTIONS
local CHUNK_IMPASSABLE = constants.CHUNK_IMPASSABLE local CHUNK_IMPASSABLE = Constants.CHUNK_IMPASSABLE
local RESOURCE_NORMALIZER = constants.RESOURCE_NORMALIZER local RESOURCE_NORMALIZER = Constants.RESOURCE_NORMALIZER
local CHUNK_TICK = constants.CHUNK_TICK local CHUNK_TICK = Constants.CHUNK_TICK
local GENERATOR_PHEROMONE_LEVEL_1 = constants.GENERATOR_PHEROMONE_LEVEL_1 local GENERATOR_PHEROMONE_LEVEL_1 = Constants.GENERATOR_PHEROMONE_LEVEL_1
local GENERATOR_PHEROMONE_LEVEL_3 = constants.GENERATOR_PHEROMONE_LEVEL_3 local GENERATOR_PHEROMONE_LEVEL_3 = Constants.GENERATOR_PHEROMONE_LEVEL_3
local GENERATOR_PHEROMONE_LEVEL_5 = constants.GENERATOR_PHEROMONE_LEVEL_5 local GENERATOR_PHEROMONE_LEVEL_5 = Constants.GENERATOR_PHEROMONE_LEVEL_5
local GENERATOR_PHEROMONE_LEVEL_6 = constants.GENERATOR_PHEROMONE_LEVEL_6 local GENERATOR_PHEROMONE_LEVEL_6 = Constants.GENERATOR_PHEROMONE_LEVEL_6
-- imported functions -- imported functions
local removeBaseResourceChunk = chunkPropertyUtils.removeBaseResourceChunk local removeBaseResourceChunk = ChunkPropertyUtils.removeBaseResourceChunk
local addBaseResourceChunk = chunkPropertyUtils.addBaseResourceChunk local addBaseResourceChunk = ChunkPropertyUtils.addBaseResourceChunk
local setAreaInQueryChunkSize = queryUtils.setAreaInQueryChunkSize local setAreaInQueryChunkSize = QueryUtils.setAreaInQueryChunkSize
local setAreaXInQuery = queryUtils.setAreaXInQuery local setAreaXInQuery = QueryUtils.setAreaXInQuery
local setAreaYInQuery = queryUtils.setAreaYInQuery local setAreaYInQuery = QueryUtils.setAreaYInQuery
local setPlayerBaseGenerator = chunkPropertyUtils.setPlayerBaseGenerator local setPlayerBaseGenerator = ChunkPropertyUtils.setPlayerBaseGenerator
local addPlayerBaseGenerator = chunkPropertyUtils.addPlayerBaseGenerator local addPlayerBaseGenerator = ChunkPropertyUtils.addPlayerBaseGenerator
local setResourceGenerator = chunkPropertyUtils.setResourceGenerator local setResourceGenerator = ChunkPropertyUtils.setResourceGenerator
local addResourceGenerator = chunkPropertyUtils.addResourceGenerator local addResourceGenerator = ChunkPropertyUtils.addResourceGenerator
local addNestCount = chunkPropertyUtils.addNestCount local addNestCount = ChunkPropertyUtils.addNestCount
local removeNestCount = chunkPropertyUtils.removeNestCount local removeNestCount = ChunkPropertyUtils.removeNestCount
local addHiveCount = chunkPropertyUtils.addHiveCount local addHiveCount = ChunkPropertyUtils.addHiveCount
local removeHiveCount = chunkPropertyUtils.removeHiveCount local removeHiveCount = ChunkPropertyUtils.removeHiveCount
local addTrapCount = chunkPropertyUtils.addTrapCount local addTrapCount = ChunkPropertyUtils.addTrapCount
local removeTrapCount = chunkPropertyUtils.removeTrapCount local removeTrapCount = ChunkPropertyUtils.removeTrapCount
local addTurretCount = chunkPropertyUtils.addTurretCount local addTurretCount = ChunkPropertyUtils.addTurretCount
local removeTurretCount = chunkPropertyUtils.removeTurretCount local removeTurretCount = ChunkPropertyUtils.removeTurretCount
local addUtilityCount = chunkPropertyUtils.addUtilityCount local addUtilityCount = ChunkPropertyUtils.addUtilityCount
local removeUtilityCount = chunkPropertyUtils.removeUtilityCount local removeUtilityCount = ChunkPropertyUtils.removeUtilityCount
local getPlayerBaseGenerator = chunkPropertyUtils.getPlayerBaseGenerator local getPlayerBaseGenerator = ChunkPropertyUtils.getPlayerBaseGenerator
local setRaidNestActiveness = chunkPropertyUtils.setRaidNestActiveness local setRaidNestActiveness = ChunkPropertyUtils.setRaidNestActiveness
local setNestActiveness = chunkPropertyUtils.setNestActiveness local setNestActiveness = ChunkPropertyUtils.setNestActiveness
local getChunkById = mapUtils.getChunkById local getChunkById = MapUtils.getChunkById
local processNestActiveness = chunkPropertyUtils.processNestActiveness local processNestActiveness = ChunkPropertyUtils.processNestActiveness
local removeChunkBase = chunkPropertyUtils.removeChunkBase local removeChunkBase = ChunkPropertyUtils.removeChunkBase
local getEnemyStructureCount = chunkPropertyUtils.getEnemyStructureCount local getEnemyStructureCount = ChunkPropertyUtils.getEnemyStructureCount
local findNearbyBase = chunkPropertyUtils.findNearbyBase local findNearbyBase = ChunkPropertyUtils.findNearbyBase
local queueUpgrade = baseUtils.queueUpgrade local queueUpgrade = BaseUtils.queueUpgrade
local createBase = baseUtils.createBase local createBase = BaseUtils.createBase
local modifyBaseUnitPoints = baseUtils.modifyBaseUnitPoints local modifyBaseUnitPoints = BaseUtils.modifyBaseUnitPoints
local euclideanDistancePoints = mathUtils.euclideanDistancePoints local euclideanDistancePoints = MathUtils.euclideanDistancePoints
local getChunkBase = chunkPropertyUtils.getChunkBase local getChunkBase = ChunkPropertyUtils.getChunkBase
local setChunkBase = chunkPropertyUtils.setChunkBase local setChunkBase = ChunkPropertyUtils.setChunkBase
local setPassable = chunkPropertyUtils.setPassable local setPassable = ChunkPropertyUtils.setPassable
local setPathRating = chunkPropertyUtils.setPathRating local setPathRating = ChunkPropertyUtils.setPathRating
local getChunkByXY = mapUtils.getChunkByXY local getChunkByXY = MapUtils.getChunkByXY
local mMin = math.min local mMin = math.min
local mMax = math.max local mMax = math.max
@@ -121,12 +126,11 @@ local mFloor = math.floor
local function getEntityOverlapChunks(map, entity) local function getEntityOverlapChunks(map, entity)
local boundingBox = entity.prototype.collision_box or entity.prototype.selection_box local boundingBox = entity.prototype.collision_box or entity.prototype.selection_box
local overlapArray = map.universe.chunkOverlapArray
overlapArray[1] = -1 --LeftTop ChunkOverlapArray[1] = -1 --LeftTop
overlapArray[2] = -1 --RightTop ChunkOverlapArray[2] = -1 --RightTop
overlapArray[3] = -1 --LeftBottom ChunkOverlapArray[3] = -1 --LeftBottom
overlapArray[4] = -1 --RightBottom ChunkOverlapArray[4] = -1 --RightBottom
if boundingBox then if boundingBox then
local center = entity.position local center = entity.position
@@ -143,18 +147,18 @@ local function getEntityOverlapChunks(map, entity)
local rightTopChunkX = mFloor((center.x + bottomXOffset) * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE local rightTopChunkX = mFloor((center.x + bottomXOffset) * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
local leftBottomChunkY = mFloor((center.y + bottomYOffset) * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE local leftBottomChunkY = mFloor((center.y + bottomYOffset) * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
overlapArray[1] = getChunkByXY(map, leftTopChunkX, leftTopChunkY) -- LeftTop ChunkOverlapArray[1] = getChunkByXY(map, leftTopChunkX, leftTopChunkY) -- LeftTop
if (leftTopChunkX ~= rightTopChunkX) then if (leftTopChunkX ~= rightTopChunkX) then
overlapArray[2] = getChunkByXY(map, rightTopChunkX, leftTopChunkY) -- RightTop ChunkOverlapArray[2] = getChunkByXY(map, rightTopChunkX, leftTopChunkY) -- RightTop
end end
if (leftTopChunkY ~= leftBottomChunkY) then if (leftTopChunkY ~= leftBottomChunkY) then
overlapArray[3] = getChunkByXY(map, leftTopChunkX, leftBottomChunkY) -- LeftBottom ChunkOverlapArray[3] = getChunkByXY(map, leftTopChunkX, leftBottomChunkY) -- LeftBottom
end end
if (leftTopChunkX ~= rightTopChunkX) and (leftTopChunkY ~= leftBottomChunkY) then if (leftTopChunkX ~= rightTopChunkX) and (leftTopChunkY ~= leftBottomChunkY) then
overlapArray[4] = getChunkByXY(map, rightTopChunkX, leftBottomChunkY) -- RightBottom ChunkOverlapArray[4] = getChunkByXY(map, rightTopChunkX, leftBottomChunkY) -- RightBottom
end end
end end
return overlapArray return ChunkOverlapArray
end end
local function scanPaths(chunk, map) local function scanPaths(chunk, map)
@@ -164,9 +168,8 @@ local function scanPaths(chunk, map)
local x = chunk.x local x = chunk.x
local y = chunk.y local y = chunk.y
local universe = map.universe local filteredEntitiesCliffQuery = Universe.spFilteredEntitiesCliffQuery
local filteredEntitiesCliffQuery = universe.spFilteredEntitiesCliffQuery local filteredTilesPathQuery = Universe.spFilteredTilesPathQuery
local filteredTilesPathQuery = universe.spFilteredTilesPathQuery
local count_entities_filtered = surface.count_entities_filtered local count_entities_filtered = surface.count_entities_filtered
local count_tiles_filtered = surface.count_tiles_filtered local count_tiles_filtered = surface.count_tiles_filtered
@@ -209,23 +212,21 @@ end
local function scorePlayerBuildings(map, chunk) local function scorePlayerBuildings(map, chunk)
local surface = map.surface local surface = map.surface
local universe = map.universe setAreaInQueryChunkSize(Universe.spbHasPlayerStructuresQuery, chunk)
setAreaInQueryChunkSize(universe.spbHasPlayerStructuresQuery, chunk) if surface.count_entities_filtered(Universe.spbHasPlayerStructuresQuery) > 0 then
if surface.count_entities_filtered(universe.spbHasPlayerStructuresQuery) > 0 then return (surface.count_entities_filtered(Universe.spbFilteredEntitiesPlayerQueryLowest) * GENERATOR_PHEROMONE_LEVEL_1) +
return (surface.count_entities_filtered(universe.spbFilteredEntitiesPlayerQueryLowest) * GENERATOR_PHEROMONE_LEVEL_1) + (surface.count_entities_filtered(Universe.spbFilteredEntitiesPlayerQueryLow) * GENERATOR_PHEROMONE_LEVEL_3) +
(surface.count_entities_filtered(universe.spbFilteredEntitiesPlayerQueryLow) * GENERATOR_PHEROMONE_LEVEL_3) + (surface.count_entities_filtered(Universe.spbFilteredEntitiesPlayerQueryHigh) * GENERATOR_PHEROMONE_LEVEL_5) +
(surface.count_entities_filtered(universe.spbFilteredEntitiesPlayerQueryHigh) * GENERATOR_PHEROMONE_LEVEL_5) + (surface.count_entities_filtered(Universe.spbFilteredEntitiesPlayerQueryHighest) * GENERATOR_PHEROMONE_LEVEL_6)
(surface.count_entities_filtered(universe.spbFilteredEntitiesPlayerQueryHighest) * GENERATOR_PHEROMONE_LEVEL_6)
end end
return 0 return 0
end end
function chunkUtils.initialScan(chunk, map, tick) function ChunkUtils.initialScan(chunk, map, tick)
local surface = map.surface local surface = map.surface
local universe = map.universe setAreaInQueryChunkSize(Universe.isFilteredTilesQuery, chunk)
setAreaInQueryChunkSize(universe.isFilteredTilesQuery, chunk)
local pass = scanPaths(chunk, map) local pass = scanPaths(chunk, map)
local enemyBuildings = surface.find_entities_filtered(universe.isFilteredEntitiesEnemyStructureQuery) local enemyBuildings = surface.find_entities_filtered(Universe.isFilteredEntitiesEnemyStructureQuery)
local playerObjects = scorePlayerBuildings(map, chunk) local playerObjects = scorePlayerBuildings(map, chunk)
if (pass ~= CHUNK_IMPASSABLE) or (#enemyBuildings > 0) or (playerObjects > 0) then if (pass ~= CHUNK_IMPASSABLE) or (#enemyBuildings > 0) or (playerObjects > 0) then
@@ -235,16 +236,16 @@ function chunkUtils.initialScan(chunk, map, tick)
if (pass ~= CHUNK_IMPASSABLE) then if (pass ~= CHUNK_IMPASSABLE) then
local neutralObjects = mMax(0, local neutralObjects = mMax(0,
mMin(1 - (surface.count_entities_filtered(universe.isFilteredEntitiesChunkNeutral) * 0.005), mMin(1 - (surface.count_entities_filtered(Universe.isFilteredEntitiesChunkNeutral) * 0.005),
1) * 0.20) 1) * 0.20)
setPassable(map, chunk, pass) setPassable(map, chunk, pass)
local waterTiles = (1 - (surface.count_tiles_filtered(universe.isFilteredTilesQuery) * 0.0009765625)) * 0.80 local waterTiles = (1 - (surface.count_tiles_filtered(Universe.isFilteredTilesQuery) * 0.0009765625)) * 0.80
setPathRating(map, chunk, waterTiles + neutralObjects) setPathRating(map, chunk, waterTiles + neutralObjects)
setPlayerBaseGenerator(map, chunk, playerObjects) setPlayerBaseGenerator(map, chunk, playerObjects)
local resources = surface.count_entities_filtered(universe.isCountResourcesQuery) * RESOURCE_NORMALIZER local resources = surface.count_entities_filtered(Universe.isCountResourcesQuery) * RESOURCE_NORMALIZER
setResourceGenerator(map, chunk, resources) setResourceGenerator(map, chunk, resources)
local counts = map.chunkScanCounts local counts = map.chunkScanCounts
@@ -258,8 +259,8 @@ function chunkUtils.initialScan(chunk, map, tick)
base = createBase(map, chunk, tick) base = createBase(map, chunk, tick)
end end
if universe.NEW_ENEMIES then if Universe.NEW_ENEMIES then
local unitList = surface.find_entities_filtered(universe.isFilteredEntitiesUnitQuery) local unitList = surface.find_entities_filtered(Universe.isFilteredEntitiesUnitQuery)
for i=1,#unitList do for i=1,#unitList do
local unit = unitList[i] local unit = unitList[i]
if (unit.valid) then if (unit.valid) then
@@ -269,7 +270,7 @@ function chunkUtils.initialScan(chunk, map, tick)
for i = 1, #enemyBuildings do for i = 1, #enemyBuildings do
local enemyBuilding = enemyBuildings[i] local enemyBuilding = enemyBuildings[i]
chunkUtils.registerEnemyBaseStructure(map, enemyBuilding, base) ChunkUtils.registerEnemyBaseStructure(map, enemyBuilding, base)
local entityName = enemyBuilding.name local entityName = enemyBuilding.name
local isVanilla = VANILLA_ENTITY_TYPE_LOOKUP[entityName] local isVanilla = VANILLA_ENTITY_TYPE_LOOKUP[entityName]
if isVanilla or (not isVanilla and not BUILDING_HIVE_TYPE_LOOKUP[entityName]) then if isVanilla or (not isVanilla and not BUILDING_HIVE_TYPE_LOOKUP[entityName]) then
@@ -283,7 +284,7 @@ function chunkUtils.initialScan(chunk, map, tick)
else else
for i=1,#enemyBuildings do for i=1,#enemyBuildings do
local building = enemyBuildings[i] local building = enemyBuildings[i]
chunkUtils.registerEnemyBaseStructure(map, building, base) ChunkUtils.registerEnemyBaseStructure(map, building, base)
end end
end end
end end
@@ -295,19 +296,18 @@ function chunkUtils.initialScan(chunk, map, tick)
return -1 return -1
end end
function chunkUtils.chunkPassScan(chunk, map) function ChunkUtils.chunkPassScan(chunk, map)
local surface = map.surface local surface = map.surface
local universe = map.universe setAreaInQueryChunkSize(Universe.cpsFilteredTilesQuery, chunk)
setAreaInQueryChunkSize(universe.cpsFilteredTilesQuery, chunk)
local pass = scanPaths(chunk, map) local pass = scanPaths(chunk, map)
local enemyCount = surface.count_entities_filtered(universe.cpsFilteredEnemyAnyFound) local enemyCount = surface.count_entities_filtered(Universe.cpsFilteredEnemyAnyFound)
local playerObjects = getPlayerBaseGenerator(map, chunk) local playerObjects = getPlayerBaseGenerator(map, chunk)
if (pass ~= CHUNK_IMPASSABLE) or (enemyCount > 0) or (playerObjects > 0) then if (pass ~= CHUNK_IMPASSABLE) or (enemyCount > 0) or (playerObjects > 0) then
local neutralObjects = mMax(0, local neutralObjects = mMax(0,
mMin(1 - (surface.count_entities_filtered(universe.cpsFilteredEntitiesChunkNeutral) * 0.005), mMin(1 - (surface.count_entities_filtered(Universe.cpsFilteredEntitiesChunkNeutral) * 0.005),
1) * 0.20) 1) * 0.20)
local waterTiles = (1 - (surface.count_tiles_filtered(universe.cpsFilteredTilesQuery) * 0.0009765625)) * 0.80 local waterTiles = (1 - (surface.count_tiles_filtered(Universe.cpsFilteredTilesQuery) * 0.0009765625)) * 0.80
if ((playerObjects > 0) or (enemyCount > 0)) and (pass == CHUNK_IMPASSABLE) then if ((playerObjects > 0) or (enemyCount > 0)) and (pass == CHUNK_IMPASSABLE) then
pass = CHUNK_ALL_DIRECTIONS pass = CHUNK_ALL_DIRECTIONS
@@ -322,28 +322,26 @@ function chunkUtils.chunkPassScan(chunk, map)
return -1 return -1
end end
function chunkUtils.mapScanPlayerChunk(chunk, map) function ChunkUtils.mapScanPlayerChunk(chunk, map)
local playerObjects = scorePlayerBuildings(map, chunk) local playerObjects = scorePlayerBuildings(map, chunk)
setPlayerBaseGenerator(map, chunk, playerObjects) setPlayerBaseGenerator(map, chunk, playerObjects)
end end
function chunkUtils.mapScanResourceChunk(chunk, map) function ChunkUtils.mapScanResourceChunk(chunk, map)
local universe = map.universe setAreaInQueryChunkSize(Universe.msrcCountResourcesQuery, chunk)
setAreaInQueryChunkSize(universe.msrcCountResourcesQuery, chunk)
local surface = map.surface local surface = map.surface
local resources = surface.count_entities_filtered(universe.msrcCountResourcesQuery) * RESOURCE_NORMALIZER local resources = surface.count_entities_filtered(Universe.msrcCountResourcesQuery) * RESOURCE_NORMALIZER
setResourceGenerator(map, chunk, resources) setResourceGenerator(map, chunk, resources)
local waterTiles = (1 - (surface.count_tiles_filtered(universe.msrcFilteredTilesQuery) * 0.0009765625)) * 0.80 local waterTiles = (1 - (surface.count_tiles_filtered(Universe.msrcFilteredTilesQuery) * 0.0009765625)) * 0.80
local neutralObjects = mMax(0, local neutralObjects = mMax(0,
mMin(1 - (surface.count_entities_filtered(universe.msrcFilteredEntitiesChunkNeutral) * 0.005), mMin(1 - (surface.count_entities_filtered(Universe.msrcFilteredEntitiesChunkNeutral) * 0.005),
1) * 0.20) 1) * 0.20)
setPathRating(map, chunk, waterTiles + neutralObjects) setPathRating(map, chunk, waterTiles + neutralObjects)
end end
function chunkUtils.mapScanEnemyChunk(chunk, map, tick) function ChunkUtils.mapScanEnemyChunk(chunk, map, tick)
local universe = map.universe setAreaInQueryChunkSize(Universe.msecFilteredEntitiesEnemyStructureQuery, chunk)
setAreaInQueryChunkSize(universe.msecFilteredEntitiesEnemyStructureQuery, chunk) local buildings = map.surface.find_entities_filtered(Universe.msecFilteredEntitiesEnemyStructureQuery)
local buildings = map.surface.find_entities_filtered(universe.msecFilteredEntitiesEnemyStructureQuery)
local counts = map.chunkScanCounts local counts = map.chunkScanCounts
for i=1,#HIVE_BUILDINGS_TYPES do for i=1,#HIVE_BUILDINGS_TYPES do
counts[HIVE_BUILDINGS_TYPES[i]] = 0 counts[HIVE_BUILDINGS_TYPES[i]] = 0
@@ -356,16 +354,16 @@ function chunkUtils.mapScanEnemyChunk(chunk, map, tick)
for i=1,#buildings do for i=1,#buildings do
local building = buildings[i] local building = buildings[i]
chunkUtils.registerEnemyBaseStructure(map, building, base) ChunkUtils.registerEnemyBaseStructure(map, building, base)
end end
end end
end end
function chunkUtils.addBasesToAllEnemyStructures(universe, tick) function ChunkUtils.addBasesToAllEnemyStructures(tick)
for chunkId, chunkPack in pairs(universe.chunkToNests) do for chunkId, chunkPack in pairs(Universe.chunkToNests) do
local map = chunkPack.map local map = chunkPack.map
if map.surface.valid then if map.surface.valid then
local chunk = getChunkById(map, chunkId) local chunk = getChunkById(chunkId)
local base = findNearbyBase(map, chunk) local base = findNearbyBase(map, chunk)
if not base then if not base then
base = createBase(map, chunk, tick) base = createBase(map, chunk, tick)
@@ -373,10 +371,10 @@ function chunkUtils.addBasesToAllEnemyStructures(universe, tick)
setChunkBase(map, chunk, base) setChunkBase(map, chunk, base)
end end
end end
for _, map in pairs(universe.maps) do for _, map in pairs(Universe.maps) do
if map.surface.valid then if map.surface.valid then
for chunkId in pairs(map.chunkToTurrets) do for chunkId in pairs(map.chunkToTurrets) do
local chunk = getChunkById(map, chunkId) local chunk = getChunkById(chunkId)
local base = findNearbyBase(map, chunk) local base = findNearbyBase(map, chunk)
if not base then if not base then
base = createBase(map, chunk, tick) base = createBase(map, chunk, tick)
@@ -384,7 +382,7 @@ function chunkUtils.addBasesToAllEnemyStructures(universe, tick)
setChunkBase(map, chunk, base) setChunkBase(map, chunk, base)
end end
for chunkId in pairs(map.chunkToHives) do for chunkId in pairs(map.chunkToHives) do
local chunk = getChunkById(map, chunkId) local chunk = getChunkById(chunkId)
local base = findNearbyBase(map, chunk) local base = findNearbyBase(map, chunk)
if not base then if not base then
base = createBase(map, chunk, tick) base = createBase(map, chunk, tick)
@@ -392,7 +390,7 @@ function chunkUtils.addBasesToAllEnemyStructures(universe, tick)
setChunkBase(map, chunk, base) setChunkBase(map, chunk, base)
end end
for chunkId in pairs(map.chunkToUtilities) do for chunkId in pairs(map.chunkToUtilities) do
local chunk = getChunkById(map, chunkId) local chunk = getChunkById(chunkId)
local base = findNearbyBase(map, chunk) local base = findNearbyBase(map, chunk)
if not base then if not base then
base = createBase(map, chunk, tick) base = createBase(map, chunk, tick)
@@ -400,7 +398,7 @@ function chunkUtils.addBasesToAllEnemyStructures(universe, tick)
setChunkBase(map, chunk, base) setChunkBase(map, chunk, base)
end end
for chunkId in pairs(map.chunkToTraps) do for chunkId in pairs(map.chunkToTraps) do
local chunk = getChunkById(map, chunkId) local chunk = getChunkById(chunkId)
local base = findNearbyBase(map, chunk) local base = findNearbyBase(map, chunk)
if not base then if not base then
base = createBase(map, chunk, tick) base = createBase(map, chunk, tick)
@@ -411,13 +409,13 @@ function chunkUtils.addBasesToAllEnemyStructures(universe, tick)
end end
end end
function chunkUtils.entityForPassScan(map, entity) function ChunkUtils.entityForPassScan(map, entity)
local overlapArray = getEntityOverlapChunks(map, entity) local overlapArray = getEntityOverlapChunks(map, entity)
for i=1,#overlapArray do for i=1,#overlapArray do
local chunk = overlapArray[i] local chunk = overlapArray[i]
if (chunk ~= -1) and not map.universe.chunkToPassScan[chunk.id] then if (chunk ~= -1) and not map.Universe.chunkToPassScan[chunk.id] then
map.universe.chunkToPassScan[chunk.id] = { map.Universe.chunkToPassScan[chunk.id] = {
map = map, map = map,
chunk = chunk chunk = chunk
} }
@@ -425,18 +423,18 @@ function chunkUtils.entityForPassScan(map, entity)
end end
end end
local function newChunkId(universe) local function newChunkId()
local id = universe.chunkId local id = Universe.chunkId
universe.chunkId = universe.chunkId + 1 Universe.chunkId = Universe.chunkId + 1
return id return id
end end
function chunkUtils.createChunk(map, topX, topY) function ChunkUtils.createChunk(map, topX, topY)
local chunk = { local chunk = {
x = topX, x = topX,
y = topY, y = topY,
dOrigin = euclideanDistancePoints(topX, topY, 0, 0), dOrigin = euclideanDistancePoints(topX, topY, 0, 0),
id = newChunkId(map.universe) id = newChunkId()
} }
chunk[BASE_PHEROMONE] = 0 chunk[BASE_PHEROMONE] = 0
chunk[PLAYER_PHEROMONE] = 0 chunk[PLAYER_PHEROMONE] = 0
@@ -447,7 +445,7 @@ function chunkUtils.createChunk(map, topX, topY)
return chunk return chunk
end end
function chunkUtils.colorChunk(chunk, surface, color, ttl) function ChunkUtils.colorChunk(chunk, surface, color, ttl)
local lx = math.floor(chunk.x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE local lx = math.floor(chunk.x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
local ly = math.floor(chunk.y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE local ly = math.floor(chunk.y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
@@ -464,7 +462,7 @@ function chunkUtils.colorChunk(chunk, surface, color, ttl)
}) })
end end
function chunkUtils.colorXY(x, y, surface, color) function ChunkUtils.colorXY(x, y, surface, color)
local lx = math.floor(x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE local lx = math.floor(x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
local ly = math.floor(y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE local ly = math.floor(y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
@@ -481,7 +479,7 @@ function chunkUtils.colorXY(x, y, surface, color)
}) })
end end
function chunkUtils.registerEnemyBaseStructure(map, entity, base, skipCount) function ChunkUtils.registerEnemyBaseStructure(map, entity, base, skipCount)
local entityType = entity.type local entityType = entity.type
local addFunc local addFunc
@@ -525,7 +523,7 @@ function chunkUtils.registerEnemyBaseStructure(map, entity, base, skipCount)
end end
end end
function chunkUtils.unregisterEnemyBaseStructure(map, entity, damageTypeName, skipCount) function ChunkUtils.unregisterEnemyBaseStructure(map, entity, damageTypeName, skipCount)
local entityType = entity.type local entityType = entity.type
local removeFunc local removeFunc
@@ -580,7 +578,7 @@ function chunkUtils.unregisterEnemyBaseStructure(map, entity, damageTypeName, sk
end end
end end
function chunkUtils.accountPlayerEntity(entity, map, addObject, base) function ChunkUtils.accountPlayerEntity(entity, map, addObject, base)
if (BUILDING_PHEROMONES[entity.type] ~= nil) and (entity.force.name ~= "enemy") then if (BUILDING_PHEROMONES[entity.type] ~= nil) and (entity.force.name ~= "enemy") then
local entityValue = BUILDING_PHEROMONES[entity.type] local entityValue = BUILDING_PHEROMONES[entity.type]
local overlapArray = getEntityOverlapChunks(map, entity) local overlapArray = getEntityOverlapChunks(map, entity)
@@ -612,7 +610,7 @@ function chunkUtils.accountPlayerEntity(entity, map, addObject, base)
return entity return entity
end end
function chunkUtils.unregisterResource(entity, map) function ChunkUtils.unregisterResource(entity, map)
if entity.prototype.infinite_resource then if entity.prototype.infinite_resource then
return return
end end
@@ -626,7 +624,7 @@ function chunkUtils.unregisterResource(entity, map)
end end
end end
function chunkUtils.registerResource(entity, map) function ChunkUtils.registerResource(entity, map)
local overlapArray = getEntityOverlapChunks(map, entity) local overlapArray = getEntityOverlapChunks(map, entity)
for i=1,#overlapArray do for i=1,#overlapArray do
@@ -637,7 +635,7 @@ function chunkUtils.registerResource(entity, map)
end end
end end
function chunkUtils.makeImmortalEntity(surface, entity) function ChunkUtils.makeImmortalEntity(surface, entity)
local repairPosition = entity.position local repairPosition = entity.position
local repairName = entity.name local repairName = entity.name
local repairForce = entity.force local repairForce = entity.force
@@ -673,5 +671,10 @@ function chunkUtils.makeImmortalEntity(surface, entity)
newEntity.destructible = false newEntity.destructible = false
end end
chunkUtilsG = chunkUtils function ChunkUtils.init(universe)
return chunkUtils Universe = universe
ChunkOverlapArray = universe.chunkOverlapArray
end
ChunkUtilsG = ChunkUtils
return ChunkUtils

View File

@@ -14,93 +14,93 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
if mapProcessorG then if MapProcessorG then
return mapProcessorG return MapProcessorG
end end
local mapProcessor = {} local MapProcessor = {}
--
local Universe
-- imports -- imports
local queryUtils = require("QueryUtils") local QueryUtils = require("QueryUtils")
local pheromoneUtils = require("PheromoneUtils") local PheromoneUtils = require("PheromoneUtils")
local aiAttackWave = require("AIAttackWave") local AiAttackWave = require("AIAttackWave")
local aiPredicates = require("AIPredicates") local AiPredicates = require("AIPredicates")
local constants = require("Constants") local Constants = require("Constants")
local mapUtils = require("MapUtils") local MapUtils = require("MapUtils")
local playerUtils = require("PlayerUtils") local PlayerUtils = require("PlayerUtils")
local chunkUtils = require("ChunkUtils") local ChunkUtils = require("ChunkUtils")
local chunkPropertyUtils = require("ChunkPropertyUtils") local ChunkPropertyUtils = require("ChunkPropertyUtils")
local baseUtils = require("BaseUtils") local BaseUtils = require("BaseUtils")
-- constants -- Constants
local PLAYER_PHEROMONE_GENERATOR_AMOUNT = constants.PLAYER_PHEROMONE_GENERATOR_AMOUNT local PLAYER_PHEROMONE_GENERATOR_AMOUNT = Constants.PLAYER_PHEROMONE_GENERATOR_AMOUNT
local DURATION_ACTIVE_NEST = constants.DURATION_ACTIVE_NEST local DURATION_ACTIVE_NEST = Constants.DURATION_ACTIVE_NEST
local PROCESS_QUEUE_SIZE = constants.PROCESS_QUEUE_SIZE local PROCESS_QUEUE_SIZE = Constants.PROCESS_QUEUE_SIZE
local RESOURCE_QUEUE_SIZE = constants.RESOURCE_QUEUE_SIZE local RESOURCE_QUEUE_SIZE = Constants.RESOURCE_QUEUE_SIZE
local ENEMY_QUEUE_SIZE = constants.ENEMY_QUEUE_SIZE local ENEMY_QUEUE_SIZE = Constants.ENEMY_QUEUE_SIZE
local PLAYER_QUEUE_SIZE = constants.PLAYER_QUEUE_SIZE local PLAYER_QUEUE_SIZE = Constants.PLAYER_QUEUE_SIZE
local CLEANUP_QUEUE_SIZE = constants.CLEANUP_QUEUE_SIZE local CLEANUP_QUEUE_SIZE = Constants.CLEANUP_QUEUE_SIZE
local PROCESS_PLAYER_BOUND = constants.PROCESS_PLAYER_BOUND local PROCESS_PLAYER_BOUND = Constants.PROCESS_PLAYER_BOUND
local CHUNK_TICK = constants.CHUNK_TICK
local PROCESS_STATIC_QUEUE_SIZE = constants.PROCESS_STATIC_QUEUE_SIZE local AI_VENGENCE_SQUAD_COST = Constants.AI_VENGENCE_SQUAD_COST
local AI_VENGENCE_SQUAD_COST = constants.AI_VENGENCE_SQUAD_COST local BASE_AI_STATE_AGGRESSIVE = Constants.BASE_AI_STATE_AGGRESSIVE
local BASE_AI_STATE_SIEGE = Constants.BASE_AI_STATE_SIEGE
local BASE_AI_STATE_PEACEFUL = Constants.BASE_AI_STATE_PEACEFUL
local BASE_AI_STATE_MIGRATING = Constants.BASE_AI_STATE_MIGRATING
local BASE_AI_STATE_AGGRESSIVE = constants.BASE_AI_STATE_AGGRESSIVE local COOLDOWN_DRAIN = Constants.COOLDOWN_DRAIN
local BASE_AI_STATE_SIEGE = constants.BASE_AI_STATE_SIEGE local COOLDOWN_RALLY = Constants.COOLDOWN_RALLY
local BASE_AI_STATE_PEACEFUL = constants.BASE_AI_STATE_PEACEFUL local COOLDOWN_RETREAT = Constants.COOLDOWN_RETREAT
local BASE_AI_STATE_MIGRATING = constants.BASE_AI_STATE_MIGRATING
local COOLDOWN_DRAIN = constants.COOLDOWN_DRAIN
local COOLDOWN_RALLY = constants.COOLDOWN_RALLY
local COOLDOWN_RETREAT = constants.COOLDOWN_RETREAT
-- imported functions -- imported functions
local setPositionInQuery = queryUtils.setPositionInQuery local setPositionInQuery = QueryUtils.setPositionInQuery
local addPlayerGenerator = chunkPropertyUtils.addPlayerGenerator local addPlayerGenerator = ChunkPropertyUtils.addPlayerGenerator
local findNearbyBase = chunkPropertyUtils.findNearbyBase local findNearbyBase = ChunkPropertyUtils.findNearbyBase
local removeChunkToNest = mapUtils.removeChunkToNest local removeChunkToNest = MapUtils.removeChunkToNest
local processStaticPheromone = pheromoneUtils.processStaticPheromone local processPheromone = PheromoneUtils.processPheromone
local processPheromone = pheromoneUtils.processPheromone
local getCombinedDeathGeneratorRating = chunkPropertyUtils.getCombinedDeathGeneratorRating local getCombinedDeathGeneratorRating = ChunkPropertyUtils.getCombinedDeathGeneratorRating
local processBaseMutation = baseUtils.processBaseMutation local processBaseMutation = BaseUtils.processBaseMutation
local processNestActiveness = chunkPropertyUtils.processNestActiveness local processNestActiveness = ChunkPropertyUtils.processNestActiveness
local getChunkBase = chunkPropertyUtils.getChunkBase local getChunkBase = ChunkPropertyUtils.getChunkBase
local formSquads = aiAttackWave.formSquads local formSquads = AiAttackWave.formSquads
local formVengenceSquad = aiAttackWave.formVengenceSquad local formVengenceSquad = AiAttackWave.formVengenceSquad
local formVengenceSettler = aiAttackWave.formVengenceSettler local formVengenceSettler = AiAttackWave.formVengenceSettler
local formSettlers = aiAttackWave.formSettlers local formSettlers = AiAttackWave.formSettlers
local getChunkByPosition = mapUtils.getChunkByPosition local getChunkByPosition = MapUtils.getChunkByPosition
local getChunkByXY = mapUtils.getChunkByXY local getChunkByXY = MapUtils.getChunkByXY
local getChunkById = mapUtils.getChunkById local getChunkById = MapUtils.getChunkById
local validPlayer = playerUtils.validPlayer local validPlayer = PlayerUtils.validPlayer
local mapScanEnemyChunk = chunkUtils.mapScanEnemyChunk local mapScanEnemyChunk = ChunkUtils.mapScanEnemyChunk
local mapScanPlayerChunk = chunkUtils.mapScanPlayerChunk local mapScanPlayerChunk = ChunkUtils.mapScanPlayerChunk
local mapScanResourceChunk = chunkUtils.mapScanResourceChunk local mapScanResourceChunk = ChunkUtils.mapScanResourceChunk
local getNestCount = chunkPropertyUtils.getNestCount local getNestCount = ChunkPropertyUtils.getNestCount
local getEnemyStructureCount = chunkPropertyUtils.getEnemyStructureCount local getEnemyStructureCount = ChunkPropertyUtils.getEnemyStructureCount
local getNestActiveness = chunkPropertyUtils.getNestActiveness local getNestActiveness = ChunkPropertyUtils.getNestActiveness
local getRaidNestActiveness = chunkPropertyUtils.getRaidNestActiveness local getRaidNestActiveness = ChunkPropertyUtils.getRaidNestActiveness
local canAttack = aiPredicates.canAttack local canAttack = AiPredicates.canAttack
local canMigrate = aiPredicates.canMigrate local canMigrate = AiPredicates.canMigrate
local tableSize = table_size local tableSize = table_size
@@ -118,7 +118,7 @@ local next = next
In theory, this might be fine as smaller bases have less surface to attack and need to have In theory, this might be fine as smaller bases have less surface to attack and need to have
pheromone dissipate at a faster rate. pheromone dissipate at a faster rate.
--]] --]]
function mapProcessor.processMap(map, tick) function MapProcessor.processMap(map, tick)
local processQueue = map.processQueue local processQueue = map.processQueue
local processQueueLength = #processQueue local processQueueLength = #processQueue
@@ -148,7 +148,7 @@ function mapProcessor.processMap(map, tick)
map.processIndex = endIndex - 1 map.processIndex = endIndex - 1
end end
end end
map.universe.processedChunks = map.universe.processedChunks + ((startIndex - endIndex) * step) Universe.processedChunks = Universe.processedChunks + ((startIndex - endIndex) * step)
for x=startIndex,endIndex,step do for x=startIndex,endIndex,step do
processPheromone(map, processQueue[x], tick) processPheromone(map, processQueue[x], tick)
@@ -156,11 +156,11 @@ function mapProcessor.processMap(map, tick)
end end
local function queueNestSpawners(map, chunk, tick) local function queueNestSpawners(map, chunk, tick)
local processActiveNest = map.universe.processActiveNest local processActiveNest = Universe.processActiveNest
local chunkId = chunk.id local chunkId = chunk.id
if not processActiveNest[chunkId] then if not processActiveNest[chunkId] then
if (getNestActiveness(map, chunk) > 0) or (getRaidNestActiveness(map, chunk) > 0) then if (getNestActiveness(chunk) > 0) or (getRaidNestActiveness(chunk) > 0) then
processActiveNest[chunkId] = { processActiveNest[chunkId] = {
map = map, map = map,
chunk = chunk, chunk = chunk,
@@ -176,7 +176,7 @@ end
vs vs
the slower passive version processing the entire map in multiple passes. the slower passive version processing the entire map in multiple passes.
--]] --]]
function mapProcessor.processPlayers(players, universe, tick) function MapProcessor.processPlayers(players, tick)
-- put down player pheromone for player hunters -- put down player pheromone for player hunters
-- randomize player order to ensure a single player isn't singled out -- randomize player order to ensure a single player isn't singled out
-- not looping everyone because the cost is high enough already in multiplayer -- not looping everyone because the cost is high enough already in multiplayer
@@ -186,7 +186,7 @@ function mapProcessor.processPlayers(players, universe, tick)
local player = players[i] local player = players[i]
if validPlayer(player) then if validPlayer(player) then
local char = player.character local char = player.character
local map = universe.maps[char.surface.index] local map = Universe.maps[char.surface.index]
if map then if map then
local playerChunk = getChunkByPosition(map, char.position) local playerChunk = getChunkByPosition(map, char.position)
@@ -198,10 +198,10 @@ function mapProcessor.processPlayers(players, universe, tick)
end end
if (#players > 0) then if (#players > 0) then
local player = players[universe.random(#players)] local player = players[Universe.random(#players)]
if validPlayer(player) then if validPlayer(player) then
local char = player.character local char = player.character
local map = universe.maps[char.surface.index] local map = Universe.maps[char.surface.index]
if map then if map then
local playerChunk = getChunkByPosition(map, char.position) local playerChunk = getChunkByPosition(map, char.position)
@@ -214,7 +214,7 @@ function mapProcessor.processPlayers(players, universe, tick)
local vengence = allowingAttacks and local vengence = allowingAttacks and
(base.unitPoints >= AI_VENGENCE_SQUAD_COST) and (base.unitPoints >= AI_VENGENCE_SQUAD_COST) and
((getEnemyStructureCount(map, playerChunk) > 0) or ((getEnemyStructureCount(map, playerChunk) > 0) or
(getCombinedDeathGeneratorRating(map, playerChunk) < universe.retreatThreshold)) (getCombinedDeathGeneratorRating(map, playerChunk) < Universe.retreatThreshold))
for x=playerChunk.x - PROCESS_PLAYER_BOUND, playerChunk.x + PROCESS_PLAYER_BOUND, 32 do for x=playerChunk.x - PROCESS_PLAYER_BOUND, playerChunk.x + PROCESS_PLAYER_BOUND, 32 do
for y=playerChunk.y - PROCESS_PLAYER_BOUND, playerChunk.y + PROCESS_PLAYER_BOUND, 32 do for y=playerChunk.y - PROCESS_PLAYER_BOUND, playerChunk.y + PROCESS_PLAYER_BOUND, 32 do
@@ -223,19 +223,19 @@ function mapProcessor.processPlayers(players, universe, tick)
if (chunk ~= -1) then if (chunk ~= -1) then
processPheromone(map, chunk, tick, true) processPheromone(map, chunk, tick, true)
if (getNestCount(map, chunk) > 0) then if (getNestCount(chunk) > 0) then
processNestActiveness(map, chunk) processNestActiveness(map, chunk)
queueNestSpawners(map, chunk, tick) queueNestSpawners(map, chunk, tick)
if vengence then if vengence then
local pack = universe.vengenceQueue[chunk.id] local pack = Universe.vengenceQueue[chunk.id]
if not pack then if not pack then
pack = { pack = {
v = 0, v = 0,
map = map, map = map,
base = base base = base
} }
universe.vengenceQueue[chunk.id] = pack Universe.vengenceQueue[chunk.id] = pack
end end
pack.v = pack.v + 1 pack.v = pack.v + 1
end end
@@ -249,8 +249,8 @@ function mapProcessor.processPlayers(players, universe, tick)
end end
end end
local function processCleanUp(universe, chunks, iterator, tick, duration) local function processCleanUp(chunks, iterator, tick, duration)
local chunkId = universe[iterator] local chunkId = Universe[iterator]
local chunkPack local chunkPack
if not chunkId then if not chunkId then
chunkId, chunkPack = next(chunks, nil) chunkId, chunkPack = next(chunks, nil)
@@ -258,33 +258,33 @@ local function processCleanUp(universe, chunks, iterator, tick, duration)
chunkPack = chunks[chunkId] chunkPack = chunks[chunkId]
end end
if not chunkId then if not chunkId then
universe[iterator] = nil Universe[iterator] = nil
else else
universe[iterator] = next(chunks, chunkId) Universe[iterator] = next(chunks, chunkId)
if (tick - chunkPack.tick) > duration then if (tick - chunkPack.tick) > duration then
chunks[chunkId] = nil chunks[chunkId] = nil
end end
end end
end end
function mapProcessor.cleanUpMapTables(universe, tick) function MapProcessor.cleanUpMapTables(tick)
local retreats = universe.chunkToRetreats local retreats = Universe.chunkToRetreats
local rallys = universe.chunkToRallys local rallys = Universe.chunkToRallys
local drained = universe.chunkToDrained local drained = Universe.chunkToDrained
for _=1,CLEANUP_QUEUE_SIZE do for _=1,CLEANUP_QUEUE_SIZE do
processCleanUp(universe, retreats, "chunkToRetreatIterator", tick, COOLDOWN_RETREAT) processCleanUp(retreats, "chunkToRetreatIterator", tick, COOLDOWN_RETREAT)
processCleanUp(universe, rallys, "chunkToRallyIterator", tick, COOLDOWN_RALLY) processCleanUp(rallys, "chunkToRallyIterator", tick, COOLDOWN_RALLY)
processCleanUp(universe, drained, "chunkToDrainedIterator", tick, COOLDOWN_DRAIN) processCleanUp(drained, "chunkToDrainedIterator", tick, COOLDOWN_DRAIN)
end end
end end
--[[ --[[
Passive scan to find entities that have been generated outside the factorio event system Passive scan to find entities that have been generated outside the factorio event system
--]] --]]
function mapProcessor.scanPlayerMap(map, tick) function MapProcessor.scanPlayerMap(map, tick)
if (map.nextProcessMap == tick) or (map.nextPlayerScan == tick) or if (map.nextProcessMap == tick) or (map.nextPlayerScan == tick) or
(map.nextEnemyScan == tick) or (map.nextChunkProcess == tick) (map.nextEnemyScan == tick) or (map.nextChunkProcess == tick)
then then
@@ -312,7 +312,7 @@ function mapProcessor.scanPlayerMap(map, tick)
end end
end end
function mapProcessor.scanEnemyMap(map, tick) function MapProcessor.scanEnemyMap(map, tick)
if (map.nextProcessMap == tick) or (map.nextPlayerScan == tick) or (map.nextChunkProcess == tick) then if (map.nextProcessMap == tick) or (map.nextPlayerScan == tick) or (map.nextChunkProcess == tick) then
return return
end end
@@ -339,7 +339,7 @@ function mapProcessor.scanEnemyMap(map, tick)
end end
end end
function mapProcessor.scanResourceMap(map, tick) function MapProcessor.scanResourceMap(map, tick)
if (map.nextProcessMap == tick) or (map.nextPlayerScan == tick) or if (map.nextProcessMap == tick) or (map.nextPlayerScan == tick) or
(map.nextEnemyScan == tick) or (map.nextChunkProcess == tick) (map.nextEnemyScan == tick) or (map.nextChunkProcess == tick)
then then
@@ -367,9 +367,9 @@ function mapProcessor.scanResourceMap(map, tick)
end end
end end
function mapProcessor.processActiveNests(universe, tick) function MapProcessor.processActiveNests(tick)
local processActiveNest = universe.processActiveNest local processActiveNest = Universe.processActiveNest
local chunkId = universe.processActiveNestIterator local chunkId = Universe.processActiveNestIterator
local chunkPack local chunkPack
if not chunkId then if not chunkId then
chunkId, chunkPack = next(processActiveNest, nil) chunkId, chunkPack = next(processActiveNest, nil)
@@ -377,9 +377,9 @@ function mapProcessor.processActiveNests(universe, tick)
chunkPack = processActiveNest[chunkId] chunkPack = processActiveNest[chunkId]
end end
if not chunkId then if not chunkId then
universe.processActiveNestIterator = nil Universe.processActiveNestIterator = nil
else else
universe.processActiveNestIterator = next(processActiveNest, chunkId) Universe.processActiveNestIterator = next(processActiveNest, chunkId)
if chunkPack.tick < tick then if chunkPack.tick < tick then
local map = chunkPack.map local map = chunkPack.map
if not map.surface.valid then if not map.surface.valid then
@@ -388,7 +388,7 @@ function mapProcessor.processActiveNests(universe, tick)
end end
local chunk = chunkPack.chunk local chunk = chunkPack.chunk
processNestActiveness(map, chunk) processNestActiveness(map, chunk)
if (getNestActiveness(map, chunk) == 0) and (getRaidNestActiveness(map, chunk) == 0) then if (getNestActiveness(chunk) == 0) and (getRaidNestActiveness(chunk) == 0) then
processActiveNest[chunkId] = nil processActiveNest[chunkId] = nil
else else
chunkPack.tick = tick + DURATION_ACTIVE_NEST chunkPack.tick = tick + DURATION_ACTIVE_NEST
@@ -397,9 +397,9 @@ function mapProcessor.processActiveNests(universe, tick)
end end
end end
function mapProcessor.processVengence(universe) function MapProcessor.processVengence()
local vengenceQueue = universe.vengenceQueue local vengenceQueue = Universe.vengenceQueue
local chunkId = universe.deployVengenceIterator local chunkId = Universe.deployVengenceIterator
local vengencePack local vengencePack
if not chunkId then if not chunkId then
chunkId, vengencePack = next(vengenceQueue, nil) chunkId, vengencePack = next(vengenceQueue, nil)
@@ -407,20 +407,20 @@ function mapProcessor.processVengence(universe)
vengencePack = vengenceQueue[chunkId] vengencePack = vengenceQueue[chunkId]
end end
if not chunkId then if not chunkId then
universe.deployVengenceIterator = nil Universe.deployVengenceIterator = nil
if (tableSize(vengenceQueue) == 0) then if (tableSize(vengenceQueue) == 0) then
universe.vengenceQueue = {} Universe.vengenceQueue = {}
end end
else else
universe.deployVengenceIterator = next(vengenceQueue, chunkId) Universe.deployVengenceIterator = next(vengenceQueue, chunkId)
vengenceQueue[chunkId] = nil vengenceQueue[chunkId] = nil
local map = vengencePack.map local map = vengencePack.map
if not map.surface.valid then if not map.surface.valid then
return return
end end
local chunk = getChunkById(map, chunkId) local chunk = getChunkById(chunkId)
local base = vengencePack.base local base = vengencePack.base
if canMigrate(map, base) and (universe.random() < 0.075) then if canMigrate(map, base) and (Universe.random() < 0.075) then
formVengenceSettler(map, chunk, base) formVengenceSettler(map, chunk, base)
else else
formVengenceSquad(map, chunk, base) formVengenceSquad(map, chunk, base)
@@ -428,28 +428,28 @@ function mapProcessor.processVengence(universe)
end end
end end
function mapProcessor.processNests(universe, tick) function MapProcessor.processNests(tick)
local chunkId = universe.processNestIterator local chunkId = Universe.processNestIterator
local chunkPack local chunkPack
if not chunkId then if not chunkId then
chunkId,chunkPack = next(universe.chunkToNests, nil) chunkId,chunkPack = next(Universe.chunkToNests, nil)
else else
chunkPack = universe.chunkToNests[chunkId] chunkPack = Universe.chunkToNests[chunkId]
end end
if not chunkId then if not chunkId then
universe.processNestIterator = nil Universe.processNestIterator = nil
else else
universe.processNestIterator = next(universe.chunkToNests, chunkId) Universe.processNestIterator = next(Universe.chunkToNests, chunkId)
local map = chunkPack.map local map = chunkPack.map
if not map.surface.valid then if not map.surface.valid then
removeChunkToNest(universe, chunkId) removeChunkToNest(chunkId)
return return
end end
local chunk = getChunkById(map, chunkId) local chunk = getChunkById(chunkId)
processNestActiveness(map, chunk) processNestActiveness(map, chunk)
queueNestSpawners(map, chunk, tick) queueNestSpawners(map, chunk, tick)
if universe.NEW_ENEMIES then if Universe.NEW_ENEMIES then
processBaseMutation(chunk, processBaseMutation(chunk,
map, map,
getChunkBase(map, chunk)) getChunkBase(map, chunk))
@@ -457,8 +457,8 @@ function mapProcessor.processNests(universe, tick)
end end
end end
local function processSpawnersBody(universe, iterator, chunks) local function processSpawnersBody(iterator, chunks)
local chunkId = universe[iterator] local chunkId = Universe[iterator]
local chunkPack local chunkPack
if not chunkId then if not chunkId then
chunkId,chunkPack = next(chunks, nil) chunkId,chunkPack = next(chunks, nil)
@@ -466,19 +466,19 @@ local function processSpawnersBody(universe, iterator, chunks)
chunkPack = chunks[chunkId] chunkPack = chunks[chunkId]
end end
if not chunkId then if not chunkId then
universe[iterator] = nil Universe[iterator] = nil
else else
universe[iterator] = next(chunks, chunkId) Universe[iterator] = next(chunks, chunkId)
local map = chunkPack.map local map = chunkPack.map
if not map.surface.valid then if not map.surface.valid then
if (iterator == "processMigrationIterator") then if (iterator == "processMigrationIterator") then
removeChunkToNest(universe, chunkId) removeChunkToNest(chunkId)
else else
chunks[chunkId] = nil chunks[chunkId] = nil
end end
return return
end end
local chunk = getChunkById(map, chunkId) local chunk = getChunkById(chunkId)
local base = findNearbyBase(map, chunk) local base = findNearbyBase(map, chunk)
if base.stateAI == BASE_AI_STATE_PEACEFUL then if base.stateAI == BASE_AI_STATE_PEACEFUL then
return return
@@ -508,34 +508,35 @@ local function processSpawnersBody(universe, iterator, chunks)
end end
end end
function mapProcessor.processAttackWaves(universe) function MapProcessor.processAttackWaves()
processSpawnersBody(universe, processSpawnersBody("processActiveSpawnerIterator",
"processActiveSpawnerIterator", Universe.chunkToActiveNest)
universe.chunkToActiveNest) processSpawnersBody("processActiveRaidSpawnerIterator",
processSpawnersBody(universe, Universe.chunkToActiveRaidNest)
"processActiveRaidSpawnerIterator", processSpawnersBody("processMigrationIterator",
universe.chunkToActiveRaidNest) Universe.chunkToNests)
processSpawnersBody(universe,
"processMigrationIterator",
universe.chunkToNests)
end end
function mapProcessor.processClouds(universe, tick) function MapProcessor.processClouds(tick)
local len = universe.settlePurpleCloud.len local len = Universe.settlePurpleCloud.len
local builderPack = universe.settlePurpleCloud[len] local builderPack = Universe.settlePurpleCloud[len]
if builderPack and (builderPack.tick <= tick) then if builderPack and (builderPack.tick <= tick) then
universe.settlePurpleCloud[len] = nil Universe.settlePurpleCloud[len] = nil
universe.settlePurpleCloud.len = len - 1 Universe.settlePurpleCloud.len = len - 1
local map = builderPack.map local map = builderPack.map
if builderPack.group.valid and map.surface.valid then if builderPack.group.valid and map.surface.valid then
setPositionInQuery( setPositionInQuery(
universe.obaCreateBuildCloudQuery, Universe.obaCreateBuildCloudQuery,
builderPack.position builderPack.position
) )
map.surface.create_entity(universe.obaCreateBuildCloudQuery) map.surface.create_entity(Universe.obaCreateBuildCloudQuery)
end end
end end
end end
mapProcessorG = mapProcessor function MapProcessor.init(universe)
return mapProcessor Universe = universe
end
MapProcessorG = MapProcessor
return MapProcessor

View File

@@ -14,37 +14,42 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
if mapUtilsG then if MapUtilsG then
return mapUtilsG return MapUtilsG
end end
local mapUtils = {} local MapUtils = {}
--
local Universe
local NeighborChunks
-- imports -- imports
local constants = require("Constants") local Constants = require("Constants")
local chunkPropertyUtils = require("ChunkPropertyUtils") local ChunkPropertyUtils = require("ChunkPropertyUtils")
-- constants -- Constants
local CHUNK_NORTH_SOUTH = constants.CHUNK_NORTH_SOUTH local CHUNK_NORTH_SOUTH = Constants.CHUNK_NORTH_SOUTH
local CHUNK_EAST_WEST = constants.CHUNK_EAST_WEST local CHUNK_EAST_WEST = Constants.CHUNK_EAST_WEST
local CHUNK_IMPASSABLE = constants.CHUNK_IMPASSABLE local CHUNK_IMPASSABLE = Constants.CHUNK_IMPASSABLE
local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS local CHUNK_ALL_DIRECTIONS = Constants.CHUNK_ALL_DIRECTIONS
local CHUNK_SIZE = constants.CHUNK_SIZE local CHUNK_SIZE = Constants.CHUNK_SIZE
local CHUNK_SIZE_DIVIDER = constants.CHUNK_SIZE_DIVIDER local CHUNK_SIZE_DIVIDER = Constants.CHUNK_SIZE_DIVIDER
-- imported functions -- imported functions
local mFloor = math.floor local mFloor = math.floor
local getPassable = chunkPropertyUtils.getPassable local getPassable = ChunkPropertyUtils.getPassable
local tRemove = table.remove local tRemove = table.remove
local mCeil = math.ceil local mCeil = math.ceil
-- module code -- module code
function mapUtils.getChunkByXY(map, x, y) function MapUtils.getChunkByXY(map, x, y)
local chunkX = map[x] local chunkX = map[x]
if chunkX then if chunkX then
return chunkX[y] or -1 return chunkX[y] or -1
@@ -52,7 +57,7 @@ function mapUtils.getChunkByXY(map, x, y)
return -1 return -1
end end
function mapUtils.getChunkByPosition(map, position) function MapUtils.getChunkByPosition(map, position)
local chunkX = map[mFloor(position.x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE] local chunkX = map[mFloor(position.x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE]
if chunkX then if chunkX then
local chunkY = mFloor(position.y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE local chunkY = mFloor(position.y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
@@ -61,50 +66,50 @@ function mapUtils.getChunkByPosition(map, position)
return -1 return -1
end end
function mapUtils.getChunkById(map, chunkId) function MapUtils.getChunkById(chunkId)
return map.universe.chunkIdToChunk[chunkId] or -1 return Universe.chunkIdToChunk[chunkId] or -1
end end
function mapUtils.positionToChunkXY(position) function MapUtils.positionToChunkXY(position)
local chunkX = mFloor(position.x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE local chunkX = mFloor(position.x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
local chunkY = mFloor(position.y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE local chunkY = mFloor(position.y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
return chunkX, chunkY return chunkX, chunkY
end end
function mapUtils.queueGeneratedChunk(universe, event) function MapUtils.queueGeneratedChunk(event)
local map = universe.maps[event.surface.index] local map = Universe.maps[event.surface.index]
if not map then if not map then
return return
end end
event.tick = (event.tick or game.tick) + 20 event.tick = (event.tick or game.tick) + 20
event.id = universe.eventId event.id = Universe.eventId
event.map = map event.map = map
universe.pendingChunks[event.id] = event Universe.pendingChunks[event.id] = event
universe.eventId = universe.eventId + 1 Universe.eventId = Universe.eventId + 1
end end
function mapUtils.nextMap(universe) function MapUtils.nextMap()
local mapIterator = universe.mapIterator local mapIterator = Universe.mapIterator
repeat repeat
local map local map
universe.mapIterator, map = next(universe.maps, universe.mapIterator) Universe.mapIterator, map = next(Universe.maps, Universe.mapIterator)
if map and map.activeSurface then if map and map.activeSurface then
return map return map
end end
until mapIterator == universe.mapIterator until mapIterator == Universe.mapIterator
end end
function mapUtils.removeChunkToNest(universe, chunkId) function MapUtils.removeChunkToNest(chunkId)
universe.chunkToNests[chunkId] = nil Universe.chunkToNests[chunkId] = nil
if (chunkId == universe.processNestIterator) then if (chunkId == Universe.processNestIterator) then
universe.processNestIterator = nil Universe.processNestIterator = nil
end end
if (chunkId == universe.processMigrationIterator) then if (chunkId == Universe.processMigrationIterator) then
universe.processMigrationIterator = nil Universe.processMigrationIterator = nil
end end
end end
function mapUtils.findInsertionPoint(processQueue, chunk) function MapUtils.findInsertionPoint(processQueue, chunk)
local low = 1 local low = 1
local high = #processQueue local high = #processQueue
local pivot local pivot
@@ -120,8 +125,8 @@ function mapUtils.findInsertionPoint(processQueue, chunk)
return low return low
end end
function mapUtils.removeProcessQueueChunk(processQueue, chunk) function MapUtils.removeProcessQueueChunk(processQueue, chunk)
local insertionPoint = mapUtils.findInsertionPoint(processQueue, chunk) local insertionPoint = MapUtils.findInsertionPoint(processQueue, chunk)
if insertionPoint > #processQueue then if insertionPoint > #processQueue then
insertionPoint = insertionPoint - 1 insertionPoint = insertionPoint - 1
end end
@@ -136,24 +141,23 @@ function mapUtils.removeProcessQueueChunk(processQueue, chunk)
end end
end end
function mapUtils.removeChunkFromMap(map, chunk) function MapUtils.removeChunkFromMap(map, chunk)
local chunkId = chunk.id local chunkId = chunk.id
local x = chunk.x local x = chunk.x
local y = chunk.y local y = chunk.y
mapUtils.removeProcessQueueChunk(map.processQueue, chunk) MapUtils.removeProcessQueueChunk(map.processQueue, chunk)
local universe = map.universe
map[x][y] = nil map[x][y] = nil
universe.chunkIdToChunk[chunkId] = nil Universe.chunkIdToChunk[chunkId] = nil
universe.chunkToActiveNest[chunkId] = nil Universe.chunkToActiveNest[chunkId] = nil
universe.chunkToActiveRaidNest[chunkId] = nil Universe.chunkToActiveRaidNest[chunkId] = nil
universe.chunkToDrained[chunkId] = nil Universe.chunkToDrained[chunkId] = nil
universe.chunkToRetreats[chunkId] = nil Universe.chunkToRetreats[chunkId] = nil
universe.chunkToRallys[chunkId] = nil Universe.chunkToRallys[chunkId] = nil
universe.chunkToPassScan[chunkId] = nil Universe.chunkToPassScan[chunkId] = nil
universe.chunkToNests[chunkId] = nil Universe.chunkToNests[chunkId] = nil
universe.vengenceQueue[chunkId] = nil Universe.vengenceQueue[chunkId] = nil
universe.processActiveNest[chunkId] = nil Universe.processActiveNest[chunkId] = nil
universe.chunkToVictory[chunkId] = nil Universe.chunkToVictory[chunkId] = nil
local base = map.chunkToBase[chunkId] local base = map.chunkToBase[chunkId]
if base then if base then
base.chunkCount = base.chunkCount - 1 base.chunkCount = base.chunkCount - 1
@@ -176,38 +180,38 @@ function mapUtils.removeChunkFromMap(map, chunk)
map.chunkToPathRating[chunkId] = nil map.chunkToPathRating[chunkId] = nil
map.chunkToDeathGenerator[chunkId] = nil map.chunkToDeathGenerator[chunkId] = nil
if universe.processActiveNestIterator == chunkId then if Universe.processActiveNestIterator == chunkId then
universe.processActiveNestIterator = nil Universe.processActiveNestIterator = nil
end end
if universe.victoryScentIterator == chunkId then if Universe.victoryScentIterator == chunkId then
universe.victoryScentIterator = nil Universe.victoryScentIterator = nil
end end
if universe.processNestIterator == chunkId then if Universe.processNestIterator == chunkId then
universe.processNestIterator = nil Universe.processNestIterator = nil
end end
if universe.chunkToDrainedIterator == chunkId then if Universe.chunkToDrainedIterator == chunkId then
universe.chunkToDrainedIterator = nil Universe.chunkToDrainedIterator = nil
end end
if universe.chunkToRetreatIterator == chunkId then if Universe.chunkToRetreatIterator == chunkId then
universe.chunkToRetreatIterator = nil Universe.chunkToRetreatIterator = nil
end end
if universe.chunkToRallyIterator == chunkId then if Universe.chunkToRallyIterator == chunkId then
universe.chunkToRallyIterator = nil Universe.chunkToRallyIterator = nil
end end
if universe.chunkToPassScanIterator == chunkId then if Universe.chunkToPassScanIterator == chunkId then
universe.chunkToPassScanIterator = nil Universe.chunkToPassScanIterator = nil
end end
if universe.processActiveSpawnerIterator == chunkId then if Universe.processActiveSpawnerIterator == chunkId then
universe.processActiveSpawnerIterator = nil Universe.processActiveSpawnerIterator = nil
end end
if universe.processActiveRaidSpawnerIterator == chunkId then if Universe.processActiveRaidSpawnerIterator == chunkId then
universe.processActiveRaidSpawnerIterator = nil Universe.processActiveRaidSpawnerIterator = nil
end end
if universe.processMigrationIterator == chunkId then if Universe.processMigrationIterator == chunkId then
universe.processMigrationIterator = nil Universe.processMigrationIterator = nil
end end
if universe.deployVengenceIterator == chunkId then if Universe.deployVengenceIterator == chunkId then
universe.deployVengenceIterator = nil Universe.deployVengenceIterator = nil
end end
end end
@@ -218,41 +222,40 @@ end
/|\ /|\
6 7 8 6 7 8
]]-- ]]--
function mapUtils.getNeighborChunks(map, x, y) function MapUtils.getNeighborChunks(map, x, y)
local neighbors = map.universe.neighbors
local chunkYRow1 = y - CHUNK_SIZE local chunkYRow1 = y - CHUNK_SIZE
local chunkYRow3 = y + CHUNK_SIZE local chunkYRow3 = y + CHUNK_SIZE
local xChunks = map[x-CHUNK_SIZE] local xChunks = map[x-CHUNK_SIZE]
if xChunks then if xChunks then
neighbors[1] = xChunks[chunkYRow1] or -1 NeighborChunks[1] = xChunks[chunkYRow1] or -1
neighbors[4] = xChunks[y] or -1 NeighborChunks[4] = xChunks[y] or -1
neighbors[6] = xChunks[chunkYRow3] or -1 NeighborChunks[6] = xChunks[chunkYRow3] or -1
else else
neighbors[1] = -1 NeighborChunks[1] = -1
neighbors[4] = -1 NeighborChunks[4] = -1
neighbors[6] = -1 NeighborChunks[6] = -1
end end
xChunks = map[x+CHUNK_SIZE] xChunks = map[x+CHUNK_SIZE]
if xChunks then if xChunks then
neighbors[3] = xChunks[chunkYRow1] or -1 NeighborChunks[3] = xChunks[chunkYRow1] or -1
neighbors[5] = xChunks[y] or -1 NeighborChunks[5] = xChunks[y] or -1
neighbors[8] = xChunks[chunkYRow3] or -1 NeighborChunks[8] = xChunks[chunkYRow3] or -1
else else
neighbors[3] = -1 NeighborChunks[3] = -1
neighbors[5] = -1 NeighborChunks[5] = -1
neighbors[8] = -1 NeighborChunks[8] = -1
end end
xChunks = map[x] xChunks = map[x]
if xChunks then if xChunks then
neighbors[2] = xChunks[chunkYRow1] or -1 NeighborChunks[2] = xChunks[chunkYRow1] or -1
neighbors[7] = xChunks[chunkYRow3] or -1 NeighborChunks[7] = xChunks[chunkYRow3] or -1
else else
neighbors[2] = -1 NeighborChunks[2] = -1
neighbors[7] = -1 NeighborChunks[7] = -1
end end
return neighbors return NeighborChunks
end end
@@ -263,7 +266,7 @@ end
/|\ /|\
6 7 8 6 7 8
]]-- ]]--
function mapUtils.canMoveChunkDirection(map, direction, startChunk, endChunk) function MapUtils.canMoveChunkDirection(map, direction, startChunk, endChunk)
local canMove = false local canMove = false
local startPassable = getPassable(map, startChunk) local startPassable = getPassable(map, startChunk)
local endPassable = getPassable(map, endChunk) local endPassable = getPassable(map, endChunk)
@@ -293,8 +296,8 @@ function mapUtils.canMoveChunkDirection(map, direction, startChunk, endChunk)
return canMove return canMove
end end
function mapUtils.getCardinalChunks(map, x, y) function MapUtils.getCardinalChunks(map, x, y)
local neighbors = map.universe.cardinalNeighbors local neighbors = Universe.cardinalNeighbors
local xChunks = map[x] local xChunks = map[x]
if xChunks then if xChunks then
neighbors[1] = xChunks[y-CHUNK_SIZE] or -1 neighbors[1] = xChunks[y-CHUNK_SIZE] or -1
@@ -320,7 +323,7 @@ function mapUtils.getCardinalChunks(map, x, y)
return neighbors return neighbors
end end
function mapUtils.positionFromDirectionAndChunk(direction, startPosition, scaling) function MapUtils.positionFromDirectionAndChunk(direction, startPosition, scaling)
local endPosition = {} local endPosition = {}
if (direction == 1) then if (direction == 1) then
endPosition.x = startPosition.x - CHUNK_SIZE * (scaling - 0.1) endPosition.x = startPosition.x - CHUNK_SIZE * (scaling - 0.1)
@@ -350,7 +353,7 @@ function mapUtils.positionFromDirectionAndChunk(direction, startPosition, scalin
return endPosition return endPosition
end end
function mapUtils.positionFromDirectionAndFlat(direction, startPosition, multipler) function MapUtils.positionFromDirectionAndFlat(direction, startPosition, multipler)
local lx = startPosition.x local lx = startPosition.x
local ly = startPosition.y local ly = startPosition.y
if not multipler then if not multipler then
@@ -383,5 +386,10 @@ function mapUtils.positionFromDirectionAndFlat(direction, startPosition, multipl
} }
end end
mapUtilsG = mapUtils function MapUtils.init(universe)
return mapUtils Universe = universe
NeighborChunks = universe.neighbors
end
MapUtilsG = MapUtils
return MapUtils

View File

@@ -14,10 +14,10 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
if mathUtilsG then if MathUtilsG then
return mathUtilsG return MathUtilsG
end end
local mathUtils = {} local MathUtils = {}
-- imports -- imports
@@ -35,26 +35,26 @@ local mAbs = math.abs
-- module code -- module code
function mathUtils.roundToFloor(number, multiple) function MathUtils.roundToFloor(number, multiple)
return mFloor(number / multiple) * multiple return mFloor(number / multiple) * multiple
end end
function mathUtils.roundToNearest(number, multiple) function MathUtils.roundToNearest(number, multiple)
local num = number + (multiple * 0.5) local num = number + (multiple * 0.5)
return num - (num % multiple) return num - (num % multiple)
end end
function mathUtils.randomTickEvent(rg, tick, low, high) function MathUtils.randomTickEvent(rg, tick, low, high)
return tick + mathUtils.randomTickDuration(rg, low, high) return tick + MathUtils.randomTickDuration(rg, low, high)
end end
function mathUtils.randomTickDuration(rg, low, high) function MathUtils.randomTickDuration(rg, low, high)
local range = high - low local range = high - low
local minutesToTick = (range * rg()) + low local minutesToTick = (range * rg()) + low
return mathUtils.roundToNearest(TICKS_A_MINUTE * minutesToTick, 1) return MathUtils.roundToNearest(TICKS_A_MINUTE * minutesToTick, 1)
end end
function mathUtils.distort(xorRandom, num, stdDev, min, max) function MathUtils.distort(xorRandom, num, stdDev, min, max)
local amin = min or num * 0.70 local amin = min or num * 0.70
local amax = max or num * 1.30 local amax = max or num * 1.30
local sd = stdDev or 0.17 local sd = stdDev or 0.17
@@ -63,14 +63,14 @@ function mathUtils.distort(xorRandom, num, stdDev, min, max)
amin = amax amin = amax
amax = t amax = t
end end
return mathUtils.roundToNearest(mathUtils.gaussianRandomRangeRG(num, num * sd, amin, amax, xorRandom), 0.01) return MathUtils.roundToNearest(MathUtils.gaussianRandomRangeRG(num, num * sd, amin, amax, xorRandom), 0.01)
end end
function mathUtils.linearInterpolation(percent, min, max) function MathUtils.linearInterpolation(percent, min, max)
return ((max - min) * percent) + min return ((max - min) * percent) + min
end end
function mathUtils.xorRandom(state) function MathUtils.xorRandom(state)
local xor = bit32.bxor local xor = bit32.bxor
local lshift = bit32.lshift local lshift = bit32.lshift
local rshift = bit32.rshift local rshift = bit32.rshift
@@ -88,7 +88,7 @@ end
--[[ --[[
Used for gaussian random numbers Used for gaussian random numbers
--]] --]]
function mathUtils.gaussianRandomRG(mean, std_dev, rg) function MathUtils.gaussianRandomRG(mean, std_dev, rg)
-- marsagliaPolarMethod -- marsagliaPolarMethod
local iid1 local iid1
local iid2 local iid2
@@ -104,7 +104,7 @@ function mathUtils.gaussianRandomRG(mean, std_dev, rg)
return mean + (v * std_dev) return mean + (v * std_dev)
end end
function mathUtils.gaussianRandomRangeRG(mean, std_dev, min, max, rg) function MathUtils.gaussianRandomRangeRG(mean, std_dev, min, max, rg)
local r local r
if (min >= max) then if (min >= max) then
return min return min
@@ -125,35 +125,35 @@ function mathUtils.gaussianRandomRangeRG(mean, std_dev, min, max, rg)
return r return r
end end
function mathUtils.euclideanDistanceNamed(p1, p2) function MathUtils.euclideanDistanceNamed(p1, p2)
local xs = p1.x - p2.x local xs = p1.x - p2.x
local ys = p1.y - p2.y local ys = p1.y - p2.y
return ((xs * xs) + (ys * ys)) ^ 0.5 return ((xs * xs) + (ys * ys)) ^ 0.5
end end
function mathUtils.euclideanDistancePoints(x1, y1, x2, y2) function MathUtils.euclideanDistancePoints(x1, y1, x2, y2)
local xs = x1 - x2 local xs = x1 - x2
local ys = y1 - y2 local ys = y1 - y2
return ((xs * xs) + (ys * ys)) ^ 0.5 return ((xs * xs) + (ys * ys)) ^ 0.5
end end
function mathUtils.manhattenDistancePoints(x1, y1, x2, y2) function MathUtils.manhattenDistancePoints(x1, y1, x2, y2)
return mAbs((x1 - x2) + (y1 - y2)) return mAbs((x1 - x2) + (y1 - y2))
end end
function mathUtils.euclideanDistanceArray(p1, p2) function MathUtils.euclideanDistanceArray(p1, p2)
local xs = p1[1] - p2[1] local xs = p1[1] - p2[1]
local ys = p1[2] - p2[2] local ys = p1[2] - p2[2]
return ((xs * xs) + (ys * ys)) ^ 0.5 return ((xs * xs) + (ys * ys)) ^ 0.5
end end
function mathUtils.distortPosition(rg, position, size) function MathUtils.distortPosition(rg, position, size)
local xDistort = mathUtils.gaussianRandomRangeRG(1, 0.5, 0, 2, rg) - 1 local xDistort = MathUtils.gaussianRandomRangeRG(1, 0.5, 0, 2, rg) - 1
local yDistort = mathUtils.gaussianRandomRangeRG(1, 0.5, 0, 2, rg) - 1 local yDistort = MathUtils.gaussianRandomRangeRG(1, 0.5, 0, 2, rg) - 1
position.x = position.x + (xDistort * size) position.x = position.x + (xDistort * size)
position.y = position.y + (yDistort * size) position.y = position.y + (yDistort * size)
return position return position
end end
mathUtilsG = mathUtils MathUtilsG = MathUtils
return mathUtils return MathUtils

View File

@@ -14,57 +14,61 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
if movementUtilsG then if MovementUtilsG then
return movementUtilsG return MovementUtilsG
end end
local movementUtils = {} local MovementUtils = {}
--
local Universe
-- imports -- imports
local constants = require("Constants") local Constants = require("Constants")
local mapUtils = require("MapUtils") local MapUtils = require("MapUtils")
local mathUtils = require("MathUtils") local MathUtils = require("MathUtils")
local unitGroupUtils = require("UnitGroupUtils") local UnitGroupUtils = require("UnitGroupUtils")
-- constants -- Constants
local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER local MAGIC_MAXIMUM_NUMBER = Constants.MAGIC_MAXIMUM_NUMBER
local SQUAD_SETTLING = constants.SQUAD_SETTLING local SQUAD_SETTLING = Constants.SQUAD_SETTLING
-- imported functions -- imported functions
local calculateSettlerMaxDistance = unitGroupUtils.calculateSettlerMaxDistance local calculateSettlerMaxDistance = UnitGroupUtils.calculateSettlerMaxDistance
local canMoveChunkDirection = mapUtils.canMoveChunkDirection local canMoveChunkDirection = MapUtils.canMoveChunkDirection
local getNeighborChunks = mapUtils.getNeighborChunks local getNeighborChunks = MapUtils.getNeighborChunks
local tableRemove = table.remove local tableRemove = table.remove
local tableInsert = table.insert local tableInsert = table.insert
local distortPosition = mathUtils.distortPosition local distortPosition = MathUtils.distortPosition
-- module code -- module code
function movementUtils.findMovementPosition(surface, position) function MovementUtils.findMovementPosition(surface, position)
local pos = position local pos = position
pos = surface.find_non_colliding_position("behemoth-biter", pos, 10, 2, false) pos = surface.find_non_colliding_position("behemoth-biter", pos, 10, 2, false)
return pos return pos
end end
function movementUtils.findMovementPositionEntity(entityName, surface, position) function MovementUtils.findMovementPositionEntity(entityName, surface, position)
local pos = position local pos = position
pos = surface.find_non_colliding_position(entityName, pos, 5, 4, true) pos = surface.find_non_colliding_position(entityName, pos, 5, 4, true)
return pos return pos
end end
function movementUtils.findMovementPositionDistort(surface, position) function MovementUtils.findMovementPositionDistort(surface, position)
local pos = position local pos = position
pos = surface.find_non_colliding_position("behemoth-biter", pos, 10, 2, false) pos = surface.find_non_colliding_position("behemoth-biter", pos, 10, 2, false)
return distortPosition(pos, 8) return distortPosition(pos, 8)
end end
function movementUtils.addMovementPenalty(squad, chunk) function MovementUtils.addMovementPenalty(squad, chunk)
if (chunk == -1) then if (chunk == -1) then
return return
end end
@@ -75,13 +79,12 @@ function movementUtils.addMovementPenalty(squad, chunk)
if (penalty.c.id == chunk.id) then if (penalty.c.id == chunk.id) then
penalty.v = penalty.v + 1 penalty.v = penalty.v + 1
if penalty.v >= 15 then if penalty.v >= 15 then
local universe = squad.map.universe if Universe.enabledMigration and
if universe.enabledMigration and (Universe.builderCount < Universe.AI_MAX_BUILDER_COUNT) then
(universe.builderCount < universe.AI_MAX_BUILDER_COUNT) then
squad.settler = true squad.settler = true
squad.originPosition.x = squad.group.position.x squad.originPosition.x = squad.group.position.x
squad.originPosition.y = squad.group.position.y squad.originPosition.y = squad.group.position.y
squad.maxDistance = calculateSettlerMaxDistance(universe) squad.maxDistance = calculateSettlerMaxDistance()
squad.status = SQUAD_SETTLING squad.status = SQUAD_SETTLING
else else
@@ -103,7 +106,7 @@ end
--[[ --[[
Expects all neighbors adjacent to a chunk Expects all neighbors adjacent to a chunk
--]] --]]
function movementUtils.scoreNeighborsForAttack(map, chunk, neighborDirectionChunks, scoreFunction) function MovementUtils.scoreNeighborsForAttack(map, chunk, neighborDirectionChunks, scoreFunction)
local highestChunk = -1 local highestChunk = -1
local highestScore = -MAGIC_MAXIMUM_NUMBER local highestScore = -MAGIC_MAXIMUM_NUMBER
local highestDirection local highestDirection
@@ -149,7 +152,7 @@ end
--[[ --[[
Expects all neighbors adjacent to a chunk Expects all neighbors adjacent to a chunk
--]] --]]
function movementUtils.scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFunction) function MovementUtils.scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFunction)
local highestChunk = -1 local highestChunk = -1
local highestScore = -MAGIC_MAXIMUM_NUMBER local highestScore = -MAGIC_MAXIMUM_NUMBER
local highestDirection = 0 local highestDirection = 0
@@ -198,7 +201,7 @@ end
--[[ --[[
Expects all neighbors adjacent to a chunk Expects all neighbors adjacent to a chunk
--]] --]]
function movementUtils.scoreNeighborsForResource(chunk, neighborDirectionChunks, validFunction, scoreFunction, map) function MovementUtils.scoreNeighborsForResource(chunk, neighborDirectionChunks, validFunction, scoreFunction, map)
local highestChunk = -1 local highestChunk = -1
local highestScore = -MAGIC_MAXIMUM_NUMBER local highestScore = -MAGIC_MAXIMUM_NUMBER
local highestDirection local highestDirection
@@ -227,7 +230,7 @@ end
--[[ --[[
Expects all neighbors adjacent to a chunk Expects all neighbors adjacent to a chunk
--]] --]]
function movementUtils.scoreNeighborsForRetreat(chunk, neighborDirectionChunks, scoreFunction, map) function MovementUtils.scoreNeighborsForRetreat(chunk, neighborDirectionChunks, scoreFunction, map)
local highestChunk = -1 local highestChunk = -1
local highestScore = -MAGIC_MAXIMUM_NUMBER local highestScore = -MAGIC_MAXIMUM_NUMBER
local highestDirection local highestDirection
@@ -278,7 +281,7 @@ end
--[[ --[[
Expects all neighbors adjacent to a chunk Expects all neighbors adjacent to a chunk
--]] --]]
function movementUtils.scoreNeighborsForFormation(neighborChunks, validFunction, scoreFunction, map) function MovementUtils.scoreNeighborsForFormation(neighborChunks, validFunction, scoreFunction, map)
local highestChunk = -1 local highestChunk = -1
local highestScore = -MAGIC_MAXIMUM_NUMBER local highestScore = -MAGIC_MAXIMUM_NUMBER
local highestDirection local highestDirection
@@ -297,5 +300,9 @@ function movementUtils.scoreNeighborsForFormation(neighborChunks, validFunction,
return highestChunk, highestDirection return highestChunk, highestDirection
end end
movementUtilsG = movementUtils function MovementUtils.init(universe)
return movementUtils Universe = universe
end
MovementUtilsG = MovementUtils
return MovementUtils

View File

@@ -14,80 +14,84 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
if pheromoneUtilsG then if PheromoneUtilsG then
return pheromoneUtilsG return PheromoneUtilsG
end end
local pheromoneUtils = {} local PheromoneUtils = {}
--
local Universe
-- imports -- imports
local mathUtils = require("MathUtils") local MathUtils = require("MathUtils")
local mapUtils = require("MapUtils") local MapUtils = require("MapUtils")
local constants = require("Constants") local Constants = require("Constants")
local chunkPropertyUtils = require("ChunkPropertyUtils") local ChunkPropertyUtils = require("ChunkPropertyUtils")
-- constants -- Constants
local CHUNK_TICK = constants.CHUNK_TICK local CHUNK_TICK = Constants.CHUNK_TICK
local ENEMY_PHEROMONE_MULTIPLER = constants.ENEMY_PHEROMONE_MULTIPLER local ENEMY_PHEROMONE_MULTIPLER = Constants.ENEMY_PHEROMONE_MULTIPLER
local VICTORY_SCENT_MULTIPLER = constants.VICTORY_SCENT_MULTIPLER local VICTORY_SCENT_MULTIPLER = Constants.VICTORY_SCENT_MULTIPLER
local VICTORY_SCENT_BOUND = constants.VICTORY_SCENT_BOUND local VICTORY_SCENT_BOUND = Constants.VICTORY_SCENT_BOUND
local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER local MAGIC_MAXIMUM_NUMBER = Constants.MAGIC_MAXIMUM_NUMBER
local BASE_PHEROMONE = constants.BASE_PHEROMONE local BASE_PHEROMONE = Constants.BASE_PHEROMONE
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE local PLAYER_PHEROMONE = Constants.PLAYER_PHEROMONE
local RESOURCE_PHEROMONE = constants.RESOURCE_PHEROMONE local RESOURCE_PHEROMONE = Constants.RESOURCE_PHEROMONE
local ENEMY_PHEROMONE = constants.ENEMY_PHEROMONE local ENEMY_PHEROMONE = Constants.ENEMY_PHEROMONE
local VICTORY_SCENT = constants.VICTORY_SCENT local VICTORY_SCENT = Constants.VICTORY_SCENT
local DEATH_PHEROMONE_GENERATOR_AMOUNT = constants.DEATH_PHEROMONE_GENERATOR_AMOUNT local DEATH_PHEROMONE_GENERATOR_AMOUNT = Constants.DEATH_PHEROMONE_GENERATOR_AMOUNT
local TEN_DEATH_PHEROMONE_GENERATOR_AMOUNT = constants.TEN_DEATH_PHEROMONE_GENERATOR_AMOUNT local TEN_DEATH_PHEROMONE_GENERATOR_AMOUNT = Constants.TEN_DEATH_PHEROMONE_GENERATOR_AMOUNT
-- imported functions -- imported functions
local decayPlayerGenerator = chunkPropertyUtils.decayPlayerGenerator local decayPlayerGenerator = ChunkPropertyUtils.decayPlayerGenerator
local addVictoryGenerator = chunkPropertyUtils.addVictoryGenerator local addVictoryGenerator = ChunkPropertyUtils.addVictoryGenerator
local getCombinedDeathGenerator = chunkPropertyUtils.getCombinedDeathGenerator local getCombinedDeathGenerator = ChunkPropertyUtils.getCombinedDeathGenerator
local getCombinedDeathGeneratorRating = chunkPropertyUtils.getCombinedDeathGeneratorRating local getCombinedDeathGeneratorRating = ChunkPropertyUtils.getCombinedDeathGeneratorRating
local setDeathGenerator = chunkPropertyUtils.setDeathGenerator local setDeathGenerator = ChunkPropertyUtils.setDeathGenerator
local getPlayerGenerator = chunkPropertyUtils.getPlayerGenerator local getPlayerGenerator = ChunkPropertyUtils.getPlayerGenerator
local addPermanentDeathGenerator = chunkPropertyUtils.addPermanentDeathGenerator local addPermanentDeathGenerator = ChunkPropertyUtils.addPermanentDeathGenerator
local canMoveChunkDirection = mapUtils.canMoveChunkDirection local canMoveChunkDirection = MapUtils.canMoveChunkDirection
local getNeighborChunks = mapUtils.getNeighborChunks local getNeighborChunks = MapUtils.getNeighborChunks
local getChunkById = mapUtils.getChunkById local getChunkById = MapUtils.getChunkById
local getEnemyStructureCount = chunkPropertyUtils.getEnemyStructureCount local getEnemyStructureCount = ChunkPropertyUtils.getEnemyStructureCount
local getPathRating = chunkPropertyUtils.getPathRating local getPathRating = ChunkPropertyUtils.getPathRating
local getPlayerBaseGenerator = chunkPropertyUtils.getPlayerBaseGenerator local getPlayerBaseGenerator = ChunkPropertyUtils.getPlayerBaseGenerator
local getResourceGenerator = chunkPropertyUtils.getResourceGenerator local getResourceGenerator = ChunkPropertyUtils.getResourceGenerator
local addDeathGenerator = chunkPropertyUtils.addDeathGenerator local addDeathGenerator = ChunkPropertyUtils.addDeathGenerator
local decayDeathGenerator = chunkPropertyUtils.decayDeathGenerator local decayDeathGenerator = ChunkPropertyUtils.decayDeathGenerator
local linearInterpolation = mathUtils.linearInterpolation local linearInterpolation = MathUtils.linearInterpolation
local getChunkByXY = mapUtils.getChunkByXY local getChunkByXY = MapUtils.getChunkByXY
local next = next local next = next
local mMax = math.max local mMax = math.max
-- module code -- module code
function pheromoneUtils.victoryScent(map, chunk, entityType) function PheromoneUtils.victoryScent(map, chunk, entityType)
local value = VICTORY_SCENT[entityType] local value = VICTORY_SCENT[entityType]
if value then if value then
addVictoryGenerator(map, chunk, value) addVictoryGenerator(map, chunk, value)
end end
end end
function pheromoneUtils.disperseVictoryScent(universe) function PheromoneUtils.disperseVictoryScent()
local chunkId = universe.victoryScentIterator local chunkId = Universe.victoryScentIterator
local chunkToVictory = universe.chunkToVictory local chunkToVictory = Universe.chunkToVictory
local pheromonePack local pheromonePack
if not chunkId then if not chunkId then
chunkId, pheromonePack = next(chunkToVictory, nil) chunkId, pheromonePack = next(chunkToVictory, nil)
@@ -95,15 +99,15 @@ function pheromoneUtils.disperseVictoryScent(universe)
pheromonePack = chunkToVictory[chunkId] pheromonePack = chunkToVictory[chunkId]
end end
if not chunkId then if not chunkId then
universe.victoryScentIterator = nil Universe.victoryScentIterator = nil
else else
universe.victoryScentIterator = next(chunkToVictory, chunkId) Universe.victoryScentIterator = next(chunkToVictory, chunkId)
chunkToVictory[chunkId] = nil chunkToVictory[chunkId] = nil
local map = pheromonePack.map local map = pheromonePack.map
if not map.surface.valid then if not map.surface.valid then
return return
end end
local chunk = getChunkById(map, chunkId) local chunk = getChunkById(chunkId)
local chunkX = chunk.x local chunkX = chunk.x
local chunkY = chunk.y local chunkY = chunk.y
local i = 1 local i = 1
@@ -121,7 +125,7 @@ function pheromoneUtils.disperseVictoryScent(universe)
end end
end end
function pheromoneUtils.deathScent(map, chunk, structure) function PheromoneUtils.deathScent(map, chunk, structure)
local amount = -DEATH_PHEROMONE_GENERATOR_AMOUNT local amount = -DEATH_PHEROMONE_GENERATOR_AMOUNT
if structure then if structure then
amount = -TEN_DEATH_PHEROMONE_GENERATOR_AMOUNT amount = -TEN_DEATH_PHEROMONE_GENERATOR_AMOUNT
@@ -130,7 +134,7 @@ function pheromoneUtils.deathScent(map, chunk, structure)
addPermanentDeathGenerator(map, chunk, amount) addPermanentDeathGenerator(map, chunk, amount)
end end
function pheromoneUtils.processPheromone(map, chunk, tick, player) function PheromoneUtils.processPheromone(map, chunk, tick, player)
if chunk[CHUNK_TICK] > tick then if chunk[CHUNK_TICK] > tick then
return return
end end
@@ -203,5 +207,9 @@ function pheromoneUtils.processPheromone(map, chunk, tick, player)
chunk[RESOURCE_PHEROMONE] = chunkDeathRating * chunkResource * 0.9 chunk[RESOURCE_PHEROMONE] = chunkDeathRating * chunkResource * 0.9
end end
pheromoneUtilsG = pheromoneUtils function PheromoneUtils.init(universe)
return pheromoneUtils Universe = universe
end
PheromoneUtilsG = PheromoneUtils
return PheromoneUtils

View File

@@ -14,34 +14,34 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
if queryUtilsG then if QueryUtilsG then
return queryUtilsG return QueryUtilsG
end end
local queryUtils = {} local QueryUtils = {}
local constants = require("Constants") local Constants = require("Constants")
local CHUNK_SIZE = constants.CHUNK_SIZE local CHUNK_SIZE = Constants.CHUNK_SIZE
function queryUtils.setPositionInQuery(query, position) function QueryUtils.setPositionInQuery(query, position)
local point = query.position local point = query.position
point[1] = position.x point[1] = position.x
point[2] = position.y point[2] = position.y
end end
function queryUtils.setPositionInCommand(cmd, position) function QueryUtils.setPositionInCommand(cmd, position)
local point = cmd.destination local point = cmd.destination
point[1] = position.x point[1] = position.x
point[2] = position.y point[2] = position.y
end end
function queryUtils.setPositionXYInQuery(query, x, y) function QueryUtils.setPositionXYInQuery(query, x, y)
local point = query.position local point = query.position
point[1] = x point[1] = x
point[2] = y point[2] = y
end end
function queryUtils.setAreaInQuery(query, topLeftPosition, size) function QueryUtils.setAreaInQuery(query, topLeftPosition, size)
local area = query.area local area = query.area
area[1][1] = topLeftPosition.x area[1][1] = topLeftPosition.x
area[1][2] = topLeftPosition.y area[1][2] = topLeftPosition.y
@@ -49,7 +49,7 @@ function queryUtils.setAreaInQuery(query, topLeftPosition, size)
area[2][2] = topLeftPosition.y + size area[2][2] = topLeftPosition.y + size
end end
function queryUtils.setAreaInQueryChunkSize(query, topLeftPosition) function QueryUtils.setAreaInQueryChunkSize(query, topLeftPosition)
local area = query.area local area = query.area
area[1][1] = topLeftPosition.x area[1][1] = topLeftPosition.x
area[1][2] = topLeftPosition.y area[1][2] = topLeftPosition.y
@@ -57,7 +57,7 @@ function queryUtils.setAreaInQueryChunkSize(query, topLeftPosition)
area[2][2] = topLeftPosition.y + CHUNK_SIZE area[2][2] = topLeftPosition.y + CHUNK_SIZE
end end
function queryUtils.setPointAreaInQuery(query, position, size) function QueryUtils.setPointAreaInQuery(query, position, size)
local area = query.area local area = query.area
area[1][1] = position.x - size area[1][1] = position.x - size
area[1][2] = position.y - size area[1][2] = position.y - size
@@ -65,17 +65,17 @@ function queryUtils.setPointAreaInQuery(query, position, size)
area[2][2] = position.y + size area[2][2] = position.y + size
end end
function queryUtils.setAreaYInQuery(query, y1, y2) function QueryUtils.setAreaYInQuery(query, y1, y2)
local area = query.area local area = query.area
area[1][2] = y1 area[1][2] = y1
area[2][2] = y2 area[2][2] = y2
end end
function queryUtils.setAreaXInQuery(query, x1, x2) function QueryUtils.setAreaXInQuery(query, x1, x2)
local area = query.area local area = query.area
area[1][1] = x1 area[1][1] = x1
area[2][1] = x2 area[2][1] = x2
end end
queryUtilsG = queryUtils QueryUtilsG = QueryUtils
return queryUtils return QueryUtils

View File

@@ -14,42 +14,46 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
if (squadAttackG) then if SquadAttackG then
return squadAttackG return SquadAttackG
end end
local squadAttack = {} local SquadAttack = {}
--
local Universe
-- imports -- imports
local constants = require("Constants") local Constants = require("Constants")
local mapUtils = require("MapUtils") local MapUtils = require("MapUtils")
local movementUtils = require("MovementUtils") local MovementUtils = require("MovementUtils")
local mathUtils = require("MathUtils") local MathUtils = require("MathUtils")
local chunkPropertyUtils = require("ChunkPropertyUtils") local ChunkPropertyUtils = require("ChunkPropertyUtils")
local queryUtils = require("QueryUtils") local QueryUtils = require("QueryUtils")
-- constants -- Constants
local PLAYER_PHEROMONE_GENERATOR_THRESHOLD = constants.PLAYER_PHEROMONE_GENERATOR_THRESHOLD local PLAYER_PHEROMONE_GENERATOR_THRESHOLD = Constants.PLAYER_PHEROMONE_GENERATOR_THRESHOLD
local COMMAND_TIMEOUT = constants.COMMAND_TIMEOUT local COMMAND_TIMEOUT = Constants.COMMAND_TIMEOUT
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE local PLAYER_PHEROMONE = Constants.PLAYER_PHEROMONE
local BASE_PHEROMONE = constants.BASE_PHEROMONE local BASE_PHEROMONE = Constants.BASE_PHEROMONE
local ENEMY_PHEROMONE = constants.ENEMY_PHEROMONE local ENEMY_PHEROMONE = Constants.ENEMY_PHEROMONE
local RESOURCE_PHEROMONE = constants.RESOURCE_PHEROMONE local RESOURCE_PHEROMONE = Constants.RESOURCE_PHEROMONE
local FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT = constants.FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT local FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT = Constants.FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT
local SQUAD_BUILDING = constants.SQUAD_BUILDING local SQUAD_BUILDING = Constants.SQUAD_BUILDING
local SQUAD_RAIDING = constants.SQUAD_RAIDING local SQUAD_RAIDING = Constants.SQUAD_RAIDING
local SQUAD_SETTLING = constants.SQUAD_SETTLING local SQUAD_SETTLING = Constants.SQUAD_SETTLING
local SQUAD_GUARDING = constants.SQUAD_GUARDING local SQUAD_GUARDING = Constants.SQUAD_GUARDING
local SQUAD_RETREATING = constants.SQUAD_RETREATING local SQUAD_RETREATING = Constants.SQUAD_RETREATING
local BASE_AI_STATE_SIEGE = constants.BASE_AI_STATE_SIEGE local BASE_AI_STATE_SIEGE = Constants.BASE_AI_STATE_SIEGE
local BASE_AI_STATE_AGGRESSIVE = constants.BASE_AI_STATE_AGGRESSIVE local BASE_AI_STATE_AGGRESSIVE = Constants.BASE_AI_STATE_AGGRESSIVE
local PLAYER_PHEROMONE_MULTIPLER = constants.PLAYER_PHEROMONE_MULTIPLER local PLAYER_PHEROMONE_MULTIPLER = Constants.PLAYER_PHEROMONE_MULTIPLER
local DEFINES_DISTRACTION_NONE = defines.distraction.none local DEFINES_DISTRACTION_NONE = defines.distraction.none
local DEFINES_DISTRACTION_BY_ENEMY = defines.distraction.by_enemy local DEFINES_DISTRACTION_BY_ENEMY = defines.distraction.by_enemy
@@ -57,33 +61,33 @@ local DEFINES_DISTRACTION_BY_ANYTHING = defines.distraction.by_anything
-- imported functions -- imported functions
local getPlayerGenerator = chunkPropertyUtils.getPlayerGenerator local getPlayerGenerator = ChunkPropertyUtils.getPlayerGenerator
local setPositionInCommand = queryUtils.setPositionInCommand local setPositionInCommand = QueryUtils.setPositionInCommand
local euclideanDistancePoints = mathUtils.euclideanDistancePoints local euclideanDistancePoints = MathUtils.euclideanDistancePoints
local findMovementPosition = movementUtils.findMovementPosition local findMovementPosition = MovementUtils.findMovementPosition
local removeSquadFromChunk = chunkPropertyUtils.removeSquadFromChunk local removeSquadFromChunk = ChunkPropertyUtils.removeSquadFromChunk
local addDeathGenerator = chunkPropertyUtils.addDeathGenerator local addDeathGenerator = ChunkPropertyUtils.addDeathGenerator
local getHiveCount = chunkPropertyUtils.getHiveCount local getHiveCount = ChunkPropertyUtils.getHiveCount
local getNestCount = chunkPropertyUtils.getNestCount local getNestCount = ChunkPropertyUtils.getNestCount
local getNeighborChunks = mapUtils.getNeighborChunks local getNeighborChunks = MapUtils.getNeighborChunks
local addSquadToChunk = chunkPropertyUtils.addSquadToChunk local addSquadToChunk = ChunkPropertyUtils.addSquadToChunk
local getChunkByXY = mapUtils.getChunkByXY local getChunkByXY = MapUtils.getChunkByXY
local positionToChunkXY = mapUtils.positionToChunkXY local positionToChunkXY = MapUtils.positionToChunkXY
local addMovementPenalty = movementUtils.addMovementPenalty local addMovementPenalty = MovementUtils.addMovementPenalty
local positionFromDirectionAndFlat = mapUtils.positionFromDirectionAndFlat local positionFromDirectionAndFlat = MapUtils.positionFromDirectionAndFlat
local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed local euclideanDistanceNamed = MathUtils.euclideanDistanceNamed
local getPlayerBaseGenerator = chunkPropertyUtils.getPlayerBaseGenerator local getPlayerBaseGenerator = ChunkPropertyUtils.getPlayerBaseGenerator
local getResourceGenerator = chunkPropertyUtils.getResourceGenerator local getResourceGenerator = ChunkPropertyUtils.getResourceGenerator
local scoreNeighborsForAttack = movementUtils.scoreNeighborsForAttack local scoreNeighborsForAttack = MovementUtils.scoreNeighborsForAttack
local scoreNeighborsForSettling = movementUtils.scoreNeighborsForSettling local scoreNeighborsForSettling = MovementUtils.scoreNeighborsForSettling
-- module code -- module code
local function scoreResourceLocation(map, neighborChunk) local function scoreResourceLocation(map, neighborChunk)
@@ -107,7 +111,6 @@ local function scoreAttackLocation(map, neighborChunk)
end end
local function settleMove(map, squad) local function settleMove(map, squad)
local universe = map.universe
local group = squad.group local group = squad.group
local targetPosition = {x=0,y=0} local targetPosition = {x=0,y=0}
@@ -141,7 +144,7 @@ local function settleMove(map, squad)
( (
(distance >= squad.maxDistance) or (distance >= squad.maxDistance) or
( (
(getResourceGenerator(map, chunk) ~= 0) and (getNestCount(map, chunk) == 0) and (getHiveCount(map, chunk) == 0) (getResourceGenerator(map, chunk) ~= 0) and (getNestCount(chunk) == 0) and (getHiveCount(map, chunk) == 0)
) )
) )
then then
@@ -151,7 +154,7 @@ local function settleMove(map, squad)
position = groupPosition position = groupPosition
end end
cmd = universe.settleCommand cmd = Universe.settleCommand
if squad.kamikaze then if squad.kamikaze then
cmd.distraction = DEFINES_DISTRACTION_NONE cmd.distraction = DEFINES_DISTRACTION_NONE
else else
@@ -173,11 +176,11 @@ local function settleMove(map, squad)
scoreFunction) scoreFunction)
if (attackChunk == -1) then if (attackChunk == -1) then
cmd = universe.wanderCommand cmd = Universe.wanderCommand
group.set_command(cmd) group.set_command(cmd)
return return
elseif (attackDirection ~= 0) then elseif (attackDirection ~= 0) then
local attackPlayerThreshold = universe.attackPlayerThreshold local attackPlayerThreshold = Universe.attackPlayerThreshold
if (nextAttackChunk ~= -1) then if (nextAttackChunk ~= -1) then
if (getPlayerBaseGenerator(map, nextAttackChunk) == 0) if (getPlayerBaseGenerator(map, nextAttackChunk) == 0)
@@ -216,7 +219,7 @@ local function settleMove(map, squad)
addDeathGenerator(map, attackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT) addDeathGenerator(map, attackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
end end
else else
cmd = universe.wanderCommand cmd = Universe.wanderCommand
group.set_command(cmd) group.set_command(cmd)
return return
end end
@@ -225,7 +228,7 @@ local function settleMove(map, squad)
((getPlayerBaseGenerator(map, nextAttackChunk) ~= 0) ((getPlayerBaseGenerator(map, nextAttackChunk) ~= 0)
or (getPlayerGenerator(map, nextAttackChunk) >= PLAYER_PHEROMONE_GENERATOR_THRESHOLD)) or (getPlayerGenerator(map, nextAttackChunk) >= PLAYER_PHEROMONE_GENERATOR_THRESHOLD))
then then
cmd = universe.settleCommand cmd = Universe.settleCommand
squad.status = SQUAD_BUILDING squad.status = SQUAD_BUILDING
if squad.kamikaze then if squad.kamikaze then
cmd.distraction = DEFINES_DISTRACTION_NONE cmd.distraction = DEFINES_DISTRACTION_NONE
@@ -235,7 +238,7 @@ local function settleMove(map, squad)
elseif (getPlayerBaseGenerator(map, attackChunk) ~= 0) or elseif (getPlayerBaseGenerator(map, attackChunk) ~= 0) or
(attackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold) (attackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold)
then then
cmd = universe.attackCommand cmd = Universe.attackCommand
if not squad.rabid then if not squad.rabid then
squad.frenzy = true squad.frenzy = true
@@ -243,7 +246,7 @@ local function settleMove(map, squad)
squad.frenzyPosition.y = groupPosition.y squad.frenzyPosition.y = groupPosition.y
end end
else else
cmd = universe.moveCommand cmd = Universe.moveCommand
if squad.rabid or squad.kamikaze then if squad.rabid or squad.kamikaze then
cmd.distraction = DEFINES_DISTRACTION_NONE cmd.distraction = DEFINES_DISTRACTION_NONE
else else
@@ -251,7 +254,7 @@ local function settleMove(map, squad)
end end
end end
else else
cmd = universe.settleCommand cmd = Universe.settleCommand
targetPosition.x = groupPosition.x targetPosition.x = groupPosition.x
targetPosition.y = groupPosition.y targetPosition.y = groupPosition.y
@@ -271,7 +274,6 @@ local function settleMove(map, squad)
end end
local function attackMove(map, squad) local function attackMove(map, squad)
local universe = map.universe
local targetPosition = {0,0} local targetPosition = {0,0}
local group = squad.group local group = squad.group
@@ -301,7 +303,7 @@ local function attackMove(map, squad)
attackScorer) attackScorer)
local cmd local cmd
if (attackChunk == -1) then if (attackChunk == -1) then
cmd = universe.wanderCommand cmd = Universe.wanderCommand
group.set_command(cmd) group.set_command(cmd)
return return
end end
@@ -329,7 +331,7 @@ local function attackMove(map, squad)
end end
if not position then if not position then
cmd = universe.wanderCommand cmd = Universe.wanderCommand
group.set_command(cmd) group.set_command(cmd)
return return
else else
@@ -343,9 +345,9 @@ local function attackMove(map, squad)
end end
if (getPlayerBaseGenerator(map, attackChunk) ~= 0) and if (getPlayerBaseGenerator(map, attackChunk) ~= 0) and
(attackChunk[PLAYER_PHEROMONE] >= universe.attackPlayerThreshold) (attackChunk[PLAYER_PHEROMONE] >= Universe.attackPlayerThreshold)
then then
cmd = universe.attackCommand cmd = Universe.attackCommand
if not squad.rabid then if not squad.rabid then
squad.frenzy = true squad.frenzy = true
@@ -353,7 +355,7 @@ local function attackMove(map, squad)
squad.frenzyPosition.y = groupPosition.y squad.frenzyPosition.y = groupPosition.y
end end
else else
cmd = universe.moveCommand cmd = Universe.moveCommand
if squad.rabid or squad.frenzy then if squad.rabid or squad.frenzy then
cmd.distraction = DEFINES_DISTRACTION_BY_ANYTHING cmd.distraction = DEFINES_DISTRACTION_BY_ANYTHING
else else
@@ -367,22 +369,21 @@ end
local function buildMove(map, squad) local function buildMove(map, squad)
local group = squad.group local group = squad.group
local universe = map.universe
local groupPosition = group.position local groupPosition = group.position
local newGroupPosition = findMovementPosition(map.surface, groupPosition) local newGroupPosition = findMovementPosition(map.surface, groupPosition)
if not newGroupPosition then if not newGroupPosition then
setPositionInCommand(universe.settleCommand, groupPosition) setPositionInCommand(Universe.settleCommand, groupPosition)
else else
setPositionInCommand(universe.settleCommand, newGroupPosition) setPositionInCommand(Universe.settleCommand, newGroupPosition)
end end
group.set_command(universe.compoundSettleCommand) group.set_command(Universe.compoundSettleCommand)
end end
function squadAttack.cleanSquads(universe, tick) function SquadAttack.cleanSquads(tick)
local squads = universe.groupNumberToSquad local squads = Universe.groupNumberToSquad
local groupId = universe.squadIterator local groupId = Universe.squadIterator
local squad local squad
if not groupId then if not groupId then
groupId, squad = next(squads, groupId) groupId, squad = next(squads, groupId)
@@ -390,13 +391,13 @@ function squadAttack.cleanSquads(universe, tick)
squad = squads[groupId] squad = squads[groupId]
end end
if not groupId then if not groupId then
universe.squadIterator = nil Universe.squadIterator = nil
if (table_size(squads) == 0) then if (table_size(squads) == 0) then
-- this is needed as the next command remembers the max length a table has been -- this is needed as the next command remembers the max length a table has been
universe.groupNumberToSquad = {} Universe.groupNumberToSquad = {}
end end
else else
universe.squadIterator = next(squads, groupId) Universe.squadIterator = next(squads, groupId)
local group = squad.group local group = squad.group
if not group.valid then if not group.valid then
if squad.chunk ~= -1 then if squad.chunk ~= -1 then
@@ -404,14 +405,14 @@ function squadAttack.cleanSquads(universe, tick)
end end
removeSquadFromChunk(squad.map, squad) removeSquadFromChunk(squad.map, squad)
if squad.settlers then if squad.settlers then
universe.builderCount = universe.builderCount - 1 Universe.builderCount = Universe.builderCount - 1
if universe.builderCount < 0 then if Universe.builderCount < 0 then
universe.builderCount = 0 Universe.builderCount = 0
end end
else else
universe.squadCount = universe.squadCount - 1 Universe.squadCount = Universe.squadCount - 1
if universe.squadCount < 0 then if Universe.squadCount < 0 then
universe.squadCount = 0 Universe.squadCount = 0
end end
if squad.type == BASE_AI_STATE_AGGRESSIVE then if squad.type == BASE_AI_STATE_AGGRESSIVE then
local base = squad.base local base = squad.base
@@ -424,13 +425,13 @@ function squadAttack.cleanSquads(universe, tick)
squads[groupId] = nil squads[groupId] = nil
elseif (group.state == 4) then elseif (group.state == 4) then
squad.wanders = 0 squad.wanders = 0
squadAttack.squadDispatch(squad.map, squad, tick) SquadAttack.squadDispatch(squad.map, squad, tick)
elseif (squad.commandTick and (squad.commandTick < tick)) then elseif (squad.commandTick and (squad.commandTick < tick)) then
if squad.wanders > 5 then if squad.wanders > 5 then
squad.group.destroy() squad.group.destroy()
else else
squad.wanders = squad.wanders + 1 squad.wanders = squad.wanders + 1
local cmd = universe.wander2Command local cmd = Universe.wander2Command
squad.commandTick = tick + COMMAND_TIMEOUT squad.commandTick = tick + COMMAND_TIMEOUT
group.set_command(cmd) group.set_command(cmd)
group.start_moving() group.start_moving()
@@ -439,7 +440,7 @@ function squadAttack.cleanSquads(universe, tick)
end end
end end
function squadAttack.squadDispatch(map, squad, tick) function SquadAttack.squadDispatch(map, squad, tick)
local group = squad.group local group = squad.group
if group and group.valid then if group and group.valid then
local status = squad.status local status = squad.status
@@ -475,5 +476,9 @@ function squadAttack.squadDispatch(map, squad, tick)
end end
end end
squadAttackG = squadAttack function SquadAttack.init(universe)
return squadAttack Universe = universe
end
SquadAttackG = SquadAttack
return SquadAttack

View File

@@ -14,47 +14,51 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
if aiDefenseG then if AiDefenseG then
return aiDefenseG return AiDefenseG
end end
local aiDefense = {} local AiDefense = {}
--
local Universe
-- imports -- imports
local constants = require("Constants") local Constants = require("Constants")
local mapUtils = require("MapUtils") local MapUtils = require("MapUtils")
local unitGroupUtils = require("UnitGroupUtils") local UnitGroupUtils = require("UnitGroupUtils")
local movementUtils = require("MovementUtils") local MovementUtils = require("MovementUtils")
local chunkPropertyUtils = require("ChunkPropertyUtils") local ChunkPropertyUtils = require("ChunkPropertyUtils")
-- constants -- Constants
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE local PLAYER_PHEROMONE = Constants.PLAYER_PHEROMONE
local BASE_PHEROMONE = constants.BASE_PHEROMONE local BASE_PHEROMONE = Constants.BASE_PHEROMONE
local PLAYER_PHEROMONE_MULTIPLER = constants.PLAYER_PHEROMONE_MULTIPLER local PLAYER_PHEROMONE_MULTIPLER = Constants.PLAYER_PHEROMONE_MULTIPLER
local SQUAD_RETREATING = constants.SQUAD_RETREATING local SQUAD_RETREATING = Constants.SQUAD_RETREATING
local COOLDOWN_RETREAT = constants.COOLDOWN_RETREAT local COOLDOWN_RETREAT = Constants.COOLDOWN_RETREAT
-- imported functions -- imported functions
local findNearbyBase = chunkPropertyUtils.findNearbyBase local findNearbyBase = ChunkPropertyUtils.findNearbyBase
local addSquadToChunk = chunkPropertyUtils.addSquadToChunk local addSquadToChunk = ChunkPropertyUtils.addSquadToChunk
local positionFromDirectionAndFlat = mapUtils.positionFromDirectionAndFlat local positionFromDirectionAndFlat = MapUtils.positionFromDirectionAndFlat
local getNeighborChunks = mapUtils.getNeighborChunks local getNeighborChunks = MapUtils.getNeighborChunks
local findNearbyRetreatingSquad = unitGroupUtils.findNearbyRetreatingSquad local findNearbyRetreatingSquad = UnitGroupUtils.findNearbyRetreatingSquad
local createSquad = unitGroupUtils.createSquad local createSquad = UnitGroupUtils.createSquad
local scoreNeighborsForRetreat = movementUtils.scoreNeighborsForRetreat local scoreNeighborsForRetreat = MovementUtils.scoreNeighborsForRetreat
local findMovementPosition = movementUtils.findMovementPosition local findMovementPosition = MovementUtils.findMovementPosition
local getRetreatTick = chunkPropertyUtils.getRetreatTick local getRetreatTick = ChunkPropertyUtils.getRetreatTick
local getPlayerBaseGenerator = chunkPropertyUtils.getPlayerBaseGenerator local getPlayerBaseGenerator = ChunkPropertyUtils.getPlayerBaseGenerator
local setRetreatTick = chunkPropertyUtils.setRetreatTick local setRetreatTick = ChunkPropertyUtils.setRetreatTick
local getEnemyStructureCount = chunkPropertyUtils.getEnemyStructureCount local getEnemyStructureCount = ChunkPropertyUtils.getEnemyStructureCount
-- module code -- module code
@@ -64,8 +68,8 @@ local function scoreRetreatLocation(map, neighborChunk)
-(getPlayerBaseGenerator(map, neighborChunk) * 1000)) -(getPlayerBaseGenerator(map, neighborChunk) * 1000))
end end
function aiDefense.retreatUnits(chunk, cause, map, tick, radius) function AiDefense.retreatUnits(chunk, cause, map, tick, radius)
if (tick - getRetreatTick(map, chunk) > COOLDOWN_RETREAT) and (getEnemyStructureCount(map, chunk) == 0) then if (tick - getRetreatTick(chunk) > COOLDOWN_RETREAT) and (getEnemyStructureCount(map, chunk) == 0) then
setRetreatTick(map, chunk, tick) setRetreatTick(map, chunk, tick)
local exitPath,exitDirection, local exitPath,exitDirection,
@@ -75,7 +79,6 @@ function aiDefense.retreatUnits(chunk, cause, map, tick, radius)
chunk.y), chunk.y),
scoreRetreatLocation, scoreRetreatLocation,
map) map)
local universe = map.universe
local position = { local position = {
x = chunk.x + 16, x = chunk.x + 16,
y = chunk.y + 16 y = chunk.y + 16
@@ -117,7 +120,7 @@ function aiDefense.retreatUnits(chunk, cause, map, tick, radius)
local created = false local created = false
if not newSquad then if not newSquad then
if (universe.squadCount < universe.AI_MAX_SQUAD_COUNT) then if (Universe.squadCount < Universe.AI_MAX_SQUAD_COUNT) then
created = true created = true
local base = findNearbyBase(map, chunk) local base = findNearbyBase(map, chunk)
if not base then if not base then
@@ -129,12 +132,12 @@ function aiDefense.retreatUnits(chunk, cause, map, tick, radius)
end end
end end
universe.fleeCommand.from = cause Universe.fleeCommand.from = cause
universe.retreatCommand.group = newSquad.group Universe.retreatCommand.group = newSquad.group
universe.formRetreatCommand.unit_search_distance = radius Universe.formRetreatCommand.unit_search_distance = radius
local foundUnits = surface.set_multi_command(universe.formRetreatCommand) local foundUnits = surface.set_multi_command(Universe.formRetreatCommand)
if (foundUnits == 0) then if (foundUnits == 0) then
if created then if created then
@@ -144,8 +147,8 @@ function aiDefense.retreatUnits(chunk, cause, map, tick, radius)
end end
if created then if created then
universe.groupNumberToSquad[newSquad.groupNumber] = newSquad Universe.groupNumberToSquad[newSquad.groupNumber] = newSquad
universe.squadCount = universe.squadCount + 1 Universe.squadCount = Universe.squadCount + 1
end end
newSquad.status = SQUAD_RETREATING newSquad.status = SQUAD_RETREATING
@@ -159,5 +162,9 @@ function aiDefense.retreatUnits(chunk, cause, map, tick, radius)
end end
end end
aiDefenseG = aiDefense function AiDefense.init(universe)
return aiDefense Universe = universe
end
AiDefenseG = AiDefense
return AiDefense

View File

@@ -14,35 +14,39 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
if unitGroupUtilsG then if UnitGroupUtilsG then
return unitGroupUtilsG return UnitGroupUtilsG
end end
local unitGroupUtils = {} local UnitGroupUtils = {}
--
local Universe
-- imports -- imports
local mapUtils = require("MapUtils") local MapUtils = require("MapUtils")
local constants = require("Constants") local Constants = require("Constants")
local chunkPropertyUtils = require("ChunkPropertyUtils") local ChunkPropertyUtils = require("ChunkPropertyUtils")
local mathUtils = require("MathUtils") local MathUtils = require("MathUtils")
-- constants -- Constants
local MINIMUM_EXPANSION_DISTANCE = constants.MINIMUM_EXPANSION_DISTANCE local MINIMUM_EXPANSION_DISTANCE = Constants.MINIMUM_EXPANSION_DISTANCE
local SQUAD_RETREATING = constants.SQUAD_RETREATING local SQUAD_RETREATING = Constants.SQUAD_RETREATING
local SQUAD_GUARDING = constants.SQUAD_GUARDING local SQUAD_GUARDING = Constants.SQUAD_GUARDING
-- imported functions -- imported functions
local gaussianRandomRangeRG = mathUtils.gaussianRandomRangeRG local gaussianRandomRangeRG = MathUtils.gaussianRandomRangeRG
local getSquadsOnChunk = chunkPropertyUtils.getSquadsOnChunk local getSquadsOnChunk = ChunkPropertyUtils.getSquadsOnChunk
local getNeighborChunks = mapUtils.getNeighborChunks local getNeighborChunks = MapUtils.getNeighborChunks
-- module code -- module code
function unitGroupUtils.findNearbyRetreatingSquad(map, chunk) function UnitGroupUtils.findNearbyRetreatingSquad(map, chunk)
for _,squad in pairs(getSquadsOnChunk(map, chunk)) do for _,squad in pairs(getSquadsOnChunk(map, chunk)) do
local unitGroup = squad.group local unitGroup = squad.group
@@ -67,7 +71,7 @@ function unitGroupUtils.findNearbyRetreatingSquad(map, chunk)
return nil return nil
end end
function unitGroupUtils.findNearbySquad(map, chunk) function UnitGroupUtils.findNearbySquad(map, chunk)
for _,squad in pairs(getSquadsOnChunk(map, chunk)) do for _,squad in pairs(getSquadsOnChunk(map, chunk)) do
local unitGroup = squad.group local unitGroup = squad.group
@@ -93,28 +97,28 @@ function unitGroupUtils.findNearbySquad(map, chunk)
return nil return nil
end end
function unitGroupUtils.calculateSettlerMaxDistance(universe) function UnitGroupUtils.calculateSettlerMaxDistance()
local targetDistance local targetDistance
local distanceRoll = universe.random() local distanceRoll = Universe.random()
if distanceRoll < 0.05 then if distanceRoll < 0.05 then
return 0 return 0
elseif distanceRoll < 0.30 then elseif distanceRoll < 0.30 then
targetDistance = universe.expansionLowTargetDistance targetDistance = Universe.expansionLowTargetDistance
elseif distanceRoll < 0.70 then elseif distanceRoll < 0.70 then
targetDistance = universe.expansionMediumTargetDistance targetDistance = Universe.expansionMediumTargetDistance
elseif distanceRoll < 0.95 then elseif distanceRoll < 0.95 then
targetDistance = universe.expansionHighTargetDistance targetDistance = Universe.expansionHighTargetDistance
else else
return universe.expansionMaxDistance return Universe.expansionMaxDistance
end end
return gaussianRandomRangeRG(targetDistance, return gaussianRandomRangeRG(targetDistance,
universe.expansionDistanceDeviation, Universe.expansionDistanceDeviation,
MINIMUM_EXPANSION_DISTANCE, MINIMUM_EXPANSION_DISTANCE,
universe.expansionMaxDistance, Universe.expansionMaxDistance,
universe.random) Universe.random)
end end
function unitGroupUtils.createSquad(position, map, group, settlers, base) function UnitGroupUtils.createSquad(position, map, group, settlers, base)
local unitGroup = group or map.surface.create_unit_group({position=position}) local unitGroup = group or map.surface.create_unit_group({position=position})
local squad = { local squad = {
@@ -140,7 +144,7 @@ function unitGroupUtils.createSquad(position, map, group, settlers, base)
} }
if settlers then if settlers then
squad.maxDistance = unitGroupUtils.calculateSettlerMaxDistance(map.universe) squad.maxDistance = UnitGroupUtils.calculateSettlerMaxDistance()
end end
if position then if position then
@@ -154,15 +158,19 @@ function unitGroupUtils.createSquad(position, map, group, settlers, base)
return squad return squad
end end
function unitGroupUtils.calculateKamikazeSquadThreshold(memberCount, universe) function UnitGroupUtils.calculateKamikazeSquadThreshold(memberCount)
local threshold = (memberCount / universe.attackWaveMaxSize) * 0.2 + (universe.evolutionLevel * 0.2) local threshold = (memberCount / Universe.attackWaveMaxSize) * 0.2 + (Universe.evolutionLevel * 0.2)
return threshold return threshold
end end
function unitGroupUtils.calculateKamikazeSettlerThreshold(memberCount, universe) function UnitGroupUtils.calculateKamikazeSettlerThreshold(memberCount)
local threshold = (memberCount / universe.expansionMaxSize) * 0.2 + (universe.evolutionLevel * 0.2) local threshold = (memberCount / Universe.expansionMaxSize) * 0.2 + (Universe.evolutionLevel * 0.2)
return threshold return threshold
end end
unitGroupUtilsG = unitGroupUtils function UnitGroupUtils.init(universe)
return unitGroupUtils Universe = universe
end
UnitGroupUtilsG = UnitGroupUtils
return UnitGroupUtils

View File

@@ -14,7 +14,7 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>. -- along with this program. If not, see <https://www.gnu.org/licenses/>.
local upgrade = {} local Upgrade = {}
-- imports -- imports
@@ -23,6 +23,10 @@ local chunkProcessor = require("libs/ChunkProcessor")
local chunkPropertyUtils = require("libs/ChunkPropertyUtils") local chunkPropertyUtils = require("libs/ChunkPropertyUtils")
local mapUtils = require("libs/MapUtils") local mapUtils = require("libs/MapUtils")
--
local Universe
-- constants -- constants
local MINIMUM_EXPANSION_DISTANCE = constants.MINIMUM_EXPANSION_DISTANCE local MINIMUM_EXPANSION_DISTANCE = constants.MINIMUM_EXPANSION_DISTANCE
@@ -60,7 +64,7 @@ local processPendingChunks = chunkProcessor.processPendingChunks
-- module code -- module code
function upgrade.isExcludedSurface(surfaceName) function Upgrade.isExcludedSurface(surfaceName)
return return
(surfaceName == "aai-signals") or (surfaceName == "aai-signals") or
(surfaceName == "RTStasisRealm") or (surfaceName == "RTStasisRealm") or
@@ -414,97 +418,170 @@ local function addCommandSet(queriesAndCommands)
} }
end end
function upgrade.excludeSurface(universe) function Upgrade.excludeSurface()
for mapId,map in pairs(universe.maps) do for mapId,map in pairs(Universe.maps) do
local toBeRemoved = not map.surface.valid or upgrade.isExcludedSurface(map.surface.name) or universe.excludedSurfaces[map.surface.name] local toBeRemoved = not map.surface.valid or Upgrade.isExcludedSurface(map.surface.name) or Universe.excludedSurfaces[map.surface.name]
if toBeRemoved then if toBeRemoved then
if universe.mapIterator == mapId then if Universe.mapIterator == mapId then
universe.mapIterator, universe.activeMap = next(universe.maps, universe.mapIterator) Universe.mapIterator, Universe.activeMap = next(Universe.maps, Universe.mapIterator)
end end
if universe.processMapAIIterator == mapId then if Universe.processMapAIIterator == mapId then
universe.processMapAIIterator = nil Universe.processMapAIIterator = nil
end end
universe.maps[mapId] = nil Universe.maps[mapId] = nil
end end
end end
end end
function upgrade.setCommandForces(universe, npcForces, enemyForces) function Upgrade.setCommandForces(npcForces, enemyForces)
for force in pairs(universe.playerForces) do for force in pairs(Universe.playerForces) do
universe.playerForces[force] = nil Universe.playerForces[force] = nil
end end
for force in pairs(universe.npcForces) do for force in pairs(Universe.npcForces) do
universe.npcForces[force] = nil Universe.npcForces[force] = nil
end end
for force in pairs(universe.enemyForces) do for force in pairs(Universe.enemyForces) do
universe.enemyForces[force] = nil Universe.enemyForces[force] = nil
end end
for force in pairs(universe.nonPlayerForces) do for force in pairs(Universe.nonPlayerForces) do
universe.nonPlayerForces[force] = nil Universe.nonPlayerForces[force] = nil
end end
for _,force in pairs(game.forces) do for _,force in pairs(game.forces) do
if not npcForces[force.name] and not enemyForces[force.name] then if not npcForces[force.name] and not enemyForces[force.name] then
universe.playerForces[#universe.playerForces+1] = force.name Universe.playerForces[#Universe.playerForces+1] = force.name
end end
end end
for force in pairs(enemyForces) do for force in pairs(enemyForces) do
universe.enemyForces[#universe.enemyForces+1] = force Universe.enemyForces[#Universe.enemyForces+1] = force
universe.nonPlayerForces[#universe.nonPlayerForces+1] = force Universe.nonPlayerForces[#Universe.nonPlayerForces+1] = force
end end
for force in pairs(npcForces) do for force in pairs(npcForces) do
universe.npcForces[#universe.npcForces+1] = force Universe.npcForces[#Universe.npcForces+1] = force
universe.nonPlayerForces[#universe.nonPlayerForces+1] = force Universe.nonPlayerForces[#Universe.nonPlayerForces+1] = force
end end
end end
function upgrade.attempt(universe) function Upgrade.addUniverseProperties()
local starting = global.version if not global.universePropertyVersion then
if not global.version or global.version < 302 then for key in pairs(global) do
global.version = 302 if key ~= "universe" then
global[key] = nil
if not universe then end
universe = {}
global.universe = universe
end end
for key in pairs(Universe) do
Universe[key] = nil
end
global.universePropertyVersion = 0
end
if global.universePropertyVersion < 1 then
global.universePropertyVersion = 1
Universe.safeEntities = {}
Universe.aiPointsScaler = settings.global["rampant--aiPointsScaler"].value
Universe.aiPointsPrintGainsToChat = settings.global["rampant--aiPointsPrintGainsToChat"].value
Universe.aiPointsPrintSpendingToChat = settings.global["rampant--aiPointsPrintSpendingToChat"].value
Universe.aiNocturnalMode = settings.global["rampant--permanentNocturnal"].value
Universe.retreatThreshold = 0
Universe.rallyThreshold = 0
Universe.formSquadThreshold = 0
Universe.attackWaveSize = 0
Universe.attackWaveDeviation = 0
Universe.attackWaveUpperBound = 0
Universe.unitRefundAmount = 0
Universe.regroupIndex = 1
Universe.kamikazeThreshold = 0
Universe.attackWaveLowerBound = 1
Universe.settlerCooldown = 0
Universe.settlerWaveDeviation = 0
Universe.settlerWaveSize = 0
Universe.enabledMigration = Universe.expansion and settings.global["rampant--enableMigration"].value
Universe.peacefulAIToggle = settings.global["rampant--peacefulAIToggle"].value
Universe.printAIStateChanges = settings.global["rampant--printAIStateChanges"].value
Universe.debugTemperament = settings.global["rampant--debugTemperament"].value
Universe.eventId = 0
Universe.chunkId = 0
Universe.maps = {}
Universe.chunkIdToChunk = {}
Universe.groupNumberToSquad = {}
Universe.chunkToVictory = {}
Universe.pendingChunks = {}
Universe.processActiveNest = {}
Universe.processActiveNestIterator = nil
Universe.deployVengenceIterator = nil
Universe.pendingUpgradeIterator = nil
Universe.victoryScentIterator = nil
Universe.squadIterator = nil
Universe.processMapAIIterator = nil
Universe.processNestIterator = nil
Universe.vengenceQueue = {}
Universe.activeMap = nil
Universe.mapIterator = nil
Universe.builderCount = 0
Universe.squadCount = 0
Universe.chunkToNests = {}
Universe.processActiveSpawnerIterator = nil
Universe.processActiveRaidSpawnerIterator = nil
Universe.processMigrationIterator = nil
Universe.chunkToDrainedIterator = nil
Universe.chunkToActiveNest = {}
Universe.chunkToActiveRaidNest = {}
Universe.chunkToDrained = {}
Universe.chunkToRetreatIterator = nil
Universe.chunkToRetreats = {}
Universe.chunkToRallyIterator = nil
Universe.chunkToRallys = {}
Universe.chunkToPassScan = {}
Universe.chunkToPassScanIterator = nil
Universe.baseId = 0
Universe.awake = false
Universe.recycleBaseIterator = nil
Universe.maxPoints = 0
Universe.maxOverflowPoints = 0
addCommandSet(Universe)
Universe.bases = {}
Universe.processBaseAIIterator = nil
for _,map in pairs(Universe.maps) do
local processQueue = map.processQueue
for i=1,#processQueue do
local chunk = processQueue[i]
chunk[CHUNK_TICK] = chunk[ENEMY_PHEROMONE]
chunk[ENEMY_PHEROMONE] = 0
end
end
Universe.excludedSurfaces = {}
Universe.pendingUpgrades = {}
Universe.settlePurpleCloud = {}
Universe.settlePurpleCloud.len = 0
end
end
function Upgrade.attempt()
if not global.gameVersion then
global.gameVersion = 1
game.forces.enemy.kill_all_units() game.forces.enemy.kill_all_units()
universe.safeEntities = {}
universe.aiPointsScaler = settings.global["rampant--aiPointsScaler"].value
universe.aiPointsPrintGainsToChat = settings.global["rampant--aiPointsPrintGainsToChat"].value
universe.aiPointsPrintSpendingToChat = settings.global["rampant--aiPointsPrintSpendingToChat"].value
universe.aiNocturnalMode = settings.global["rampant--permanentNocturnal"].value
universe.mapIterator = nil
universe.retreatThreshold = 0
universe.rallyThreshold = 0
universe.formSquadThreshold = 0
universe.attackWaveSize = 0
universe.attackWaveDeviation = 0
universe.attackWaveUpperBound = 0
universe.unitRefundAmount = 0
universe.regroupIndex = 1
game.map_settings.path_finder.min_steps_to_check_path_find_termination = game.map_settings.path_finder.min_steps_to_check_path_find_termination =
constants.PATH_FINDER_MIN_STEPS_TO_CHECK_PATH constants.PATH_FINDER_MIN_STEPS_TO_CHECK_PATH
universe.kamikazeThreshold = 0
universe.attackWaveLowerBound = 1
universe.expansionMaxDistanceDerivation = nil
universe.settlerCooldown = 0
universe.settlerWaveDeviation = 0
universe.settlerWaveSize = 0
universe.enabledMigration = universe.expansion and settings.global["rampant--enableMigration"].value
universe.peacefulAIToggle = settings.global["rampant--peacefulAIToggle"].value
universe.printAIStateChanges = settings.global["rampant--printAIStateChanges"].value
universe.debugTemperament = settings.global["rampant--debugTemperament"].value
game.map_settings.unit_group.min_group_radius = constants.UNIT_GROUP_MAX_RADIUS * 0.5 game.map_settings.unit_group.min_group_radius = constants.UNIT_GROUP_MAX_RADIUS * 0.5
game.map_settings.unit_group.max_group_radius = constants.UNIT_GROUP_MAX_RADIUS game.map_settings.unit_group.max_group_radius = constants.UNIT_GROUP_MAX_RADIUS
@@ -517,60 +594,9 @@ function upgrade.attempt(universe)
game.map_settings.unit_group.tick_tolerance_when_member_arrives = 60 game.map_settings.unit_group.tick_tolerance_when_member_arrives = 60
game.forces.enemy.ai_controllable = true game.forces.enemy.ai_controllable = true
universe.evolutionLevel = game.forces.enemy.evolution_factor Universe.evolutionLevel = game.forces.enemy.evolution_factor
global.pendingChunks = nil -- removes old pendingChunks
global.natives = nil -- removes old natives
global.map = nil -- removes old map
universe.eventId = 0 for _,map in pairs(Universe.maps) do
universe.chunkId = 0
universe.randomGenerator = nil
game.forces.enemy.kill_all_units()
universe.maps = {}
universe.chunkIdToChunk = {}
universe.groupNumberToSquad = {}
universe.chunkToVictory = {}
universe.pendingChunks = {}
universe.processActiveNest = {}
universe.processActiveNestIterator = nil
universe.deployVengenceIterator = nil
universe.pendingUpgradeIterator = nil
universe.victoryScentIterator = nil
universe.squadIterator = nil
universe.processMapAIIterator = nil
universe.processNestIterator = nil
universe.vengenceQueue = {}
universe.activeMap = nil
universe.mapIterator = nil
universe.builderCount = 0
universe.squadCount = 0
universe.chunkToNests = {}
universe.processActiveSpawnerIterator = nil
universe.processActiveRaidSpawnerIterator = nil
universe.processMigrationIterator = nil
universe.chunkToDrainedIterator = nil
universe.chunkToActiveNest = {}
universe.chunkToActiveRaidNest = {}
universe.chunkToDrained = {}
universe.chunkToRetreatIterator = nil
universe.chunkToRetreats = {}
universe.chunkToRallyIterator = nil
universe.chunkToRallys = {}
universe.chunkToPassScan = {}
universe.chunkToPassScanIterator = nil
universe.baseId = 0
universe.awake = false
universe.recycleBaseIterator = nil
universe.maxPoints = 0
universe.maxOverflowPoints = 0
addCommandSet(universe)
universe.bases = {}
for _,map in pairs(universe.maps) do
if (map.surface.valid) then if (map.surface.valid) then
local entities = map.surface.find_entities_filtered({type="land-mine"}) local entities = map.surface.find_entities_filtered({type="land-mine"})
for i=1,#entities do for i=1,#entities do
@@ -582,73 +608,26 @@ function upgrade.attempt(universe)
end end
end end
upgrade.excludeSurface(universe) Universe.random = game.create_random_generator()
universe.processBaseAIIterator = nil Upgrade.excludeSurface()
end
if global.version < 304 then
global.version = 304
universe.random = game.create_random_generator()
for _,map in pairs(universe.maps) do
map.random = universe.random
local processQueue = map.processQueue
for i=1,#processQueue do
local chunk = processQueue[i]
chunk[CHUNK_TICK] = chunk[ENEMY_PHEROMONE]
chunk[ENEMY_PHEROMONE] = 0
end
end
end
if global.version < 305 then
global.version = 305
universe.excludedSurfaces = {}
universe.evolutionTableAlignment = nil
universe.buildingSpaceLookup = nil
universe.enemyAlignmentLookup = nil
universe.upgradeLookup = nil
universe.buildingEvolveLookup = nil
universe.costLookup = nil
universe.buildingHiveTypeLookup = nil
universe.proxyEntityLookup = nil
universe.vanillaEntityTypeLookup = nil
universe.entitySkipCountLookup = nil
universe.evoToTierMapping = nil
end
if global.version < 307 then
global.version = 307
local minDiffuse = game.map_settings.pollution.min_to_diffuse local minDiffuse = game.map_settings.pollution.min_to_diffuse
universe.pollutionDiffuseMinimum = minDiffuse * 0.75 Universe.pollutionDiffuseMinimum = minDiffuse * 0.75
universe.expansion = game.map_settings.enemy_expansion.enabled Universe.expansion = game.map_settings.enemy_expansion.enabled
universe.expansionMaxDistance = game.map_settings.enemy_expansion.max_expansion_distance * CHUNK_SIZE Universe.expansionMaxDistance = game.map_settings.enemy_expansion.max_expansion_distance * CHUNK_SIZE
universe.expansionMinTime = game.map_settings.enemy_expansion.min_expansion_cooldown / TICKS_A_MINUTE Universe.expansionMinTime = game.map_settings.enemy_expansion.min_expansion_cooldown / TICKS_A_MINUTE
universe.expansionMaxTime = game.map_settings.enemy_expansion.max_expansion_cooldown / TICKS_A_MINUTE Universe.expansionMaxTime = game.map_settings.enemy_expansion.max_expansion_cooldown / TICKS_A_MINUTE
universe.expansionMinSize = game.map_settings.enemy_expansion.settler_group_min_size Universe.expansionMinSize = game.map_settings.enemy_expansion.settler_group_min_size
universe.expansionMaxSize = game.map_settings.enemy_expansion.settler_group_max_size Universe.expansionMaxSize = game.map_settings.enemy_expansion.settler_group_max_size
universe.expansionLowTargetDistance = (universe.expansionMaxDistance + MINIMUM_EXPANSION_DISTANCE) * 0.33 Universe.expansionLowTargetDistance = (Universe.expansionMaxDistance + MINIMUM_EXPANSION_DISTANCE) * 0.33
universe.expansionMediumTargetDistance = (universe.expansionMaxDistance + MINIMUM_EXPANSION_DISTANCE) * 0.50 Universe.expansionMediumTargetDistance = (Universe.expansionMaxDistance + MINIMUM_EXPANSION_DISTANCE) * 0.50
universe.expansionHighTargetDistance = (universe.expansionMaxDistance + MINIMUM_EXPANSION_DISTANCE) * 0.75 Universe.expansionHighTargetDistance = (Universe.expansionMaxDistance + MINIMUM_EXPANSION_DISTANCE) * 0.75
universe.expansionDistanceDeviation = universe.expansionMediumTargetDistance * 0.33 Universe.expansionDistanceDeviation = Universe.expansionMediumTargetDistance * 0.33
universe.pendingUpgrades = {} for _,map in pairs(Universe.maps) do
universe.settlePurpleCloud = {}
universe.settlePurpleCloud.len = 0
for _,base in pairs(universe.bases) do
base.maxExpansionGroups = 0
base.sentExpansionGroups = 0
base.resetExpensionGroupsTick = 0
base.alignmentHistory = {}
base.resourceChunks = {}
base.resourceChunkCount = 0
end
for _,map in pairs(universe.maps) do
if (map.surface.valid) then if (map.surface.valid) then
for _, chunk in pairs(map.processQueue) do for _, chunk in pairs(map.processQueue) do
if getResourceGenerator(map, chunk) > 0 then if getResourceGenerator(map, chunk) > 0 then
@@ -663,16 +642,12 @@ function upgrade.attempt(universe)
map.chunkToPermanentDeathGenerator = {} map.chunkToPermanentDeathGenerator = {}
end end
end end
game.print("Rampant - Version 3.2.0")
end end
return (starting ~= global.version) and global.version
end end
function upgrade.prepMap(universe, surface) function Upgrade.prepMap(surface)
local surfaceName = surface.name local surfaceName = surface.name
if upgrade.isExcludedSurface(surfaceName) then if Upgrade.isExcludedSurface(surfaceName) then
return return
end end
@@ -680,12 +655,12 @@ function upgrade.prepMap(universe, surface)
local surfaceIndex = surface.index local surfaceIndex = surface.index
if not universe.maps then if not Universe.maps then
universe.maps = {} Universe.maps = {}
end end
local map = {} local map = {}
universe.maps[surfaceIndex] = map Universe.maps[surfaceIndex] = map
map.activatedMap = false map.activatedMap = false
@@ -729,35 +704,35 @@ function upgrade.prepMap(universe, surface)
map.emptySquadsOnChunk = {} map.emptySquadsOnChunk = {}
map.surface = surface map.surface = surface
map.universe = universe
map.bases = {} map.bases = {}
map.squads = nil map.squads = nil
map.pendingAttack = nil map.pendingAttack = nil
map.building = nil map.building = nil
map.random = universe.random
-- queue all current chunks that wont be generated during play -- queue all current chunks that wont be generated during play
local tick = game.tick local tick = game.tick
for chunk in surface.get_chunks() do for chunk in surface.get_chunks() do
if surface.is_chunk_generated(chunk) then if surface.is_chunk_generated(chunk) then
queueGeneratedChunk(universe, queueGeneratedChunk({
{ surface = surface,
surface = surface, tick = tick,
tick = tick, area = {
area = { left_top = {
left_top = { x = chunk.x * 32,
x = chunk.x * 32, y = chunk.y * 32
y = chunk.y * 32 }
} }
}
} }
) )
end end
end end
processPendingChunks(universe, tick, true) processPendingChunks(tick, true)
end end
return upgrade function Upgrade.init(universe)
Universe = universe
end
return Upgrade

View File

@@ -24,7 +24,6 @@
(string->path "COPYING") (string->path "COPYING")
(string->path "tests.lua") (string->path "tests.lua")
(string->path "changelog.txt") (string->path "changelog.txt")
(string->path "Upgrade.lua")
(string->path "settings.lua") (string->path "settings.lua")
(string->path "README.md") (string->path "README.md")
(string->path "thumbnail.png") (string->path "thumbnail.png")
@@ -67,7 +66,6 @@
(copyFile "data-final-fixes.lua" modFolder) (copyFile "data-final-fixes.lua" modFolder)
(copyFile "settings.lua" modFolder) (copyFile "settings.lua" modFolder)
(copyFile "changelog.txt" modFolder) (copyFile "changelog.txt" modFolder)
(copyFile "Upgrade.lua" modFolder)
(copyFile "tests.lua" modFolder) (copyFile "tests.lua" modFolder)
(copyFile "thumbnail.png" modFolder) (copyFile "thumbnail.png" modFolder)
(copyDirectory "libs" modFolder) (copyDirectory "libs" modFolder)