diff --git a/DevShortcuts/DevShortcuts.cs b/DevShortcuts/DevShortcuts.cs index 3a9df22..432e292 100644 --- a/DevShortcuts/DevShortcuts.cs +++ b/DevShortcuts/DevShortcuts.cs @@ -6,13 +6,15 @@ namespace DevShortcuts; [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] public class DevShortcuts : BaseUnityPlugin { + private new static readonly BepInEx.Logging.ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME); + + private bool _cfgEnabled = true; + private void Awake() { + _cfgEnabled = Config.Bind("General", "Enabled", _cfgEnabled, "enable/disable this plugin").Value; + if (!_cfgEnabled) return; Logger.LogInfo($"Plugin {PluginInfo.PLUGIN_GUID} is loaded!"); - } - - private void Start() - { Harmony.CreateAndPatchAll(typeof(DevShortcuts)); } diff --git a/LogisticMiner/LogisticMiner.cs b/LogisticMiner/LogisticMiner.cs index 48e7a9b..f5e73dc 100644 --- a/LogisticMiner/LogisticMiner.cs +++ b/LogisticMiner/LogisticMiner.cs @@ -10,32 +10,67 @@ namespace LogisticMiner; [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] public class LogisticMiner : BaseUnityPlugin { - private static LogisticMiner _this; - private const int VeinEnergyRatio = 200000; - private const int WaterEnergyRatio = 50000; - private const int WaterSpeed = 100; + private new static readonly BepInEx.Logging.ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME); - private static float _frame, _nextFrame; + private static int _veinEnergyRatio = 200000; + private static int _waterEnergyRatio = 50000; + private static int _waterSpeed = 100; + private static int _miningScale = 100; + + private static float _frame; private static float _miningCostRate; private static uint _miningCostBarrier; private static uint _seed = (uint)Random.Range(int.MinValue, int.MaxValue); private static readonly Dictionary> Veins = new(); + private static readonly Dictionary FrameNext = new(); + + private bool _cfgEnabled = true; private void Awake() { + _cfgEnabled = Config.Bind("General", "Enabled", _cfgEnabled, "enable/disable this plugin").Value; + _veinEnergyRatio = Config.Bind("General", "EnergyConsumptionEachVein", _veinEnergyRatio / 1000, "200 for default. Energy consumption for each vein(in kJ)").Value * 1000; + _waterEnergyRatio = Config.Bind("General", "EnergyConsumptionEachWater", _waterEnergyRatio / 1000, "50 for default. Energy consumption for each water(in kJ)").Value * 1000; + _waterSpeed = Config.Bind("General", "WaterMiningSpeed", _waterSpeed, "100 for default. Water mining speed (count per second)").Value; + _miningScale = Config.Bind("General", "MiningScale", _miningScale, "100 for default. Must not be less than 100. Mining scale(in percents) for slots nearly empty (mining scale will slowly reduce to 1 till reach half of slot limits)").Value; + if (_miningScale < 100) + { + _miningScale = 100; + } + if (!_cfgEnabled) return; Logger.LogInfo($"Plugin {PluginInfo.PLUGIN_GUID} is loaded!"); - _this = this; - } - - private void Start() - { Harmony.CreateAndPatchAll(typeof(LogisticMiner)); } - private void FixedUpdate() + [HarmonyPostfix] + [HarmonyPatch(typeof(DSPGame), "StartGame", typeof(GameDesc))] + [HarmonyPatch(typeof(DSPGame), "StartGame", typeof(string))] + private static void OnGameStart() { + Logger.LogInfo("Game Start"); + FrameNext.Clear(); + _frame = 0f; + Veins.Clear(); + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(GameData), "GameTick")] + private static void FrameTick() + { + var main = GameMain.instance; + if (main.isMenuDemo) + { + return; + } _frame++; + if (_frame <= 1000000f) return; + /* keep precision of floats by limiting them <= 1000000f */ + _frame -= 1000000f; + foreach(var key in FrameNext.Keys.ToList()) + { + FrameNext[key] -= 1000000f; + } } [HarmonyPostfix] @@ -44,49 +79,68 @@ public class LogisticMiner : BaseUnityPlugin [HarmonyPatch(typeof(PlanetFactory), "RecalculateAllVeinGroups")] private static void NeedRecalcVeins(PlanetFactory __instance) { - VeinData[] veinPool = __instance.veinPool; - Veins.Clear(); + RecalcVeins(__instance); + } + + private static void RecalcVeins(PlanetFactory factory) + { + VeinData[] veinPool = factory.veinPool; + var planetId = factory.planetId; + /* remove planet veins from dict */ + Veins.Keys.Where(key => (key >> 16) == planetId).ToList().ForEach(key => Veins.Remove(key)); + /* re-add all veins to dict */ for (var i = 0; i < veinPool.Length; i++) { var veinData = veinPool[i]; if (veinData.amount > 0 && veinData.type > EVeinType.None) { - AddVeinData(__instance.planetId, veinData.productId, i); + AddVeinData(planetId, veinData.productId, i); } } } [HarmonyPostfix] - [HarmonyPatch(typeof(FactorySystem), "GameTickLabResearchMode")] + [HarmonyPatch(typeof(FactorySystem), "CheckBeforeGameTick")] private static void Miner(FactorySystem __instance) { - if (_nextFrame > _frame) - return; var history = GameMain.history; var miningSpeedScale = history.miningSpeedScale; if (miningSpeedScale <= 0f) return; + var factory = __instance.factory; + var planetId = factory.planetId; + if (FrameNext.TryGetValue(planetId, out var frameNext)) + { + if (frameNext > _frame) + return; + } + else + { + FrameNext[planetId] = _frame + 60f / miningSpeedScale; + return; + } + + var miningFrames = 60f / miningSpeedScale; var miningCostRate = history.miningCostRate; if (!miningCostRate.Equals(_miningCostRate)) { _miningCostRate = miningCostRate; _miningCostBarrier = (uint)(int)Math.Ceiling(2147483646.0 * miningCostRate); } - - var miningFrames = 60f / miningSpeedScale; - var factory = __instance.factory; - var key0 = factory.planetId << 16; + var key0 = planetId << 16; var veinPool = factory.veinPool; var planetTransport = __instance.planet.factory.transport; var factoryProductionStat = GameMain.statistics.production.factoryStatPool[__instance.factory.index]; var productRegister = factoryProductionStat?.productRegister; + PerformanceMonitor.BeginSample(ECpuWorkEntry.Miner); do { for (var j = 1; j < planetTransport.stationCursor; j++) { var stationComponent = planetTransport.stationPool[j]; if (stationComponent == null) continue; + /* skip Orbital Collectors and Advanced Mining Machines */ if (stationComponent.isCollector || stationComponent.isVeinCollector) continue; var storage = stationComponent.storage; if (storage == null) continue; @@ -105,7 +159,7 @@ public class LogisticMiner : BaseUnityPlugin int energyRatio; if (isVein) { - if (stationComponent.energy < VeinEnergyRatio) + if (stationComponent.energy < _veinEnergyRatio) { isCollecting = true; k = int.MaxValue - 1; @@ -114,33 +168,33 @@ public class LogisticMiner : BaseUnityPlugin if (veinPool[val.First()].type == EVeinType.Oil) amount = (int)val - .Where(item => veinPool.Length > item && veinPool[item].type > EVeinType.None) - .Sum(item => veinPool[item].amount / 6000f); + .Where(item => item < veinPool.Length && veinPool[item].type > EVeinType.None) + .Sum(item => veinPool[item].amount * VeinData.oilSpeedMultiplier * 2f); else amount = val.Sum( - item2 => GetMine(veinPool, item2, __instance.planet.factory) ? 1 : 0); - energyRatio = VeinEnergyRatio; + item => GetMine(veinPool, item, __instance.planet.factory) ? 1 : 0); + energyRatio = _veinEnergyRatio; } else { - if (stationComponent.energy < WaterEnergyRatio) + if (stationComponent.energy < _waterEnergyRatio) { isCollecting = true; k = int.MaxValue - 1; continue; } - amount = WaterSpeed; - energyRatio = WaterEnergyRatio; + amount = _waterSpeed; + energyRatio = _waterEnergyRatio; } if (amount == 0) continue; isCollecting = true; - var energyConsume = energyRatio * amount; + var energyConsume = (int)Math.Ceiling(energyRatio * amount / miningSpeedScale); if (energyConsume > stationComponent.energy) { - amount = (int)(stationComponent.energy / energyRatio); - energyConsume = energyRatio * amount; + amount = (int)(stationComponent.energy * miningSpeedScale / energyRatio); + energyConsume = (int)Math.Ceiling(energyRatio * amount / miningSpeedScale); } stationStore.count += amount; @@ -169,14 +223,10 @@ public class LogisticMiner : BaseUnityPlugin } } - _nextFrame += miningFrames; - } while (_nextFrame <= _frame); - - if (_frame >= 1000000f) - { - _frame -= 1000000f; - _nextFrame -= 1000000f; - } + frameNext += miningFrames; + } while (frameNext <= _frame); + PerformanceMonitor.EndSample(ECpuWorkEntry.Miner); + FrameNext[planetId] = frameNext; } private static void AddVeinData(int planetId, int productId, int index) @@ -193,6 +243,7 @@ public class LogisticMiner : BaseUnityPlugin if (veinDatas.Length == 0 || veinDatas[index].type == EVeinType.None) return false; + short groupIndex; if (veinDatas[index].amount > 0) { bool flag = true; @@ -208,7 +259,7 @@ public class LogisticMiner : BaseUnityPlugin factory.veinGroups[veinDatas[index].groupIndex].amount--; if (veinDatas[index].amount <= 0) { - short groupIndex = veinDatas[index].groupIndex; + groupIndex = veinDatas[index].groupIndex; factory.veinGroups[groupIndex].count--; factory.RemoveVeinWithComponents(index); factory.RecalculateVeinGroup(groupIndex); @@ -218,10 +269,10 @@ public class LogisticMiner : BaseUnityPlugin return true; } - short groupIndex2 = veinDatas[index].groupIndex; - factory.veinGroups[groupIndex2].count--; + groupIndex = veinDatas[index].groupIndex; + factory.veinGroups[groupIndex].count--; factory.RemoveVeinWithComponents(index); - factory.RecalculateVeinGroup(groupIndex2); + factory.RecalculateVeinGroup(groupIndex); return false; } -} \ No newline at end of file +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..00d6585 --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# DSP Mods by Soar Qin + +## [DevShortcuts](DevShortcuts) +### Restore Developer Mode keyboard Shortcuts hidden in original game codes, as following: +* Shift+F4 to switch Developer Mode on/off (no message, tip or sounds on switch). +* Numpad 1: Gets all items and extends bag. +* Numpad 2: Boosts walk speed, gathering speed and mecha energy restoration. +* Numpad 3: Fills planet with foundations and bury all veins. +* Numpad 4: +1 construction drone. +* Numpad 5: Upgrades drone engine tech to full. +* Numpad 6: Unlocks researching tech. +* Numpad 7: Unlocks Drive Engine 1. +* Numpad 8: Unlocks Drive Engine 2 and maximize energy. +* Numpad 9: Unlocks ability to warp. +* Numpad 0: No costs for Logistic Storages' output. +* LCtrl + T: Unlocks all techs (not upgrades) +* LCtrl + A: Resets all local achievements. +* LCtrl + Q: Adds 10000 to every metadata. +* LCtrl + W: Enters Sandbox Mode. +* Numpad *: Proliferates items on hand. +* Numpad /: Removes proliferations from items on hand. +* PageDown: Remembers Pose of game camera. +* PageUp: Locks game camera using remembered Pose. + + +## [LogisticMiner](LogisticMiner) +### Logistic Storages can mine all ores/water on current planet +* The same speed as normal Mining Machine for normal ores and 100/s for water. +* Energy costs: 200kJ for each vein or oil, 50kJ for each water. `Veins Utilization` upgrades does not increase power consumption. +* `Veins Utilization` upgrades affects mining speed and ore consume as normal. +### TODO +* Make Oil mining logic the same as normal (reduce speed periodically) +* Support mining scale in config \ No newline at end of file