From 5e501ea649dd08d769e9c5a392209377efc9bd54 Mon Sep 17 00:00:00 2001 From: Soar Qin Date: Fri, 6 Mar 2026 00:59:40 +0800 Subject: [PATCH] UXAssist: add 3 options to `Initialize Planet` --- UXAssist/Common/KnownItemId.cs | 9 + UXAssist/Functions/FactoryFunctions.cs | 4 +- UXAssist/Functions/PlanetFunctions.cs | 311 ++++++++++++++++++++++++- UXAssist/Patches/LogisticsPatch.cs | 8 - UXAssist/UIConfigWindow.cs | 10 + UXAssist/UXAssist.cs | 6 + 6 files changed, 332 insertions(+), 16 deletions(-) create mode 100644 UXAssist/Common/KnownItemId.cs diff --git a/UXAssist/Common/KnownItemId.cs b/UXAssist/Common/KnownItemId.cs new file mode 100644 index 0000000..b24a299 --- /dev/null +++ b/UXAssist/Common/KnownItemId.cs @@ -0,0 +1,9 @@ +namespace UXAssist.Common; + +public enum KnownItemId : int +{ + Drone = 5001, + Ship = 5002, + Bot = 5003, + Warper = 1210, +} diff --git a/UXAssist/Functions/FactoryFunctions.cs b/UXAssist/Functions/FactoryFunctions.cs index b93700e..8bb6bf4 100644 --- a/UXAssist/Functions/FactoryFunctions.cs +++ b/UXAssist/Functions/FactoryFunctions.cs @@ -105,8 +105,8 @@ public static class FactoryFunctions if (sc is null || sc.id != stationId) continue; for (int i = 0; i < sc.storage.Length; i++) { - int package = player.TryAddItemToPackage(sc.storage[i].itemId, sc.storage[i].count, sc.storage[i].inc, true, objId); - UIItemup.Up(sc.storage[i].itemId, package); + int added = player.TryAddItemToPackage(sc.storage[i].itemId, sc.storage[i].count, sc.storage[i].inc, true, objId); + if (added > 0) UIItemup.Up(sc.storage[i].itemId, added); } sc.storage = new StationStore[sc.storage.Length]; sc.needs = new int[sc.needs.Length]; diff --git a/UXAssist/Functions/PlanetFunctions.cs b/UXAssist/Functions/PlanetFunctions.cs index 7c03bef..4bcc18a 100644 --- a/UXAssist/Functions/PlanetFunctions.cs +++ b/UXAssist/Functions/PlanetFunctions.cs @@ -1,6 +1,6 @@ using System; using System.IO; -using System.Threading; +using System.Collections.Generic; using BepInEx.Configuration; using UnityEngine; @@ -9,7 +9,12 @@ namespace UXAssist.Functions; public static class PlanetFunctions { public static ConfigEntry OrbitalCollectorMaxBuildCount; + public static ConfigEntry ReturnBuildingsOnInitializeEnabled; + public static ConfigEntry ReturnLogisticStorageItemsOnInitializeEnabled; + public static ConfigEntry ReturnBeltAFactoryItemsOnInitializeEnabled; + private const int OrbitalCollectorItemId = 2105; + public static void DismantleAll(bool toBag) { var player = GameMain.mainPlayer; @@ -28,8 +33,8 @@ public static class PlanetFunctions { for (var i = sc.storage.Length - 1; i >= 0; i--) { - var added = player.TryAddItemToPackage(sc.storage[i].itemId, sc.storage[i].count, 0, true, etd.id); - UIItemup.Up(sc.storage[i].itemId, added); + var added = player.TryAddItemToPackage(sc.storage[i].itemId, sc.storage[i].count, sc.storage[i].inc, true, etd.id); + if (added > 0) UIItemup.Up(sc.storage[i].itemId, added); sc.storage[i].count = 0; } } @@ -116,18 +121,306 @@ public static class PlanetFunctions constructionModule.checkItemCursor = 0; var gameData = GameMain.data; - //planet.data = new PlanetRawData(planet.precision); - //planet.data.CalcVerts(); + + var returnBuildings = ReturnBuildingsOnInitializeEnabled.Value; + var returnLogisticStorageItems = ReturnLogisticStorageItemsOnInitializeEnabled.Value; + var returnBeltAFactoryItems = ReturnBeltAFactoryItemsOnInitializeEnabled.Value; + var returnedItems = new Dictionary(); + + static void AddReturnedItem(int itemId, int count, int inc, Dictionary returnedItems) + { + if (returnedItems.TryGetValue(itemId, out var value)) + { + returnedItems[itemId] = (value.count + count, value.inc + inc); + } + else + { + returnedItems[itemId] = (count, inc); + } + } + + if (returnBuildings || returnBeltAFactoryItems) + { + var factoryStorage = factory.factoryStorage; + var factorySystem = factory.factorySystem; + var planetTransport = factory.transport; + var defenseSystem = factory.defenseSystem; + var powerSystem = factory.powerSystem; + var cargoTraffic = factory.cargoTraffic; + for (var i = factory.entityCursor - 1; i > 0; i--) + { + ref var ed = ref factory.entityPool[i]; + if (ed.id != i) continue; + if (ed.protoId <= 0) continue; + if (returnBuildings) AddReturnedItem(ed.protoId, 1, 0, returnedItems); + if (!returnBeltAFactoryItems) continue; + #region Storage Items + var storageId = ed.storageId; + if (storageId > 0) + { + var storage = factoryStorage.storagePool[storageId]; + if (storage != null) + { + for (var j = storage.size - 1; j >= 0; j--) + { + var count = storage.grids[j].count; + if (count <= 0) continue; + AddReturnedItem(storage.grids[j].itemId, count, storage.grids[j].inc, returnedItems); + } + } + } + #endregion + #region Tank Items + var tankId = ed.tankId; + if (tankId > 0) + { + ref var tank = ref factoryStorage.tankPool[tankId]; + var fluidId = tank.fluidId; + var fluidCount = tank.fluidCount; + if (fluidId > 0 && fluidCount > 0) AddReturnedItem(fluidId, fluidCount, tank.fluidInc, returnedItems); + } + #endregion + #region Miner Items + var minerId = ed.minerId; + if (minerId > 0) + { + ref var miner = ref factorySystem.minerPool[minerId]; + var productId = miner.productId; + var productCount = miner.productCount; + if (productId > 0 && productCount > 0) AddReturnedItem(productId, productCount, 0, returnedItems); + } + #endregion + #region Inserter Items + var inserterId = ed.inserterId; + if (inserterId > 0) + { + ref var inserter = ref factorySystem.inserterPool[inserterId]; + var itemId = inserter.itemId; + var itemCount = inserter.itemCount; + if (itemId > 0 && itemCount > 0) AddReturnedItem(itemId, itemCount, inserter.itemInc, returnedItems); + } + #endregion + #region Assembler Items + var assemblerId = ed.assemblerId; + if (assemblerId > 0) + { + ref var assembler = ref factorySystem.assemblerPool[assemblerId]; + if (assembler.recipeId > 0) + { + var products = assembler.recipeExecuteData.products; + var requires = assembler.recipeExecuteData.requires; + var requireCounts = assembler.recipeExecuteData.requireCounts; + for (var j = products.Length - 1; j >= 0; j--) + { + var product = products[j]; + var produced = assembler.produced[j]; + if (produced > 0) AddReturnedItem(product, produced, 0, returnedItems); + } + for (var j = requires.Length - 1; j >= 0; j--) + { + var require = requires[j]; + var served = assembler.served[j]; + var incServed = assembler.incServed[j]; + if (incServed > served * 10) incServed = served * 10; + if (assembler.replicating) served += requireCounts[j]; + if (served > 0) AddReturnedItem(require, served, incServed, returnedItems); + } + } + } + #endregion + #region Fractionator Items + var fractionatorId = ed.fractionatorId; + if (fractionatorId > 0) + { + ref var fractionator = ref factorySystem.fractionatorPool[fractionatorId]; + var fluidId = fractionator.fluidId; + var fluidInputCount = fractionator.fluidInputCount; + if (fluidInputCount > 0) AddReturnedItem(fluidId, fluidInputCount, fractionator.fluidInputInc, returnedItems); + var fluidOutputCount = fractionator.fluidOutputCount; + if (fluidOutputCount > 0) AddReturnedItem(fluidId, fluidOutputCount, fractionator.fluidOutputInc, returnedItems); + var productOutputCount = fractionator.productOutputCount; + if (productOutputCount > 0) AddReturnedItem(fractionator.productId, productOutputCount, 0, returnedItems); + } + #endregion + #region Ejector Items + var ejectorId = ed.ejectorId; + if (ejectorId > 0) + { + ref var ejector = ref factorySystem.ejectorPool[ejectorId]; + var bulletCount = ejector.bulletCount; + if (bulletCount > 0) AddReturnedItem(ejector.bulletId, bulletCount, ejector.bulletInc, returnedItems); + } + #endregion + #region Silo Items + var siloId = ed.siloId; + if (siloId > 0) + { + ref var silo = ref factorySystem.siloPool[siloId]; + var itemCount = silo.bulletCount; + if (itemCount > 0) AddReturnedItem(silo.bulletId, itemCount, silo.bulletInc, returnedItems); + } + #endregion + #region Lab Items + var labId = ed.labId; + if (labId > 0) + { + ref var lab = ref factorySystem.labPool[labId]; + if (lab.recipeId > 0) + { + var products = lab.recipeExecuteData.products; + var requires = lab.recipeExecuteData.requires; + var requireCounts = lab.recipeExecuteData.requireCounts; + for (var j = products.Length - 1; j >= 0; j--) + { + var produced = lab.produced[j]; + if (produced > 0) AddReturnedItem(products[j], produced, 0, returnedItems); + } + for (var j = requires.Length - 1; j >= 0; j--) + { + var served = lab.served[j]; + var incServed = lab.incServed[j]; + if (incServed > served * 10) incServed = served * 10; + if (lab.replicating) served += requireCounts[j]; + if (served > 0) AddReturnedItem(requires[j], served, incServed, returnedItems); + } + } + if (lab.researchMode && lab.matrixServed != null) + { + for (var k = lab.matrixServed.Length - 1; k >= 0; k--) + { + var served = lab.matrixServed[k] / 3600; + if (served > 0) AddReturnedItem(LabComponent.matrixIds[k], served, lab.matrixIncServed[k] / 3600, returnedItems); + } + } + } + #endregion + #region Dispenser Items + var dispenserId = ed.dispenserId; + if (dispenserId > 0) + { + var dispenser = planetTransport.dispenserPool[dispenserId]; + var holdupPackage = dispenser.holdupPackage; + for (var j = holdupPackage.Length - 1; j >= 0; j--) + { + var count = holdupPackage[j].count; + if (count > 0) AddReturnedItem(holdupPackage[j].itemId, count, holdupPackage[j].inc, returnedItems); + } + var courierCount = dispenser.idleCourierCount + dispenser.workCourierCount; + if (courierCount > 0) AddReturnedItem((int)Common.KnownItemId.Bot, courierCount, 0, returnedItems); + } + #endregion + #region Turret Items + var turretId = ed.turretId; + if (turretId > 0) + { + ref var turret = ref defenseSystem.turrets.buffer[turretId]; + var itemCount = turret.itemCount; + if (itemCount > 0) AddReturnedItem(turret.itemId, itemCount, turret.itemInc, returnedItems); + } + #endregion + #region Battle Base Items + var battleBaseId = ed.battleBaseId; + if (battleBaseId > 0) + { + ref var battleBase = ref defenseSystem.battleBases.buffer[battleBaseId]; + var combatModule = battleBase.combatModule; + if (combatModule != null && combatModule.moduleFleets[0].fleetId <= 0) + { + var fighters = combatModule.moduleFleets[0].fighters; + for (var j = fighters.Length - 1; j >= 0; j--) + { + var fighterItemId = fighters[j].itemId; + var fighterCount = fighters[j].count; + if (fighterItemId > 0 && fighterCount > 0) AddReturnedItem(fighterItemId, fighterCount, 0, returnedItems); + } + } + } + #endregion + #region Power Generator Items + var powerGeneratorId = ed.powerGenId; + if (powerGeneratorId > 0) + { + ref var powerGen = ref powerSystem.genPool[powerGeneratorId]; + if (powerGen.fuelId > 0 && powerGen.fuelCount > 0) AddReturnedItem(powerGen.fuelId, powerGen.fuelCount, powerGen.fuelInc, returnedItems); + if (powerGen.gamma) + { + var productId = powerGen.productId; + var productCount = (int)powerGen.productCount; + if (productId != 0 && productCount > 0) AddReturnedItem(productId, productCount, 0, returnedItems); + int catalystId = powerGen.catalystId; + var catalystPointDiv = powerGen.catalystPoint / 3600; + if (catalystId != 0 && catalystPointDiv > 0) AddReturnedItem(catalystId, catalystPointDiv, powerGen.catalystIncPoint / 3600, returnedItems); + } + } + #endregion + #region Power Exchanger Items + var powerExchangerId = ed.powerExcId; + if (powerExchangerId > 0) + { + ref var powerExchanger = ref powerSystem.excPool[powerExchangerId]; + var emptyCount = (int)powerExchanger.emptyCount; + if (emptyCount > 0) AddReturnedItem(powerExchanger.emptyId, emptyCount, powerExchanger.emptyInc, returnedItems); + var fullCount = (int)powerExchanger.fullCount; + if (fullCount > 0) AddReturnedItem(powerExchanger.fullId, fullCount, powerExchanger.fullInc, returnedItems); + } + #endregion + #region Spraycoater Items + var spraycoaterId = ed.spraycoaterId; + if (spraycoaterId > 0) + { + ref var spraycoater = ref cargoTraffic.spraycoaterPool[spraycoaterId]; + if (spraycoater.incItemId != 0 && spraycoater.incCount != 0) + { + var itemProto = LDB.items.Select(spraycoater.incItemId); + var count = spraycoater.incCount / itemProto.HpMax; + if (count != 0) AddReturnedItem(spraycoater.incItemId, count, 0, returnedItems); + } + } + #endregion + #region Piler Items + var pilerId = ed.pilerId; + if (pilerId > 0) + { + ref var piler = ref cargoTraffic.pilerPool[pilerId]; + var cacheCargoStack = (int)piler.cacheCargoStack1; + if (cacheCargoStack > 0) AddReturnedItem(piler.cacheItemId1, cacheCargoStack, piler.cacheCargoInc1, returnedItems); + var cacheCargoStack2 = (int)piler.cacheCargoStack2; + if (cacheCargoStack2 > 0) AddReturnedItem(piler.cacheItemId2, cacheCargoStack2, piler.cacheCargoInc2, returnedItems); + } + #endregion + } + } + var stationPool = factory.transport?.stationPool; if (stationPool != null) { + var galacticTransport = gameData.galacticTransport; for (var i = factory.transport.stationCursor - 1; i > 0; i--) { var sc = stationPool[i]; if (sc is null || sc.id != i) continue; - gameData.galacticTransport.RemoveStationComponent(sc.id); + if (returnLogisticStorageItems) + { + for (var j = 0; j < sc.storage.Length; j++) + { + var count = sc.storage[j].count; + if (count > 0) AddReturnedItem(sc.storage[j].itemId, count, sc.storage[j].inc, returnedItems); + } + var droneCount = sc.idleDroneCount + sc.workDroneCount; + if (droneCount > 0) AddReturnedItem((int)Common.KnownItemId.Drone, droneCount, 0, returnedItems); + var shipCount = sc.idleShipCount + sc.workShipCount; + if (shipCount > 0) AddReturnedItem((int)Common.KnownItemId.Ship, shipCount, 0, returnedItems); + var warperCount = sc.warperCount; + if (warperCount > 0) AddReturnedItem((int)Common.KnownItemId.Warper, warperCount, 0, returnedItems); + } + galacticTransport.RemoveStation2StationRoute(sc.gid); + galacticTransport.RefreshTraffic(sc.gid); sc.Reset(); } + if (galacticTransport.OnStellarStationRemoved != null) + { + galacticTransport.OnStellarStationRemoved(); + } } var physics = planet.physics; @@ -326,6 +619,12 @@ public static class PlanetFunctions //GameMain.data.statistics.production.CreateFactoryStat(index); gameData.ArrivePlanet(planet); + + foreach (var kvp in returnedItems) + { + var added = player.TryAddItemToPackage(kvp.Key, (int)kvp.Value.count, kvp.Value.inc, true); + if (added > 0) UIItemup.Up(kvp.Key, added); + } } public static void BuildOrbitalCollectors() diff --git a/UXAssist/Patches/LogisticsPatch.cs b/UXAssist/Patches/LogisticsPatch.cs index 115f09a..54940b1 100644 --- a/UXAssist/Patches/LogisticsPatch.cs +++ b/UXAssist/Patches/LogisticsPatch.cs @@ -109,14 +109,6 @@ public static class LogisticsPatch private class AutoConfigLogistics : PatchImpl { - enum KnownItemId : int - { - Drone = 5001, - Ship = 5002, - Bot = 5003, - Warper = 1210, - } - protected override void OnEnable() { ToggleLimitAutoReplenishCount(); diff --git a/UXAssist/UIConfigWindow.cs b/UXAssist/UIConfigWindow.cs index 5de0e90..6c20415 100644 --- a/UXAssist/UIConfigWindow.cs +++ b/UXAssist/UIConfigWindow.cs @@ -130,6 +130,9 @@ public static class UIConfigWindow I18N.Add("Treat stack items as single in monitor components", "Treat stack items as single in monitor components", "在流速计中将堆叠物品视为单个物品"); I18N.Add("Initialize This Planet", "Initialize this planet", "初始化本行星"); I18N.Add("Initialize This Planet Confirm", "This operation will destroy all buildings and revert terrains on this planet, are you sure?", "此操作将会摧毁本行星上的所有建筑并恢复地形,确定吗?"); + I18N.Add("Return buildings to player when initializing planet", "Return buildings to player when initializing planet", "初始化行星时将建筑归还给玩家"); + I18N.Add("Return logistic storage items to player when initializing planet", "Return logistic storage items to player when initializing planet", "初始化行星时将物流塔存储的物品归还给玩家"); + I18N.Add("Return belt and factory items to player when initializing planet", "Return belt and factory items to player when initializing planet", "初始化行星时将传送带和工厂里的物品归还给玩家"); I18N.Add("Dismantle All Buildings", "Dismantle all buildings", "拆除所有建筑"); I18N.Add("Dismantle All Buildings Confirm", "This operation will dismantle all buildings on this planet, are you sure?", "此操作将会拆除本行星上的所有建筑,确定吗?"); I18N.Add("Quick build Orbital Collectors", "Quick build Orbital Collectors", "快速建造轨道采集器"); @@ -439,6 +442,13 @@ public static class UIConfigWindow UIMessageBox.Show("Initialize This Planet".Translate(), "Initialize This Planet Confirm".Translate(), "取消".Translate(), "确定".Translate(), UIMessageBox.QUESTION, null, () => { PlanetFunctions.RecreatePlanet(true); }) ); + y += 24f; + wnd.AddCheckBox(x + 10f, y, tab2, PlanetFunctions.ReturnBuildingsOnInitializeEnabled, "Return buildings to player when initializing planet", 13); + y += 24f; + wnd.AddCheckBox(x + 10f, y, tab2, PlanetFunctions.ReturnLogisticStorageItemsOnInitializeEnabled, "Return logistic storage items to player when initializing planet", 13); + y += 24f; + wnd.AddCheckBox(x + 10f, y, tab2, PlanetFunctions.ReturnBeltAFactoryItemsOnInitializeEnabled, "Return belt and factory items to player when initializing planet", 13); + y += 36f; wnd.AddButton(x, y, tab2, "Dismantle All Buildings", 16, "button-dismantle-all", () => UIMessageBox.Show("Dismantle All Buildings".Translate(), "Dismantle All Buildings Confirm".Translate(), "取消".Translate(), "确定".Translate(), UIMessageBox.QUESTION, null, diff --git a/UXAssist/UXAssist.cs b/UXAssist/UXAssist.cs index 659366a..15bd4ea 100644 --- a/UXAssist/UXAssist.cs +++ b/UXAssist/UXAssist.cs @@ -108,6 +108,12 @@ public class UXAssist : BaseUnityPlugin, IModCanSave FactoryPatch.NightLightAngleY = Config.Bind("Factory", "NightLightAngleY", -2f, "Night light angle Y"); PlanetPatch.PlayerActionsInGlobeViewEnabled = Config.Bind("Planet", "PlayerActionsInGlobeView", false, "Enable player actions in globe view"); + PlanetFunctions.ReturnBuildingsOnInitializeEnabled = Config.Bind("Planet", "ReturnBuildingsOnInitialize", false, + "Return buildings to player when initializing planet"); + PlanetFunctions.ReturnLogisticStorageItemsOnInitializeEnabled = Config.Bind("Planet", "ReturnLogisticStorageItemsOnInitialize", false, + "Return logistic storage items to player when initializing planet"); + PlanetFunctions.ReturnBeltAFactoryItemsOnInitializeEnabled = Config.Bind("Planet", "ReturnBeltAFactoryItemsOnInitialize", false, + "Return belt and factory items to player when initializing planet"); FactoryPatch.RemoveBuildRangeLimitEnabled = Config.Bind("Factory", "RemoveBuildRangeLimit", false, "Remove limit for build range and maximum count of drag building belts/buildings\nNote: this does not affect range limit for mecha drones' action"); FactoryPatch.LargerAreaForUpgradeAndDismantleEnabled = Config.Bind("Factory", "LargerAreaForUpgradeAndDismantle", false,