1
0
mirror of https://github.com/veden/Rampant.git synced 2024-12-26 20:54:12 +02:00
Rampant/libs/Upgrade.lua
2023-04-04 22:50:59 -07:00

583 lines
17 KiB
Lua

-- Copyright (C) 2022 veden
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
local Upgrade = {}
-- imports
local Constants = require("libs/Constants")
--
local Universe
-- Constants
local BASE_PHEROMONE = Constants.BASE_PHEROMONE
local PLAYER_PHEROMONE = Constants.PLAYER_PHEROMONE
local RESOURCE_PHEROMONE = Constants.RESOURCE_PHEROMONE
local ENEMY_PHEROMONE = Constants.ENEMY_PHEROMONE
local KAMIKAZE_PHEROMONE = Constants.KAMIKAZE_PHEROMONE
local CHUNK_TICK = Constants.CHUNK_TICK
local MINIMUM_EXPANSION_DISTANCE = Constants.MINIMUM_EXPANSION_DISTANCE
local DEFINES_COMMAND_GROUP = defines.command.group
local DEFINES_COMMAND_WANDER = defines.command.wander
local DEFINES_COMMAND_BUILD_BASE = defines.command.build_base
local DEFINES_COMMAND_ATTACK_AREA = defines.command.attack_area
local DEFINES_COMMAND_GO_TO_LOCATION = defines.command.go_to_location
local DEFINES_COMMMAD_COMPOUND = defines.command.compound
local DEFINES_COMMAND_FLEE = defines.command.flee
local DEFINES_COMMAND_STOP = defines.command.stop
local DEFINES_COMPOUND_COMMAND_RETURN_LAST = defines.compound_command.return_last
local DEFINES_DISTRACTION_NONE = defines.distraction.none
local DEFINES_DISTRACTION_BY_ENEMY = defines.distraction.by_enemy
local DEFINES_DISTRACTION_BY_ANYTHING = defines.distraction.by_anything
local CHUNK_SIZE = Constants.CHUNK_SIZE
local TRIPLE_CHUNK_SIZE = Constants.TRIPLE_CHUNK_SIZE
local TICKS_A_MINUTE = Constants.TICKS_A_MINUTE
-- imported functions
-- module code
local function addCommandSet()
-- preallocating memory to be used in code, making it fast by reducing garbage generated.
Universe.playerForces = {}
Universe.enemyForces = {}
Universe.npcForces = {}
Universe.nonPlayerForces = {}
Universe.mapUtilsQueries = {}
Universe.mapUtilsQueries.neighbors = {
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1
}
Universe.mapUtilsQueries.position = {0,0}
Universe.chunkOverlapArray = {
-1,
-1,
-1,
-1
}
Universe.chunkPropertyUtilsQueries = {}
Universe.chunkPropertyUtilsQueries.position = {0,0}
-- pb
Universe.pbFilteredEntitiesPointQueryLimited = {
position = {0, 0},
radius = 10,
limit = 1,
force = Universe.enemyForces,
type = {
"unit-spawner",
"turret"
}
}
-- msec
Universe.msecFilteredEntitiesEnemyStructureQuery = {
area={
{0,0},
{0,0}
},
force=Universe.enemyForces,
type={
"turret",
"unit-spawner"
}
}
-- oba
Universe.obaCreateBuildCloudQuery = {
name = "build-clear-cloud-rampant",
position = {0,0}
}
-- sp
local spbSharedChunkArea = {
{0,0},
{0,0}
}
Universe.spbHasPlayerStructuresQuery = {
area=spbSharedChunkArea,
force=Universe.nonPlayerForces,
invert=true,
limit=1
}
Universe.spbFilteredEntitiesPlayerQueryLowest = {
area=spbSharedChunkArea,
force=Universe.playerForces,
collision_mask = "player-layer",
type={
"wall",
"transport-belt"
}
}
Universe.spbFilteredEntitiesPlayerQueryLow = {
area=spbSharedChunkArea,
force=Universe.playerForces,
collision_mask = "player-layer",
type={
"splitter",
"pump",
"offshore-pump",
"lamp",
"solar-panel",
"programmable-speaker",
"accumulator",
"assembling-machine",
"turret",
"ammo-turret"
}
}
Universe.spbFilteredEntitiesPlayerQueryHigh = {
area=spbSharedChunkArea,
force=Universe.playerForces,
collision_mask = "player-layer",
type={
"furnace",
"lab",
"roboport",
"beacon",
"radar",
"electric-turret",
"boiler",
"generator",
"fluid-turret",
"mining-drill"
}
}
Universe.spbFilteredEntitiesPlayerQueryHighest = {
area=spbSharedChunkArea,
force=Universe.playerForces,
collision_mask = "player-layer",
type={
"artillery-turret",
"reactor",
"rocket-silo"
}
}
-- is
local isSharedChunkArea = {
{0,0},
{0,0}
}
Universe.isFilteredTilesQuery = {
collision_mask="water-tile",
area=isSharedChunkArea
}
Universe.isFilteredEntitiesChunkNeutral = {
area=isSharedChunkArea,
collision_mask = "player-layer",
type={
"tree",
"simple-entity"
}
}
Universe.isFilteredEntitiesEnemyStructureQuery = {
area=isSharedChunkArea,
force=Universe.enemyForces,
type={
"turret",
"unit-spawner"
}
}
Universe.isCountResourcesQuery = {
area=isSharedChunkArea,
type="resource"
}
Universe.isFilteredEntitiesUnitQuery = {
area=isSharedChunkArea,
force=Universe.enemyForces,
type="unit"
}
-- cps
local cpsSharedChunkArea = {
{0,0},
{0,0}
}
Universe.cpsFilteredTilesQuery = {
collision_mask="water-tile",
area=cpsSharedChunkArea
}
Universe.cpsFilteredEntitiesChunkNeutral = {
area=cpsSharedChunkArea,
collision_mask = "player-layer",
type={
"tree",
"simple-entity"
}
}
Universe.cpsFilteredEnemyAnyFound = {
area=cpsSharedChunkArea,
force=Universe.enemyForces,
type={
"turret",
"unit-spawner"
},
limit = 1
}
-- msrc
local msrcSharedChunkArea = {
{0,0},
{0,0}
}
Universe.msrcFilteredTilesQuery = {
collision_mask="water-tile",
area=msrcSharedChunkArea
}
Universe.msrcFilteredEntitiesChunkNeutral = {
area=msrcSharedChunkArea,
collision_mask = "player-layer",
type={
"tree",
"simple-entity"
}
}
Universe.msrcCountResourcesQuery = {
area=msrcSharedChunkArea,
type="resource"
}
-- sp
local spSharedAreaChunk = {
{0,0},
{0,0}
}
Universe.spFilteredEntitiesCliffQuery = {
area=spSharedAreaChunk,
type="cliff",
limit = 1
}
Universe.spFilteredTilesPathQuery = {
area=spSharedAreaChunk,
collision_mask="water-tile",
limit = 1
}
-- ouc
Universe.oucCliffQuery = {
area={
{0,0},
{0,0}
},
type="cliff"
}
-- ppu
Universe.baseUtilsQueries = {}
Universe.baseUtilsQueries.createEntityQuery = {
name = "",
position = {0,0},
raise_built = true
}
Universe.squadQueries = {}
Universe.squadQueries.targetPosition = {0,0}
Universe.squadQueries.createEntityQuery = {
name = "",
position = {0,0}
}
Universe.squadQueries.attackCommand = {
type = DEFINES_COMMAND_ATTACK_AREA,
destination = {0,0},
radius = CHUNK_SIZE * 1.5,
distraction = DEFINES_DISTRACTION_BY_ANYTHING
}
Universe.squadQueries.moveCommand = {
type = DEFINES_COMMAND_GO_TO_LOCATION,
destination = {0,0},
pathfind_flags = { cache = true },
distraction = DEFINES_DISTRACTION_BY_ENEMY
}
Universe.squadQueries.settleCommand = {
type = DEFINES_COMMAND_BUILD_BASE,
destination = {0,0},
distraction = DEFINES_DISTRACTION_BY_ENEMY,
ignore_planner = true
}
Universe.squadQueries.wanderCommand = {
type = DEFINES_COMMAND_WANDER,
wander_in_group = false,
radius = TRIPLE_CHUNK_SIZE*2,
ticks_to_wait = 20 * 60
}
Universe.squadQueries.wander2Command = {
type = DEFINES_COMMAND_WANDER,
wander_in_group = true,
radius = TRIPLE_CHUNK_SIZE*2,
ticks_to_wait = 2 * 60
}
Universe.squadQueries.stopCommand = {
type = DEFINES_COMMAND_STOP
}
Universe.squadQueries.compoundSettleCommand = {
type = DEFINES_COMMMAD_COMPOUND,
structure_type = DEFINES_COMPOUND_COMMAND_RETURN_LAST,
commands = {
Universe.squadQueries.wonder2Command,
Universe.squadQueries.settleCommand
}
}
Universe.squadQueries.retreatCommand = {
type = DEFINES_COMMAND_GROUP,
group = nil,
distraction = DEFINES_DISTRACTION_BY_ANYTHING,
use_group_distraction = true
}
Universe.squadQueries.fleeCommand = {
type = DEFINES_COMMAND_FLEE,
from = nil,
distraction = DEFINES_DISTRACTION_NONE
}
Universe.squadQueries.compoundRetreatGroupCommand = {
type = DEFINES_COMMMAD_COMPOUND,
structure_type = DEFINES_COMPOUND_COMMAND_RETURN_LAST,
commands = {
Universe.squadQueries.stopCommand,
Universe.squadQueries.fleeCommand,
Universe.squadQueries.retreatCommand
}
}
Universe.squadQueries.formGroupCommand = {
type = DEFINES_COMMAND_GROUP,
group = nil,
distraction = DEFINES_DISTRACTION_BY_ANYTHING,
use_group_distraction = false
}
Universe.squadQueries.formCommand = {
command = Universe.squadQueries.formGroupCommand,
unit_count = 0,
unit_search_distance = TRIPLE_CHUNK_SIZE
}
Universe.squadQueries.formRetreatCommand = {
command = Universe.squadQueries.compoundRetreatGroupCommand,
unit_count = 1,
unit_search_distance = CHUNK_SIZE
}
Universe.squadQueries.searchPath = {
{chunk=-1, direction=-1},
{chunk=-1, direction=-1},
{chunk=-1, direction=-1},
{chunk=-1, direction=-1}
}
Universe.squadQueries.renderText = {
target = nil,
text = "",
target_offset = {0, -10},
color = {r=1,g=1,b=1,a=0.5},
surface = nil,
scale = 5
}
end
function Upgrade.setCommandForces(npcForces, enemyForces)
for force in pairs(Universe.playerForces) do
Universe.playerForces[force] = nil
end
for force in pairs(Universe.npcForces) do
Universe.npcForces[force] = nil
end
for force in pairs(Universe.enemyForces) do
Universe.enemyForces[force] = nil
end
for force in pairs(Universe.nonPlayerForces) do
Universe.nonPlayerForces[force] = nil
end
for _,force in pairs(game.forces) do
if not npcForces[force.name] and not enemyForces[force.name] then
Universe.playerForces[#Universe.playerForces+1] = force.name
end
end
for force in pairs(enemyForces) do
Universe.enemyForces[#Universe.enemyForces+1] = force
Universe.nonPlayerForces[#Universe.nonPlayerForces+1] = force
end
for force in pairs(npcForces) do
Universe.npcForces[#Universe.npcForces+1] = force
Universe.nonPlayerForces[#Universe.nonPlayerForces+1] = force
end
end
function Upgrade.addUniverseProperties()
if not global.universePropertyVersion then
for key in pairs(global) do
if key ~= "universe" then
global[key] = nil
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.flushPendingChunks = false
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.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.upgradeId = 0
Universe.eventId = 0
Universe.chunkId = 0
Universe.maps = {}
Universe.activeMaps = {}
Universe.groupNumberToSquad = {}
Universe.pendingChunks = {}
Universe.squadIterator = nil
Universe.processMapAIIterator = nil
Universe.processNestIterator = nil
Universe.vengenceQueue = {}
Universe.currentMap = nil
Universe.mapIterator = nil
Universe.builderCount = 0
Universe.squadCount = 0
Universe.processActiveSpawnerIterator = nil
Universe.processActiveRaidSpawnerIterator = nil
Universe.processMigrationIterator = nil
Universe.chunkToNests = {}
Universe.chunkToHives = {}
Universe.chunkToUtilities = {}
Universe.chunkToVictory = {}
Universe.chunkToActiveNest = {}
Universe.chunkToActiveRaidNest = {}
Universe.chunkToDrained = {}
Universe.chunkToRetreats = {}
Universe.chunkToRallys = {}
Universe.chunkToPassScan = {}
Universe.hiveData = {}
Universe.hives = {}
Universe.activeHives = {}
Universe.hiveIterator = nil
Universe.baseId = 0
Universe.awake = false
Universe.recycleBaseIterator = nil
Universe.maxPoints = 0
Universe.maxOverflowPoints = 0
addCommandSet()
Universe.bases = {}
Universe.processBaseAIIterator = nil
Universe.excludedSurfaces = {}
Universe.pendingUpgrades = {}
Universe.pendingUpgradesLength = 0
Universe.settlePurpleCloud = {}
end
end
function Upgrade.attempt()
if not global.gameVersion then
global.gameVersion = 1
game.forces.enemy.kill_all_units()
Universe.evolutionLevel = game.forces.enemy.evolution_factor
Universe.random = game.create_random_generator(Constants.ENEMY_SEED)
local minDiffuse = game.map_settings.pollution.min_to_diffuse
Universe.pollutionDiffuseMinimum = minDiffuse * 0.75
Universe.expansion = game.map_settings.enemy_expansion.enabled
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.expansionMaxTime = game.map_settings.enemy_expansion.max_expansion_cooldown / TICKS_A_MINUTE
Universe.expansionMinSize = game.map_settings.enemy_expansion.settler_group_min_size
Universe.expansionMaxSize = game.map_settings.enemy_expansion.settler_group_max_size
Universe.expansionLowTargetDistance = (Universe.expansionMaxDistance + MINIMUM_EXPANSION_DISTANCE) * 0.33
Universe.expansionMediumTargetDistance = (Universe.expansionMaxDistance + MINIMUM_EXPANSION_DISTANCE) * 0.50
Universe.expansionHighTargetDistance = (Universe.expansionMaxDistance + MINIMUM_EXPANSION_DISTANCE) * 0.75
Universe.expansionDistanceDeviation = Universe.expansionMediumTargetDistance * 0.33
Universe.modAddedTick = game.tick
end
if global.gameVersion < 2 then
global.gameVersion = 2
for _, map in pairs(Universe.maps) do
for _, chunk in pairs(map.processQueue) do
chunk[CHUNK_TICK] = 0
chunk[BASE_PHEROMONE] = 0
chunk[PLAYER_PHEROMONE] = 0
chunk[RESOURCE_PHEROMONE] = 0
chunk[ENEMY_PHEROMONE] = 0
chunk[KAMIKAZE_PHEROMONE] = 0
end
end
end
end
function Upgrade.init(universe)
Universe = universe
end
return Upgrade