From a0cabf408cf114358d37c7fe7e8715505eb6a4a1 Mon Sep 17 00:00:00 2001 From: Aaron Veden Date: Sat, 7 May 2022 05:03:24 -0700 Subject: [PATCH] FACTO-131: Fixed hive building generation desync due to land-mines --- changelog.txt | 1 + control.lua | 112 ++++++++++++++------------ libs/BaseUtils.lua | 5 +- libs/ChunkProcessor.lua | 5 +- libs/Constants.lua | 4 + locale/en/locale.cfg | 2 +- prototypes/SwarmUtils.lua | 6 +- prototypes/buildings/ChunkScanner.lua | 74 ++++++++++++----- 8 files changed, 131 insertions(+), 78 deletions(-) diff --git a/changelog.txt b/changelog.txt index a617719..3a59dd7 100644 --- a/changelog.txt +++ b/changelog.txt @@ -7,6 +7,7 @@ Version: 3.1.0 - Runtime number generator just uses the map seed now Bugfixes: - Fixed the period of the xor number generator being cut in half + - Fixed desync when hives would generate buildings using the landmine event (workaround before created_effect existed) --------------------------------------------------------------------------------------------------- Version: 3.0.3 diff --git a/control.lua b/control.lua index 941b933..895f344 100644 --- a/control.lua +++ b/control.lua @@ -50,6 +50,10 @@ local RETREAT_SPAWNER_GRAB_RADIUS = constants.RETREAT_SPAWNER_GRAB_RADIUS local UNIT_DEATH_POINT_COST = constants.UNIT_DEATH_POINT_COST +local MAX_HIVE_TTL = constants.MAX_HIVE_TTL +local MIN_HIVE_TTL = constants.MIN_HIVE_TTL +local DEV_HIVE_TTL = constants.DEV_HIVE_TTL + -- imported functions local planning = aiPlanning.planning @@ -62,6 +66,8 @@ local setPositionInQuery = queryUtils.setPositionInQuery local nextMap = mapUtils.nextMap local distortPosition = mathUtils.distortPosition +local linearInterpolation = mathUtils.linearInterpolation +local gaussianRandomRangeRG = mathUtils.gaussianRandomRangeRG local prepMap = upgrade.prepMap local processBaseAIs = aiPlanning.processBaseAIs @@ -660,8 +666,60 @@ local function onRocketLaunch(event) end end +local function onEntitySpawned(entity, tick) + if universe.NEW_ENEMIES and entity.valid then + local map = universe.maps[entity.surface.index] + if not map then + return + end + if universe.buildingHiveTypeLookup[entity.name] then + map.activeSurface = true + local disPos = distortPosition(universe.random, entity.position, 8) + + local chunk = getChunkByPosition(map, disPos) + if (chunk ~= -1) then + local base = findNearbyBase(map, chunk) + if not base then + base = createBase(map, + chunk, + tick) + end + + local meanTTL = linearInterpolation(universe.evolutionLevel, MAX_HIVE_TTL, MIN_HIVE_TTL) + + upgradeEntity(entity, + base, + map, + disPos, + true, + true, + tick + gaussianRandomRangeRG(meanTTL, + DEV_HIVE_TTL, + MIN_HIVE_TTL, + MAX_HIVE_TTL, + universe.random)) + else + local x,y = positionToChunkXY(entity.position) + onChunkGenerated({ + surface = entity.surface, + tick = tick, + area = { + left_top = { + x = x, + y = y + } + } + }) + entity.destroy() + end + end + end +end + local function onTriggerEntityCreated(event) - if (event.effect_id == "rampant-drain-trigger") then + if (event.effect_id == "hive-spawned--rampant") then + onEntitySpawned(event.source_entity, event.tick) + elseif (event.effect_id == "rampant-drain-trigger") then local entity = event.target_entity if (entity and entity.valid) then local map = universe.maps[event.surface_index] @@ -694,52 +752,6 @@ local function onInit() onConfigChanged() end -local function onEntitySpawned(event) - local entity = event.mine - if universe.NEW_ENEMIES and entity.valid then - local map = universe.maps[entity.surface.index] - if not map then - return - end - if universe.buildingHiveTypeLookup[entity.name] then - map.activeSurface = true - local disPos = distortPosition(universe.random, entity.position, 8) - - local chunk = getChunkByPosition(map, disPos) - if (chunk ~= -1) then - local base = findNearbyBase(map, chunk) - if not base then - base = createBase(map, - chunk, - event.tick) - end - - registerEnemyBaseStructure(map, entity, base, true) - - upgradeEntity(entity, - base, - map, - disPos, - true, - true) - else - local x,y = positionToChunkXY(entity.position) - onChunkGenerated({ - surface = entity.surface, - tick = event.tick, - area = { - left_top = { - x = x, - y = y - } - } - }) - entity.destroy() - end - end - end -end - local function onUnitGroupCreated(event) local group = event.group if (group.force.name ~= "enemy") then @@ -1012,8 +1024,8 @@ script.on_event(defines.events.on_tick, processBaseAIs(universe, tick) processActiveNests(universe, tick) - processPendingUpgrades(universe) - processPendingUpgrades(universe) + processPendingUpgrades(universe, tick) + processPendingUpgrades(universe, tick) cleanSquads(universe, tick) -- game.print({"", "--dispatch4 ", profiler, ", ", pick, ", ", game.tick, " ", universe.random()}) @@ -1049,8 +1061,6 @@ script.on_event({defines.events.on_built_entity, defines.events.script_raised_built, defines.events.script_raised_revive}, onBuild) -script.on_event(defines.events.on_land_mine_armed, onEntitySpawned) - script.on_event(defines.events.on_rocket_launched, onRocketLaunch) script.on_event({defines.events.on_entity_died, defines.events.script_raised_destroy}, onDeath) diff --git a/libs/BaseUtils.lua b/libs/BaseUtils.lua index 71deb27..8cb86c8 100644 --- a/libs/BaseUtils.lua +++ b/libs/BaseUtils.lua @@ -281,7 +281,7 @@ function baseUtils.recycleBases(universe) end end -function baseUtils.upgradeEntity(entity, base, map, disPos, evolve, register) +function baseUtils.upgradeEntity(entity, base, map, disPos, evolve, register, timeDelay) local position = entity.position local currentEvo = entity.prototype.build_base_evolution_requirement or 0 @@ -314,7 +314,8 @@ function baseUtils.upgradeEntity(entity, base, map, disPos, evolve, register) ["register"] = register, ["map"] = map, ["base"] = base, - ["entity"] = entity + ["entity"] = entity, + ["delayTLL"] = timeDelay } map.universe.pendingUpgrades[entity.unit_number] = entityData return spawnerName diff --git a/libs/ChunkProcessor.lua b/libs/ChunkProcessor.lua index 85b8e02..65267b8 100644 --- a/libs/ChunkProcessor.lua +++ b/libs/ChunkProcessor.lua @@ -125,7 +125,7 @@ function chunkProcessor.processPendingChunks(universe, tick, flush) universe.chunkProcessorIterator = eventId end -function chunkProcessor.processPendingUpgrades(universe) +function chunkProcessor.processPendingUpgrades(universe, tick) local entityId = universe.pendingUpgradeIterator local entityData if not entityId then @@ -142,6 +142,9 @@ function chunkProcessor.processPendingUpgrades(universe) local entity = entityData.entity if entity.valid then universe.pendingUpgradeIterator = next(universe.pendingUpgrades, entityId) + if entityData.delayTLL and tick < entityData.delayTLL then + return + end universe.pendingUpgrades[entityId] = nil local surface = entity.surface local query = universe.ppuUpgradeEntityQuery diff --git a/libs/Constants.lua b/libs/Constants.lua index 01df724..3648527 100644 --- a/libs/Constants.lua +++ b/libs/Constants.lua @@ -1661,5 +1661,9 @@ function constants.gpsDebug(x, y, msg) game.print("[gps=".. x .. "," .. y .. "]" .. msg) end +constants.MAX_HIVE_TTL = 2485 +constants.MIN_HIVE_TTL = 890 +constants.DEV_HIVE_TTL = 150 + constantsG = constants return constants diff --git a/locale/en/locale.cfg b/locale/en/locale.cfg index e39ef1d..c0a7429 100644 --- a/locale/en/locale.cfg +++ b/locale/en/locale.cfg @@ -19,7 +19,7 @@ spawner=Spawner poison=Poison energy=Sapper energy-thief=Sapper -entity-proxy= +entity-proxy=Spawning biter=Biter: spitter=Spitter: diff --git a/prototypes/SwarmUtils.lua b/prototypes/SwarmUtils.lua index 2e34664..6b3cfc3 100644 --- a/prototypes/SwarmUtils.lua +++ b/prototypes/SwarmUtils.lua @@ -439,12 +439,10 @@ local unitSpawnerAttributeNumeric = { local hiveAttributeNumeric = { ["health"] = { 700, 1000, 1500, 3000, 7000, 15000, 22000, 40000, 60000, 90000 }, ["healing"] = { 0.02, 0.02, 0.022, 0.024, 0.026, 0.028, 0.03, 0.032, 0.034, 0.036 }, - ["spawningCooldownStart"] = { 4970, 4930, 4890, 4850, 4810, 4780, 4740, 4700, 4660, 4620 }, - -- ["spawningCooldownStart"] = { 60, 60, 60, 60, 60, 60, 60, 60, 60, 60 }, + ["spawningCooldownStart"] = { 2485, 2465, 2445, 2425, 2405, 2390, 2370, 2350, 2330, 2310 }, ["spawningRadius"] = { 10, 13, 15, 17, 20, 23, 26, 29, 32, 35 }, ["spawningSpacing"] = { 5, 5, 5, 6, 6, 6, 7, 7, 7, 8 }, - ["spawningCooldownEnd"] = { 1785, 1780, 1775, 1770, 1765, 1760, 1755, 1750, 1745, 1740 }, - -- ["spawningCooldownEnd"] = { 60, 60, 60, 60, 60, 60, 60, 60, 60, 60 }, + ["spawningCooldownEnd"] = { 890, 887, 885, 882, 880, 877, 875, 872, 870 }, ["unitsToSpawn"] = { 3000, 3000, 300, 3000, 3000, 3000, 3000, 3000, 3000, 3000 }, ["scale"] = { 1.0, 1.05, 1.1, 1.15, 1.20, 1.25, 1.30, 1.35, 1.4, 1.45 }, ["unitsOwned"] = { 7, 7, 8, 8, 9, 9, 10, 10, 11, 11 }, diff --git a/prototypes/buildings/ChunkScanner.lua b/prototypes/buildings/ChunkScanner.lua index 836e5f2..7e8c96f 100644 --- a/prototypes/buildings/ChunkScanner.lua +++ b/prototypes/buildings/ChunkScanner.lua @@ -100,10 +100,50 @@ for si=1,#subTypes do -- local scale = scales[st][t] local scale = scales["biter-spawner"][t] + local eggPicture + if (st == "turret") then + eggPicture = { + filename = "__base__/graphics/entity/spawner/hr-spawner-idle-integration.png", + -- priority = "very-low", + -- flags = {"low-object"}, + draw_as_shadow = true, + scale = 0.25, + width = 522, + height = 380 + } + elseif (st == "biter-spawner") or (st == "spitter-spawner") then + eggPicture = { + filename = "__base__/graphics/entity/spawner/hr-spawner-idle-integration.png", + -- priority = "very-low", + -- flags = {"low-object"}, + draw_as_shadow = true, + scale = 0.5, + width = 522, + height = 380 + } + elseif (st == "hive") then + eggPicture = { + filename = "__base__/graphics/entity/spawner/hr-spawner-idle-integration.png", + -- priority = "very-low", + -- flags = {"low-object"}, + draw_as_shadow = true, + scale = 0.75, + width = 522, + height = 380 + } + -- else + -- eggPicture = { + -- filename = "__core__/graphics/empty.png", + -- priority = "extra-high", + -- width = 1, + -- height = 1 + -- } + end + data:extend( { { - type = "land-mine", + type = "simple-entity-with-force", name = "entity-proxy-" .. st .. "-t" .. t .. "-rampant", localised_name = biterUtils.getLocalisedName({ faction="entity-proxy", @@ -115,31 +155,27 @@ for si=1,#subTypes do icon_size = 32, flags = {}, build_base_evolution_requirement = 0.08 * (t-1), - order = "s-e-w-f", collision_mask = {"player-layer", "object-layer", "water-tile", "train-layer"}, minable = nil, - max_health = 100, + max_health = 300 * t, corpse = nil, - timeout = 1, - trigger_radius = 0, - -- collision_box = generateCollisionBox(scale, st), collision_box = generateCollisionBox(scale, "biter-spawner"), - selection_box = nil, + selection_box = generateCollisionBox(scale, "biter-spawner"), - picture_safe = + picture = eggPicture, + + created_effect = { { - filename = "__core__/graphics/empty.png", - priority = "extra-high", - width = 1, - height = 1 - }, - picture_set = - { - filename = "__core__/graphics/empty.png", - priority = "extra-high", - width = 1, - height = 1 + type = "direct", + action_delivery = { + type = "instant", + source_effects = { + type = "script", + effect_id = "hive-spawned--rampant" + } + } } + } } } )