1
0
mirror of https://github.com/soarqin/DSP_Mods.git synced 2026-02-05 05:02:20 +08:00

Compare commits

...

5 Commits

Author SHA1 Message Date
09cdaf3a12 balance tweaks 2025-10-30 16:03:11 +08:00
8d5bb140e1 fix crashes 2025-10-30 00:12:47 +08:00
c99c59a117 work in progress 2025-10-29 22:30:10 +08:00
61811f9a8c crash fix 2025-10-29 21:51:52 +08:00
cf3117e0da minor opt 2025-10-29 21:38:53 +08:00
5 changed files with 88 additions and 66 deletions

View File

@@ -19,19 +19,21 @@ public class LogisticHub : BaseUnityPlugin
{ {
Module.Miner.Enabled = Config.Bind("Miner", "Enabled", true, "enable/disable this plugin"); Module.Miner.Enabled = Config.Bind("Miner", "Enabled", true, "enable/disable this plugin");
Module.Miner.OreEnergyConsume = Config.Bind("Miner", "EnergyConsumptionForOre", 2000000L, Module.Miner.OreEnergyConsume = Config.Bind("Miner", "EnergyConsumptionForOre", 2000000L,
"Energy consumption for each ore vein group(in 0.5W)"); "Energy consumption for each ore vein group(in W)");
Module.Miner.OilEnergyConsume = Config.Bind("Miner", "EnergyConsumptionForOil", 3600000L, Module.Miner.OreMiningMultiplier = Config.Bind("Miner", "OreMiningMultiplier", 3,
"Energy consumption for each oil seep(in 0.5W)"); new ConfigDescription("Mining multiplier for ore veins, multiplies to the number of veins in the group", new AcceptableValueRange<int>(1, 100)));
Module.Miner.WaterEnergyConsume = Config.Bind("Miner", "EnergyConsumptionForWater", 2000000L, Module.Miner.OreMiningScale = Config.Bind("Miner", "OreMiningScale", 100,
"Energy consumption for water slot(in kW)");
Module.Miner.WaterSpeed = Config.Bind("Miner", "WaterMiningSpeed", 10,
"Water mining speed (count per second)");
Module.Miner.MiningScale = Config.Bind("Miner", "MiningScale", 0,
""" """
0 for Auto(which means having researched makes mining scale 300, otherwise 100). 0 for Auto(which means having researched advanced mining machine makes mining scale 300, otherwise 100).
Mining scale(in percents) for slots below half of slot limits, and the scale reduces to 100% smoothly till reach full. Mining scale(in percents) for slots below half of slot limits, and the scale reduces to 100% smoothly till reach full.
Please note that the power consumption increases by the square of the scale which is the same as Advanced Mining Machine. Please note that the power consumption increases by the square of the scale which is the same as Advanced Mining Machine.
"""); """);
Module.Miner.OilEnergyConsume = Config.Bind("Miner", "EnergyConsumptionForOil", 1800000L,
"Energy consumption for each oil seep(in W)");
Module.Miner.WaterEnergyConsume = Config.Bind("Miner", "EnergyConsumptionForWater", 2000000L,
"Energy consumption for water slot(in W)");
Module.Miner.WaterSpeed = Config.Bind("Miner", "WaterMiningSpeed", 10,
"Water mining speed (count per second)");
Module.Miner.FuelIlsSlot = Config.Bind("Miner", "ILSFuelSlot", 4, Module.Miner.FuelIlsSlot = Config.Bind("Miner", "ILSFuelSlot", 4,
new ConfigDescription("Fuel slot for ILS, set 0 to disable.", new AcceptableValueRange<int>(0, 5))); new ConfigDescription("Fuel slot for ILS, set 0 to disable.", new AcceptableValueRange<int>(0, 5)));
Module.Miner.FuelPlsSlot = Config.Bind("Miner", "PLSFuelSlot", 4, Module.Miner.FuelPlsSlot = Config.Bind("Miner", "PLSFuelSlot", 4,

View File

@@ -1,7 +1,6 @@
using System; using System;
using BepInEx.Configuration; using BepInEx.Configuration;
using HarmonyLib; using HarmonyLib;
using UnityEngine;
using UXAssist.Common; using UXAssist.Common;
using Random = UnityEngine.Random; using Random = UnityEngine.Random;
using GameLogicProc = UXAssist.Common.GameLogic; using GameLogicProc = UXAssist.Common.GameLogic;
@@ -12,19 +11,21 @@ public class Miner : PatchImpl<Miner>
{ {
public static ConfigEntry<bool> Enabled; public static ConfigEntry<bool> Enabled;
public static ConfigEntry<long> OreEnergyConsume; public static ConfigEntry<long> OreEnergyConsume;
public static ConfigEntry<int> OreMiningScale;
public static ConfigEntry<int> OreMiningMultiplier;
public static ConfigEntry<long> OilEnergyConsume; public static ConfigEntry<long> OilEnergyConsume;
public static ConfigEntry<long> WaterEnergyConsume; public static ConfigEntry<long> WaterEnergyConsume;
public static ConfigEntry<int> WaterSpeed; public static ConfigEntry<int> WaterSpeed;
public static ConfigEntry<int> MiningScale;
public static ConfigEntry<int> FuelIlsSlot; public static ConfigEntry<int> FuelIlsSlot;
public static ConfigEntry<int> FuelPlsSlot; public static ConfigEntry<int> FuelPlsSlot;
private static float _frame; private static long _frame;
private static float _miningCostRateByTech; private static float _miningCostRateByTech;
private static float _miningSpeedScaleByTech; private static long _miningFrames;
private static float _miningFrames;
private static long _miningSpeedScaleLong; private static long _miningSpeedScaleLong;
private static bool _advancedMiningMachineUnlocked; private static bool _advancedMiningMachineUnlocked;
private static int _miningMultiplier = 3;
private static int _miningScale = 100;
private static uint _miningCostBarrier; private static uint _miningCostBarrier;
private static uint _miningCostBarrierOil; private static uint _miningCostBarrierOil;
private static int[] _mineIndex; private static int[] _mineIndex;
@@ -73,8 +74,7 @@ public class Miner : PatchImpl<Miner>
private static void OnGameBegin() private static void OnGameBegin()
{ {
VeinManager.Clear(); _frame = 0L;
_frame = 0f;
UpdateMiningCostRate(); UpdateMiningCostRate();
UpdateSpeedScale(); UpdateSpeedScale();
CheckRecipes(); CheckRecipes();
@@ -93,6 +93,15 @@ public class Miner : PatchImpl<Miner>
private static void CheckRecipes() private static void CheckRecipes()
{ {
_advancedMiningMachineUnlocked = GameMain.history.recipeUnlocked.Contains(119); _advancedMiningMachineUnlocked = GameMain.history.recipeUnlocked.Contains(119);
_miningMultiplier = OreMiningMultiplier.Value;
if (OreMiningScale.Value == 0)
{
_miningScale = _advancedMiningMachineUnlocked ? 300 : 100;
}
else
{
_miningScale = OreMiningScale.Value;
}
} }
private static void UpdateMiningCostRate() private static void UpdateMiningCostRate()
@@ -104,9 +113,8 @@ public class Miner : PatchImpl<Miner>
private static void UpdateSpeedScale() private static void UpdateSpeedScale()
{ {
_miningSpeedScaleByTech = GameMain.history.miningSpeedScale; _miningSpeedScaleLong = (long)Math.Round(GameMain.history.miningSpeedScale * 100f);
_miningSpeedScaleLong = (long)(_miningSpeedScaleByTech * 100); _miningFrames = _miningSpeedScaleLong * 6000L;
_miningFrames = _miningSpeedScaleByTech * 600000f;
} }
[HarmonyPostfix] [HarmonyPostfix]
@@ -130,45 +138,44 @@ public class Miner : PatchImpl<Miner>
{ {
var main = GameMain.instance; var main = GameMain.instance;
if (main.isMenuDemo) return; if (main.isMenuDemo) return;
if (_miningSpeedScaleLong <= 0) return; if (_miningSpeedScaleLong <= 0L) return;
DeepProfiler.BeginSample(DPEntry.Miner);
if (main.timei % 60 != 0) return; if (main.timei % 60 != 0) return;
_frame += _miningFrames; _frame += _miningFrames;
var frameCounter = Mathf.FloorToInt(_frame / 1200000f); var frameCounter = _frame / 1200000L;
if (frameCounter <= 0) return; if (frameCounter <= 0) return;
_frame -= frameCounter * 1200000f; _frame -= frameCounter * 1200000L;
// LogisticHub.Logger.LogDebug($"FrameCounter: {frameCounter}");
DeepProfiler.BeginSample(DPEntry.Miner);
var data = GameMain.data; var data = GameMain.data;
if (_mineIndex == null || data.factoryCount > _mineIndex.Length)
Array.Resize(ref _mineIndex, data.factoryCount);
var factoryStatPool = GameMain.statistics.production.factoryStatPool;
for (var factoryIndex = data.factoryCount - 1; factoryIndex >= 0; factoryIndex--) for (var factoryIndex = data.factoryCount - 1; factoryIndex >= 0; factoryIndex--)
{ {
var factory = data.factories[factoryIndex]; var factory = data.factories[factoryIndex];
var veins = VeinManager.GetVeins(factoryIndex); var veins = VeinManager.GetVeins(factoryIndex);
if (veins == null) return; if (veins == null) continue;
var stations = StationManager.GetStations(factoryIndex); var stations = StationManager.GetStations(factoryIndex);
var planetTransport = factory.transport; var planetTransport = factory.transport;
var factoryProductionStat = GameMain.statistics.production.factoryStatPool[factoryIndex]; var productRegister = factoryStatPool[factoryIndex]?.productRegister;
var productRegister = factoryProductionStat?.productRegister;
var demands = stations.StorageIndices[1]; var demands = stations.StorageIndices[1];
if (_mineIndex == null || factoryIndex >= _mineIndex.Length) if (demands == null) continue;
Array.Resize(ref _mineIndex, factoryIndex + 1);
foreach (var (itemIndex, itemId) in VeinList) foreach (var (itemIndex, itemId) in VeinList)
{ {
foreach (var storageIndex in demands[itemIndex]) if (itemIndex >= demands.Length) continue;
var demandList = demands[itemIndex];
if (demandList == null) continue;
foreach (var storageIndex in demandList)
{ {
var station = planetTransport.stationPool[storageIndex / 100]; var station = planetTransport.stationPool[storageIndex / 100];
if (station == null) if (station == null)
continue; continue;
ref var storage = ref station.storage[storageIndex % 100]; ref var storage = ref station.storage[storageIndex % 100];
if (storage.count >= storage.max) continue;
int amount; int amount;
long energyConsume; long energyConsume;
var miningScale = MiningScale.Value; var miningScale = _miningScale;
if (miningScale == 0)
{
miningScale = _advancedMiningMachineUnlocked ? 300 : 100;
}
if (miningScale > 100 && storage.count * 2 > storage.max) if (miningScale > 100 && storage.count * 2 > storage.max)
{ {
miningScale = 100 + ((miningScale - 100) * (storage.max - storage.count) * 2 + storage.max - 1) / storage.max; miningScale = 100 + ((miningScale - 100) * (storage.max - storage.count) * 2 + storage.max - 1) / storage.max;
@@ -176,7 +183,7 @@ public class Miner : PatchImpl<Miner>
if (itemIndex > 0) if (itemIndex > 0)
{ {
(amount, energyConsume) = Mine(factory, veins, itemId, miningScale, frameCounter, station.energy); (amount, energyConsume) = Mine(factory, veins, itemId, miningScale, (int)frameCounter, _miningMultiplier, station.energy);
if (amount < 0) continue; if (amount < 0) continue;
} }
else else
@@ -188,7 +195,7 @@ public class Miner : PatchImpl<Miner>
if (amount <= 0) continue; if (amount <= 0) continue;
storage.count += amount; storage.count += amount;
if (factoryProductionStat != null) if (productRegister != null)
productRegister[itemId] += amount; productRegister[itemId] += amount;
station.energy -= energyConsume; station.energy -= energyConsume;
} }
@@ -197,7 +204,7 @@ public class Miner : PatchImpl<Miner>
for (var i = planetTransport.stationCursor - 1; i > 0; i--) for (var i = planetTransport.stationCursor - 1; i > 0; i--)
{ {
var stationComponent = planetTransport.stationPool[i]; var stationComponent = planetTransport.stationPool[i];
if (stationComponent.isCollector || stationComponent.isVeinCollector || stationComponent.energy * 2 >= stationComponent.energyMax) continue; if (stationComponent == null || stationComponent.isCollector || stationComponent.isVeinCollector || stationComponent.energy * 2 >= stationComponent.energyMax) continue;
var index = (stationComponent.isStellar ? FuelIlsSlot.Value : FuelPlsSlot.Value) - 1; var index = (stationComponent.isStellar ? FuelIlsSlot.Value : FuelPlsSlot.Value) - 1;
var storage = stationComponent.storage; var storage = stationComponent.storage;
if (index < 0 || index >= storage.Length) if (index < 0 || index >= storage.Length)
@@ -243,7 +250,7 @@ public class Miner : PatchImpl<Miner>
} }
} }
private static (int, long) Mine(PlanetFactory factory, ProductVeinData[] allVeins, int productId, int percent, int counter, long energyMax) private static (int, long) Mine(PlanetFactory factory, ProductVeinData[] allVeins, int productId, int percent, int counter, int multiplier, long energyMax)
{ {
var veins = allVeins[productId - 1000]; var veins = allVeins[productId - 1000];
if (veins == null) if (veins == null)
@@ -258,7 +265,7 @@ public class Miner : PatchImpl<Miner>
/* if is Oil */ /* if is Oil */
if (productId == 1007) if (productId == 1007)
{ {
energy = (OilEnergyConsume.Value * length * percent * percent + 9999L) / 10000L; energy = OilEnergyConsume.Value * length;
if (energy > energyMax) if (energy > energyMax)
return (-1, -1L); return (-1, -1L);
var countf = 0f; var countf = 0f;
@@ -267,8 +274,7 @@ public class Miner : PatchImpl<Miner>
{ {
countf += veinsPool[veinIndices[i]].amount * 4 * VeinData.oilSpeedMultiplier; countf += veinsPool[veinIndices[i]].amount * 4 * VeinData.oilSpeedMultiplier;
} }
count = (int)(countf * (counter * percent) / 100f);
count = ((int)countf * counter * percent + 99) / 100;
if (count == 0) if (count == 0)
return (-1, -1L); return (-1, -1L);
barrier = _miningCostBarrierOil; barrier = _miningCostBarrierOil;
@@ -276,7 +282,7 @@ public class Miner : PatchImpl<Miner>
} }
else else
{ {
count = (length * counter * percent + 99) / 100; count = (length * multiplier * counter * percent + 99) / 100;
if (count == 0) if (count == 0)
return (-1, -1L); return (-1, -1L);
energy = (OreEnergyConsume.Value * veins.GroupCount * percent * percent + 9999L) / 10000L; energy = (OreEnergyConsume.Value * veins.GroupCount * percent * percent + 9999L) / 10000L;

View File

@@ -12,6 +12,7 @@ public class PlanetStations
public void AddStationStorage(bool demand, int id, int stationId, int storageIdx) public void AddStationStorage(bool demand, int id, int stationId, int storageIdx)
{ {
LogisticHub.Logger.LogDebug($"AddStationStorage: demand={demand}, id={id}, stationId={stationId}, storageIdx={storageIdx}");
var stations = StorageIndices[demand ? 1 : 0]; var stations = StorageIndices[demand ? 1 : 0];
if (stations == null || id >= stations.Length) if (stations == null || id >= stations.Length)
{ {
@@ -54,34 +55,37 @@ public class StationManager : PatchImpl<StationManager>
public static void Init() public static void Init()
{ {
GameLogicProc.OnGameBegin += () => GameLogicProc.OnGameBegin += OnGameBegin;
{
_stations = null;
var data = GameMain.data;
for (var index = data.factoryCount - 1; index >= 0; index--)
{
var factory = data.factories[index];
if (factory == null || factory.index != index) continue;
var planetIndex = factory.index;
var stations = StationsByPlanet(planetIndex);
var transport = factory.transport;
var pool = transport.stationPool;
for (var i = transport.stationCursor - 1; i > 0; i--)
{
var station = pool[i];
if (station == null || station.id != i || station.isCollector || station.isVeinCollector) continue;
UpdateStationInfo(stations, station);
}
}
};
Enable(true); Enable(true);
} }
public static void Uninit() public static void Uninit()
{ {
GameLogicProc.OnGameBegin -= OnGameBegin;
Enable(false); Enable(false);
} }
private static void OnGameBegin()
{
_stations = null;
var data = GameMain.data;
for (var index = data.factoryCount - 1; index >= 0; index--)
{
var factory = data.factories[index];
if (factory == null || factory.index != index) continue;
var planetIndex = factory.index;
var stations = StationsByPlanet(planetIndex);
var transport = factory.transport;
var pool = transport.stationPool;
for (var i = transport.stationCursor - 1; i > 0; i--)
{
var station = pool[i];
if (station == null || station.id != i || station.isCollector || station.isVeinCollector) continue;
UpdateStationInfo(stations, station);
}
}
}
private static int ItemIdToIndex(int itemId) private static int ItemIdToIndex(int itemId)
{ {
return itemId switch return itemId switch

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using HarmonyLib; using HarmonyLib;
using UXAssist.Common; using UXAssist.Common;
using GameLogicProc = UXAssist.Common.GameLogic;
namespace LogisticHub.Module; namespace LogisticHub.Module;
@@ -19,16 +20,25 @@ public class VeinManager : PatchImpl<VeinManager>
public static void Init() public static void Init()
{ {
Enable(true); Enable(true);
GameLogicProc.OnGameBegin += OnGameBegin;
} }
public static void Uninit() public static void Uninit()
{ {
GameLogicProc.OnGameBegin -= OnGameBegin;
Enable(false); Enable(false);
} }
public static void Clear() private static void OnGameBegin()
{ {
_veins = null; _veins = null;
var data = GameMain.data;
for (var index = data.factoryCount - 1; index >= 0; index--)
{
var factory = data.factories[index];
if (factory == null || factory.index != index) continue;
RecalcVeins(factory);
}
} }
public static ProductVeinData[] GetVeins(int planetIndex) public static ProductVeinData[] GetVeins(int planetIndex)

View File

@@ -6,7 +6,7 @@
## Usage ## Usage
* Miner(and fuel burning) functions * Miner(and fuel burning) functions
+Inspired by [PlanetMiner](https://dsp.thunderstore.io/package/blacksnipebiu/PlanetMiner)([github](https://github.com/blacksnipebiu/PlanetMiner)) + Inspired by [PlanetMiner](https://dsp.thunderstore.io/package/blacksnipebiu/PlanetMiner)([github](https://github.com/blacksnipebiu/PlanetMiner))
But it is heavily optimized to resolve performance, accuracy and other issues in PlanetMiner. But it is heavily optimized to resolve performance, accuracy and other issues in PlanetMiner.
+ (Optimization to PlanetMiner) Only recalculate count of veins when vein chunks are changed (added/removed by foundations/Sandbox-Mode, or exhausted), so this removes Dictionary allocation on each planet for every frame. + (Optimization to PlanetMiner) Only recalculate count of veins when vein chunks are changed (added/removed by foundations/Sandbox-Mode, or exhausted), so this removes Dictionary allocation on each planet for every frame.
+ (Optimization to PlanetMiner) More accurate frame counting by use float number. + (Optimization to PlanetMiner) More accurate frame counting by use float number.