mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2026-03-27 20:27:12 +08:00
Compare commits
30 Commits
cdfe5aa842
...
logistic_h
| Author | SHA1 | Date | |
|---|---|---|---|
| 09cdaf3a12 | |||
| 8d5bb140e1 | |||
| c99c59a117 | |||
| 61811f9a8c | |||
| cf3117e0da | |||
| dfd34601cf | |||
| 6934607fca | |||
| be9de43492 | |||
| 2dbf017a5e | |||
| 3c7744047c | |||
| a9959a2f07 | |||
| 77f5803a24 | |||
| e9bbcf5e2c | |||
| a183485286 | |||
| 5a6cfb18c9 | |||
| 49226001be | |||
| 7c1e88f86d | |||
| 16429936a9 | |||
| d711dd25ef | |||
| e909b6d9d2 | |||
| 2a4008deac | |||
| 6b423225fe | |||
| 9d9a12c1af | |||
| 1d11ba90bd | |||
| a5dc7c5825 | |||
| 73ebcf1aa3 | |||
| dc092d7f6f | |||
| d9f87ca4e9 | |||
| a3c60c32ca | |||
| 96a9e8a570 |
BIN
AssemblyFromGame/Assembly-CSharp.dll
Normal file
BIN
AssemblyFromGame/Assembly-CSharp.dll
Normal file
Binary file not shown.
BIN
AssemblyFromGame/UnityEngine.UI.dll
Normal file
BIN
AssemblyFromGame/UnityEngine.UI.dll
Normal file
Binary file not shown.
@@ -3,6 +3,9 @@
|
||||
|
||||
## Changlog
|
||||
|
||||
* 2.4.0
|
||||
* Support game version 0.10.33
|
||||
* `Generate illegal dyson shell`: This function is open to all users now, enabling certain config entry is not needed any more.
|
||||
* 2.3.32
|
||||
* `Complete Dyson Sphere Shells instantly`: Fix a crash.
|
||||
* 2.3.31
|
||||
@@ -162,6 +165,9 @@
|
||||
|
||||
## 更新日志
|
||||
|
||||
* 2.4.0
|
||||
* 支持游戏版本 0.10.33
|
||||
* `生成仙术戴森壳`:此功能现在对所有用户开放,不再需要启用特定的配置项。
|
||||
* 2.3.32
|
||||
* `立即完成戴森壳建造`:修复了一个崩溃问题
|
||||
* 2.3.31
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<BepInExPluginGuid>org.soardev.cheatenabler</BepInExPluginGuid>
|
||||
<Description>DSP MOD - CheatEnabler</Description>
|
||||
<Version>2.3.32</Version>
|
||||
<Version>2.4.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<PackageId>CheatEnabler</PackageId>
|
||||
@@ -16,15 +16,14 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BepInEx.Core" Version="5.*" />
|
||||
<PackageReference Include="BepInEx.PluginInfoProps" Version="1.*" />
|
||||
<PackageReference Include="DysonSphereProgram.GameLibs" Version="0.10.32.*-r.*" />
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2018.4.12" IncludeAssets="compile" />
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2022.3.53" IncludeAssets="compile" />
|
||||
<!-- <PackageReference Include="DysonSphereProgram.GameLibs" Version="0.10.32.*-r.*" /> -->
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\AssemblyFromGame\Assembly-CSharp.dll</HintPath>
|
||||
@@ -33,13 +32,12 @@
|
||||
<HintPath>..\AssemblyFromGame\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
-->
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\UXAssist\UXAssist.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="del /F /Q package\$(ProjectName)-$(Version).zip
powershell Compress-Archive -Force -DestinationPath 'package/$(ProjectName)-$(Version).zip' -Path '$(TargetPath)', package/icon.png, package/manifest.json, README.md, CHANGELOG.md" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -5,7 +5,6 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using Unity.Jobs;
|
||||
using UnityEngine;
|
||||
using UXAssist.Common;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Reflection.Emit;
|
||||
using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
using GameLogic = UXAssist.Common.GameLogic;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace CheatEnabler.Patches;
|
||||
|
||||
@@ -134,12 +134,12 @@ public class DysonSpherePatch : PatchImpl<DysonSpherePatch>
|
||||
{
|
||||
UpdateSailLifeTime();
|
||||
UpdateSailsCacheForThisGame();
|
||||
GameLogic.OnGameBegin += GameMain_Begin_Postfix;
|
||||
GameLogicProc.OnGameBegin += GameMain_Begin_Postfix;
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
GameLogic.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
GameLogicProc.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
}
|
||||
|
||||
private static void UpdateSailLifeTime()
|
||||
@@ -296,7 +296,7 @@ public class DysonSpherePatch : PatchImpl<DysonSpherePatch>
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(DysonSwarm), "GameTick")]
|
||||
[HarmonyPatch(typeof(DysonSwarm), nameof(DysonSwarm.GameTick))]
|
||||
public static void DysonSwarm_GameTick_Prefix(DysonSwarm __instance, long time)
|
||||
{
|
||||
var index = __instance.starData.index;
|
||||
|
||||
@@ -8,7 +8,7 @@ using HarmonyLib;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UXAssist.Common;
|
||||
using GameLogic = UXAssist.Common.GameLogic;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace CheatEnabler.Patches;
|
||||
|
||||
@@ -94,14 +94,14 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
ControlPanelRemoteLogistics.Enable(ControlPanelRemoteLogisticsEnabled.Value);
|
||||
Enable(true);
|
||||
CargoTrafficPatch.Enable(true);
|
||||
GameLogic.OnGameBegin += GameMain_Begin_Postfix_For_ImmBuild;
|
||||
GameLogic.OnDataLoaded += OnDataLoaded;
|
||||
GameLogicProc.OnGameBegin += GameMain_Begin_Postfix_For_ImmBuild;
|
||||
GameLogicProc.OnDataLoaded += OnDataLoaded;
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
{
|
||||
GameLogic.OnDataLoaded -= OnDataLoaded;
|
||||
GameLogic.OnGameBegin -= GameMain_Begin_Postfix_For_ImmBuild;
|
||||
GameLogicProc.OnDataLoaded -= OnDataLoaded;
|
||||
GameLogicProc.OnGameBegin -= GameMain_Begin_Postfix_For_ImmBuild;
|
||||
CargoTrafficPatch.Enable(false);
|
||||
Enable(false);
|
||||
ImmediateBuild.Enable(false);
|
||||
@@ -496,7 +496,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(StorageComponent), "GetItemCount", typeof(int))]
|
||||
[HarmonyPatch(typeof(StorageComponent), nameof(StorageComponent.GetItemCount), typeof(int))]
|
||||
public static void GetItemCountPatch(StorageComponent __instance, int itemId, ref int __result)
|
||||
{
|
||||
if (__result > 99) return;
|
||||
@@ -629,12 +629,12 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
protected override void OnEnable()
|
||||
{
|
||||
InitSignalBelts();
|
||||
GameLogic.OnGameBegin += GameMain_Begin_Postfix;
|
||||
GameLogicProc.OnGameBegin += GameMain_Begin_Postfix;
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
GameLogic.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
GameLogicProc.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
_initialized = false;
|
||||
_signalBelts = null;
|
||||
_signalBeltsCapacity = 0;
|
||||
@@ -995,7 +995,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
var data = GameMain.data;
|
||||
var factories = data?.factories;
|
||||
if (factories == null) return;
|
||||
PerformanceMonitor.BeginSample(ECpuWorkEntry.Belt);
|
||||
DeepProfiler.BeginSample(DPEntry.Belt);
|
||||
for (var index = data.factoryCount - 1; index >= 0; index--)
|
||||
{
|
||||
var factory = factories[index];
|
||||
@@ -1123,23 +1123,16 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
}
|
||||
}
|
||||
|
||||
PerformanceMonitor.EndSample(ECpuWorkEntry.Belt);
|
||||
DeepProfiler.EndSample(DPEntry.Belt);
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(GameData), "GameTick")]
|
||||
public static IEnumerable<CodeInstruction> GameData_GameTick_Transpiler(IEnumerable<CodeInstruction> instructions)
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameLogic), nameof(GameLogic.OnFactoryFrameBegin))]
|
||||
public static void GameLogic_OnFactoryFrameBegin_Postfix()
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(PerformanceMonitor), nameof(PerformanceMonitor.EndSample)))
|
||||
).Advance(1).Insert(
|
||||
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(BeltSignalGenerator), nameof(ProcessBeltSignals)))
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
ProcessBeltSignals();
|
||||
}
|
||||
|
||||
|
||||
/* BEGIN: Item sources calculation */
|
||||
private static readonly Dictionary<int, ItemSource> ItemSources = [];
|
||||
private static bool _itemSourcesInitialized;
|
||||
|
||||
@@ -64,19 +64,19 @@ public static class GamePatch
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), "NotifyBeforeGameSave")]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnAssemblerRecipePick")]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnGameBegin")]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnMechaForgeTaskComplete")]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnUnlockTech")]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), "NotifyOnUseConsole")]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), nameof(AbnormalityLogic.NotifyBeforeGameSave))]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), nameof(AbnormalityLogic.NotifyOnAssemblerRecipePick))]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), nameof(AbnormalityLogic.NotifyOnGameBegin))]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), nameof(AbnormalityLogic.NotifyOnMechaForgeTaskComplete))]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), nameof(AbnormalityLogic.NotifyOnUnlockTech))]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), nameof(AbnormalityLogic.NotifyOnUseConsole))]
|
||||
private static bool DisableAbnormalLogic()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), "InitDeterminators")]
|
||||
[HarmonyPatch(typeof(AbnormalityLogic), nameof(AbnormalityLogic.InitDeterminators))]
|
||||
private static void DisableAbnormalDeterminators(AbnormalityLogic __instance)
|
||||
{
|
||||
_savedDeterminators = __instance.determinators;
|
||||
@@ -282,7 +282,7 @@ public static class GamePatch
|
||||
}
|
||||
}
|
||||
|
||||
history.VarifyTechQueue();
|
||||
history.VerifyTechQueue();
|
||||
if (history.currentTech != history.techQueue[0])
|
||||
{
|
||||
history.currentTech = history.techQueue[0];
|
||||
|
||||
@@ -31,10 +31,10 @@ public static class ResourcePatch
|
||||
|
||||
private class InfiniteResource : PatchImpl<InfiniteResource>
|
||||
{
|
||||
static private readonly float InfiniteResourceRate = 0f;
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(FactorySystem), nameof(FactorySystem.GameTick), typeof(long), typeof(bool))]
|
||||
[HarmonyPatch(typeof(FactorySystem), nameof(FactorySystem.GameTick), typeof(long), typeof(bool), typeof(int), typeof(int), typeof(int))]
|
||||
[HarmonyPatch(typeof(ItemProto), nameof(ItemProto.GetPropValue))]
|
||||
[HarmonyPatch(typeof(GameLogic), nameof(GameLogic._miner_parallel))]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.GameTick))]
|
||||
[HarmonyPatch(typeof(UIChartAstroResource), nameof(UIChartAstroResource.CalculateMaxAmount))]
|
||||
[HarmonyPatch(typeof(UIChartVeinGroup), nameof(UIChartVeinGroup.CalculateMaxAmount))]
|
||||
@@ -42,18 +42,29 @@ public static class ResourcePatch
|
||||
[HarmonyPatch(typeof(UIControlPanelVeinCollectorPanel), nameof(UIControlPanelVeinCollectorPanel._OnUpdate))]
|
||||
[HarmonyPatch(typeof(UIMinerWindow), nameof(UIMinerWindow._OnUpdate))]
|
||||
[HarmonyPatch(typeof(UIMiningUpgradeLabel), nameof(UIMiningUpgradeLabel.Update))]
|
||||
[HarmonyPatch(typeof(UIStationStorage), nameof(UIStationStorage.RefreshValues))]
|
||||
[HarmonyPatch(typeof(UIVeinCollectorPanel), nameof(UIVeinCollectorPanel._OnUpdate))]
|
||||
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(GameHistoryData), nameof(GameHistoryData.miningCostRate)))
|
||||
new CodeMatch(ci => (ci.opcode == OpCodes.Ldfld || ci.opcode == OpCodes.Ldflda) && ci.OperandIs(AccessTools.Field(typeof(GameHistoryData), nameof(GameHistoryData.miningCostRate))))
|
||||
).Repeat(codeMatcher =>
|
||||
codeMatcher.RemoveInstruction().InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Pop),
|
||||
new CodeInstruction(OpCodes.Ldc_R4, 0f)
|
||||
)
|
||||
{
|
||||
if (codeMatcher.Instruction.opcode == OpCodes.Ldfld)
|
||||
{
|
||||
codeMatcher.RemoveInstruction().InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Pop),
|
||||
new CodeInstruction(OpCodes.Ldc_R4, InfiniteResourceRate)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
codeMatcher.RemoveInstruction().InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Pop),
|
||||
new CodeInstruction(OpCodes.Ldsflda, AccessTools.Field(typeof(InfiniteResource), nameof(InfiniteResourceRate)))
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
@@ -61,29 +72,51 @@ public static class ResourcePatch
|
||||
|
||||
private class FastMining : PatchImpl<FastMining>
|
||||
{
|
||||
static private readonly float FastMiningSpeed = 2400f;
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(FactorySystem), "GameTick", typeof(long), typeof(bool))]
|
||||
[HarmonyPatch(typeof(FactorySystem), "GameTick", typeof(long), typeof(bool), typeof(int), typeof(int), typeof(int))]
|
||||
[HarmonyPatch(typeof(ItemProto), "GetPropValue")]
|
||||
[HarmonyPatch(typeof(PlanetTransport), "GameTick")]
|
||||
[HarmonyPatch(typeof(UIMinerWindow), "_OnUpdate")]
|
||||
[HarmonyPatch(typeof(UIMiningUpgradeLabel), "Update")]
|
||||
[HarmonyPatch(typeof(UIPlanetDetail), "OnPlanetDataSet")]
|
||||
[HarmonyPatch(typeof(UIPlanetDetail), "RefreshDynamicProperties")]
|
||||
[HarmonyPatch(typeof(UIStarDetail), "OnStarDataSet")]
|
||||
[HarmonyPatch(typeof(UIStarDetail), "RefreshDynamicProperties")]
|
||||
[HarmonyPatch(typeof(UIStationStorage), "RefreshValues")]
|
||||
[HarmonyPatch(typeof(UIVeinCollectorPanel), "_OnUpdate")]
|
||||
[HarmonyPatch(typeof(AstroResourceStatPlan), nameof(AstroResourceStatPlan.AddPlanetResources))]
|
||||
[HarmonyPatch(typeof(BuildingGizmo), nameof(BuildingGizmo.Update))]
|
||||
[HarmonyPatch(typeof(FactorySystem), nameof(FactorySystem.GameTick), typeof(long), typeof(bool))]
|
||||
[HarmonyPatch(typeof(GameLogic), nameof(GameLogic._miner_parallel))]
|
||||
[HarmonyPatch(typeof(ItemProto), nameof(ItemProto.GetPropValue))]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.GameTick))]
|
||||
[HarmonyPatch(typeof(ProductionExtraInfoCalculator), nameof(ProductionExtraInfoCalculator.CalculateFactory))]
|
||||
[HarmonyPatch(typeof(UIChartAstroResource), nameof(UIChartAstroResource.CalculateMaxAmount))]
|
||||
[HarmonyPatch(typeof(UIChartVeinGroup), nameof(UIChartVeinGroup.CalculateMaxAmount))]
|
||||
[HarmonyPatch(typeof(UIControlPanelStationStorage), nameof(UIControlPanelStationStorage.RefreshValues))]
|
||||
[HarmonyPatch(typeof(UIControlPanelVeinCollectorPanel), nameof(UIControlPanelVeinCollectorPanel._OnUpdate))]
|
||||
[HarmonyPatch(typeof(UIMinerWindow), nameof(UIMinerWindow._OnUpdate))]
|
||||
[HarmonyPatch(typeof(UIMiningUpgradeLabel), nameof(UIMiningUpgradeLabel.Update))]
|
||||
[HarmonyPatch(typeof(UIPlanetDetail), nameof(UIPlanetDetail.OnPlanetDataSet))]
|
||||
[HarmonyPatch(typeof(UIPlanetDetail), nameof(UIPlanetDetail.RefreshDynamicProperties))]
|
||||
[HarmonyPatch(typeof(UIReferenceSpeedTip), nameof(UIReferenceSpeedTip.AddEntryDataWithFactory))]
|
||||
[HarmonyPatch(typeof(UIStarDetail), nameof(UIStarDetail.OnStarDataSet))]
|
||||
[HarmonyPatch(typeof(UIStarDetail), nameof(UIStarDetail.RefreshDynamicProperties))]
|
||||
[HarmonyPatch(typeof(UIStationStorage), nameof(UIStationStorage.RefreshValues))]
|
||||
[HarmonyPatch(typeof(UIVeinCollectorPanel), nameof(UIVeinCollectorPanel._OnUpdate))]
|
||||
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(GameHistoryData), nameof(GameHistoryData.miningSpeedScale)))
|
||||
new CodeMatch(ci => (ci.opcode == OpCodes.Ldfld || ci.opcode == OpCodes.Ldflda) && ci.OperandIs(AccessTools.Field(typeof(GameHistoryData), nameof(GameHistoryData.miningSpeedScale))))
|
||||
).Repeat(codeMatcher =>
|
||||
codeMatcher.RemoveInstruction().InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Pop),
|
||||
new CodeInstruction(OpCodes.Ldc_R4, 2400f)
|
||||
)
|
||||
{
|
||||
if (codeMatcher.Instruction.opcode == OpCodes.Ldfld)
|
||||
{
|
||||
codeMatcher.RemoveInstruction().InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Pop),
|
||||
new CodeInstruction(OpCodes.Ldc_R4, FastMiningSpeed)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
codeMatcher.RemoveInstruction().InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Pop),
|
||||
new CodeInstruction(OpCodes.Ldsflda, AccessTools.Field(typeof(FastMining), nameof(FastMiningSpeed)))
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
* Eject anyway
|
||||
* Unlock Dyson Sphere max orbit radius
|
||||
* Complete Dyson Sphere Shells instantly
|
||||
* Buttons for creating illegal Dyson Sphere Shells, you must enable `IllegalDysonShellFunctionsEnabled` of `DysonSphere` section in config to see them.
|
||||
* Buttons for creating illegal Dyson Sphere Shells, you must enable `IllegalDysonShellFunctionsEnabled` of `DysonSphere` section in config to see the last 2 buttons.
|
||||
* Generate an illegal dyson shell
|
||||
* Keep max production shells and remove others
|
||||
* Duplicate shells from that with highest production
|
||||
@@ -123,7 +123,7 @@
|
||||
* 全球弹射
|
||||
* 解锁戴森球最大轨道半径
|
||||
* 立即完成戴森壳建造
|
||||
* 用于制作仙术戴森壳的按钮,你必须在设置文件里开启`DysonSphere`分类的`IllegalDysonShellFunctionsEnabled`才能看到它们
|
||||
* 用于制作仙术戴森壳的按钮,你必须在设置文件里开启`DysonSphere`分类的`IllegalDysonShellFunctionsEnabled`才能看到后面两个按钮
|
||||
* 生成单层仙术戴森壳
|
||||
* 保留发电量最高的戴森壳并移除其他戴森壳
|
||||
* 从发电量最高的壳复制戴森壳
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "CheatEnabler",
|
||||
"version_number": "2.3.32",
|
||||
"version_number": "2.4.0",
|
||||
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/CheatEnabler",
|
||||
"description": "Add various cheat functions while disabling abnormal determinants / 添加一些作弊功能,同时屏蔽异常检测",
|
||||
"dependencies": [
|
||||
"xiaoye97-BepInEx-5.4.17",
|
||||
"soarqin-UXAssist-1.2.0"
|
||||
"soarqin-UXAssist-1.4.0"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UXAssist", "UXAssist\UXAssi
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CheatEnabler", "CheatEnabler\CheatEnabler.csproj", "{F9F16B62-D1D3-466B-BE22-E64B9EA957C2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogisticMiner", "LogisticMiner\LogisticMiner.csproj", "{7149D717-C913-4153-9425-38CB9D087F83}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogisticHub", "LogisticHub\LogisticHub.csproj", "{7149D717-C913-4153-9425-38CB9D087F83}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HideTips", "HideTips\HideTips.csproj", "{4EABD71D-477F-448B-801B-48F8745A3FA7}"
|
||||
EndProject
|
||||
|
||||
@@ -152,7 +152,7 @@ public class HideTips : BaseUnityPlugin
|
||||
class HideMenuDemo
|
||||
{
|
||||
[HarmonyPriority(Priority.First), HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(DSPGame), "StartDemoGame", typeof(int))]
|
||||
[HarmonyPatch(typeof(DSPGame), nameof(DSPGame.StartDemoGame), typeof(int))]
|
||||
private static bool DSPGame_StartDemoGame_Prefix()
|
||||
{
|
||||
if (DSPGame.Game != null)
|
||||
@@ -188,7 +188,7 @@ class HideMenuDemo
|
||||
}
|
||||
|
||||
[HarmonyPriority(Priority.First), HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(VFPreload), "IsMenuDemoLoaded")]
|
||||
[HarmonyPatch(typeof(VFPreload), nameof(VFPreload.IsMenuDemoLoaded))]
|
||||
private static bool VFPreload_IsMenuDemoLoaded_Prefix(ref bool __result)
|
||||
{
|
||||
__result = true;
|
||||
@@ -196,18 +196,18 @@ class HideMenuDemo
|
||||
}
|
||||
|
||||
[HarmonyPriority(Priority.First), HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(DSPGame), "LateUpdate")]
|
||||
[HarmonyPatch(typeof(GameMain), "LateUpdate")]
|
||||
[HarmonyPatch(typeof(GameMain), "FixedUpdate")]
|
||||
[HarmonyPatch(typeof(GameMain), "Update")]
|
||||
[HarmonyPatch(typeof(GameCamera), "LateUpdate")]
|
||||
[HarmonyPatch(typeof(DSPGame), nameof(DSPGame.LateUpdate))]
|
||||
[HarmonyPatch(typeof(GameMain), nameof(GameMain.LateUpdate))]
|
||||
[HarmonyPatch(typeof(GameMain), nameof(GameMain.FixedUpdate))]
|
||||
[HarmonyPatch(typeof(GameMain), nameof(GameMain.Update))]
|
||||
[HarmonyPatch(typeof(GameCamera), nameof(GameCamera.LateUpdate))]
|
||||
private static bool DSPGame_LateUpdate_Prefix()
|
||||
{
|
||||
return !DSPGame.IsMenuDemo;
|
||||
}
|
||||
|
||||
[HarmonyPriority(Priority.First), HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(GameMain), "Begin")]
|
||||
[HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))]
|
||||
private static bool GameMain_Begin_Prefix()
|
||||
{
|
||||
if (!DSPGame.IsMenuDemo) return true;
|
||||
|
||||
57
LogisticHub/LogisticHub.cs
Normal file
57
LogisticHub/LogisticHub.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using BepInEx;
|
||||
using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
|
||||
namespace LogisticHub;
|
||||
|
||||
[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)]
|
||||
public class LogisticHub : BaseUnityPlugin
|
||||
{
|
||||
public new static readonly BepInEx.Logging.ManualLogSource Logger =
|
||||
BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME);
|
||||
|
||||
private Type[] _modules;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Module.Miner.Enabled = Config.Bind("Miner", "Enabled", true, "enable/disable this plugin");
|
||||
Module.Miner.OreEnergyConsume = Config.Bind("Miner", "EnergyConsumptionForOre", 2000000L,
|
||||
"Energy consumption for each ore vein group(in W)");
|
||||
Module.Miner.OreMiningMultiplier = Config.Bind("Miner", "OreMiningMultiplier", 3,
|
||||
new ConfigDescription("Mining multiplier for ore veins, multiplies to the number of veins in the group", new AcceptableValueRange<int>(1, 100)));
|
||||
Module.Miner.OreMiningScale = Config.Bind("Miner", "OreMiningScale", 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.
|
||||
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,
|
||||
new ConfigDescription("Fuel slot for ILS, set 0 to disable.", new AcceptableValueRange<int>(0, 5)));
|
||||
Module.Miner.FuelPlsSlot = Config.Bind("Miner", "PLSFuelSlot", 4,
|
||||
new ConfigDescription("Fuel slot for PLS, set 0 to disable.", new AcceptableValueRange<int>(0, 4)));
|
||||
|
||||
_modules = Util.GetTypesFiltered(Assembly.GetExecutingAssembly(),
|
||||
t => string.Equals(t.Namespace, "LogisticHub.Module", StringComparison.Ordinal));
|
||||
_modules?.Do(type => type.GetMethod("Init")?.Invoke(null, null));
|
||||
Harmony.CreateAndPatchAll(typeof(LogisticHub));
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_modules?.Do(type => type.GetMethod("Start")?.Invoke(null, null));
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
_modules?.Do(type => type.GetMethod("Uninit")?.Invoke(null, null));
|
||||
}
|
||||
}
|
||||
39
LogisticHub/LogisticHub.csproj
Normal file
39
LogisticHub/LogisticHub.csproj
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<BepInExPluginGuid>org.soardev.logistichub</BepInExPluginGuid>
|
||||
<Description>DSP MOD - LogisticHub</Description>
|
||||
<Version>0.1.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<RestoreAdditionalProjectSources>https://nuget.bepinex.dev/v3/index.json</RestoreAdditionalProjectSources>
|
||||
<PackageId>LogisticHub</PackageId>
|
||||
<RootNamespace>LogisticHub</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BepInEx.Core" Version="5.*" />
|
||||
<PackageReference Include="BepInEx.PluginInfoProps" Version="1.*" />
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2022.3.53" IncludeAssets="compile" />
|
||||
<!-- <PackageReference Include="DysonSphereProgram.GameLibs" Version="0.10.32.*-r.*" /> -->
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\AssemblyFromGame\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>..\AssemblyFromGame\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\UXAssist\UXAssist.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
33
LogisticHub/Module/AuxData.cs
Normal file
33
LogisticHub/Module/AuxData.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace LogisticHub.Module;
|
||||
|
||||
using UXAssist.Common;
|
||||
|
||||
public static class AuxData
|
||||
{
|
||||
public static (long, bool)[] Fuels;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
GameLogic.OnDataLoaded += () =>
|
||||
{
|
||||
var maxId = LDB.items.dataArray.Select(data => data.ID).Prepend(0).Max();
|
||||
Fuels = new (long, bool)[maxId + 1];
|
||||
foreach (var data in LDB.items.dataArray)
|
||||
Fuels[data.ID] = (data.HeatValue, data.Productive);
|
||||
};
|
||||
}
|
||||
|
||||
public static int AlignUpToPowerOf2(int n)
|
||||
{
|
||||
if (n < 16) return 16;
|
||||
n--;
|
||||
n |= n >> 1;
|
||||
n |= n >> 2;
|
||||
n |= n >> 4;
|
||||
n |= n >> 8;
|
||||
n |= n >> 16;
|
||||
return n + 1;
|
||||
}
|
||||
}
|
||||
0
LogisticHub/Module/Ejector.cs
Normal file
0
LogisticHub/Module/Ejector.cs
Normal file
345
LogisticHub/Module/Miner.cs
Normal file
345
LogisticHub/Module/Miner.cs
Normal file
@@ -0,0 +1,345 @@
|
||||
using System;
|
||||
using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
using Random = UnityEngine.Random;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace LogisticHub.Module;
|
||||
|
||||
public class Miner : PatchImpl<Miner>
|
||||
{
|
||||
public static ConfigEntry<bool> Enabled;
|
||||
public static ConfigEntry<long> OreEnergyConsume;
|
||||
public static ConfigEntry<int> OreMiningScale;
|
||||
public static ConfigEntry<int> OreMiningMultiplier;
|
||||
public static ConfigEntry<long> OilEnergyConsume;
|
||||
public static ConfigEntry<long> WaterEnergyConsume;
|
||||
public static ConfigEntry<int> WaterSpeed;
|
||||
public static ConfigEntry<int> FuelIlsSlot;
|
||||
public static ConfigEntry<int> FuelPlsSlot;
|
||||
|
||||
private static long _frame;
|
||||
private static float _miningCostRateByTech;
|
||||
private static long _miningFrames;
|
||||
private static long _miningSpeedScaleLong;
|
||||
private static bool _advancedMiningMachineUnlocked;
|
||||
private static int _miningMultiplier = 3;
|
||||
private static int _miningScale = 100;
|
||||
private static uint _miningCostBarrier;
|
||||
private static uint _miningCostBarrierOil;
|
||||
private static int[] _mineIndex;
|
||||
|
||||
private static uint _miningSeed = (uint)Random.Range(0, int.MaxValue);
|
||||
|
||||
private static readonly (int, int)[] VeinList =
|
||||
[
|
||||
(0, 1000),
|
||||
(1, 1001),
|
||||
(2, 1002),
|
||||
(3, 1003),
|
||||
(4, 1004),
|
||||
(5, 1005),
|
||||
(6, 1006),
|
||||
(7, 1007),
|
||||
(11, 1011),
|
||||
(12, 1012),
|
||||
(13, 1013),
|
||||
(14, 1014),
|
||||
(15, 1015),
|
||||
(16, 1016)
|
||||
];
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
Enabled.SettingChanged += (_, _) => { Enable(Enabled.Value); };
|
||||
|
||||
Enable(Enabled.Value);
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
{
|
||||
Enable(false);
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
GameLogicProc.OnGameBegin += OnGameBegin;
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin;
|
||||
}
|
||||
|
||||
private static void OnGameBegin()
|
||||
{
|
||||
_frame = 0L;
|
||||
UpdateMiningCostRate();
|
||||
UpdateSpeedScale();
|
||||
CheckRecipes();
|
||||
}
|
||||
|
||||
private static int SplitIncLevel(ref int n, ref int m, int p)
|
||||
{
|
||||
var level = m / n;
|
||||
var left = m - level * n;
|
||||
n -= p;
|
||||
left -= n;
|
||||
m -= left > 0 ? level * p + left : level * p;
|
||||
return level;
|
||||
}
|
||||
|
||||
private static void CheckRecipes()
|
||||
{
|
||||
_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()
|
||||
{
|
||||
_miningCostRateByTech = GameMain.history.miningCostRate;
|
||||
_miningCostBarrier = (uint)(int)Math.Ceiling(2147483646.0 * _miningCostRateByTech);
|
||||
_miningCostBarrierOil = (uint)(int)Math.Ceiling(2147483646.0 * _miningCostRateByTech * 0.401116669f / Math.Max(DSPGame.GameDesc.resourceMultiplier, 0.416666657f));
|
||||
}
|
||||
|
||||
private static void UpdateSpeedScale()
|
||||
{
|
||||
_miningSpeedScaleLong = (long)Math.Round(GameMain.history.miningSpeedScale * 100f);
|
||||
_miningFrames = _miningSpeedScaleLong * 6000L;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.UnlockTechFunction))]
|
||||
private static void OnUnlockTech(int func)
|
||||
{
|
||||
switch (func)
|
||||
{
|
||||
case 20:
|
||||
UpdateMiningCostRate();
|
||||
break;
|
||||
case 21:
|
||||
UpdateSpeedScale();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(GameLogic), nameof(GameLogic.OnFactoryFrameBegin))]
|
||||
private static void GameLogic_OnFactoryFrameBegin_Prefix()
|
||||
{
|
||||
var main = GameMain.instance;
|
||||
if (main.isMenuDemo) return;
|
||||
if (_miningSpeedScaleLong <= 0L) return;
|
||||
|
||||
if (main.timei % 60 != 0) return;
|
||||
_frame += _miningFrames;
|
||||
var frameCounter = _frame / 1200000L;
|
||||
if (frameCounter <= 0) return;
|
||||
_frame -= frameCounter * 1200000L;
|
||||
|
||||
DeepProfiler.BeginSample(DPEntry.Miner);
|
||||
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--)
|
||||
{
|
||||
var factory = data.factories[factoryIndex];
|
||||
var veins = VeinManager.GetVeins(factoryIndex);
|
||||
if (veins == null) continue;
|
||||
var stations = StationManager.GetStations(factoryIndex);
|
||||
var planetTransport = factory.transport;
|
||||
var productRegister = factoryStatPool[factoryIndex]?.productRegister;
|
||||
var demands = stations.StorageIndices[1];
|
||||
if (demands == null) continue;
|
||||
foreach (var (itemIndex, itemId) in VeinList)
|
||||
{
|
||||
if (itemIndex >= demands.Length) continue;
|
||||
var demandList = demands[itemIndex];
|
||||
if (demandList == null) continue;
|
||||
foreach (var storageIndex in demandList)
|
||||
{
|
||||
var station = planetTransport.stationPool[storageIndex / 100];
|
||||
if (station == null)
|
||||
continue;
|
||||
ref var storage = ref station.storage[storageIndex % 100];
|
||||
if (storage.count >= storage.max) continue;
|
||||
int amount;
|
||||
long energyConsume;
|
||||
var miningScale = _miningScale;
|
||||
if (miningScale > 100 && storage.count * 2 > storage.max)
|
||||
{
|
||||
miningScale = 100 + ((miningScale - 100) * (storage.max - storage.count) * 2 + storage.max - 1) / storage.max;
|
||||
}
|
||||
|
||||
if (itemIndex > 0)
|
||||
{
|
||||
(amount, energyConsume) = Mine(factory, veins, itemId, miningScale, (int)frameCounter, _miningMultiplier, station.energy);
|
||||
if (amount < 0) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
energyConsume = (WaterEnergyConsume.Value * frameCounter * miningScale * miningScale + 9999L) / 10000L;
|
||||
if (station.energy < energyConsume) continue;
|
||||
amount = WaterSpeed.Value * miningScale / 100;
|
||||
}
|
||||
|
||||
if (amount <= 0) continue;
|
||||
storage.count += amount;
|
||||
if (productRegister != null)
|
||||
productRegister[itemId] += amount;
|
||||
station.energy -= energyConsume;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = planetTransport.stationCursor - 1; i > 0; i--)
|
||||
{
|
||||
var stationComponent = planetTransport.stationPool[i];
|
||||
if (stationComponent == null || stationComponent.isCollector || stationComponent.isVeinCollector || stationComponent.energy * 2 >= stationComponent.energyMax) continue;
|
||||
var index = (stationComponent.isStellar ? FuelIlsSlot.Value : FuelPlsSlot.Value) - 1;
|
||||
var storage = stationComponent.storage;
|
||||
if (index < 0 || index >= storage.Length)
|
||||
continue;
|
||||
var fuelCount = storage[index].count;
|
||||
if (fuelCount == 0) continue;
|
||||
var (heat, prod) = AuxData.Fuels[storage[index].itemId];
|
||||
if (heat <= 0)
|
||||
continue;
|
||||
/* Sprayed fuels */
|
||||
int pretendIncLevel;
|
||||
if (prod && (pretendIncLevel = storage[index].inc / storage[index].count) > 0)
|
||||
{
|
||||
var count = (int)((stationComponent.energyMax - stationComponent.energy) * 1000L / Cargo.incTable[pretendIncLevel] / 7L);
|
||||
if (count > fuelCount)
|
||||
count = fuelCount;
|
||||
var incLevel = SplitIncLevel(ref storage[index].count, ref storage[index].inc, count);
|
||||
if (incLevel > 10)
|
||||
incLevel = 10;
|
||||
stationComponent.energy += heat * count * (1000L + Cargo.incTable[incLevel]) / 1000L;
|
||||
}
|
||||
else
|
||||
{
|
||||
var count = (int)((stationComponent.energyMax - stationComponent.energy) / heat);
|
||||
if (count > fuelCount)
|
||||
count = fuelCount;
|
||||
SplitIncLevel(ref storage[index].count, ref storage[index].inc, count);
|
||||
stationComponent.energy += heat * count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeepProfiler.EndSample(DPEntry.Miner);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.UnlockRecipe))]
|
||||
private static void OnUnlockRecipe(int recipeId)
|
||||
{
|
||||
if (recipeId == 119)
|
||||
{
|
||||
CheckRecipes();
|
||||
}
|
||||
}
|
||||
|
||||
private static (int, long) Mine(PlanetFactory factory, ProductVeinData[] allVeins, int productId, int percent, int counter, int multiplier, long energyMax)
|
||||
{
|
||||
var veins = allVeins[productId - 1000];
|
||||
if (veins == null)
|
||||
return (-1, -1L);
|
||||
|
||||
var veinIndices = veins.VeinIndices;
|
||||
uint barrier;
|
||||
int limit;
|
||||
int count;
|
||||
long energy;
|
||||
var length = veinIndices.Count - 1;
|
||||
/* if is Oil */
|
||||
if (productId == 1007)
|
||||
{
|
||||
energy = OilEnergyConsume.Value * length;
|
||||
if (energy > energyMax)
|
||||
return (-1, -1L);
|
||||
var countf = 0f;
|
||||
var veinsPool = factory.veinPool;
|
||||
for (var i = length; i > 0; i--)
|
||||
{
|
||||
countf += veinsPool[veinIndices[i]].amount * 4 * VeinData.oilSpeedMultiplier;
|
||||
}
|
||||
count = (int)(countf * (counter * percent) / 100f);
|
||||
if (count == 0)
|
||||
return (-1, -1L);
|
||||
barrier = _miningCostBarrierOil;
|
||||
limit = 2500;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = (length * multiplier * counter * percent + 99) / 100;
|
||||
if (count == 0)
|
||||
return (-1, -1L);
|
||||
energy = (OreEnergyConsume.Value * veins.GroupCount * percent * percent + 9999L) / 10000L;
|
||||
if (energy > energyMax)
|
||||
return (-1, -1L);
|
||||
barrier = _miningCostBarrier;
|
||||
limit = 0;
|
||||
}
|
||||
|
||||
var veinsData = factory.veinPool;
|
||||
var total = 0;
|
||||
var factoryIndex = factory.index;
|
||||
var mineIndex = _mineIndex[factoryIndex];
|
||||
for (; count > 0; count--)
|
||||
{
|
||||
mineIndex = mineIndex % length + 1;
|
||||
var index = veinIndices[mineIndex];
|
||||
ref var vd = ref veinsData[index];
|
||||
int groupIndex;
|
||||
|
||||
if (vd.amount <= 0)
|
||||
{
|
||||
groupIndex = vd.groupIndex;
|
||||
factory.veinGroups[groupIndex].count--;
|
||||
factory.RemoveVeinWithComponents(index);
|
||||
factory.RecalculateVeinGroup(groupIndex);
|
||||
length = veinIndices.Count - 1;
|
||||
if (length <= 0) break;
|
||||
continue;
|
||||
}
|
||||
|
||||
total++;
|
||||
|
||||
if (vd.amount <= limit) continue;
|
||||
var consume = true;
|
||||
if (barrier < 2147483646u)
|
||||
{
|
||||
_miningSeed = (uint)((int)((ulong)((_miningSeed % 2147483646u + 1) * 48271L) % 2147483647uL) - 1);
|
||||
consume = _miningSeed < barrier;
|
||||
}
|
||||
|
||||
if (!consume) continue;
|
||||
|
||||
vd.amount--;
|
||||
groupIndex = vd.groupIndex;
|
||||
factory.veinGroups[groupIndex].amount--;
|
||||
|
||||
if (vd.amount > 0) continue;
|
||||
factory.veinGroups[groupIndex].count--;
|
||||
factory.RemoveVeinWithComponents(index);
|
||||
factory.RecalculateVeinGroup(groupIndex);
|
||||
length = veinIndices.Count - 1;
|
||||
if (length <= 0) break;
|
||||
}
|
||||
|
||||
_mineIndex[factoryIndex] = mineIndex;
|
||||
|
||||
return (total, energy);
|
||||
}
|
||||
}
|
||||
325
LogisticHub/Module/StationManager.cs
Normal file
325
LogisticHub/Module/StationManager.cs
Normal file
@@ -0,0 +1,325 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace LogisticHub.Module;
|
||||
|
||||
public class PlanetStations
|
||||
{
|
||||
public readonly List<int>[][] StorageIndices = [null, null];
|
||||
|
||||
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];
|
||||
if (stations == null || id >= stations.Length)
|
||||
{
|
||||
Array.Resize(ref stations, AuxData.AlignUpToPowerOf2(id + 1));
|
||||
StorageIndices[demand ? 1 : 0] = stations;
|
||||
}
|
||||
|
||||
var list = stations[id];
|
||||
if (list == null)
|
||||
{
|
||||
list = [];
|
||||
stations[id] = list;
|
||||
}
|
||||
|
||||
var value = stationId * 100 + storageIdx;
|
||||
var index = list.BinarySearch(value);
|
||||
if (index < 0)
|
||||
list.Insert(~index, value);
|
||||
}
|
||||
|
||||
public void RemoveStationStorage(bool demand, int id, int stationId, int storageIdx)
|
||||
{
|
||||
var stations = StorageIndices[demand ? 1 : 0];
|
||||
if (stations == null || id >= stations.Length)
|
||||
return;
|
||||
var list = stations[id];
|
||||
if (list == null)
|
||||
return;
|
||||
|
||||
var value = stationId * 100 + storageIdx;
|
||||
var index = list.BinarySearch(value);
|
||||
if (index >= 0)
|
||||
list.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
public class StationManager : PatchImpl<StationManager>
|
||||
{
|
||||
private static PlanetStations[] _stations;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
GameLogicProc.OnGameBegin += OnGameBegin;
|
||||
Enable(true);
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
{
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin;
|
||||
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)
|
||||
{
|
||||
return itemId switch
|
||||
{
|
||||
>= 1000 and < 2000 => itemId - 1000,
|
||||
>= 5000 and < 5050 => itemId - 5000 + 900,
|
||||
>= 6000 and < 6050 => itemId - 6000 + 950,
|
||||
_ => -1
|
||||
};
|
||||
}
|
||||
|
||||
public static int IndexToItemId(int index)
|
||||
{
|
||||
return index switch
|
||||
{
|
||||
< 900 => index + 1000,
|
||||
< 950 => index - 900 + 5000,
|
||||
< 1000 => index - 950 + 6000,
|
||||
_ => -1
|
||||
};
|
||||
}
|
||||
|
||||
public static PlanetStations GetStations(int planetIndex)
|
||||
{
|
||||
return _stations != null && planetIndex < _stations.Length ? _stations[planetIndex] : null;
|
||||
}
|
||||
|
||||
private static PlanetStations StationsByPlanet(int planetIndex)
|
||||
{
|
||||
if (_stations == null || _stations.Length <= planetIndex)
|
||||
Array.Resize(ref _stations, AuxData.AlignUpToPowerOf2(planetIndex + 1));
|
||||
var stations = _stations[planetIndex];
|
||||
if (stations != null) return stations;
|
||||
stations = new PlanetStations();
|
||||
_stations[planetIndex] = stations;
|
||||
return stations;
|
||||
}
|
||||
|
||||
private static void DebugLog()
|
||||
{
|
||||
for (var idx = 0; idx < _stations.Length; idx++)
|
||||
{
|
||||
var stations = _stations[idx];
|
||||
if (stations == null) continue;
|
||||
LogisticHub.Logger.LogDebug($"Planet {idx}:");
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
var storage = stations.StorageIndices[i];
|
||||
if (storage == null) continue;
|
||||
LogisticHub.Logger.LogDebug(i == 1 ? " Demand:" : " Supply:");
|
||||
for (var j = 0; j < storage.Length; j++)
|
||||
{
|
||||
var list = storage[j];
|
||||
if (list == null) continue;
|
||||
var count = list.Count;
|
||||
if (count <= 0) continue;
|
||||
var itemId = IndexToItemId(j);
|
||||
LogisticHub.Logger.LogDebug($" {itemId}: {string.Join(", ", list)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateStationInfo(PlanetStations stations, StationComponent station, int storageIdx = -1)
|
||||
{
|
||||
var storage = station.storage;
|
||||
var stationId = station.id;
|
||||
if (storageIdx >= 0)
|
||||
{
|
||||
if (storageIdx >= storage.Length) return;
|
||||
var itemId = ItemIdToIndex(storage[storageIdx].itemId);
|
||||
if (itemId <= 0) return;
|
||||
var logic = storage[storageIdx].localLogic;
|
||||
switch (logic)
|
||||
{
|
||||
case ELogisticStorage.Demand:
|
||||
stations.AddStationStorage(true, itemId, stationId, storageIdx);
|
||||
break;
|
||||
case ELogisticStorage.Supply:
|
||||
stations.AddStationStorage(false, itemId, stationId, storageIdx);
|
||||
break;
|
||||
case ELogisticStorage.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = storage.Length - 1; i >= 0; i--)
|
||||
{
|
||||
var itemId = ItemIdToIndex(storage[i].itemId);
|
||||
if (itemId <= 0) continue;
|
||||
var logic = storage[i].localLogic;
|
||||
switch (logic)
|
||||
{
|
||||
case ELogisticStorage.Demand:
|
||||
stations.AddStationStorage(true, itemId, stationId, i);
|
||||
break;
|
||||
case ELogisticStorage.Supply:
|
||||
stations.AddStationStorage(false, itemId, stationId, i);
|
||||
break;
|
||||
case ELogisticStorage.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RemoveStationInfo(PlanetStations stations, StationComponent station, int storageIdx = -1)
|
||||
{
|
||||
var storage = station.storage;
|
||||
var stationId = station.id;
|
||||
if (storageIdx >= 0)
|
||||
{
|
||||
var itemId = ItemIdToIndex(storage[storageIdx].itemId);
|
||||
if (itemId <= 0) return;
|
||||
var logic = storage[storageIdx].localLogic;
|
||||
switch (logic)
|
||||
{
|
||||
case ELogisticStorage.Demand:
|
||||
stations.RemoveStationStorage(true, itemId, stationId, storageIdx);
|
||||
break;
|
||||
case ELogisticStorage.Supply:
|
||||
stations.RemoveStationStorage(false, itemId, stationId, storageIdx);
|
||||
break;
|
||||
case ELogisticStorage.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = storage.Length - 1; i >= 0; i--)
|
||||
{
|
||||
var itemId = ItemIdToIndex(storage[i].itemId);
|
||||
if (itemId <= 0) continue;
|
||||
var logic = storage[i].localLogic;
|
||||
switch (logic)
|
||||
{
|
||||
case ELogisticStorage.Demand:
|
||||
stations.RemoveStationStorage(true, itemId, stationId, i);
|
||||
break;
|
||||
case ELogisticStorage.Supply:
|
||||
stations.RemoveStationStorage(false, itemId, stationId, i);
|
||||
break;
|
||||
case ELogisticStorage.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.Init))]
|
||||
private static void PlanetTransport_Init_Postfix(PlanetTransport __instance)
|
||||
{
|
||||
var factory = __instance.factory;
|
||||
var planetIndex = factory.index;
|
||||
|
||||
if (_stations == null || _stations.Length <= planetIndex)
|
||||
Array.Resize(ref _stations, AuxData.AlignUpToPowerOf2(planetIndex + 1));
|
||||
var stations = new PlanetStations();
|
||||
_stations[planetIndex] = stations;
|
||||
|
||||
var pool = __instance.stationPool;
|
||||
for (var i = __instance.stationCursor - 1; i > 0; i--)
|
||||
{
|
||||
var station = pool[i];
|
||||
if (station == null || station.id != i || station.isCollector || station.isVeinCollector) continue;
|
||||
UpdateStationInfo(stations, station);
|
||||
}
|
||||
// DebugLog();
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(BuildingParameters), nameof(BuildingParameters.ApplyPrebuildParametersToEntity))]
|
||||
private static void BuildingParameters_ApplyPrebuildParametersToEntity_Postfix(int entityId, PlanetFactory factory)
|
||||
{
|
||||
if (entityId <= 0) return;
|
||||
ref var entity = ref factory.entityPool[entityId];
|
||||
var stationId = entity.stationId;
|
||||
if (stationId <= 0) return;
|
||||
var station = factory.transport.stationPool[stationId];
|
||||
if (station == null || station.id != stationId || station.isCollector || station.isVeinCollector) return;
|
||||
UpdateStationInfo(StationsByPlanet(factory.index), station);
|
||||
// DebugLog();
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.RemoveStationComponent))]
|
||||
private static void PlanetTransport_RemoveStationComponent_Prefix(PlanetTransport __instance, int id)
|
||||
{
|
||||
if (id <= 0) return;
|
||||
var station = __instance.stationPool[id];
|
||||
if (station == null || station.id != id || station.isCollector || station.isVeinCollector) return;
|
||||
RemoveStationInfo(StationsByPlanet(__instance.factory.index), station);
|
||||
// DebugLog();
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.SetStationStorage))]
|
||||
private static void PlanetTransport_SetStationStorage_Prefix(PlanetTransport __instance, int stationId, int storageIdx, int itemId, ELogisticStorage localLogic, out bool __state)
|
||||
{
|
||||
var station = __instance.stationPool[stationId];
|
||||
if (station == null || station.id != stationId || station.isCollector || station.isVeinCollector || storageIdx < 0 || storageIdx >= station.storage.Length)
|
||||
{
|
||||
__state = false;
|
||||
return;
|
||||
}
|
||||
|
||||
ref var storage = ref station.storage[storageIdx];
|
||||
var oldItemId = storage.itemId;
|
||||
var oldLocalLogic = storage.localLogic;
|
||||
if (localLogic == oldLocalLogic && itemId == oldItemId)
|
||||
{
|
||||
__state = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (oldItemId > 0 && oldLocalLogic != ELogisticStorage.None)
|
||||
RemoveStationInfo(StationsByPlanet(__instance.factory.index), station, storageIdx);
|
||||
__state = localLogic != ELogisticStorage.None;
|
||||
// if (!__state) DebugLog();
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.SetStationStorage))]
|
||||
private static void PlanetTransport_SetStationStorage_Postfix(PlanetTransport __instance, int stationId, int storageIdx, bool __state)
|
||||
{
|
||||
if (!__state) return;
|
||||
var station = __instance.stationPool[stationId];
|
||||
UpdateStationInfo(StationsByPlanet(__instance.factory.index), station, storageIdx);
|
||||
// DebugLog();
|
||||
}
|
||||
}
|
||||
123
LogisticHub/Module/VeinManager.cs
Normal file
123
LogisticHub/Module/VeinManager.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace LogisticHub.Module;
|
||||
|
||||
public class ProductVeinData
|
||||
{
|
||||
public readonly List<int> VeinIndices = [];
|
||||
public readonly HashSet<int> GroupIndices = [];
|
||||
public int GroupCount = 0;
|
||||
}
|
||||
|
||||
public class VeinManager : PatchImpl<VeinManager>
|
||||
{
|
||||
private static ProductVeinData[][] _veins;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
Enable(true);
|
||||
GameLogicProc.OnGameBegin += OnGameBegin;
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
{
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin;
|
||||
Enable(false);
|
||||
}
|
||||
|
||||
private static void OnGameBegin()
|
||||
{
|
||||
_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)
|
||||
{
|
||||
if (_veins == null || _veins.Length <= planetIndex)
|
||||
return null;
|
||||
return _veins[planetIndex];
|
||||
}
|
||||
|
||||
private static ProductVeinData[] GetOrCreateVeins(int planetIndex)
|
||||
{
|
||||
if (_veins == null || _veins.Length <= planetIndex)
|
||||
Array.Resize(ref _veins, AuxData.AlignUpToPowerOf2(planetIndex + 1));
|
||||
var veins = _veins[planetIndex];
|
||||
if (veins != null) return veins;
|
||||
veins = new ProductVeinData[20];
|
||||
_veins[planetIndex] = veins;
|
||||
return veins;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlanetFactory), nameof(PlanetFactory.Init))]
|
||||
[HarmonyPatch(typeof(PlanetFactory), nameof(PlanetFactory.RecalculateVeinGroup))]
|
||||
[HarmonyPatch(typeof(PlanetFactory), nameof(PlanetFactory.RecalculateAllVeinGroups))]
|
||||
private static void PlanetFactory_RecalculateAllVeinGroups_Postfix(PlanetFactory __instance)
|
||||
{
|
||||
RecalcVeins(__instance);
|
||||
}
|
||||
|
||||
private static void DebugLog()
|
||||
{
|
||||
foreach (var veins in _veins)
|
||||
{
|
||||
if (veins == null) continue;
|
||||
for (var i = 0; i < veins.Length; i++)
|
||||
{
|
||||
var pvd = veins[i];
|
||||
if (pvd == null) continue;
|
||||
LogisticHub.Logger.LogInfo($"Product {i} VeinTypeCount={pvd.VeinIndices.Count} GroupCount={pvd.GroupCount}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RecalcVeins(PlanetFactory factory)
|
||||
{
|
||||
var planetIndex = factory.index;
|
||||
var veins = GetOrCreateVeins(planetIndex);
|
||||
var veinPool = factory.veinPool;
|
||||
|
||||
foreach (var pvd in veins)
|
||||
{
|
||||
if (pvd == null) continue;
|
||||
pvd.VeinIndices.Clear();
|
||||
pvd.GroupIndices.Clear();
|
||||
pvd.GroupCount = 0;
|
||||
}
|
||||
|
||||
for (var i = factory.veinCursor - 1; i > 0; i--)
|
||||
{
|
||||
if (veinPool[i].id != i || veinPool[i].amount <= 0 || veinPool[i].type == EVeinType.None) continue;
|
||||
var productId = veinPool[i].productId - 1000;
|
||||
if (productId is < 0 or >= 20) continue;
|
||||
var pvd = veins[productId];
|
||||
if (pvd == null)
|
||||
{
|
||||
pvd = new ProductVeinData();
|
||||
veins[productId] = pvd;
|
||||
}
|
||||
|
||||
pvd.VeinIndices.Add(i);
|
||||
pvd.GroupIndices.Add(veinPool[i].groupIndex);
|
||||
}
|
||||
|
||||
foreach (var pvd in veins)
|
||||
{
|
||||
if (pvd == null) continue;
|
||||
pvd.GroupCount = pvd.GroupIndices.Count;
|
||||
}
|
||||
|
||||
// DebugLog();
|
||||
}
|
||||
}
|
||||
47
LogisticHub/README.md
Normal file
47
LogisticHub/README.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# LogisticHub
|
||||
|
||||
#### Cheat functions for Logistic Storages, make them mine resources on the planet and exchange items from certain buildings
|
||||
#### 物流塔作弊功能,使其可以在星球上采矿并与特定建筑物交换物品
|
||||
|
||||
## Usage
|
||||
|
||||
* Miner(and fuel burning) functions
|
||||
+ 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.
|
||||
+ (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) Does not increase power consumptions on `Veins Utilization` upgrades.
|
||||
+ (Optimization to PlanetMiner) Separate power consumptions for veins, oil seeps and water.
|
||||
+ (Optimization to PlanetMiner) Power consumptions are counted by groups of veins and count of oil seeps, which is more sensible.
|
||||
+ Can burn fuels in certain slot when energy below half of max.
|
||||
- (Optimization to PlanetMiner) Sprayed fuels generates extra energy as normal.
|
||||
+ (Optimization to PlanetMiner) All used parameters are configurable:
|
||||
- LogisticHub has the same speed as normal Mining Machine for normal ores by default.
|
||||
But you can set mining scale in configuration, which makes LogisticHub working like Advance Mining Machines:
|
||||
power consumption increases by the square of the scale, and gradually decrease mining speed over half of the maximum count.
|
||||
This applies to all of veins, oils and water.
|
||||
Mining scale can be set to 0(by default), which means it is automatically set by tech unlocks, set to 300 when you reaches Advanced Mining Machine, otherwise 100.
|
||||
- 100/s for water by default.
|
||||
- Energy costs: 1MW/vein-group & 10MW/water-slot & 1.8MW/oil-seep(configurable)
|
||||
- Fuels burning slot. Default: 4th for ILS and PLS. Set to 0 to disable it.
|
||||
|
||||
## 使用说明
|
||||
|
||||
* 采矿(和燃料燃烧)功能
|
||||
+ 创意来自 [PlanetMiner](https://dsp.thunderstore.io/package/blacksnipebiu/PlanetMiner)([github](https://github.com/blacksnipebiu/PlanetMiner))
|
||||
对性能重度优化,并解决了PlanetMiner的精度等问题。
|
||||
+ (对PlanetMiner的优化) 仅当矿堆发生变化(填埋/恢复/采完)时重新计算矿堆数据,解决每行星每计算帧要重建字典的性能问题。
|
||||
+ (对PlanetMiner的优化) 用浮点数保证更精确的帧计算。
|
||||
+ (对PlanetMiner的优化) 升级`矿物利用`不会提升能耗。
|
||||
+ (对PlanetMiner的优化) 分开矿物,油井和水的采集能耗。
|
||||
+ (对PlanetMiner的优化) 采集能耗以矿物组,油井为单位,相对更加合理。
|
||||
+ 剩余电量少于一半时可以燃烧指定格子的燃料补充。
|
||||
- (对PlanetMiner的优化) 喷涂了增产剂的燃料按照正常的计算方式提供更多的能量(除了原本就不增加能量输出的反物质燃料棒)。
|
||||
+ (对PlanetMiner的优化) 所有参数都可以在设置文件内配置:
|
||||
- 物流塔枢纽和普通矿机采矿速度一样(等同于同时采集所有对应矿物)。
|
||||
你可以设置采矿倍率改变物流塔枢纽采矿速度,和高级采矿机相同地,能耗和倍率的平方成正比,并且在存储矿物量多于一半时逐渐降低采矿倍率。
|
||||
此倍率对各种矿物,油井和水的采集都生效。
|
||||
倍率可以设置为0(默认),此时倍率会随科技解锁而变化,默认是100%,解锁高级采矿机后变为300%。
|
||||
- 水的采集速度默认为100/s。
|
||||
- 能耗:每矿物组 1MW,单格水 10MW,每油井 1.8MW。
|
||||
- 燃料格位置。默认:星际物流塔和行星内物流塔第4格。设为0则关闭燃料补充能量功能。
|
||||
10
LogisticHub/package/manifest.json
Normal file
10
LogisticHub/package/manifest.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "LogisticHub",
|
||||
"version_number": "0.1.0",
|
||||
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/LogisticHub",
|
||||
"description": "Cheat functions to Logistic Storages which make them miner and items hub / 物流塔作弊功能,使其成为矿机和物品枢纽",
|
||||
"dependencies": [
|
||||
"xiaoye97-BepInEx-5.4.17",
|
||||
"soarqin-UXAssist-1.2.0"
|
||||
]
|
||||
}
|
||||
@@ -1,485 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BepInEx;
|
||||
using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace LogisticMiner;
|
||||
|
||||
[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)]
|
||||
public class LogisticMiner : BaseUnityPlugin
|
||||
{
|
||||
private new static readonly BepInEx.Logging.ManualLogSource Logger =
|
||||
BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME);
|
||||
|
||||
private static long _oreEnergyConsume = 2000000;
|
||||
private static long _oilEnergyConsume = 3600000;
|
||||
private static long _waterEnergyConsume = 20000000;
|
||||
private static int _waterSpeed = 100;
|
||||
private static int _miningScale;
|
||||
private static int _fuelIlsSlot = 3;
|
||||
private static int _fuelPlsSlot = 2;
|
||||
|
||||
private static float _frame;
|
||||
private static float _miningCostRateByTech;
|
||||
private static float _miningSpeedScaleByTech;
|
||||
private static float _miningFrames;
|
||||
private static long _miningSpeedScaleLong;
|
||||
private static bool _advancedMiningMachineUnlocked;
|
||||
private static uint _miningCostBarrier;
|
||||
private static uint _miningCostBarrierOil;
|
||||
|
||||
private static uint _seed = (uint)Random.Range(int.MinValue, int.MaxValue);
|
||||
private static readonly Dictionary<int, VeinCacheData> PlanetVeinCacheData = new();
|
||||
private static readonly Dictionary<int, (long, bool)> Fuels = new();
|
||||
|
||||
private bool _cfgEnabled = true;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_cfgEnabled = Config.Bind("General", "Enabled", _cfgEnabled, "enable/disable this plugin").Value;
|
||||
_oreEnergyConsume = Config.Bind("General", "EnergyConsumptionForOre", _oreEnergyConsume / 2000,
|
||||
"Energy consumption for each ore vein group(in kW)").Value * 2000;
|
||||
_oilEnergyConsume = Config.Bind("General", "EnergyConsumptionForOil", _oilEnergyConsume / 2000,
|
||||
"Energy consumption for each oil seep(in kW)").Value * 2000;
|
||||
_waterEnergyConsume = Config.Bind("General", "EnergyConsumptionForWater", _waterEnergyConsume / 2000,
|
||||
"Energy consumption for water slot(in kW)").Value * 2000;
|
||||
_waterSpeed = Config.Bind("General", "WaterMiningSpeed", _waterSpeed,
|
||||
"Water mining speed (count per second)").Value;
|
||||
_miningScale = Config.Bind("General", "MiningScale", _miningScale,
|
||||
"0 for Auto(which means having researched 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. Please note that the power consumption increases by the square of the scale which is the same as Advanced Mining Machine")
|
||||
.Value;
|
||||
_fuelIlsSlot = Config.Bind("General", "ILSFuelSlot", _fuelIlsSlot + 1,
|
||||
new ConfigDescription("Fuel slot for ILS, set to 0 to disable",
|
||||
new AcceptableValueRange<int>(0, 5), Array.Empty<object>()))
|
||||
.Value - 1;
|
||||
_fuelPlsSlot = Config.Bind("General", "PLSFuelSlot", _fuelPlsSlot + 1,
|
||||
new ConfigDescription("Fuel slot for PLS, set to 0 to disable",
|
||||
new AcceptableValueRange<int>(0, 4), Array.Empty<object>()))
|
||||
.Value - 1;
|
||||
if (!_cfgEnabled) return;
|
||||
|
||||
Harmony.CreateAndPatchAll(typeof(LogisticMiner));
|
||||
}
|
||||
|
||||
private static int SplitIncLevel(ref int n, ref int m, int p)
|
||||
{
|
||||
var level = m / n;
|
||||
var left = m - level * n;
|
||||
n -= p;
|
||||
left -= n;
|
||||
m -= left > 0 ? level * p + left : level * p;
|
||||
return level;
|
||||
}
|
||||
|
||||
private static void CheckRecipes()
|
||||
{
|
||||
_advancedMiningMachineUnlocked = GameMain.history.recipeUnlocked.Contains(119);
|
||||
}
|
||||
|
||||
private static void UpdateMiningCostRate()
|
||||
{
|
||||
_miningCostRateByTech = GameMain.history.miningCostRate;
|
||||
_miningCostBarrier = (uint)(int)Math.Ceiling(2147483646.0 * _miningCostRateByTech);
|
||||
_miningCostBarrierOil =
|
||||
(uint)(int)Math.Ceiling(2147483646.0 * _miningCostRateByTech * 0.401116669f /
|
||||
DSPGame.GameDesc.resourceMultiplier);
|
||||
}
|
||||
|
||||
private static void UpdateSpeedScale()
|
||||
{
|
||||
_miningSpeedScaleByTech = GameMain.history.miningSpeedScale;
|
||||
_miningSpeedScaleLong = (long)(_miningSpeedScaleByTech * 100);
|
||||
lock (PlanetVeinCacheData)
|
||||
{
|
||||
_miningFrames = 120f / _miningSpeedScaleByTech;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(DSPGame), "StartGame", typeof(GameDesc))]
|
||||
[HarmonyPatch(typeof(DSPGame), "StartGame", typeof(string))]
|
||||
private static void OnGameStart()
|
||||
{
|
||||
Logger.LogInfo("Game Start");
|
||||
PlanetVeinCacheData.Clear();
|
||||
Fuels.Clear();
|
||||
foreach (var data in LDB.items.dataArray)
|
||||
{
|
||||
if (data.HeatValue > 0)
|
||||
{
|
||||
Fuels.Add(data.ID, (data.HeatValue, data.Productive));
|
||||
}
|
||||
}
|
||||
/* Thinking: storage max may affect mining scale?
|
||||
_localStationMax = LDB.items.Select(2103).prefabDesc.stationMaxItemCount;
|
||||
_remoteStationMax = LDB.items.Select(2104).prefabDesc.stationMaxItemCount;
|
||||
*/
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameMain), "Start")]
|
||||
private static void OnGameLoaded()
|
||||
{
|
||||
_frame = 0f;
|
||||
|
||||
UpdateMiningCostRate();
|
||||
UpdateSpeedScale();
|
||||
CheckRecipes();
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameHistoryData), "UnlockTechFunction")]
|
||||
private static void OnUnlockTech(int func)
|
||||
{
|
||||
switch (func)
|
||||
{
|
||||
case 20:
|
||||
UpdateMiningCostRate();
|
||||
break;
|
||||
case 21:
|
||||
UpdateSpeedScale();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[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 pair in PlanetVeinCacheData)
|
||||
{
|
||||
pair.Value.FrameNext -= 1000000f;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameHistoryData), "UnlockRecipe")]
|
||||
private static void OnUnlockRecipe(int recipeId)
|
||||
{
|
||||
if (recipeId == 119)
|
||||
{
|
||||
CheckRecipes();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlanetFactory), "Init")]
|
||||
[HarmonyPatch(typeof(PlanetFactory), "RecalculateVeinGroup")]
|
||||
[HarmonyPatch(typeof(PlanetFactory), "RecalculateAllVeinGroups")]
|
||||
private static void NeedRecalcVeins(PlanetFactory __instance)
|
||||
{
|
||||
RecalcVeins(__instance);
|
||||
}
|
||||
|
||||
private static void RecalcVeins(PlanetFactory factory)
|
||||
{
|
||||
var planetId = factory.planetId;
|
||||
lock (PlanetVeinCacheData)
|
||||
{
|
||||
/* remove planet veins from dict */
|
||||
if (PlanetVeinCacheData.TryGetValue(planetId, out var vcd))
|
||||
{
|
||||
vcd.GenVeins(factory);
|
||||
}
|
||||
else
|
||||
{
|
||||
vcd = new VeinCacheData();
|
||||
vcd.GenVeins(factory);
|
||||
vcd.FrameNext = _frame + _miningFrames;
|
||||
PlanetVeinCacheData.Add(planetId, vcd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(FactorySystem), "CheckBeforeGameTick")]
|
||||
private static void FactorySystemLogisticMiner(FactorySystem __instance)
|
||||
{
|
||||
if (_miningSpeedScaleLong <= 0)
|
||||
return;
|
||||
var factory = __instance.factory;
|
||||
var planetId = factory.planetId;
|
||||
lock (PlanetVeinCacheData)
|
||||
{
|
||||
if (PlanetVeinCacheData.TryGetValue(planetId, out var vcd))
|
||||
{
|
||||
if (vcd.FrameNext > _frame)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlanetVeinCacheData[planetId] = new VeinCacheData
|
||||
{
|
||||
FrameNext = _frame + _miningFrames
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
var isCollecting = false;
|
||||
for (var k = 0; k < stationComponent.storage.Length; k++)
|
||||
{
|
||||
ref var stationStore = ref storage[k];
|
||||
if (stationStore.localLogic != ELogisticStorage.Demand ||
|
||||
stationStore.max <= stationStore.count)
|
||||
continue;
|
||||
|
||||
var isVein = vcd.HasVein(stationStore.itemId);
|
||||
var isVeinOrWater = isVein || stationStore.itemId == __instance.planet.waterItemId;
|
||||
if (!isVeinOrWater) continue;
|
||||
int amount;
|
||||
long energyConsume;
|
||||
isCollecting = true;
|
||||
var miningScale = _miningScale;
|
||||
if (miningScale == 0)
|
||||
{
|
||||
miningScale = _advancedMiningMachineUnlocked ? 300 : 100;
|
||||
}
|
||||
|
||||
if (miningScale > 100 && stationStore.count * 2 > stationStore.max)
|
||||
{
|
||||
miningScale = 100 +
|
||||
((miningScale - 100) * (stationStore.max - stationStore.count) * 2 +
|
||||
stationStore.max - 1) / stationStore.max;
|
||||
}
|
||||
|
||||
if (isVein)
|
||||
{
|
||||
(amount, energyConsume) = vcd.Mine(factory, stationStore.itemId, miningScale,
|
||||
_miningSpeedScaleLong,
|
||||
stationComponent.energy);
|
||||
if (amount < 0)
|
||||
{
|
||||
k = int.MaxValue - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
energyConsume = (_waterEnergyConsume * miningScale * miningScale + 9999L) / 100L /
|
||||
_miningSpeedScaleLong;
|
||||
if (stationComponent.energy < energyConsume)
|
||||
{
|
||||
k = int.MaxValue - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
amount = _waterSpeed * miningScale / 100;
|
||||
}
|
||||
|
||||
if (amount <= 0) continue;
|
||||
stationStore.count += amount;
|
||||
if (factoryProductionStat != null)
|
||||
productRegister[stationStore.itemId] += amount;
|
||||
stationComponent.energy -= energyConsume;
|
||||
}
|
||||
|
||||
if (!isCollecting || stationComponent.energy * 2 >= stationComponent.energyMax) continue;
|
||||
var index = stationComponent.isStellar ? _fuelIlsSlot : _fuelPlsSlot;
|
||||
if (index < 0 || index >= storage.Length)
|
||||
continue;
|
||||
var fuelCount = storage[index].count;
|
||||
if (fuelCount == 0) continue;
|
||||
if (!Fuels.TryGetValue(storage[index].itemId, out var val) || val.Item1 <= 0)
|
||||
continue;
|
||||
/* Sprayed fuels */
|
||||
int pretendIncLevel;
|
||||
if (val.Item2 && (pretendIncLevel = storage[index].inc / storage[index].count) > 0)
|
||||
{
|
||||
var count = (int)((stationComponent.energyMax - stationComponent.energy) * 1000L /
|
||||
Cargo.incTable[pretendIncLevel] / 7L);
|
||||
if (count > fuelCount)
|
||||
count = fuelCount;
|
||||
var incLevel = SplitIncLevel(ref storage[index].count, ref storage[index].inc, count);
|
||||
if (incLevel > 10)
|
||||
incLevel = 10;
|
||||
stationComponent.energy += val.Item1 * count * (1000L + Cargo.incTable[incLevel]) / 1000L;
|
||||
}
|
||||
else
|
||||
{
|
||||
var count = (int)((stationComponent.energyMax - stationComponent.energy) / val.Item1);
|
||||
if (count > fuelCount)
|
||||
count = fuelCount;
|
||||
SplitIncLevel(ref storage[index].count, ref storage[index].inc, count);
|
||||
stationComponent.energy += val.Item1 * count;
|
||||
}
|
||||
}
|
||||
|
||||
vcd.FrameNext += _miningFrames;
|
||||
} while (vcd.FrameNext <= _frame);
|
||||
|
||||
PerformanceMonitor.EndSample(ECpuWorkEntry.Miner);
|
||||
}
|
||||
}
|
||||
|
||||
private class VeinCacheData
|
||||
{
|
||||
public float FrameNext;
|
||||
|
||||
/* stores list of indices to veinData, with an extra INT which indicates cout of veinGroups at last */
|
||||
private Dictionary<int, List<int>> _veins = new();
|
||||
private int _mineIndex = -1;
|
||||
|
||||
public bool HasVein(int productId)
|
||||
{
|
||||
return _veins.ContainsKey(productId);
|
||||
}
|
||||
|
||||
public void GenVeins(PlanetFactory factory)
|
||||
{
|
||||
_veins = new Dictionary<int, List<int>>();
|
||||
var veinPool = factory.veinPool;
|
||||
var vg = new Dictionary<int, HashSet<int>>();
|
||||
for (var i = 0; i < veinPool.Length; i++)
|
||||
{
|
||||
if (veinPool[i].amount <= 0 || veinPool[i].type == EVeinType.None) continue;
|
||||
var productId = veinPool[i].productId;
|
||||
if (_veins.TryGetValue(productId, out var l))
|
||||
{
|
||||
l.Add(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
_veins.Add(productId, [i]);
|
||||
}
|
||||
|
||||
if (vg.TryGetValue(productId, out var hs))
|
||||
{
|
||||
hs.Add(veinPool[i].groupIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
vg.Add(productId, [veinPool[i].groupIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var pair in vg)
|
||||
{
|
||||
_veins[pair.Key].Add(pair.Value.Count);
|
||||
}
|
||||
}
|
||||
|
||||
public (int, long) Mine(PlanetFactory factory, int productId, int percent, long miningSpeedScale,
|
||||
long energyMax)
|
||||
{
|
||||
if (!_veins.TryGetValue(productId, out var veins))
|
||||
{
|
||||
return (-1, -1L);
|
||||
}
|
||||
|
||||
uint barrier;
|
||||
int limit;
|
||||
int count;
|
||||
long energy;
|
||||
var length = veins.Count - 1;
|
||||
/* if is Oil */
|
||||
if (productId == 1007)
|
||||
{
|
||||
energy = (_oilEnergyConsume * length * percent * percent + 9999L) / 100L / miningSpeedScale;
|
||||
if (energy > energyMax)
|
||||
return (-1, -1L);
|
||||
float countf = 0f;
|
||||
var veinsPool = factory.veinPool;
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
ref var vd = ref veinsPool[veins[i]];
|
||||
countf += vd.amount * 4 * VeinData.oilSpeedMultiplier;
|
||||
}
|
||||
|
||||
count = ((int)countf * percent + 99) / 100;
|
||||
if (count == 0)
|
||||
return (-1, -1L);
|
||||
barrier = _miningCostBarrierOil;
|
||||
limit = 2500;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = (length * percent + 99) / 100;
|
||||
if (count == 0)
|
||||
return (-1, -1L);
|
||||
energy = (_oreEnergyConsume * veins[length] * percent * percent + 9999L) / 100L / miningSpeedScale;
|
||||
if (energy > energyMax)
|
||||
return (-1, -1L);
|
||||
barrier = _miningCostBarrier;
|
||||
limit = 0;
|
||||
}
|
||||
|
||||
var veinsData = factory.veinPool;
|
||||
var total = 0;
|
||||
for (; count > 0; count--)
|
||||
{
|
||||
_mineIndex = (_mineIndex + 1) % length;
|
||||
var index = veins[_mineIndex];
|
||||
ref var vd = ref veinsData[index];
|
||||
int groupIndex;
|
||||
if (vd.amount > 0)
|
||||
{
|
||||
total++;
|
||||
if (vd.amount > limit)
|
||||
{
|
||||
var consume = true;
|
||||
if (barrier < 2147483646u)
|
||||
{
|
||||
_seed = (uint)((int)((ulong)((_seed % 2147483646u + 1) * 48271L) % 2147483647uL) - 1);
|
||||
consume = _seed < barrier;
|
||||
}
|
||||
|
||||
if (consume)
|
||||
{
|
||||
vd.amount--;
|
||||
groupIndex = vd.groupIndex;
|
||||
factory.veinGroups[groupIndex].amount--;
|
||||
if (vd.amount <= 0)
|
||||
{
|
||||
factory.veinGroups[groupIndex].count--;
|
||||
factory.RemoveVeinWithComponents(index);
|
||||
factory.RecalculateVeinGroup(groupIndex);
|
||||
if (!_veins.TryGetValue(productId, out veins))
|
||||
break;
|
||||
length = veins.Count - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
groupIndex = vd.groupIndex;
|
||||
factory.veinGroups[groupIndex].count--;
|
||||
factory.RemoveVeinWithComponents(index);
|
||||
factory.RecalculateVeinGroup(groupIndex);
|
||||
if (!_veins.TryGetValue(productId, out veins))
|
||||
break;
|
||||
length = veins.Count - 1;
|
||||
}
|
||||
|
||||
return (total, energy);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>LogisticMiner</AssemblyName>
|
||||
<BepInExPluginGuid>org.soardev.logisticminer</BepInExPluginGuid>
|
||||
<Description>DSP MOD - LogisticMiner</Description>
|
||||
<Version>0.1.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<RestoreAdditionalProjectSources>https://nuget.bepinex.dev/v3/index.json</RestoreAdditionalProjectSources>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BepInEx.Core" Version="5.*" />
|
||||
<PackageReference Include="BepInEx.PluginInfoProps" Version="1.*" />
|
||||
<PackageReference Include="DysonSphereProgram.GameLibs" Version="0.10.32.*-r.*" />
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2018.4.12" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,50 +0,0 @@
|
||||
# LogisticMiner
|
||||
|
||||
#### Logistic Storages can mine all ores/water on current planet
|
||||
#### 物流塔可以采集当前星球的全部矿产(以及水)
|
||||
|
||||
## Usage
|
||||
|
||||
* 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.
|
||||
* (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) Does not increase power consumptions on `Veins Utilization` upgrades.
|
||||
* (Optimization to PlanetMiner) Separate power consumptions for veins, oil seeps and water.
|
||||
* (Optimization to PlanetMiner) Power consumptions are counted by groups of veins and count of oil seeps, which is more sensible.
|
||||
* Can burn fuels in certain slot when energy below half of max.
|
||||
* (Optimization to PlanetMiner) Sprayed fuels generates extra energy as normal.
|
||||
* (Optimization to PlanetMiner) All used parameters are configurable:
|
||||
* Logistic Miner has the same speed as normal Mining Machine for normal ores by default.
|
||||
But you can set mining scale in configuration, which makes Logistic Miner working like Advance Mining Machines:
|
||||
power
|
||||
consumption increases by the square of the scale, and gradually decrease mining speed over half of the maximum
|
||||
count.
|
||||
This applies to all of veins, oils and water.
|
||||
Mining scale can be set to 0(by default), which means it is automatically set by tech unlocks, set to 300 when you
|
||||
reaches Advanced Mining Machine, otherwise 100.
|
||||
* 100/s for water by default.
|
||||
* Energy costs: 1MW/vein-group & 10MW/water-slot & 1.8MW/oil-seep(configurable)
|
||||
* Fuels burning slot. Default: 4th for ILS, 3rd for PLS. Set to 0 to disable it.
|
||||
|
||||
## 使用说明
|
||||
|
||||
* 创意来自 [PlanetMiner](https://dsp.thunderstore.io/package/blacksnipebiu/PlanetMiner)([github](https://github.com/blacksnipebiu/PlanetMiner))
|
||||
对性能重度优化,并解决了PlanetMiner的精度等问题。
|
||||
* (对PlanetMiner的优化) 仅当矿堆发生变化(填埋/恢复/采完)时重新计算矿堆数据,解决每行星每计算帧要重建字典的性能问题。
|
||||
* (对PlanetMiner的优化) 用浮点数保证更精确的帧计算。
|
||||
* (对PlanetMiner的优化) 升级`矿物利用`不会提升能耗。
|
||||
* (对PlanetMiner的优化) 分开矿物,油井和水的采集能耗。
|
||||
* (对PlanetMiner的优化) 采集能耗以矿物组,油井为单位,相对更加合理。
|
||||
* 剩余电量少于一半时可以燃烧指定格子的燃料补充。
|
||||
* (对PlanetMiner的优化) 喷涂了增产剂的燃料按照正常的计算方式提供更多的能量(除了原本就不增加能量输出的反物质燃料棒)。
|
||||
* (对PlanetMiner的优化) 所有参数都可以在设置文件内配置:
|
||||
* 物流塔矿机和普通矿机采矿速度一样(等同于同时采集所有对应矿物)。
|
||||
你可以设置采矿倍率改变物流塔矿机采矿速度,和高级采矿机相同地,能耗和倍率的平方成正比,并且在存储矿物量多于一半时逐渐降低采矿倍率。
|
||||
此倍率对各种矿物,油井和水的采集都生效。
|
||||
倍率可以设置为0(默认),此时倍率会随科技解锁而变化,默认是100%,解锁高级采矿机后变为300%。
|
||||
* 水的采集速度默认为100/s。
|
||||
* 能耗:每矿物组 1MW,单格水 10MW,每油井 1.8MW。
|
||||
* 燃料格位置。默认:星际物流塔第4格,行星内物流塔第3格。设为0则关闭燃料补充能量功能。
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"name": "LogisticMiner",
|
||||
"version_number": "0.1.0",
|
||||
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/LogisticMiner",
|
||||
"description": "Logistic Storages can mine all ores/water on current planet / 物流塔可以采集当前星球的全部矿产(以及水)",
|
||||
"dependencies": [
|
||||
"xiaoye97-BepInEx-5.4.17"
|
||||
]
|
||||
}
|
||||
@@ -9,10 +9,10 @@ Add various cheat functions while disabling abnormal determinants
|
||||
|
||||
Moved [to another repo](https://github.com/soarqin/DSP_Mods_TO/tree/master/CompressSave)
|
||||
|
||||
## [LogisticMiner](LogisticMiner)
|
||||
## [LogisticHub](LogisticHub)
|
||||
|
||||
Logistic Storages can mine all ores/water on current planet
|
||||
物流塔可以采集当前星球的全部矿产(以及水)
|
||||
Cheat functions for Logistic Storages, make them mine resources on the planet and exchange items from certain buildings
|
||||
物流塔作弊功能,使其可以在星球上采矿并与特定建筑物交换物品
|
||||
|
||||
## [HideTips](HideTips)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -131,9 +131,6 @@ public static class WinApi
|
||||
[DllImport("user32", ExactSpelling = true)]
|
||||
public static extern IntPtr MonitorFromRect([In] ref Rect lpRect, uint dwFlags);
|
||||
|
||||
[DllImport("kernel32", ExactSpelling = true, SetLastError = true)]
|
||||
public static extern bool GetProcessAffinityMask(IntPtr hProcess, out ulong lpProcessAffinityMask, out ulong lpSystemAffinityMask);
|
||||
|
||||
[DllImport("kernel32", ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr GetCurrentProcess();
|
||||
|
||||
@@ -143,9 +140,6 @@ public static class WinApi
|
||||
[DllImport("kernel32", ExactSpelling = true)]
|
||||
public static extern IntPtr GetConsoleWindow();
|
||||
|
||||
[DllImport("kernel32", ExactSpelling = true, SetLastError = true)]
|
||||
public static extern bool SetProcessAffinityMask(IntPtr hProcess, ulong dwProcessAffinityMask);
|
||||
|
||||
// GetPriorityClass and SetPriorityClass
|
||||
[DllImport("kernel32", ExactSpelling = true, SetLastError = true)]
|
||||
public static extern int GetPriorityClass(IntPtr hProcess);
|
||||
@@ -160,126 +154,4 @@ public static class WinApi
|
||||
public static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetLogicalProcessorInformationEx
|
||||
|
||||
[Flags]
|
||||
private enum LOGICAL_PROCESSOR_RELATIONSHIP
|
||||
{
|
||||
RelationProcessorCore,
|
||||
RelationNumaNode,
|
||||
RelationCache,
|
||||
RelationProcessorPackage,
|
||||
RelationGroup,
|
||||
RelationAll = 0xffff
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
private struct GROUP_AFFINITY
|
||||
{
|
||||
public nuint Mask;
|
||||
public ushort Group;
|
||||
public ushort Reserved0;
|
||||
public ushort Reserved1;
|
||||
public ushort Reserved3;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
private struct PROCESSOR_RELATIONSHIP
|
||||
{
|
||||
public byte Flags;
|
||||
public byte EfficiencyClass;
|
||||
public ushort Reserved0;
|
||||
public uint Reserved1;
|
||||
public uint Reserved2;
|
||||
public uint Reserved3;
|
||||
public uint Reserved4;
|
||||
public ushort Reserved5;
|
||||
public ushort GroupCount;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
public GROUP_AFFINITY[] GroupMask;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
|
||||
{
|
||||
public LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
|
||||
public uint Size;
|
||||
public PROCESSOR_RELATIONSHIP Processor;
|
||||
}
|
||||
|
||||
[DllImport("kernel32", SetLastError = true)]
|
||||
private static extern bool GetLogicalProcessorInformationEx(
|
||||
LOGICAL_PROCESSOR_RELATIONSHIP relationshipType,
|
||||
IntPtr buffer,
|
||||
ref uint returnLength
|
||||
);
|
||||
|
||||
public struct LogicalProcessorDetails
|
||||
{
|
||||
public int CoreCount;
|
||||
public int ThreadCount;
|
||||
public int PerformanceCoreCount;
|
||||
public int EfficiencyCoreCount;
|
||||
public ulong PerformanceCoreMask;
|
||||
public ulong EfficiencyCoreMask;
|
||||
public bool HybridArchitecture => PerformanceCoreCount > 0 && EfficiencyCoreCount > 0;
|
||||
}
|
||||
|
||||
public static LogicalProcessorDetails GetLogicalProcessorDetails()
|
||||
{
|
||||
uint returnLength = 0;
|
||||
GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore, IntPtr.Zero, ref returnLength);
|
||||
var result = new LogicalProcessorDetails();
|
||||
if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) return result;
|
||||
var ptr = Marshal.AllocHGlobal((int)returnLength);
|
||||
try
|
||||
{
|
||||
if (!GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore, ptr, ref returnLength))
|
||||
return result;
|
||||
uint offset = 0;
|
||||
var item = ptr;
|
||||
while (offset < returnLength)
|
||||
{
|
||||
var buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)Marshal.PtrToStructure(item, typeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX));
|
||||
offset += buffer.Size;
|
||||
item += (int)buffer.Size;
|
||||
if (buffer.Relationship != LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore) continue;
|
||||
result.CoreCount++;
|
||||
var mask = buffer.Processor.GroupMask[0].Mask;
|
||||
var tcount = CountBitsSet(mask);
|
||||
result.ThreadCount += tcount;
|
||||
if (buffer.Processor.EfficiencyClass > 0)
|
||||
{
|
||||
result.PerformanceCoreCount++;
|
||||
result.PerformanceCoreMask |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.EfficiencyCoreCount++;
|
||||
result.EfficiencyCoreMask |= mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
int CountBitsSet(ulong mask)
|
||||
{
|
||||
var count = 0;
|
||||
while (mask != 0)
|
||||
{
|
||||
mask &= mask - 1;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -124,7 +124,7 @@ public static class PlanetFunctions
|
||||
var combatStatId = enemyData.combatStatId;
|
||||
planet.factory.skillSystem.OnRemovingSkillTarget(combatStatId, planet.factory.skillSystem.combatStats.buffer[combatStatId].originAstroId, ETargetType.CombatStat);
|
||||
planet.factory.skillSystem.combatStats.Remove(combatStatId);
|
||||
planet.factory.KillEnemyFinally(player, i, ref CombatStat.empty);
|
||||
planet.factory.KillEnemyFinally(i, ref CombatStat.empty);
|
||||
}
|
||||
planet.factory.enemySystem.Free();
|
||||
UIRoot.instance.uiGame.dfAssaultTip.ClearAllSpots();
|
||||
|
||||
@@ -288,7 +288,7 @@ public static class TechFunctions
|
||||
{
|
||||
UnlockTechImmediately(techProto, toLevel, withPrerequisites);
|
||||
}
|
||||
history.VarifyTechQueue();
|
||||
history.VerifyTechQueue();
|
||||
if (history.currentTech != history.techQueue[0])
|
||||
{
|
||||
history.currentTech = history.techQueue[0];
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UXAssist.UI;
|
||||
using UXAssist.Common;
|
||||
using GameLogic = UXAssist.Common.GameLogic;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace UXAssist.Functions;
|
||||
|
||||
@@ -322,7 +322,7 @@ public static class UIFunctions
|
||||
}
|
||||
|
||||
I18N.OnInitialized += UpdateI18N;
|
||||
GameLogic.OnDataLoaded += () =>
|
||||
GameLogicProc.OnDataLoaded += () =>
|
||||
{
|
||||
VeinProto veinProto;
|
||||
ItemProto itemProto;
|
||||
@@ -348,7 +348,7 @@ public static class UIFunctions
|
||||
UpdateI18N();
|
||||
};
|
||||
|
||||
GameLogic.OnGameBegin += () =>
|
||||
GameLogicProc.OnGameBegin += () =>
|
||||
{
|
||||
if (DSPGame.IsMenuDemo) return;
|
||||
|
||||
@@ -429,7 +429,7 @@ public static class UIFunctions
|
||||
OnPlanetScanEnded();
|
||||
}
|
||||
};
|
||||
GameLogic.OnGameEnd += () =>
|
||||
GameLogicProc.OnGameEnd += () =>
|
||||
{
|
||||
_starOrderNames = null;
|
||||
ShowStarName = null;
|
||||
@@ -679,18 +679,18 @@ public static class UIFunctions
|
||||
switch (_cornerComboBoxIndex)
|
||||
{
|
||||
case 1:
|
||||
starUI.nameText.text = String.Format("{0}-{1:0.00}", _starOrderNames[star.index], GetStarDist(star));
|
||||
starUI.nameText.text = String.Format("{0:00}-{1}-{2:0.00}", star.index + 1, _starOrderNames[star.index], GetStarDist(star));
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
var (nongas, total) = GetStarPlanetCount(star);
|
||||
starUI.nameText.text = String.Format("{0}-{1}-{2}", _starOrderNames[star.index], nongas, total);
|
||||
starUI.nameText.text = String.Format("{0:00}-{1}-{2}-{3}", star.index + 1, _starOrderNames[star.index], nongas, total);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
var (nongas, total) = GetStarPlanetCount(star);
|
||||
starUI.nameText.text = String.Format("{0}-{1:0.00}-{2}-{3}", _starOrderNames[star.index], GetStarDist(star), nongas, total);
|
||||
starUI.nameText.text = String.Format("{0:00}-{1}-{2:0.00}-{3}-{4}", star.index + 1, _starOrderNames[star.index], GetStarDist(star), nongas, total);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -16,10 +16,7 @@ public static class WindowFunctions
|
||||
private static IntPtr _oldWndProc = IntPtr.Zero;
|
||||
private static IntPtr _gameWindowHandle = IntPtr.Zero;
|
||||
|
||||
public static WinApi.LogicalProcessorDetails ProcessorDetails { get; private set; }
|
||||
|
||||
public static ConfigEntry<int> ProcessPriority;
|
||||
public static ConfigEntry<int> ProcessAffinity;
|
||||
|
||||
private static readonly int[] ProrityFlags =
|
||||
[
|
||||
@@ -34,12 +31,6 @@ public static class WindowFunctions
|
||||
{
|
||||
if (_initialized) return;
|
||||
_initialized = true;
|
||||
I18N.Add("Cores: {0}\nThreads: {1}", "Cores: {0}\nThreads: {1}", "核心数: {0}\n线程数: {1}");
|
||||
I18N.Add("\nP-Cores: {0}\nE-Cores: {1}", "\nP-Cores: {0}\nE-Cores: {1}", "\n性能核心: {0}\n能效核心: {1}");
|
||||
I18N.Add("\nPriority: {0}", "\nProcess priority: {0}", "\n进程优先级: {0}");
|
||||
I18N.Add("\nEnabled CPUs: ", "\nEnabled CPUs: ", "\n使用的CPU: ");
|
||||
I18N.Add("Unknown", "Unknown", "未知");
|
||||
ProcessorDetails = WinApi.GetLogicalProcessorDetails();
|
||||
SetWindowTitle();
|
||||
}
|
||||
|
||||
@@ -54,37 +45,6 @@ public static class WindowFunctions
|
||||
|
||||
ProcessPriority.SettingChanged += (_, _) => WinApi.SetPriorityClass(WinApi.GetCurrentProcess(), ProrityFlags[ProcessPriority.Value]);
|
||||
WinApi.SetPriorityClass(WinApi.GetCurrentProcess(), ProrityFlags[ProcessPriority.Value]);
|
||||
ProcessAffinity.SettingChanged += (_, _) => UpdateAffinity();
|
||||
UpdateAffinity();
|
||||
return;
|
||||
|
||||
static void UpdateAffinity()
|
||||
{
|
||||
var process = WinApi.GetCurrentProcess();
|
||||
if (!WinApi.GetProcessAffinityMask(process, out _, out var systemMask))
|
||||
{
|
||||
systemMask = ulong.MaxValue;
|
||||
}
|
||||
|
||||
switch (ProcessAffinity.Value)
|
||||
{
|
||||
case 0:
|
||||
WinApi.SetProcessAffinityMask(process, systemMask);
|
||||
break;
|
||||
case 1:
|
||||
WinApi.SetProcessAffinityMask(process, systemMask & ((1UL << (ProcessorDetails.ThreadCount / 2)) - 1UL));
|
||||
break;
|
||||
case 2:
|
||||
WinApi.SetProcessAffinityMask(process, systemMask & (ProcessorDetails.ThreadCount > 16 ? 0xFFUL : 1UL));
|
||||
break;
|
||||
case 3:
|
||||
WinApi.SetProcessAffinityMask(process, systemMask & ProcessorDetails.PerformanceCoreMask);
|
||||
break;
|
||||
case 4:
|
||||
WinApi.SetProcessAffinityMask(process, systemMask & ProcessorDetails.EfficiencyCoreMask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IntPtr GameWndProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam)
|
||||
@@ -118,50 +78,6 @@ public static class WindowFunctions
|
||||
};
|
||||
}
|
||||
|
||||
public static void ShowCPUInfo()
|
||||
{
|
||||
var details = ProcessorDetails;
|
||||
var msg = string.Format("Cores: {0}\nThreads: {1}".Translate(), details.CoreCount, details.ThreadCount);
|
||||
var hybrid = details.HybridArchitecture;
|
||||
if (hybrid)
|
||||
{
|
||||
msg += string.Format("\nP-Cores: {0}\nE-Cores: {1}".Translate(), details.PerformanceCoreCount, details.EfficiencyCoreCount);
|
||||
}
|
||||
|
||||
var handle = WinApi.GetCurrentProcess();
|
||||
var prio = GetPriorityName(WinApi.GetPriorityClass(handle));
|
||||
msg += string.Format("\nPriority: {0}".Translate(), prio);
|
||||
|
||||
var aff = 0UL;
|
||||
if (WinApi.GetProcessAffinityMask(handle, out var processMask, out var systemMask))
|
||||
aff = processMask & systemMask;
|
||||
|
||||
msg += "\nEnabled CPUs: ".Translate();
|
||||
var first = true;
|
||||
for (var i = 0; aff != 0UL; i++)
|
||||
{
|
||||
if ((aff & 1UL) != 0)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
msg += ",";
|
||||
msg += i;
|
||||
if (hybrid)
|
||||
{
|
||||
if ((details.PerformanceCoreMask & (1UL << i)) != 0)
|
||||
msg += "(P)";
|
||||
else if ((details.EfficiencyCoreMask & (1UL << i)) != 0)
|
||||
msg += "(E)";
|
||||
}
|
||||
}
|
||||
|
||||
aff >>= 1;
|
||||
}
|
||||
|
||||
UIMessageBox.Show("CPU Info".Translate(), msg, "确定".Translate(), -1);
|
||||
}
|
||||
|
||||
public static void SetWindowTitle()
|
||||
{
|
||||
// Get profile name from command line arguments, and set window title accordingly
|
||||
|
||||
23
UXAssist/ModsCompat/PlanetVeinUtilization.cs
Normal file
23
UXAssist/ModsCompat/PlanetVeinUtilization.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using HarmonyLib;
|
||||
|
||||
namespace UXAssist.ModsCompat;
|
||||
|
||||
class PlanetVeinUtilization
|
||||
{
|
||||
public const string PlanetVeinUtilizationGuid = "testpostpleaseignore.dsp.planet_vein_utilization";
|
||||
|
||||
public static bool Run(Harmony harmony)
|
||||
{
|
||||
if (!BepInEx.Bootstrap.Chainloader.PluginInfos.TryGetValue(PlanetVeinUtilizationGuid, out var pluginInfo)) return false;
|
||||
var assembly = pluginInfo.Instance.GetType().Assembly;
|
||||
var classType = assembly.GetType("PlanetVeinUtilization.PlanetVeinUtilization");
|
||||
harmony.Patch(AccessTools.Method(classType, "Awake"),
|
||||
new HarmonyMethod(typeof(PlanetVeinUtilization).GetMethod("PatchPlanetVeinUtilizationAwake")));
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool PatchPlanetVeinUtilizationAwake()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using UnityEngine.UI;
|
||||
using UXAssist.Common;
|
||||
using GameLogic = UXAssist.Common.GameLogic;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace UXAssist.Patches;
|
||||
|
||||
@@ -269,14 +269,14 @@ public class DysonSpherePatch : PatchImpl<DysonSpherePatch>
|
||||
protected override void OnEnable()
|
||||
{
|
||||
InitNodeForAbsorb();
|
||||
GameLogic.OnGameBegin += GameMain_Begin_Postfix;
|
||||
GameLogic.OnGameEnd += GameMain_End_Postfix;
|
||||
GameLogicProc.OnGameBegin += GameMain_Begin_Postfix;
|
||||
GameLogicProc.OnGameEnd += GameMain_End_Postfix;
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
GameLogic.OnGameEnd -= GameMain_End_Postfix;
|
||||
GameLogic.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
GameLogicProc.OnGameEnd -= GameMain_End_Postfix;
|
||||
GameLogicProc.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
_initialized = false;
|
||||
_nodeForAbsorb = null;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ using HarmonyLib;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UXAssist.Common;
|
||||
using GameLogic = UXAssist.Common.GameLogic;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace UXAssist.Patches;
|
||||
|
||||
@@ -276,12 +276,12 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
GameLogic.OnGameEnd += GameMain_End_Postfix;
|
||||
GameLogicProc.OnGameEnd += GameMain_End_Postfix;
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
GameLogic.OnGameEnd -= GameMain_End_Postfix;
|
||||
GameLogicProc.OnGameEnd -= GameMain_End_Postfix;
|
||||
if (_sunlight)
|
||||
{
|
||||
_sunlight.transform.localEulerAngles = new Vector3(0f, 180f);
|
||||
@@ -359,7 +359,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(StarSimulator), "LateUpdate")]
|
||||
[HarmonyPatch(typeof(StarSimulator), nameof(StarSimulator.LateUpdate))]
|
||||
private static IEnumerable<CodeInstruction> StarSimulator_LateUpdate_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
@@ -385,7 +385,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(PlanetSimulator), "LateUpdate")]
|
||||
[HarmonyPatch(typeof(PlanetSimulator), nameof(PlanetSimulator.LateUpdate))]
|
||||
private static IEnumerable<CodeInstruction> PlanetSimulator_LateUpdate_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
// var vec = (NightlightEnabled ? GameMain.mainPlayer.transform.up : (Quaternion.Inverse(localPlanet.runtimeRotation) * (__instance.planetData.star.uPosition - __instance.planetData.uPosition).normalized));
|
||||
@@ -1150,7 +1150,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
var pos = veinPool[veinId].pos;
|
||||
factory.RemoveVeinWithComponents(veinId);
|
||||
factory.RecalculateVeinGroup(groupIndex);
|
||||
factory.NotifyVeinExhausted(venType, pos);
|
||||
factory.NotifyVeinExhausted(venType, groupIndex, pos);
|
||||
veinCount = __instance.veinCount;
|
||||
}
|
||||
else
|
||||
@@ -1251,7 +1251,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
factory.veinAnimPool[veinId].time = amount >= 25000 ? 0f : 1f - amount * VeinData.oilSpeedMultiplier;
|
||||
if (amount <= 2500)
|
||||
{
|
||||
factory.NotifyVeinExhausted((int)veinPool[veinId].type, veinPool[veinId].pos);
|
||||
factory.NotifyVeinExhausted((int)veinPool[veinId].type, groupIndex, veinPool[veinId].pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1401,20 +1401,20 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
{
|
||||
private static readonly List<bool> OldDragBuild = [];
|
||||
private static readonly List<Vector2> OldDragBuildDist = [];
|
||||
private static readonly int[] PowerPoleIds = [2201, 2202, 2212];
|
||||
private static readonly int[] PowerPoleIds = [2202, 2212];
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
GameLogic.OnGameBegin += GameMain_Begin_Postfix;
|
||||
GameLogic.OnGameEnd += GameMain_End_Postfix;
|
||||
GameLogicProc.OnGameBegin += GameMain_Begin_Postfix;
|
||||
GameLogicProc.OnGameEnd += GameMain_End_Postfix;
|
||||
FixProto();
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
UnfixProto();
|
||||
GameLogic.OnGameEnd -= GameMain_End_Postfix;
|
||||
GameLogic.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
GameLogicProc.OnGameEnd -= GameMain_End_Postfix;
|
||||
GameLogicProc.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
}
|
||||
|
||||
public static void AlternatelyChanged()
|
||||
@@ -1435,13 +1435,13 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
OldDragBuildDist.Clear();
|
||||
foreach (var id in PowerPoleIds)
|
||||
{
|
||||
var powerPole = LDB.items.Select(id);
|
||||
if (powerPole?.prefabDesc == null) return;
|
||||
OldDragBuild.Add(powerPole.prefabDesc.dragBuild);
|
||||
OldDragBuildDist.Add(powerPole.prefabDesc.dragBuildDist);
|
||||
powerPole.prefabDesc.dragBuild = true;
|
||||
var distance = (id == 2201 && DragBuildPowerPolesAlternatelyEnabled.Value ? LDB.items.Select(2202) : powerPole).prefabDesc.powerConnectDistance - 0.72f;
|
||||
powerPole.prefabDesc.dragBuildDist = new Vector2(distance, distance);
|
||||
var prefabDesc = LDB.items.Select(id)?.prefabDesc;
|
||||
if (prefabDesc == null) return;
|
||||
OldDragBuild.Add(prefabDesc.dragBuild);
|
||||
OldDragBuildDist.Add(prefabDesc.dragBuildDist);
|
||||
prefabDesc.dragBuild = true;
|
||||
var distance = prefabDesc.powerConnectDistance - 0.72f;
|
||||
prefabDesc.dragBuildDist = new Vector2(distance, distance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1509,13 +1509,13 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
return finalCount;
|
||||
}
|
||||
|
||||
private static int PlanetAuxDataSnapDotsNonAllocNotAligned(PlanetAuxData aux, Vector3 begin, Vector3 end, Vector2 interval, float yaw, float gap, Vector3[] snaps)
|
||||
private static int PlanetAuxDataSnapDotsNonAllocNotAligned(PlanetAuxData aux, Vector3 begin, Vector3 end, Vector2 interval, float height, float yaw, float gap, Vector3[] snaps)
|
||||
{
|
||||
var num = 0;
|
||||
var magnitude = begin.magnitude;
|
||||
if (aux.activeGrid != null)
|
||||
{
|
||||
num = PlanetGridSnapDotsNonAllocNotAligned(aux.activeGrid, begin, end, interval, yaw, aux.planet.realRadius, gap, snaps);
|
||||
num = PlanetGridSnapDotsNonAllocNotAligned(aux.activeGrid, begin, end, interval, yaw, aux.planet.realRadius + height, gap, snaps);
|
||||
for (var i = 0; i < num; i++)
|
||||
{
|
||||
snaps[i] *= magnitude;
|
||||
@@ -1560,17 +1560,28 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
new CodeMatch(OpCodes.Ldarg_0),
|
||||
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(BuildTool_Click), nameof(BuildTool_Click.handPrefabDesc))),
|
||||
new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(BuildPreview), nameof(BuildPreview.desc)))
|
||||
).Advance(2).InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 6)).SetInstructionAndAdvance(Transpilers.EmitDelegate((BuildTool_Click click, int i) =>
|
||||
);
|
||||
var pos = matcher.Pos;
|
||||
matcher.MatchBack(false,
|
||||
new CodeMatch(ci => ci.IsLdloc()),
|
||||
new CodeMatch(ci => ci.IsLdloc()),
|
||||
new CodeMatch(OpCodes.Mul),
|
||||
new CodeMatch(ci => ci.IsLdloc()),
|
||||
new CodeMatch(OpCodes.Add)
|
||||
);
|
||||
var operand = matcher.Operand;
|
||||
matcher.Start().Advance(pos);
|
||||
matcher.Advance(2).InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, operand)).SetInstructionAndAdvance(Transpilers.EmitDelegate((BuildTool_Click click, int i) =>
|
||||
{
|
||||
if (!DragBuildPowerPolesAlternatelyEnabled.Value || (i & 1) == 0) return click.handItem;
|
||||
var id = click.handItem.ID;
|
||||
if (id != 2201 && id != 2202) return click.handItem;
|
||||
if (id != 2202) return click.handItem;
|
||||
return LDB.items.Select(id ^ 3);
|
||||
})).Advance(3).InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 6)).SetInstructionAndAdvance(Transpilers.EmitDelegate((BuildTool_Click click, int i) =>
|
||||
})).Advance(3).InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, operand)).SetInstructionAndAdvance(Transpilers.EmitDelegate((BuildTool_Click click, int i) =>
|
||||
{
|
||||
if (!DragBuildPowerPolesAlternatelyEnabled.Value || (i & 1) == 0) return click.handPrefabDesc;
|
||||
var id = click.handItem.ID;
|
||||
if (id != 2201 && id != 2202) return click.handPrefabDesc;
|
||||
if (id != 2202) return click.handPrefabDesc;
|
||||
return LDB.items.Select(id ^ 3).prefabDesc;
|
||||
}));
|
||||
return matcher.InstructionEnumeration();
|
||||
@@ -1770,14 +1781,14 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
protected override void OnEnable()
|
||||
{
|
||||
AddBeltSignalProtos();
|
||||
GameLogic.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
GameLogic.OnGameBegin += GameMain_Begin_Postfix;
|
||||
GameLogicProc.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
GameLogicProc.OnGameBegin += GameMain_Begin_Postfix;
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
GameLogic.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
GameLogic.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
GameLogicProc.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
GameLogicProc.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
}
|
||||
|
||||
private static void VFPreload_InvokeOnLoadWorkEnded_Postfix()
|
||||
@@ -1833,91 +1844,82 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(GameData), "GameTick")]
|
||||
public static IEnumerable<CodeInstruction> GameData_GameTick_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameLogic), nameof(GameLogic.OnFactoryFrameBegin))]
|
||||
public static void GameLogic_OnFactoryFrameBegin_Postfix()
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(PerformanceMonitor), nameof(PerformanceMonitor.EndSample)))
|
||||
).Advance(1).Insert(
|
||||
Transpilers.EmitDelegate(() =>
|
||||
var factories = GameMain.data?.factories;
|
||||
if (factories == null) return;
|
||||
var factoriesCount = factories.Length;
|
||||
var propertySystem = DSPGame.propertySystem;
|
||||
List<int> factoriesToRemove = null;
|
||||
foreach (var factoryIndex in SignalBeltFactoryIndices)
|
||||
{
|
||||
if (factoryIndex >= factoriesCount)
|
||||
{
|
||||
var factories = GameMain.data?.factories;
|
||||
if (factories == null) return;
|
||||
var factoriesCount = factories.Length;
|
||||
var propertySystem = DSPGame.propertySystem;
|
||||
List<int> factoriesToRemove = null;
|
||||
foreach (var factoryIndex in SignalBeltFactoryIndices)
|
||||
if (factoriesToRemove == null)
|
||||
factoriesToRemove = [factoryIndex];
|
||||
else
|
||||
factoriesToRemove.Add(factoryIndex);
|
||||
continue;
|
||||
}
|
||||
var signalBelts = GetSignalBelts(factoryIndex);
|
||||
if (signalBelts == null) continue;
|
||||
var factory = factories[factoryIndex];
|
||||
if (factory == null) continue;
|
||||
var cargoTraffic = factory.cargoTraffic;
|
||||
var beltCount = cargoTraffic.beltCursor;
|
||||
List<int> beltsToRemove = null;
|
||||
foreach (var kvp in signalBelts)
|
||||
{
|
||||
if (kvp.Key >= beltCount)
|
||||
{
|
||||
if (factoryIndex >= factoriesCount)
|
||||
{
|
||||
if (factoriesToRemove == null)
|
||||
factoriesToRemove = [factoryIndex];
|
||||
else
|
||||
factoriesToRemove.Add(factoryIndex);
|
||||
continue;
|
||||
}
|
||||
var signalBelts = GetSignalBelts(factoryIndex);
|
||||
if (signalBelts == null) continue;
|
||||
var factory = factories[factoryIndex];
|
||||
if (factory == null) continue;
|
||||
var cargoTraffic = factory.cargoTraffic;
|
||||
var beltCount = cargoTraffic.beltCursor;
|
||||
List<int> beltsToRemove = null;
|
||||
foreach (var kvp in signalBelts)
|
||||
{
|
||||
if (kvp.Key >= beltCount)
|
||||
{
|
||||
if (beltsToRemove == null)
|
||||
beltsToRemove = [kvp.Key];
|
||||
else
|
||||
beltsToRemove.Add(kvp.Key);
|
||||
continue;
|
||||
}
|
||||
ref var belt = ref cargoTraffic.beltPool[kvp.Key];
|
||||
var cargoPath = cargoTraffic.GetCargoPath(belt.segPathId);
|
||||
var itemIdx = kvp.Value;
|
||||
if (cargoPath == null) continue;
|
||||
var itemId = DarkFogItemIds[itemIdx];
|
||||
var consume = (byte)Math.Min(DarkFogItemsInVoid[itemIdx], 4);
|
||||
if (consume < 4)
|
||||
{
|
||||
var metaverse = propertySystem.GetItemAvaliableProperty(_clusterSeedKey, 6006);
|
||||
if (metaverse > 0)
|
||||
{
|
||||
if (metaverse > 10)
|
||||
metaverse = 10;
|
||||
propertySystem.AddItemConsumption(_clusterSeedKey, 6006, metaverse);
|
||||
var mainPlayer = GameMain.mainPlayer;
|
||||
GameMain.history.AddPropertyItemConsumption(6006, metaverse, true);
|
||||
var count = DarkFogItemExchangeRate[itemIdx] * metaverse;
|
||||
DarkFogItemsInVoid[itemIdx] += count;
|
||||
consume = (byte)Math.Min(DarkFogItemsInVoid[itemIdx], 4);
|
||||
mainPlayer.mecha.AddProductionStat(itemId, count, mainPlayer.nearestFactory);
|
||||
}
|
||||
}
|
||||
|
||||
if (consume > 0 && cargoPath.TryInsertItem(belt.segIndex + belt.segPivotOffset, itemId, consume, 0))
|
||||
DarkFogItemsInVoid[itemIdx] -= consume;
|
||||
}
|
||||
if (beltsToRemove == null) continue;
|
||||
foreach (var beltId in beltsToRemove)
|
||||
signalBelts.Remove(beltId);
|
||||
if (signalBelts.Count > 0) continue;
|
||||
if (factoriesToRemove == null)
|
||||
factoriesToRemove = [factoryIndex];
|
||||
if (beltsToRemove == null)
|
||||
beltsToRemove = [kvp.Key];
|
||||
else
|
||||
factoriesToRemove.Add(factoryIndex);
|
||||
beltsToRemove.Add(kvp.Key);
|
||||
continue;
|
||||
}
|
||||
if (factoriesToRemove == null) return;
|
||||
foreach (var factoryIndex in factoriesToRemove)
|
||||
ref var belt = ref cargoTraffic.beltPool[kvp.Key];
|
||||
var cargoPath = cargoTraffic.GetCargoPath(belt.segPathId);
|
||||
var itemIdx = kvp.Value;
|
||||
if (cargoPath == null) continue;
|
||||
var itemId = DarkFogItemIds[itemIdx];
|
||||
var consume = (byte)Math.Min(DarkFogItemsInVoid[itemIdx], 4);
|
||||
if (consume < 4)
|
||||
{
|
||||
RemovePlanetSignalBelts(factoryIndex);
|
||||
var metaverse = propertySystem.GetItemAvaliableProperty(_clusterSeedKey, 6006);
|
||||
if (metaverse > 0)
|
||||
{
|
||||
if (metaverse > 10)
|
||||
metaverse = 10;
|
||||
propertySystem.AddItemConsumption(_clusterSeedKey, 6006, metaverse);
|
||||
var mainPlayer = GameMain.mainPlayer;
|
||||
GameMain.history.AddPropertyItemConsumption(6006, metaverse, true);
|
||||
var count = DarkFogItemExchangeRate[itemIdx] * metaverse;
|
||||
DarkFogItemsInVoid[itemIdx] += count;
|
||||
consume = (byte)Math.Min(DarkFogItemsInVoid[itemIdx], 4);
|
||||
mainPlayer.mecha.AddProductionStat(itemId, count, mainPlayer.nearestFactory);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
|
||||
if (consume > 0 && cargoPath.TryInsertItem(belt.segIndex + belt.segPivotOffset, itemId, consume, 0))
|
||||
DarkFogItemsInVoid[itemIdx] -= consume;
|
||||
}
|
||||
if (beltsToRemove == null) continue;
|
||||
foreach (var beltId in beltsToRemove)
|
||||
signalBelts.Remove(beltId);
|
||||
if (signalBelts.Count > 0) continue;
|
||||
if (factoriesToRemove == null)
|
||||
factoriesToRemove = [factoryIndex];
|
||||
else
|
||||
factoriesToRemove.Add(factoryIndex);
|
||||
}
|
||||
if (factoriesToRemove == null) return;
|
||||
foreach (var factoryIndex in factoriesToRemove)
|
||||
{
|
||||
RemovePlanetSignalBelts(factoryIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@ public class GamePatch : PatchImpl<GamePatch>
|
||||
public static ConfigEntry<bool> EnableWindowResizeEnabled;
|
||||
public static ConfigEntry<bool> LoadLastWindowRectEnabled;
|
||||
|
||||
public static ConfigEntry<int> MouseCursorScaleUpMultiplier;
|
||||
|
||||
// public static ConfigEntry<bool> AutoSaveOptEnabled;
|
||||
public static ConfigEntry<bool> ConvertSavesFromPeaceEnabled;
|
||||
public static ConfigEntry<Vector4> LastWindowRect;
|
||||
@@ -87,11 +85,6 @@ public class GamePatch : PatchImpl<GamePatch>
|
||||
FixLastWindowRect();
|
||||
}
|
||||
};
|
||||
MouseCursorScaleUpMultiplier.SettingChanged += (_, _) =>
|
||||
{
|
||||
MouseCursorScaleUp.NeedReloadCursors = true;
|
||||
MouseCursorScaleUp.Enable(MouseCursorScaleUpMultiplier.Value > 1);
|
||||
};
|
||||
// AutoSaveOptEnabled.SettingChanged += (_, _) => AutoSaveOpt.Enable(AutoSaveOptEnabled.Value);
|
||||
ConvertSavesFromPeaceEnabled.SettingChanged += (_, _) => ConvertSavesFromPeace.Enable(ConvertSavesFromPeaceEnabled.Value);
|
||||
ProfileBasedSaveFolderEnabled.SettingChanged += (_, _) => RefreshSavePath();
|
||||
@@ -123,8 +116,6 @@ public class GamePatch : PatchImpl<GamePatch>
|
||||
}
|
||||
}
|
||||
EnableWindowResize.Enable(EnableWindowResizeEnabled.Value);
|
||||
MouseCursorScaleUp.NeedReloadCursors = false;
|
||||
MouseCursorScaleUp.Enable(MouseCursorScaleUpMultiplier.Value > 1);
|
||||
// AutoSaveOpt.Enable(AutoSaveOptEnabled.Value);
|
||||
ConvertSavesFromPeace.Enable(ConvertSavesFromPeaceEnabled.Value);
|
||||
Enable(true);
|
||||
@@ -136,8 +127,6 @@ public class GamePatch : PatchImpl<GamePatch>
|
||||
{
|
||||
Enable(false);
|
||||
EnableWindowResize.Enable(false);
|
||||
MouseCursorScaleUp.NeedReloadCursors = false;
|
||||
MouseCursorScaleUp.Enable(false);
|
||||
// AutoSaveOpt.Enable(false);
|
||||
ConvertSavesFromPeace.Enable(false);
|
||||
}
|
||||
@@ -160,7 +149,7 @@ public class GamePatch : PatchImpl<GamePatch>
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPriority(Priority.First)]
|
||||
[HarmonyPatch(typeof(GameConfig), "gameSaveFolder", MethodType.Getter)]
|
||||
[HarmonyPatch(typeof(GameConfig), nameof(GameConfig.gameSaveFolder), MethodType.Getter)]
|
||||
public static void GameConfig_gameSaveFolder_Postfix(ref string __result)
|
||||
{
|
||||
if (!ProfileBasedSaveFolderEnabled.Value || string.IsNullOrEmpty(WindowFunctions.ProfileName)) return;
|
||||
@@ -231,7 +220,7 @@ public class GamePatch : PatchImpl<GamePatch>
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(Screen), nameof(Screen.SetResolution), typeof(int), typeof(int), typeof(FullScreenMode), typeof(int))]
|
||||
[HarmonyPatch(typeof(Screen), nameof(Screen.SetResolution), typeof(int), typeof(int), typeof(FullScreenMode), typeof(RefreshRate))]
|
||||
private static void Screen_SetResolution_Prefix(ref int width, ref int height, FullScreenMode fullscreenMode, ref Vector2Int __state)
|
||||
{
|
||||
if (fullscreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow) return;
|
||||
@@ -258,7 +247,7 @@ public class GamePatch : PatchImpl<GamePatch>
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(Screen), nameof(Screen.SetResolution), typeof(int), typeof(int), typeof(FullScreenMode), typeof(int))]
|
||||
[HarmonyPatch(typeof(Screen), nameof(Screen.SetResolution), typeof(int), typeof(int), typeof(FullScreenMode), typeof(RefreshRate))]
|
||||
private static void Screen_SetResolution_Postfix(FullScreenMode fullscreenMode, Vector2Int __state)
|
||||
{
|
||||
if (fullscreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow) return;
|
||||
@@ -282,36 +271,6 @@ public class GamePatch : PatchImpl<GamePatch>
|
||||
ThreadingHelper.Instance.StartCoroutine(SetWindowPositionCoroutine(wnd, x, y));
|
||||
}
|
||||
|
||||
private static GameOption _gameOption;
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(UIOptionWindow), nameof(UIOptionWindow._OnOpen))]
|
||||
private static void UIOptionWindow__OnOpen_Postfix()
|
||||
{
|
||||
_gameOption = DSPGame.globalOption;
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(GameOption), nameof(GameOption.Apply))]
|
||||
private static IEnumerable<CodeInstruction> UIOptionWindow_ApplyOptions_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
var label1 = generator.DefineLabel();
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(Screen), nameof(Screen.SetResolution), [typeof(int), typeof(int), typeof(bool), typeof(int)]))
|
||||
).Advance(1).Labels.Add(label1);
|
||||
matcher.Start().Insert(
|
||||
Transpilers.EmitDelegate(() =>
|
||||
_gameOption.fullscreen == DSPGame.globalOption.fullscreen &&
|
||||
_gameOption.resolution.width == DSPGame.globalOption.resolution.width &&
|
||||
_gameOption.resolution.height == DSPGame.globalOption.resolution.height &&
|
||||
_gameOption.resolution.refreshRate == DSPGame.globalOption.resolution.refreshRate
|
||||
),
|
||||
new CodeInstruction(OpCodes.Brtrue, label1)
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
private class EnableWindowResize : PatchImpl<EnableWindowResize>
|
||||
{
|
||||
private static bool _enabled;
|
||||
@@ -601,131 +560,4 @@ public class GamePatch : PatchImpl<GamePatch>
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[PatchSetCallbackFlag(PatchCallbackFlag.CallOnDisableAfterUnpatch)]
|
||||
private class MouseCursorScaleUp : PatchImpl<MouseCursorScaleUp>
|
||||
{
|
||||
public static bool NeedReloadCursors;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
if (!NeedReloadCursors) return;
|
||||
if (!UICursor.loaded) return;
|
||||
UICursor.loaded = false;
|
||||
UICursor.LoadCursors();
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
if (!NeedReloadCursors) return;
|
||||
if (!UICursor.loaded) return;
|
||||
UICursor.loaded = false;
|
||||
UICursor.LoadCursors();
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(UICursor), nameof(UICursor.LoadCursors))]
|
||||
private static IEnumerable<CodeInstruction> UICursor_LoadCursors_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
/*
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldc_I4_S),
|
||||
new CodeMatch(OpCodes.Newarr)
|
||||
);
|
||||
var startPos = matcher.Pos;
|
||||
matcher.Advance(2).MatchForward(false,
|
||||
new CodeMatch(OpCodes.Stsfld, AccessTools.Field(typeof(UICursor), nameof(UICursor.cursorTexs)))
|
||||
);
|
||||
var endPos = matcher.Pos + 1;
|
||||
matcher.Start().Advance(startPos).RemoveInstructions(endPos - startPos);
|
||||
matcher.InsertAndAdvance(
|
||||
Transpilers.EmitDelegate(() =>
|
||||
{
|
||||
var pluginfolder = Util.PluginFolder;
|
||||
UICursor.cursorTexs =
|
||||
[
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-transfer.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-target-in.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-target-out.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-target-a.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-target-b.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-ban.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-delete.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-reform.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-dyson-node-create.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-painter.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-eyedropper.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-eraser.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-upgrade.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-downgrade.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-blank.png"),
|
||||
Util.LoadTexture($"{pluginfolder}/assets/cursor/cursor-remove.png")
|
||||
];
|
||||
})
|
||||
);
|
||||
*/
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Stsfld, AccessTools.Field(typeof(UICursor), nameof(UICursor.cursorHots))),
|
||||
new CodeMatch(OpCodes.Ldc_I4_1),
|
||||
new CodeMatch(OpCodes.Stsfld, AccessTools.Field(typeof(UICursor), nameof(UICursor.loaded)))
|
||||
).Advance(1).InsertAndAdvance(
|
||||
Transpilers.EmitDelegate(() =>
|
||||
{
|
||||
var multiplier = MouseCursorScaleUpMultiplier.Value;
|
||||
for (var i = 0; i < UICursor.cursorTexs.Length; i++)
|
||||
{
|
||||
var cursor = UICursor.cursorTexs[i];
|
||||
if (cursor == null) continue;
|
||||
var newWidth = 32 * multiplier;
|
||||
var newHeight = 32 * multiplier;
|
||||
if (cursor.width == newWidth && cursor.height == newHeight) continue;
|
||||
UICursor.cursorTexs[i] = ResizeTexture2D(cursor, newWidth, newHeight);
|
||||
}
|
||||
|
||||
if (multiplier <= 1) return;
|
||||
for (var i = UICursor.cursorHots.Length - 1; i >= 0; i--)
|
||||
{
|
||||
UICursor.cursorHots[i] = new Vector2(UICursor.cursorHots[i].x * multiplier, UICursor.cursorHots[i].y * multiplier);
|
||||
}
|
||||
})
|
||||
).MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldc_I4_0),
|
||||
new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(Cursor), nameof(Cursor.SetCursor), [typeof(Texture2D), typeof(Vector2), typeof(CursorMode)]))
|
||||
).SetInstruction(new CodeInstruction(OpCodes.Ldc_I4_1));
|
||||
return matcher.InstructionEnumeration();
|
||||
|
||||
Texture2D ResizeTexture2D(Texture2D texture2D, int targetWidth, int targetHeight)
|
||||
{
|
||||
var oldActive = RenderTexture.active;
|
||||
var rt = new RenderTexture(targetWidth, targetHeight, 32)
|
||||
{
|
||||
antiAliasing = 8
|
||||
};
|
||||
RenderTexture.active = rt;
|
||||
Graphics.Blit(texture2D, rt);
|
||||
rt.ResolveAntiAliasedSurface();
|
||||
var result = new Texture2D(targetWidth, targetHeight, texture2D.format, false);
|
||||
result.ReadPixels(new Rect(0, 0, targetWidth, targetHeight), 0, 0);
|
||||
result.filterMode = FilterMode.Trilinear;
|
||||
result.Apply();
|
||||
RenderTexture.active = oldActive;
|
||||
rt.Release();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(UICursor), nameof(UICursor.cursorIndexApply), MethodType.Setter)]
|
||||
private static IEnumerable<CodeInstruction> UICursor_set_cursorIndexApply_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.Start().MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldc_I4_0),
|
||||
new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(Cursor), nameof(Cursor.SetCursor), [typeof(Texture2D), typeof(Vector2), typeof(CursorMode)]))
|
||||
).SetInstruction(new CodeInstruction(OpCodes.Ldc_I4_1));
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,8 @@ using UnityEngine.EventSystems;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.UI;
|
||||
using UXAssist.Common;
|
||||
using GameLogic = UXAssist.Common.GameLogic;
|
||||
using Object = UnityEngine.Object;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace UXAssist.Patches;
|
||||
|
||||
@@ -74,14 +74,14 @@ public static class LogisticsPatch
|
||||
RealtimeLogisticsInfoPanel.Enable(RealtimeLogisticsInfoPanelEnabled.Value);
|
||||
RealtimeLogisticsInfoPanel.EnableBars(RealtimeLogisticsInfoPanelBarsEnabled.Value);
|
||||
|
||||
GameLogic.OnGameBegin += RealtimeLogisticsInfoPanel.OnGameBegin;
|
||||
GameLogic.OnDataLoaded += RealtimeLogisticsInfoPanel.OnDataLoaded;
|
||||
GameLogicProc.OnGameBegin += RealtimeLogisticsInfoPanel.OnGameBegin;
|
||||
GameLogicProc.OnDataLoaded += RealtimeLogisticsInfoPanel.OnDataLoaded;
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
{
|
||||
GameLogic.OnDataLoaded -= RealtimeLogisticsInfoPanel.OnDataLoaded;
|
||||
GameLogic.OnGameBegin -= RealtimeLogisticsInfoPanel.OnGameBegin;
|
||||
GameLogicProc.OnDataLoaded -= RealtimeLogisticsInfoPanel.OnDataLoaded;
|
||||
GameLogicProc.OnGameBegin -= RealtimeLogisticsInfoPanel.OnGameBegin;
|
||||
|
||||
AutoConfigLogistics.Enable(false);
|
||||
AutoConfigLogisticsSetDefaultRemoteLogicToStorage.Enable(false);
|
||||
@@ -719,6 +719,7 @@ public static class LogisticsPatch
|
||||
{
|
||||
private static StationTip[] _stationTips = new StationTip[16];
|
||||
private static readonly StationTip[] StationTipsRecycle = new StationTip[128];
|
||||
private static readonly Sprite[] StateSprite = [null, null, null];
|
||||
private static int _stationTipsRecycleCount;
|
||||
private static GameObject _stationTipsRoot;
|
||||
private static GameObject _tipPrefab;
|
||||
@@ -727,7 +728,7 @@ public static class LogisticsPatch
|
||||
private static readonly Color OrderInColor = new(108f / 255, 187f / 255, 214f / 255);
|
||||
private static readonly Color OrderOutColor = new(255f / 255, 161f / 255, 109.5f / 255);
|
||||
|
||||
private static PlanetData _lastPlanet;
|
||||
private static int _lastPlanetId;
|
||||
|
||||
private static int _localStorageMax = 5000;
|
||||
private static int _remoteStorageMax = 10000;
|
||||
@@ -769,12 +770,19 @@ public static class LogisticsPatch
|
||||
if (_stationTipsRoot == null) return;
|
||||
if (!on)
|
||||
{
|
||||
RecycleStationTips();
|
||||
_lastPlanetId = 0;
|
||||
_stationTipsRoot.SetActive(false);
|
||||
return;
|
||||
}
|
||||
if (DSPGame.IsMenuDemo || !GameMain.isRunning) return;
|
||||
_lastPlanet = GameMain.localPlanet;
|
||||
_stationTipsRoot.SetActive(on && _lastPlanet != null);
|
||||
if (DSPGame.IsMenuDemo || !GameMain.isRunning)
|
||||
{
|
||||
_lastPlanetId = 0;
|
||||
_stationTipsRoot.SetActive(false);
|
||||
return;
|
||||
}
|
||||
_lastPlanetId = GameMain.data?.localPlanet?.id ?? 0;
|
||||
_stationTipsRoot.SetActive(_lastPlanetId != 0);
|
||||
}
|
||||
|
||||
public static void EnableBars(bool on)
|
||||
@@ -788,7 +796,9 @@ public static class LogisticsPatch
|
||||
|
||||
public static void OnGameBegin()
|
||||
{
|
||||
_lastPlanet = null;
|
||||
RecycleStationTips();
|
||||
_lastPlanetId = 0;
|
||||
_stationTipsRoot?.SetActive(false);
|
||||
}
|
||||
|
||||
public static void OnDataLoaded()
|
||||
@@ -842,7 +852,7 @@ public static class LogisticsPatch
|
||||
|
||||
var sliderBgPrefab = GameObject.Find("UI Root/Overlay Canvas/In Game/Windows/Station Window/storage-box-0/slider-bg");
|
||||
|
||||
_tipPrefab = Object.Instantiate(GameObject.Find("UI Root/Overlay Canvas/In Game/Scene UIs/Vein Marks/vein-tip-prefab"), _stationTipsRoot.transform);
|
||||
_tipPrefab = Object.Instantiate(GameObject.Find("UI Root/Overlay Canvas/In Game/Scene UIs/Vein Marks/vein-tips/vein-tip-prefab"), _stationTipsRoot.transform);
|
||||
_tipPrefab.name = "tipPrefab";
|
||||
Object.Destroy(_tipPrefab.GetComponent<UIVeinDetailNode>());
|
||||
var image = _tipPrefab.GetComponent<Image>();
|
||||
@@ -993,6 +1003,11 @@ public static class LogisticsPatch
|
||||
|
||||
tipIconPrefab.gameObject.SetActive(false);
|
||||
_tipPrefab.SetActive(false);
|
||||
_stationTipsRoot.SetActive(false);
|
||||
|
||||
StateSprite[0] = Util.LoadEmbeddedSprite("assets/icon/keep.png");
|
||||
StateSprite[1] = Util.LoadEmbeddedSprite("assets/icon/out.png");
|
||||
StateSprite[2] = Util.LoadEmbeddedSprite("assets/icon/in.png");
|
||||
}
|
||||
|
||||
private static void RecycleStationTips()
|
||||
@@ -1012,9 +1027,27 @@ public static class LogisticsPatch
|
||||
}
|
||||
}
|
||||
|
||||
Array.Resize(ref _stationTips, 16);
|
||||
Array.Clear(_stationTips, 0, _stationTips.Length);
|
||||
}
|
||||
|
||||
private static void RecycleStationTip(int index)
|
||||
{
|
||||
var stationTip = _stationTips[index];
|
||||
if (!stationTip) return;
|
||||
if (_stationTipsRecycleCount < 128)
|
||||
{
|
||||
stationTip.ResetStationTip();
|
||||
stationTip.gameObject.SetActive(false);
|
||||
StationTipsRecycle[_stationTipsRecycleCount++] = stationTip;
|
||||
}
|
||||
else
|
||||
{
|
||||
Object.Destroy(stationTip);
|
||||
}
|
||||
_stationTips[index] = null;
|
||||
}
|
||||
|
||||
private static StationTip AllocateStationTip()
|
||||
{
|
||||
if (_stationTipsRecycleCount > 0)
|
||||
@@ -1033,21 +1066,31 @@ public static class LogisticsPatch
|
||||
public static void StationInfoPanelsUpdate()
|
||||
{
|
||||
if (DSPGame.IsMenuDemo || !GameMain.isRunning) return;
|
||||
var localPlanet = GameMain.localPlanet;
|
||||
if (localPlanet == null)
|
||||
var localPlanet = GameMain.data?.localPlanet;
|
||||
if (localPlanet == null || !localPlanet.factoryLoaded)
|
||||
{
|
||||
_stationTipsRoot.SetActive(false);
|
||||
if (_lastPlanetId == 0) return;
|
||||
RecycleStationTips();
|
||||
_lastPlanetId = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_lastPlanetId != localPlanet.id)
|
||||
{
|
||||
RecycleStationTips();
|
||||
_lastPlanetId = localPlanet.id;
|
||||
}
|
||||
|
||||
var factory = localPlanet.factory;
|
||||
var transport = factory?.transport;
|
||||
if (transport is not { stationCursor: > 1 } || (UIGame.viewMode != EViewMode.Normal && UIGame.viewMode != EViewMode.Globe))
|
||||
{
|
||||
if (_lastPlanet == null) return;
|
||||
_lastPlanet = null;
|
||||
_stationTipsRoot.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_lastPlanet != localPlanet)
|
||||
{
|
||||
RecycleStationTips();
|
||||
_lastPlanet = localPlanet;
|
||||
}
|
||||
|
||||
_stationTipsRoot.SetActive(true);
|
||||
if (UpdateStorageMax())
|
||||
{
|
||||
foreach (var tip in _stationTips)
|
||||
@@ -1056,26 +1099,14 @@ public static class LogisticsPatch
|
||||
}
|
||||
}
|
||||
|
||||
var factory = localPlanet.factory;
|
||||
var transport = factory?.transport;
|
||||
if (transport is not { stationCursor: > 1 } || (UIGame.viewMode != EViewMode.Normal && UIGame.viewMode != EViewMode.Globe))
|
||||
{
|
||||
if (_stationTipsRoot.activeSelf)
|
||||
{
|
||||
_stationTipsRoot.SetActive(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
_stationTipsRoot.SetActive(true);
|
||||
var localPosition = GameCamera.main.transform.localPosition;
|
||||
var forward = GameCamera.main.transform.forward;
|
||||
var realRadius = localPlanet.realRadius;
|
||||
|
||||
var stationCount = transport.stationCursor;
|
||||
if (stationCount >= _stationTips.Length)
|
||||
if (stationCount > _stationTips.Length)
|
||||
{
|
||||
var newSize = stationCount;
|
||||
var newSize = stationCount - 1;
|
||||
newSize |= newSize >> 1;
|
||||
newSize |= newSize >> 2;
|
||||
newSize |= newSize >> 4;
|
||||
@@ -1088,21 +1119,24 @@ public static class LogisticsPatch
|
||||
for (var i = stationCount - 1; i > 0; i--)
|
||||
{
|
||||
var stationComponent = transport.stationPool[i];
|
||||
var storageArray = stationComponent?.storage;
|
||||
if (stationComponent == null || i != stationComponent.id)
|
||||
{
|
||||
RecycleStationTip(i);
|
||||
continue;
|
||||
}
|
||||
var storageArray = stationComponent.storage;
|
||||
if (storageArray == null)
|
||||
{
|
||||
_stationTips[i]?.gameObject.SetActive(false);
|
||||
RecycleStationTip(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if (i != stationComponent.id)
|
||||
var stationTip = _stationTips[i];
|
||||
if (!stationTip)
|
||||
{
|
||||
UXAssist.Logger.LogWarning($"Station index mismatch: {i} != {stationComponent.id}");
|
||||
_stationTips[i]?.gameObject.SetActive(false);
|
||||
continue;
|
||||
stationTip = AllocateStationTip();
|
||||
_stationTips[i] = stationTip;
|
||||
}
|
||||
#endif
|
||||
|
||||
var position = factory.entityPool[stationComponent.entityId].pos.normalized;
|
||||
var radius = realRadius;
|
||||
@@ -1135,17 +1169,10 @@ public static class LogisticsPatch
|
||||
|| Phys.RayCastSphere(localPosition, vec / magnitude, magnitude, Vector3.zero, realRadius, out _)
|
||||
|| storageArray.Select(x => x.itemId).All(x => x == 0))
|
||||
{
|
||||
_stationTips[i]?.gameObject.SetActive(false);
|
||||
stationTip.gameObject.SetActive(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
var stationTip = _stationTips[i];
|
||||
if (!stationTip)
|
||||
{
|
||||
stationTip = AllocateStationTip();
|
||||
_stationTips[i] = stationTip;
|
||||
}
|
||||
|
||||
stationTip.gameObject.SetActive(true);
|
||||
|
||||
var localScaleMultiple = magnitude switch
|
||||
@@ -1165,7 +1192,6 @@ public static class LogisticsPatch
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class StationTip : MonoBehaviour
|
||||
{
|
||||
[FormerlySerializedAs("RectTransform")]
|
||||
@@ -1209,13 +1235,6 @@ public static class LogisticsPatch
|
||||
public ELogisticStorage RemoteState;
|
||||
}
|
||||
|
||||
private static readonly Sprite[] StateSprite =
|
||||
[
|
||||
Util.LoadEmbeddedSprite("assets/icon/keep.png"),
|
||||
Util.LoadEmbeddedSprite("assets/icon/out.png"),
|
||||
Util.LoadEmbeddedSprite("assets/icon/in.png")
|
||||
];
|
||||
|
||||
private enum EStationTipLayout
|
||||
{
|
||||
None,
|
||||
@@ -1392,6 +1411,7 @@ public static class LogisticsPatch
|
||||
|
||||
var itemCount = storage.count;
|
||||
var itemLimit = _layout == EStationTipLayout.InterstellarLogistics ? _remoteStorageMaxTotal : _localStorageMaxTotal;
|
||||
var barPositionChanged = false;
|
||||
if (storageState.ItemCount != itemCount)
|
||||
{
|
||||
storageState.ItemCount = itemCount;
|
||||
@@ -1411,8 +1431,13 @@ public static class LogisticsPatch
|
||||
);
|
||||
_sliderCurrent[i].gameObject.SetActive(true);
|
||||
}
|
||||
barPositionChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (itemCount > itemLimit) itemCount = itemLimit;
|
||||
}
|
||||
|
||||
if (barEnabled)
|
||||
{
|
||||
@@ -1420,6 +1445,10 @@ public static class LogisticsPatch
|
||||
if (storageState.ItemOrdered != itemOrdered)
|
||||
{
|
||||
storageState.ItemOrdered = itemOrdered;
|
||||
barPositionChanged = true;
|
||||
}
|
||||
if (barPositionChanged)
|
||||
{
|
||||
switch (itemOrdered)
|
||||
{
|
||||
case > 0:
|
||||
@@ -1434,7 +1463,6 @@ public static class LogisticsPatch
|
||||
_pixelPerItem * itemOrdered + 0.49f,
|
||||
StorageSliderHeight
|
||||
);
|
||||
_sliderOrdered[i].gameObject.SetActive(true);
|
||||
break;
|
||||
case < 0:
|
||||
if (itemOrdered + itemCount < 0) itemOrdered = -itemCount;
|
||||
@@ -1459,6 +1487,7 @@ public static class LogisticsPatch
|
||||
{
|
||||
storageState.ItemMax = itemMax;
|
||||
_sliderBg[i].gameObject.SetActive(itemMax > 0);
|
||||
if (itemMax > itemLimit) itemMax = itemLimit;
|
||||
((RectTransform)_sliderMax[i].transform).sizeDelta = new Vector2(
|
||||
_pixelPerItem * itemMax,
|
||||
StorageSliderHeight
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection.Emit;
|
||||
using HarmonyLib;
|
||||
using UnityEngine;
|
||||
@@ -41,29 +38,6 @@ public class PersistPatch : PatchImpl<PersistPatch>
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
// Patch to fix the issue that warning popup on VeinUtil upgraded to level 8000+
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(ABN_VeinsUtil), nameof(ABN_VeinsUtil.CheckValue))]
|
||||
private static IEnumerable<CodeInstruction> ABN_VeinsUtil_CheckValue_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldelem_R8),
|
||||
new CodeMatch(OpCodes.Conv_R4),
|
||||
new CodeMatch(OpCodes.Add),
|
||||
new CodeMatch(OpCodes.Stloc_1)
|
||||
);
|
||||
// loc1 = Mathf.Round(n * 1000f) / 1000f;
|
||||
matcher.Advance(3).Insert(
|
||||
new CodeInstruction(OpCodes.Ldc_R4, 1000f),
|
||||
new CodeInstruction(OpCodes.Mul),
|
||||
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Mathf), nameof(Mathf.Round))),
|
||||
new CodeInstruction(OpCodes.Ldc_R4, 1000f),
|
||||
new CodeInstruction(OpCodes.Div)
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
// Bring popup tip window to top layer
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(UIButton), nameof(UIButton.LateUpdate))]
|
||||
|
||||
@@ -5,7 +5,7 @@ using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using UnityEngine.UI;
|
||||
using UXAssist.Common;
|
||||
using GameLogic = UXAssist.Common.GameLogic;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace UXAssist.Patches;
|
||||
|
||||
@@ -46,11 +46,11 @@ public static class TechPatch
|
||||
if (enable)
|
||||
{
|
||||
TryPatchProto(true);
|
||||
GameLogic.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
GameLogicProc.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
}
|
||||
else
|
||||
{
|
||||
GameLogic.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
GameLogicProc.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
TryPatchProto(false);
|
||||
}
|
||||
}
|
||||
@@ -189,11 +189,11 @@ public static class TechPatch
|
||||
{
|
||||
if (DSPGame.GameDesc != null)
|
||||
TryPatchProto(DSPGame.GameDesc.isPeaceMode);
|
||||
GameLogic.OnGameBegin += OnGameBegin;
|
||||
GameLogicProc.OnGameBegin += OnGameBegin;
|
||||
}
|
||||
else
|
||||
{
|
||||
GameLogic.OnGameBegin -= OnGameBegin;
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin;
|
||||
TryPatchProto(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,331 @@
|
||||
namespace UXAssist.Patches;
|
||||
|
||||
using Common;
|
||||
using System.Linq;
|
||||
using HarmonyLib;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using BepInEx.Configuration;
|
||||
using Common;
|
||||
using GameLogicProc = Common.GameLogic;
|
||||
|
||||
[PatchGuid(PluginInfo.PLUGIN_GUID)]
|
||||
public class UIPatch : PatchImpl<UIPatch>
|
||||
{
|
||||
public static ConfigEntry<bool> PlanetVeinUtilizationEnabled;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
PlanetVeinUtilizationEnabled.SettingChanged += (_, _) => PlanetVeinUtilization.Enable(PlanetVeinUtilizationEnabled.Value);
|
||||
}
|
||||
|
||||
public static void Start()
|
||||
{
|
||||
GameLogicProc.OnGameBegin += PlanetVeinUtilization.OnGameBegin;
|
||||
Enable(true);
|
||||
Functions.UIFunctions.InitMenuButtons();
|
||||
PlanetVeinUtilization.Enable(PlanetVeinUtilizationEnabled.Value);
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
{
|
||||
PlanetVeinUtilization.Enable(false);
|
||||
Enable(false);
|
||||
GameLogicProc.OnGameBegin -= PlanetVeinUtilization.OnGameBegin;
|
||||
}
|
||||
|
||||
private class PlanetVeinUtilization : PatchImpl<PlanetVeinUtilization>
|
||||
{
|
||||
private static VeinTypeInfo[] planetVeinCount = null;
|
||||
private static VeinTypeInfo[] starVeinCount = null;
|
||||
private static readonly Dictionary<int, bool> tmpGroups = [];
|
||||
|
||||
public static void OnGameBegin()
|
||||
{
|
||||
if (planetVeinCount != null)
|
||||
{
|
||||
foreach (VeinTypeInfo vti in planetVeinCount)
|
||||
{
|
||||
if (vti.textCtrl != null)
|
||||
{
|
||||
Object.Destroy(vti.textCtrl.gameObject);
|
||||
}
|
||||
}
|
||||
planetVeinCount = null;
|
||||
}
|
||||
if (starVeinCount != null)
|
||||
{
|
||||
foreach (VeinTypeInfo vti in starVeinCount)
|
||||
{
|
||||
if (vti.textCtrl != null)
|
||||
{
|
||||
Object.Destroy(vti.textCtrl.gameObject);
|
||||
}
|
||||
}
|
||||
starVeinCount = null;
|
||||
}
|
||||
var maxVeinId = LDB.veins.dataArray.Max(vein => vein.ID);
|
||||
planetVeinCount = new VeinTypeInfo[maxVeinId + 1];
|
||||
starVeinCount = new VeinTypeInfo[maxVeinId + 1];
|
||||
InitializeVeinCountArray(planetVeinCount);
|
||||
InitializeVeinCountArray(starVeinCount);
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
if (planetVeinCount != null)
|
||||
{
|
||||
foreach (VeinTypeInfo vti in planetVeinCount)
|
||||
{
|
||||
vti.Reset();
|
||||
vti.textCtrl?.gameObject.SetActive(true);
|
||||
}
|
||||
UIPlanetDetail_RefreshDynamicProperties_Postfix(UIRoot.instance.uiGame.planetDetail);
|
||||
}
|
||||
if (starVeinCount != null)
|
||||
{
|
||||
foreach (VeinTypeInfo vti in starVeinCount)
|
||||
{
|
||||
vti.Reset();
|
||||
vti.textCtrl?.gameObject.SetActive(true);
|
||||
}
|
||||
UIStarDetail_RefreshDynamicProperties_Postfix(UIRoot.instance.uiGame.starDetail);
|
||||
}
|
||||
}
|
||||
|
||||
private static Vector2 GetAdjustedSizeDelta(Vector2 origSizeDelta)
|
||||
{
|
||||
return new Vector2(origSizeDelta.x + 40f, origSizeDelta.y);
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
if (planetVeinCount != null)
|
||||
{
|
||||
foreach (VeinTypeInfo vti in planetVeinCount)
|
||||
{
|
||||
vti.Reset();
|
||||
vti.textCtrl?.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
if (starVeinCount != null)
|
||||
{
|
||||
foreach (VeinTypeInfo vti in starVeinCount)
|
||||
{
|
||||
vti.Reset();
|
||||
vti.textCtrl?.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Helper functions
|
||||
private static void ProcessVeinData(VeinTypeInfo[] veinCount, VeinData[] veinPool)
|
||||
{
|
||||
lock (veinPool)
|
||||
{
|
||||
foreach (VeinData veinData in veinPool)
|
||||
{
|
||||
if (veinData.groupIndex == 0 || veinData.amount == 0) continue;
|
||||
if (tmpGroups.TryGetValue(veinData.groupIndex, out bool hasMiner))
|
||||
{
|
||||
if (hasMiner) continue;
|
||||
hasMiner = veinData.minerCount > 0;
|
||||
if (!hasMiner) continue;
|
||||
tmpGroups[veinData.groupIndex] = true;
|
||||
VeinTypeInfo vti = veinCount[(int)veinData.type];
|
||||
vti.numVeinGroupsWithCollector++;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMiner = veinData.minerCount > 0;
|
||||
tmpGroups.Add(veinData.groupIndex, hasMiner);
|
||||
VeinTypeInfo vti = veinCount[(int)veinData.type];
|
||||
vti.numVeinGroups++;
|
||||
if (hasMiner)
|
||||
{
|
||||
vti.numVeinGroupsWithCollector++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tmpGroups.Clear();
|
||||
}
|
||||
|
||||
private static void FormatResource(int refId, UIResAmountEntry uiresAmountEntry, VeinTypeInfo vt)
|
||||
{
|
||||
if (vt.textCtrl == null)
|
||||
{
|
||||
var parent = uiresAmountEntry.labelText.transform.parent;
|
||||
vt.textCtrl = Object.Instantiate(uiresAmountEntry.valueText, parent);
|
||||
vt.textCtrl.font = uiresAmountEntry.labelText.font;
|
||||
RectTransform trans = vt.textCtrl.rectTransform;
|
||||
var pos = uiresAmountEntry.rectTrans.localPosition;
|
||||
pos.x = pos.x + uiresAmountEntry.iconImage.rectTransform.localPosition.x - 25f;
|
||||
trans.localPosition = pos;
|
||||
Vector2 size = trans.sizeDelta;
|
||||
size.x = 40f;
|
||||
trans.sizeDelta = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
RectTransform trans = vt.textCtrl.rectTransform;
|
||||
Vector3 pos = trans.localPosition;
|
||||
pos.y = uiresAmountEntry.rectTrans.localPosition.y;
|
||||
trans.localPosition = pos;
|
||||
}
|
||||
vt.textCtrl.text = $"{vt.numVeinGroupsWithCollector}/{vt.numVeinGroups}";
|
||||
}
|
||||
|
||||
private static void InitializeVeinCountArray(VeinTypeInfo[] veinCountArray)
|
||||
{
|
||||
for (int i = 0; i < veinCountArray.Length; i++)
|
||||
{
|
||||
veinCountArray[i] = new VeinTypeInfo();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UIPlanetDetail patches
|
||||
[HarmonyPrefix, HarmonyPatch(typeof(UIPlanetDetail), nameof(UIPlanetDetail.OnPlanetDataSet))]
|
||||
public static void UIPlanetDetail_OnPlanetDataSet_Prefix(UIPlanetDetail __instance)
|
||||
{
|
||||
foreach (VeinTypeInfo vti in planetVeinCount)
|
||||
{
|
||||
vti.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIPlanetDetail), nameof(UIPlanetDetail.RefreshDynamicProperties))]
|
||||
public static void UIPlanetDetail_RefreshDynamicProperties_Postfix(UIPlanetDetail __instance)
|
||||
{
|
||||
PlanetData planet = __instance.planet;
|
||||
if (planet == null || planet.runtimeVeinGroups == null || __instance.tabIndex != 0) { return; }
|
||||
|
||||
int observeLevelCheck = __instance.planet == GameMain.localPlanet ? 1 : 2;
|
||||
if (GameMain.history.universeObserveLevel < observeLevelCheck) { return; }
|
||||
|
||||
foreach (VeinTypeInfo vti in planetVeinCount)
|
||||
{
|
||||
vti.numVeinGroups = 0;
|
||||
vti.numVeinGroupsWithCollector = 0;
|
||||
}
|
||||
// count up the total number of vein groups per resource type, as well as the total number of groups that have a miner attached
|
||||
PlanetFactory factory = planet.factory;
|
||||
if (factory != null)
|
||||
{
|
||||
ProcessVeinData(planetVeinCount, factory.veinPool);
|
||||
}
|
||||
else
|
||||
{
|
||||
VeinGroup[] veinGroups = planet.runtimeVeinGroups;
|
||||
lock (planet.veinGroupsLock)
|
||||
{
|
||||
for (int i = 1; i < veinGroups.Length; i++)
|
||||
{
|
||||
planetVeinCount[(int)veinGroups[i].type].numVeinGroups++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update each resource to show the following vein group info:
|
||||
// Iron: <number of vein groups with miners> / <total number of vein groups>
|
||||
foreach (UIResAmountEntry uiresAmountEntry in __instance.entries)
|
||||
{
|
||||
int refId = uiresAmountEntry.refId;
|
||||
if (refId > 0 && refId < (int)EVeinType.Max)
|
||||
{
|
||||
var vt = planetVeinCount[refId];
|
||||
if (vt.numVeinGroups > 0)
|
||||
{
|
||||
FormatResource(refId, uiresAmountEntry, vt);
|
||||
}
|
||||
else if (vt.textCtrl != null)
|
||||
{
|
||||
vt.textCtrl.text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UIStarDetail patches
|
||||
[HarmonyPrefix, HarmonyPatch(typeof(UIStarDetail), nameof(UIStarDetail.OnStarDataSet))]
|
||||
public static void UIStaretail_OnStarDataSet_Prefix(UIStarDetail __instance)
|
||||
{
|
||||
foreach (VeinTypeInfo vti in starVeinCount)
|
||||
{
|
||||
vti.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIStarDetail), nameof(UIStarDetail.RefreshDynamicProperties))]
|
||||
public static void UIStarDetail_RefreshDynamicProperties_Postfix(UIStarDetail __instance)
|
||||
{
|
||||
if (__instance.star == null || __instance.tabIndex != 0) { return; }
|
||||
if (GameMain.history.universeObserveLevel < 2) { return; }
|
||||
|
||||
foreach (VeinTypeInfo vti in starVeinCount)
|
||||
{
|
||||
vti.numVeinGroups = 0;
|
||||
vti.numVeinGroupsWithCollector = 0;
|
||||
}
|
||||
foreach (PlanetData planet in __instance.star.planets)
|
||||
{
|
||||
if (planet.runtimeVeinGroups == null) { continue; }
|
||||
PlanetFactory factory = planet.factory;
|
||||
if (factory != null)
|
||||
{
|
||||
ProcessVeinData(starVeinCount, factory.veinPool);
|
||||
}
|
||||
else
|
||||
{
|
||||
VeinGroup[] veinGroups = planet.runtimeVeinGroups;
|
||||
lock (planet.veinGroupsLock)
|
||||
{
|
||||
for (int i = 1; i < veinGroups.Length; i++)
|
||||
{
|
||||
starVeinCount[(int)veinGroups[i].type].numVeinGroups++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// update each resource to show the following vein group info:
|
||||
// Iron: <number of vein groups with miners> / <total number of vein groups>
|
||||
foreach (UIResAmountEntry uiresAmountEntry in __instance.entries)
|
||||
{
|
||||
int refId = uiresAmountEntry.refId;
|
||||
if (refId > 0 && refId < (int)EVeinType.Max)
|
||||
{
|
||||
var vt = starVeinCount[refId];
|
||||
if (vt.numVeinGroups > 0)
|
||||
{
|
||||
FormatResource(refId, uiresAmountEntry, vt);
|
||||
}
|
||||
else if (vt.textCtrl != null)
|
||||
{
|
||||
vt.textCtrl.text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class VeinTypeInfo
|
||||
{
|
||||
public int numVeinGroups;
|
||||
public int numVeinGroupsWithCollector;
|
||||
public Text textCtrl;
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
numVeinGroups = 0;
|
||||
numVeinGroupsWithCollector = 0;
|
||||
if (textCtrl != null)
|
||||
{
|
||||
textCtrl.text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add config button to main menu
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
* Enable game window resize
|
||||
* Remember window position and size on last exit
|
||||
* Convert Peace-Mode saves to Combat-Mode on loading
|
||||
* Scale up mouse cursor
|
||||
* Note: This will enable software cursor mode, which may cause mouse movement lag on heavy load.
|
||||
* Mod manager profile based save folder
|
||||
* Save files are stored in `Save\<ProfileName>` folder.
|
||||
* Will use original save location if matching default profile name.
|
||||
@@ -38,12 +36,8 @@
|
||||
* When set game speed in mod `Auxilaryfunction`, this feature will be disabled.
|
||||
* When mod `BulletTime` is installed, this feature will be hidden, but patch `BulletTime`'s speed control, to make its maximum speed 10x.
|
||||
* Set process priority
|
||||
* Set enabled CPU threads
|
||||
* Increase maximum count of Metadata Instantiations to 20000 (from 2000)
|
||||
* Increase capacity of player order queue to 128 (from 16)
|
||||
* Starmap view:
|
||||
* Add a star name filter, you can filter displayed star names by ores or planet types now.
|
||||
* Add a dropdown box to show all stars' distance and/or planet count.
|
||||
* Factory
|
||||
* Sunlight at night
|
||||
* Remove some build conditions
|
||||
@@ -112,9 +106,6 @@
|
||||
* Enable player actions in globe view
|
||||
* Hide tips for soil piles changes
|
||||
* Enhanced count control for hand-make
|
||||
* Shortcut keys for showing stars' name
|
||||
* Add a shortcut key to always show all star names in starmap when holding, default is `Alt`
|
||||
* Add a shortcut key to toggle between three star name display states in starmap: `Original state`, `Show all names`, `Hide all names`, default is `Tab`, will restore to original state when closing starmap
|
||||
* Auto navigation on sailings
|
||||
* It keeps Icarus on course to the target planet
|
||||
* It will try to bypass any obstacles(planets, stars or dark-fog hives) on the way
|
||||
@@ -136,6 +127,14 @@
|
||||
* This enables batch buying out techs with their prerequisites. Buy-out button is shown for all locked techs/upgrads.
|
||||
* Combat
|
||||
* Open Dark Fog Communicator anywhere
|
||||
* UI
|
||||
* Embedded [Planet Vein Untilization](https://thunderstore.io/c/dyson-sphere-program/p/testpushpleaseignore/Planet_Vein_Utilization/) due to its lack of maintainance, with minor bug fixes.
|
||||
* Shortcut keys for showing stars' name
|
||||
* Add a shortcut key to always show all star names in starmap when holding, default is `Alt`
|
||||
* Add a shortcut key to toggle between three star name display states in starmap: `Original state`, `Show all names`, `Hide all names`, default is `Tab`, will restore to original state when closing starmap
|
||||
* Starmap view:
|
||||
* Add a star name filter, you can filter displayed star names by ores or planet types now.
|
||||
* Add a dropdown box to show all stars' distance and/or planet count.
|
||||
|
||||
## Notes
|
||||
|
||||
@@ -150,6 +149,7 @@
|
||||
* [LSTM](https://github.com/hetima/DSP_LSTM) & [PlanetFinder](https://github.com/hetima/DSP_PlanetFinder): UI implementations
|
||||
* [OffGridConstruction](https://github.com/Velociraptor115-DSPModding/OffGridConstruction): Off-grid building & stepped rotation implementations
|
||||
* [CruiseAssist](https://dsp.thunderstore.io/package/tanu/CruiseAssist/) and its extension [AutoPilot](https://dsp.thunderstore.io/package/tanu/AutoPilot/): `Auto navigation on sailings` and `Auto-cruise` implementations
|
||||
* [Planet Vein Untilization](https://thunderstore.io/c/dyson-sphere-program/p/testpushpleaseignore/Planet_Vein_Utilization/)
|
||||
|
||||
</details>
|
||||
|
||||
@@ -179,8 +179,6 @@
|
||||
* 可调整游戏窗口大小(可最大化和拖动边框)
|
||||
* 记住上次退出时的窗口位置和大小
|
||||
* 在加载和平模式存档时将其转换为战斗模式
|
||||
* 放大鼠标指针
|
||||
* 注意:这将启用软件指针模式,可能会在CPU负载较重时导致鼠标移动延迟
|
||||
* 基于mod管理器配置档案名的存档文件夹
|
||||
* 存档文件会存储在`Save\<ProfileName>`文件夹中
|
||||
* 如果匹配默认配置档案名则使用原始存档位置
|
||||
@@ -195,12 +193,8 @@
|
||||
* 当在`Auxilaryfunction`mod中设置游戏速度时,此功能将被禁用
|
||||
* 当安装了`BulletTime`mod时,此功能将被隐藏,但会对`BulletTime`的速度控制打补丁,使其最大速度变为10倍
|
||||
* 设置进程优先级
|
||||
* 设置使用的CPU线程
|
||||
* 将元数据提取的最大数量增加到20000(原来为2000)
|
||||
* 将玩家指令队列的容量增加到128(原来为16)
|
||||
* 星图:
|
||||
* 添加星系名过滤器,现在可以按矿物或行星类型过滤显示的星系名
|
||||
* 添加了一个下拉框用以切换显示所有星系的距离和/或行星数量
|
||||
* 工厂
|
||||
* 夜间日光灯
|
||||
* 移除部分不影响游戏逻辑的建造条件
|
||||
@@ -270,9 +264,6 @@
|
||||
* 在行星视图中允许玩家操作
|
||||
* 隐藏沙土数量变动的提示
|
||||
* 手动制造物品的数量控制改进
|
||||
* 启用显示所有星系名称的快捷键
|
||||
* 新增一个快捷键,按住后始终在星图显示所有星系名称,默认为`Alt`
|
||||
* 新增一个快捷键,在星图视图切换三种星系名称显示状态:`原始显示状态`,`显示所有名称`,`隐藏所有名称`,默认为`Tab`,关闭星图时会恢复到原始状态
|
||||
* 航行时自动导航
|
||||
* 它会保持伊卡洛斯飞向目标星球
|
||||
* 它会尝试绕过途中的任何障碍物(行星、恒星或黑雾巢穴)
|
||||
@@ -294,6 +285,14 @@
|
||||
* 这使得可以批量买断科技及其所有前置科技。所有未解锁的科技/升级都会显示买断按钮。
|
||||
* 战斗
|
||||
* 在任意位置打开黑雾通讯器
|
||||
* UI
|
||||
* 启用显示所有星系名称的快捷键
|
||||
* 新增一个快捷键,按住后始终在星图显示所有星系名称,默认为`Alt`
|
||||
* 新增一个快捷键,在星图视图切换三种星系名称显示状态:`原始显示状态`,`显示所有名称`,`隐藏所有名称`,默认为`Tab`,关闭星图时会恢复到原始状态
|
||||
* 星图:
|
||||
* 添加星系名过滤器,现在可以按矿物或行星类型过滤显示的星系名
|
||||
* 添加了一个下拉框用以切换显示所有星系的距离和/或行星数量
|
||||
* 由于缺乏维护,整合内置了[Planet Vein Untilization](https://thunderstore.io/c/dyson-sphere-program/p/testpushpleaseignore/Planet_Vein_Utilization/),并修复了一些小错误。
|
||||
|
||||
## 注意事项
|
||||
|
||||
@@ -308,5 +307,6 @@
|
||||
* [LSTM](https://github.com/hetima/DSP_LSTM) & [PlanetFinder](https://github.com/hetima/DSP_PlanetFinder): UI实现
|
||||
* [OffGridConstruction](https://github.com/Velociraptor115-DSPModding/OffGridConstruction): 脱离网格建造以及小角度旋转的实现
|
||||
* [CruiseAssist](https://dsp.thunderstore.io/package/tanu/CruiseAssist/)及其扩展[AutoPilot](https://dsp.thunderstore.io/package/tanu/AutoPilot/): `航行时自动导航`和`自动巡航`的实现
|
||||
* [Planet Vein Untilization](https://thunderstore.io/c/dyson-sphere-program/p/testpushpleaseignore/Planet_Vein_Utilization/)
|
||||
|
||||
</details>
|
||||
|
||||
@@ -613,7 +613,7 @@ public abstract class MyWindowManager
|
||||
|
||||
/*
|
||||
//_Create -> _Init
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIGame), "_OnCreate")]
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIGame), nameof(UIGame._OnCreate))]
|
||||
public static void UIGame__OnCreate_Postfix()
|
||||
{
|
||||
}
|
||||
@@ -638,7 +638,7 @@ public abstract class MyWindowManager
|
||||
}
|
||||
|
||||
/*
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIGame), "_OnFree")]
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIGame), nameof(UIGame._OnFree))]
|
||||
public static void UIGame__OnFree_Postfix()
|
||||
{
|
||||
foreach (var win in Windows)
|
||||
|
||||
@@ -24,10 +24,9 @@ public static class UIConfigWindow
|
||||
I18N.Add("Logistics", "Logistics", "物流");
|
||||
I18N.Add("Player/Mecha", "Player/Mecha", "玩家/机甲");
|
||||
I18N.Add("Dyson Sphere", "Dyson Sphere", "戴森球");
|
||||
I18N.Add("Tech/Combat", "Tech/Combat", "科研/战斗");
|
||||
I18N.Add("Tech/Combat/UI", "Tech/Combat/UI", "科研/战斗/UI");
|
||||
I18N.Add("Enable game window resize", "Enable game window resize (maximum box and thick frame)", "可调整游戏窗口大小(可最大化和拖动边框)");
|
||||
I18N.Add("Remeber window position and size on last exit", "Remeber window position and size on last exit", "记住上次退出时的窗口位置和大小");
|
||||
I18N.Add("Scale up mouse cursor", "Scale up mouse cursor", "放大鼠标指针");
|
||||
/*
|
||||
I18N.Add("Better auto-save mechanism", "Better auto-save mechanism", "更好的自动存档机制");
|
||||
I18N.Add("Better auto-save mechanism tips", "Auto saves are stored in 'Save\\AutoSaves' folder, filenames are combined with cluster address and date-time", "自动存档会以星区地址和日期时间组合为文件名存储在'Save\\AutoSaves'文件夹中");
|
||||
@@ -48,14 +47,6 @@ public static class UIConfigWindow
|
||||
I18N.Add("Normal", "Normal", "正常");
|
||||
I18N.Add("Below Normal", "Below Normal", "低于正常");
|
||||
I18N.Add("Idle", "Idle", "空闲");
|
||||
I18N.Add("Enabled CPUs", "Enabled CPU Threads", "使用CPU线程");
|
||||
I18N.Add("All CPUs", "All CPUs", "所有CPU");
|
||||
I18N.Add("First {0} CPUs", "First {0} CPUs", "前{0}个CPU");
|
||||
I18N.Add("First 8 CPUs", "First 8 CPUs", "前8个CPU");
|
||||
I18N.Add("First CPU only", "First CPU only", "仅第一个CPU");
|
||||
I18N.Add("All P-Cores", "All P-Cores", "所有性能(P)核心");
|
||||
I18N.Add("All E-Cores", "All E-Cores", "所有能效(E)核心");
|
||||
I18N.Add("CPU Info", "CPU Info", "CPU信息");
|
||||
I18N.Add("Unlimited interactive range", "Unlimited interactive range", "无限交互距离");
|
||||
I18N.Add("Night Light", "Sunlight at night", "夜间日光灯");
|
||||
I18N.Add("Angle X:", "Angle X:", "入射角度X:");
|
||||
@@ -153,6 +144,7 @@ public static class UIConfigWindow
|
||||
I18N.Add("Set \"Sorter Cargo Stacking\" to unresearched state", "Set \"Sorter Cargo Stacking\" to unresearched state", "将\"分拣器货物叠加\"设为未研究状态");
|
||||
I18N.Add("Unlock all techs with metadata", "Unlock all techs with metadata", "使用元数据解锁所有科技");
|
||||
I18N.Add("Open Dark Fog Communicator", "Open Dark Fog Communicator", "打开黑雾通讯器");
|
||||
I18N.Add("Planet vein utilization", "Planet vein utilization in star map", "宇宙视图行星/星系矿脉数量显示");
|
||||
I18N.Apply();
|
||||
MyConfigWindow.OnUICreated += CreateUI;
|
||||
MyConfigWindow.OnUpdateUI += UpdateUI;
|
||||
@@ -293,6 +285,7 @@ public static class UIConfigWindow
|
||||
|
||||
private static void CreateUI(MyConfigWindow wnd, RectTransform trans)
|
||||
{
|
||||
UnityEngine.UI.Text txt;
|
||||
_windowTrans = trans;
|
||||
wnd.AddTabGroup(trans, "UXAssist", "tab-group-uxassist");
|
||||
var tab1 = wnd.AddTab(trans, "General");
|
||||
@@ -301,9 +294,6 @@ public static class UIConfigWindow
|
||||
wnd.AddCheckBox(x, y, tab1, GamePatch.EnableWindowResizeEnabled, "Enable game window resize");
|
||||
y += 36f;
|
||||
wnd.AddCheckBox(x, y, tab1, GamePatch.LoadLastWindowRectEnabled, "Remeber window position and size on last exit");
|
||||
y += 36f;
|
||||
var txt = wnd.AddText2(x + 2f, y, tab1, "Scale up mouse cursor", 15, "text-scale-up-mouse-cursor");
|
||||
wnd.AddSlider(x + txt.preferredWidth + 7f, y + 6f, tab1, GamePatch.MouseCursorScaleUpMultiplier, [1, 2, 3, 4], "0x", 100f);
|
||||
/*
|
||||
y += 30f;
|
||||
wnd.AddCheckBox(x, y, tab1, GamePatch.AutoSaveOptEnabled, "Better auto-save mechanism");
|
||||
@@ -341,25 +331,6 @@ public static class UIConfigWindow
|
||||
}
|
||||
y += 36f;
|
||||
wnd.AddComboBox(x + 2f, y, tab1, "Process priority").WithItems("High", "Above Normal", "Normal", "Below Normal", "Idle").WithSize(100f, 0f).WithConfigEntry(WindowFunctions.ProcessPriority);
|
||||
var details = WindowFunctions.ProcessorDetails;
|
||||
string[] affinities;
|
||||
if (details.HybridArchitecture)
|
||||
{
|
||||
affinities = new string[5];
|
||||
affinities[3] = "All P-Cores";
|
||||
affinities[4] = "All E-Cores";
|
||||
}
|
||||
else
|
||||
{
|
||||
affinities = new string[3];
|
||||
}
|
||||
affinities[0] = "All CPUs";
|
||||
affinities[1] = string.Format("First {0} CPUs".Translate(), details.ThreadCount / 2);
|
||||
affinities[2] = details.ThreadCount > 16 ? "First 8 CPUs" : "First CPU only";
|
||||
y += 36f;
|
||||
wnd.AddComboBox(x + 2f, y, tab1, "Enabled CPUs").WithItems(affinities).WithSize(200f, 0f).WithConfigEntry(WindowFunctions.ProcessAffinity);
|
||||
y += 36f;
|
||||
((RectTransform)wnd.AddButton(x, y, tab1, "CPU Info", 16, "button-show-cpu-info", WindowFunctions.ShowCPUInfo).transform).sizeDelta = new Vector2(100f, 25f);
|
||||
|
||||
var tab2 = wnd.AddTab(trans, "Factory");
|
||||
x = 0f;
|
||||
@@ -754,9 +725,12 @@ public static class UIConfigWindow
|
||||
wnd.AddSlider(x + txt.preferredWidth + 5f, y + 6f, tab5, DysonSpherePatch.AutoConstructMultiplier, [1, 2, 5, 10, 20, 50, 100], "0", 100f);
|
||||
_dysonTab = tab5;
|
||||
|
||||
var tab6 = wnd.AddTab(trans, "Tech/Combat");
|
||||
var tab6 = wnd.AddTab(trans, "Tech/Combat/UI");
|
||||
x = 10;
|
||||
y = 10;
|
||||
wnd.AddCheckBox(x, y, tab6, UIPatch.PlanetVeinUtilizationEnabled, "Planet vein utilization");
|
||||
y += 36f;
|
||||
y += 36f;
|
||||
wnd.AddCheckBox(x, y, tab6, TechPatch.BatchBuyoutTechEnabled, "Buy out techs with their prerequisites");
|
||||
y += 36f;
|
||||
wnd.AddCheckBox(x, y, tab6, TechPatch.SorterCargoStackingEnabled, "Restore upgrades of \"Sorter Cargo Stacking\" on panel");
|
||||
|
||||
@@ -14,7 +14,7 @@ using UXAssist.Functions;
|
||||
using UXAssist.Patches;
|
||||
using UXAssist.UI;
|
||||
using Util = UXAssist.Common.Util;
|
||||
using GameLogic = UXAssist.Common.GameLogic;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace UXAssist;
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace UXAssist;
|
||||
[BepInDependency(DSPModSavePlugin.MODGUID)]
|
||||
[CommonAPISubmoduleDependency(nameof(CustomKeyBindSystem))]
|
||||
[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)]
|
||||
[BepInDependency(ModsCompat.PlanetVeinUtilization.PlanetVeinUtilizationGuid, BepInDependency.DependencyFlags.SoftDependency)]
|
||||
public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
{
|
||||
public new static readonly ManualLogSource Logger =
|
||||
@@ -29,6 +30,7 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
|
||||
private static ConfigFile _dummyConfig;
|
||||
private Type[] _patches, _compats;
|
||||
private readonly Harmony _harmony = new(PluginInfo.PLUGIN_GUID);
|
||||
|
||||
#region IModCanSave
|
||||
private const ushort ModSaveVersion = 1;
|
||||
@@ -51,6 +53,11 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
}
|
||||
#endregion
|
||||
|
||||
UXAssist()
|
||||
{
|
||||
ModsCompat.PlanetVeinUtilization.Run(_harmony);
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_dummyConfig = new ConfigFile(Path.Combine(Paths.ConfigPath, PluginInfo.PLUGIN_GUID + "_dummy.cfg"), false)
|
||||
@@ -63,8 +70,6 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
"Load last window position and size when game starts");
|
||||
GamePatch.LastWindowRect = Config.Bind("Game", "LastWindowRect", new Vector4(0f, 0f, 0f, 0f),
|
||||
"Last window position and size");
|
||||
GamePatch.MouseCursorScaleUpMultiplier = Config.Bind("Game", "MouseCursorScaleUpMultiplier", 1,
|
||||
"Mouse cursor scale up multiplier");
|
||||
GamePatch.ProfileBasedSaveFolderEnabled = Config.Bind("Game", "ProfileBasedSaveFolder", false,
|
||||
"Profile-based save folder");
|
||||
GamePatch.ProfileBasedOptionEnabled = Config.Bind("Game", "ProfileBasedOption", false,
|
||||
@@ -81,12 +86,6 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
"Game UPS factor (1.0 for normal speed)");
|
||||
WindowFunctions.ProcessPriority = Config.Bind("Game", "ProcessPriority", 2,
|
||||
new ConfigDescription("Game process priority\n 0: High 1: Above Normal 2: Normal 3: Below Normal 4: Idle", new AcceptableValueRange<int>(0, 4)));
|
||||
WindowFunctions.ProcessAffinity = Config.Bind("Game", "CPUAffinity", -1,
|
||||
new ConfigDescription("""
|
||||
Game process CPU affinity
|
||||
0: All 1: First-half CPUs 2. First 8 CPUs (if total CPUs are greater than 16)
|
||||
3. All Performance Cores(If Intel 13th or greater) 4. All Efficiency Cores(If Intel 13th or greater)
|
||||
""", new AcceptableValueRange<int>(0, 4)));
|
||||
|
||||
FactoryPatch.UnlimitInteractiveEnabled = Config.Bind("Factory", "UnlimitInteractive", false,
|
||||
"Unlimit interactive range");
|
||||
@@ -203,12 +202,14 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
DysonSpherePatch.OnlyConstructNodesEnabled = Config.Bind("DysonSphere", "OnlyConstructNodes", false,
|
||||
"Construct only nodes but frames");
|
||||
DysonSpherePatch.AutoConstructMultiplier = Config.Bind("DysonSphere", "AutoConstructMultiplier", 1, "Dyson Sphere auto-construct speed multiplier");
|
||||
UIPatch.PlanetVeinUtilizationEnabled = Config.Bind("UI", "PlanetVeinUtilization", false,
|
||||
"Planet vein utilization");
|
||||
|
||||
I18N.Init();
|
||||
I18N.Add("UXAssist Config", "UXAssist Config", "UX助手设置");
|
||||
|
||||
// UI Patches
|
||||
GameLogic.Enable(true);
|
||||
GameLogicProc.Enable(true);
|
||||
|
||||
UIConfigWindow.Init();
|
||||
|
||||
@@ -228,7 +229,7 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
|
||||
_patches?.Do(type => type.GetMethod("Start")?.Invoke(null, null));
|
||||
|
||||
object[] parameters = [UIPatch.GetHarmony()];
|
||||
object[] parameters = [_harmony];
|
||||
_compats?.Do(type => type.GetMethod("Start")?.Invoke(null, parameters));
|
||||
}
|
||||
|
||||
@@ -236,9 +237,8 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
{
|
||||
_patches?.Do(type => type.GetMethod("Uninit")?.Invoke(null, null));
|
||||
|
||||
UIPatch.Enable(false);
|
||||
MyWindowManager.Enable(false);
|
||||
GameLogic.Enable(false);
|
||||
GameLogicProc.Enable(false);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
@@ -254,10 +254,7 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
GamePatch.OnInputUpdate();
|
||||
FactoryPatch.OnInputUpdate();
|
||||
PlayerPatch.OnInputUpdate();
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
LogisticsPatch.OnUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<BepInExPluginGuid>org.soardev.uxassist</BepInExPluginGuid>
|
||||
<Description>DSP MOD - UXAssist</Description>
|
||||
<Version>1.3.6</Version>
|
||||
<Version>1.4.3</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<PackageId>UXAssist</PackageId>
|
||||
@@ -15,13 +15,12 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BepInEx.Core" Version="5.*" />
|
||||
<PackageReference Include="BepInEx.PluginInfoProps" Version="1.*" />
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2018.4.12" IncludeAssets="compile" />
|
||||
<PackageReference Include="DysonSphereProgram.GameLibs" Version="0.10.32.*-r.*" />
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2022.3.53" IncludeAssets="compile" />
|
||||
<!-- <PackageReference Include="DysonSphereProgram.GameLibs" Version="0.10.32.*-r.*" /> -->
|
||||
<PackageReference Include="DysonSphereProgram.Modding.CommonAPI" Version="1.6.5" />
|
||||
<PackageReference Include="DysonSphereProgram.Modding.DSPModSave" Version="1.*" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\AssemblyFromGame\Assembly-CSharp.dll</HintPath>
|
||||
@@ -30,7 +29,6 @@
|
||||
<HintPath>..\AssemblyFromGame\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
-->
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="assets/signal/energy-fragment.png" />
|
||||
@@ -63,7 +61,7 @@
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="del /F /Q package\$(ProjectName)-$(Version).zip
powershell Compress-Archive -Force -DestinationPath 'package/$(ProjectName)-$(Version).zip' -Path "$(TargetPath)", package/icon.png, package/manifest.json, README.md, CHANGELOG.md" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "UXAssist",
|
||||
"version_number": "1.3.6",
|
||||
"version_number": "1.4.3",
|
||||
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/UXAssist",
|
||||
"description": "Some functions and patches for better user experience / 一些提升用户体验的功能和补丁",
|
||||
"dependencies": [
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
using GameLogic = UXAssist.Common.GameLogic;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace UniverseGenTweaks;
|
||||
public static class BirthPlanetPatch
|
||||
@@ -75,12 +74,12 @@ public static class BirthPlanetPatch
|
||||
HighLuminosityBirthStar.SettingChanged += (_, _) => PatchBirthThemeData();
|
||||
PatchBirthThemeData();
|
||||
_patch ??= Harmony.CreateAndPatchAll(typeof(BirthPlanetPatch));
|
||||
GameLogic.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
GameLogicProc.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
{
|
||||
GameLogic.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
GameLogicProc.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
_patch?.UnpatchSelf();
|
||||
_patch = null;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
## Changelog
|
||||
|
||||
* 1.2.11
|
||||
* Fix issues which cause universe settings not applied on staring a new game (again again).
|
||||
* 1.2.10
|
||||
* Fix issues which cause universe settings not applied on staring a new game or loading game (again).
|
||||
* Reset star distance/flatten settings on entering galaxy creation screen.
|
||||
@@ -46,6 +48,8 @@
|
||||
|
||||
## 更新日志
|
||||
|
||||
* 1.2.11
|
||||
* (再次再次)修复新建游戏时宇宙设置没有应用的问题
|
||||
* 1.2.10
|
||||
* (再次)修复新建游戏或加载存档时宇宙设置没有应用的问题
|
||||
* 进入宇宙创建界面时重置星系间距/扁平度设置
|
||||
|
||||
@@ -153,7 +153,7 @@ public static class EpicDifficulty
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(GameDesc), "get_oilAmountMultiplier")]
|
||||
[HarmonyPatch(typeof(GameDesc), nameof(GameDesc.oilAmountMultiplier), MethodType.Getter)]
|
||||
private static IEnumerable<CodeInstruction> GameDesc_get_oilAmountMultiplier_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
|
||||
@@ -99,17 +99,14 @@ public class MoreSettings
|
||||
_minDistSlider.maxValue = 50f;
|
||||
_minDistSlider.value = (float)(_minDist * 10.0);
|
||||
|
||||
_minStepTitle.name = "min-step";
|
||||
_minStepSlider.minValue = (float)(_minDist * 10.0);
|
||||
_minStepSlider.maxValue = (float)(_maxStep * 10.0);
|
||||
_minStepSlider.value = (float)(_minStep * 10.0);
|
||||
|
||||
_maxStepTitle.name = "max-step";
|
||||
_maxStepSlider.minValue = (float)(_minStep * 10.0);
|
||||
_maxStepSlider.maxValue = 100f;
|
||||
_maxStepSlider.value = (float)(_maxStep * 10.0);
|
||||
|
||||
_flattenTitle.name = "flatten";
|
||||
_flattenSlider.minValue = 1f;
|
||||
_flattenSlider.maxValue = 50f;
|
||||
_flattenSlider.value = (float)(_flatten * 50.0);
|
||||
@@ -118,6 +115,8 @@ public class MoreSettings
|
||||
_minStepText.text = _minStep.ToString();
|
||||
_maxStepText.text = _maxStep.ToString();
|
||||
_flattenText.text = _flatten.ToString();
|
||||
|
||||
UniverseGenTweaks.Logger.LogDebug($"Updated slider controls: {_minStepSlider.minValue}, {_minStepSlider.maxValue}, {_maxStepSlider.minValue}, {_maxStepSlider.maxValue}");
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
@@ -136,24 +135,9 @@ public class MoreSettings
|
||||
flattenLocalizer.stringKey = "扁平度";
|
||||
|
||||
_minDistTitle.name = "min-dist";
|
||||
_minDistSlider.minValue = 10f;
|
||||
_minDistSlider.maxValue = 50f;
|
||||
_minDistSlider.value = (float)(_minDist * 10.0);
|
||||
|
||||
_minStepTitle.name = "min-step";
|
||||
_minStepSlider.minValue = (float)(_minDist * 10.0);
|
||||
_minStepSlider.maxValue = (float)(_maxStep * 10.0);
|
||||
_minStepSlider.value = (float)(_minStep * 10.0);
|
||||
|
||||
_maxStepTitle.name = "max-step";
|
||||
_maxStepSlider.minValue = (float)(_minStep * 10.0);
|
||||
_maxStepSlider.maxValue = 100f;
|
||||
_maxStepSlider.value = (float)(_maxStep * 10.0);
|
||||
|
||||
_flattenTitle.name = "flatten";
|
||||
_flattenSlider.minValue = 1f;
|
||||
_flattenSlider.maxValue = 50f;
|
||||
_flattenSlider.value = (float)(_flatten * 50.0);
|
||||
|
||||
TransformDeltaY(_minDistTitle.transform, -36f);
|
||||
TransformDeltaY(_minStepTitle.transform, -36f * 2);
|
||||
@@ -164,25 +148,36 @@ public class MoreSettings
|
||||
TransformDeltaY(__instance.sandboxToggle.transform.parent, -36f * 4);
|
||||
TransformDeltaY(__instance.propertyMultiplierText.transform, -36f * 4);
|
||||
TransformDeltaY(__instance.addrText.transform.parent, -36f * 4);
|
||||
|
||||
RemoveAllListeners();
|
||||
UpdateSliderControls();
|
||||
AddListeners(__instance);
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(UIGalaxySelect), nameof(UIGalaxySelect._OnOpen))]
|
||||
private static void UIGalaxySelect__OnOpen_Prefix()
|
||||
private static void UIGalaxySelect__OnOpen_Prefix(UIGalaxySelect __instance)
|
||||
{
|
||||
_minDist = DEFAULT_MIN_DIST;
|
||||
_minStep = DEFAULT_MIN_STEP;
|
||||
_maxStep = DEFAULT_MAX_STEP;
|
||||
_flatten = DEFAULT_FLATTEN;
|
||||
|
||||
RemoveAllListeners();
|
||||
UpdateSliderControls();
|
||||
AddListeners(__instance);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(UIGalaxySelect), nameof(UIGalaxySelect._OnRegEvent))]
|
||||
private static void UIGalaxySelect__OnRegEvent_Postfix(UIGalaxySelect __instance)
|
||||
private static void RemoveAllListeners()
|
||||
{
|
||||
_minDistSlider.onValueChanged.RemoveAllListeners();
|
||||
_minStepSlider.onValueChanged.RemoveAllListeners();
|
||||
_maxStepSlider.onValueChanged.RemoveAllListeners();
|
||||
_flattenSlider.onValueChanged.RemoveAllListeners();
|
||||
}
|
||||
|
||||
private static void AddListeners(UIGalaxySelect uiGalaxySelect)
|
||||
{
|
||||
_minDistSlider.onValueChanged.AddListener(val =>
|
||||
{
|
||||
var newVal = Mathf.Round(val) / 10.0;
|
||||
@@ -202,9 +197,8 @@ public class MoreSettings
|
||||
}
|
||||
}
|
||||
_minStepSlider.minValue = (float)(_minDist * 10.0);
|
||||
__instance.SetStarmapGalaxy();
|
||||
uiGalaxySelect.SetStarmapGalaxy();
|
||||
});
|
||||
_minStepSlider.onValueChanged.RemoveAllListeners();
|
||||
_minStepSlider.onValueChanged.AddListener(val =>
|
||||
{
|
||||
var newVal = Mathf.Round(val) / 10.0;
|
||||
@@ -212,9 +206,8 @@ public class MoreSettings
|
||||
_minStep = newVal;
|
||||
_maxStepSlider.minValue = (float)(newVal * 10.0);
|
||||
_minStepText.text = _minStep.ToString();
|
||||
__instance.SetStarmapGalaxy();
|
||||
uiGalaxySelect.SetStarmapGalaxy();
|
||||
});
|
||||
_maxStepSlider.onValueChanged.RemoveAllListeners();
|
||||
_maxStepSlider.onValueChanged.AddListener(val =>
|
||||
{
|
||||
var newVal = Mathf.Round(val) / 10.0;
|
||||
@@ -222,16 +215,15 @@ public class MoreSettings
|
||||
_maxStep = newVal;
|
||||
_minStepSlider.maxValue = (float)(newVal * 10.0);
|
||||
_maxStepText.text = _maxStep.ToString();
|
||||
__instance.SetStarmapGalaxy();
|
||||
uiGalaxySelect.SetStarmapGalaxy();
|
||||
});
|
||||
_flattenSlider.onValueChanged.RemoveAllListeners();
|
||||
_flattenSlider.onValueChanged.AddListener(val =>
|
||||
{
|
||||
var newVal = Mathf.Round(val) / 50.0;
|
||||
if (newVal.Equals(_flatten)) return;
|
||||
_flatten = newVal;
|
||||
_flattenText.text = _flatten.ToString();
|
||||
__instance.SetStarmapGalaxy();
|
||||
uiGalaxySelect.SetStarmapGalaxy();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -266,26 +258,21 @@ public class MoreSettings
|
||||
[HarmonyPatch(typeof(GameMain), nameof(GameMain.Start))]
|
||||
private static void GameMain_Start_Prefix()
|
||||
{
|
||||
_gameMinDist = DEFAULT_MIN_DIST;
|
||||
_gameMinStep = DEFAULT_MIN_STEP;
|
||||
_gameMaxStep = DEFAULT_MAX_STEP;
|
||||
_gameFlatten = DEFAULT_FLATTEN;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(GameData), nameof(GameData.NewGame))]
|
||||
private static void GameData_NewGame_Prefix()
|
||||
{
|
||||
if (!Enabled.Value) return;
|
||||
_gameMinDist = _minDist;
|
||||
_gameMinStep = _minStep;
|
||||
_gameMaxStep = _maxStep;
|
||||
_gameFlatten = _flatten;
|
||||
|
||||
_minDist = DEFAULT_MIN_DIST;
|
||||
_minStep = DEFAULT_MIN_STEP;
|
||||
_maxStep = DEFAULT_MAX_STEP;
|
||||
_flatten = DEFAULT_FLATTEN;
|
||||
if (DSPGame.GameDesc != null)
|
||||
{
|
||||
if (GameMain.data != null) return;
|
||||
_gameMinDist = _minDist;
|
||||
_gameMinStep = _minStep;
|
||||
_gameMaxStep = _maxStep;
|
||||
_gameFlatten = _flatten;
|
||||
}
|
||||
else
|
||||
{
|
||||
_gameMinDist = DEFAULT_MIN_DIST;
|
||||
_gameMinStep = DEFAULT_MIN_STEP;
|
||||
_gameMaxStep = DEFAULT_MAX_STEP;
|
||||
_gameFlatten = DEFAULT_FLATTEN;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<AssemblyName>UniverseGenTweaks</AssemblyName>
|
||||
<BepInExPluginGuid>org.soardev.universegentweaks</BepInExPluginGuid>
|
||||
<Description>DSP MOD - UniverseGenTweaks</Description>
|
||||
<Version>1.2.10</Version>
|
||||
<Version>1.2.11</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<RestoreAdditionalProjectSources>https://nuget.bepinex.dev/v3/index.json</RestoreAdditionalProjectSources>
|
||||
@@ -15,8 +15,8 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BepInEx.Core" Version="5.*" />
|
||||
<PackageReference Include="BepInEx.PluginInfoProps" Version="1.*" />
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2018.4.12" IncludeAssets="compile" />
|
||||
<PackageReference Include="DysonSphereProgram.GameLibs" Version="0.10.32.*-r.*" />
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2022.3.53" IncludeAssets="compile" />
|
||||
<!-- <PackageReference Include="DysonSphereProgram.GameLibs" Version="0.10.32.*-r.*" /> -->
|
||||
<PackageReference Include="DysonSphereProgram.Modding.DSPModSave" Version="1.*" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -24,6 +24,15 @@
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\AssemblyFromGame\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>..\AssemblyFromGame\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\UXAssist\UXAssist.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "UniverseGenTweaks",
|
||||
"version_number": "1.2.10",
|
||||
"version_number": "1.2.11",
|
||||
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/UniverseGenTweaks",
|
||||
"description": "Universe Generation Tweaks / 宇宙生成参数调节",
|
||||
"dependencies": [
|
||||
|
||||
Reference in New Issue
Block a user