mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2026-06-19 16:41:10 +08:00
Compare commits
37 Commits
| 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 | |||
| d6a8275938 | |||
| b995503f58 | |||
| a25f74443d | |||
| 5f37b8b6d6 | |||
| 4584895345 | |||
| 5b4633e54c | |||
| 31b1d90d5d |
Binary file not shown.
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>
|
||||
|
||||
@@ -15,12 +15,70 @@ public static class DysonSphereFunctions
|
||||
public static ConfigEntry<bool> IllegalDysonShellFunctionsEnabled;
|
||||
public static ConfigEntry<int> ShellsCountForFunctions;
|
||||
|
||||
const ulong rawNum0 = 0x3FED4D1BA3920BFAUL; // cosr
|
||||
const ulong rawNum1 = 0x3FD9B9832ADBFC16UL; // sinr
|
||||
const ulong rawNum2 = 0x3FE279A74590331DUL;
|
||||
const ulong rawNum3 = 0x3FEBB67AE8584CAAUL; // cos30
|
||||
private static readonly double factor0 = RawToDouble(rawNum0);
|
||||
private static readonly double factor1 = RawToDouble(rawNum1);
|
||||
private static readonly double factor2 = RawToDouble(rawNum2);
|
||||
private static readonly double factor3 = RawToDouble(rawNum3);
|
||||
private static readonly PrecalculatedTriangle[] PrecalculatedTriangles = [
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 6869, PosA = new Vector3() { x = RawToFloat(0x00000000U), y = RawToFloat(0x00000000U), z = RawToFloat(0x45D66000U)}, PosB = new Vector3() { x = RawToFloat(0x2C88BEC4U), y = RawToFloat(0x00000000U), z = RawToFloat(0xC5D66000U)}, PosC = new Vector3() { x = RawToFloat(0xC5D66000U), y = RawToFloat(0x00000000U), z = RawToFloat(0xABB1589BU)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 13573, PosA = new Vector3() { x = RawToFloat(0x46540800U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2C87400AU)}, PosB = new Vector3() { x = RawToFloat(0x4652DEA6U), y = RawToFloat(0x00000000U), z = RawToFloat(0xC4B14E71U)}, PosC = new Vector3() { x = RawToFloat(0xC6540800U), y = RawToFloat(0x00000000U), z = RawToFloat(0xAC2F683EU)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 21257, PosA = new Vector3() { x = RawToFloat(0x46A60400U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2CD3CBAAU)}, PosB = new Vector3() { x = RawToFloat(0xC6070C9DU), y = RawToFloat(0x00000000U), z = RawToFloat(0xC697A9AEU)}, PosC = new Vector3() { x = RawToFloat(0xC6A60400U), y = RawToFloat(0x00000000U), z = RawToFloat(0xAC8956FFU)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 29718, PosA = new Vector3() { x = RawToFloat(0x469B4FBEU), y = RawToFloat(0x00000000U), z = RawToFloat(0x46AC7DAAU)}, PosB = new Vector3() { x = RawToFloat(0x46E81C00U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2D140EBCU)}, PosC = new Vector3() { x = RawToFloat(0xC6E81C00U), y = RawToFloat(0x00000000U), z = RawToFloat(0xACC0046AU)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 38834, PosA = new Vector3() { x = RawToFloat(0x4717AE00U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2D4181A3U)}, PosB = new Vector3() { x = RawToFloat(0x45FC49B0U), y = RawToFloat(0x00000000U), z = RawToFloat(0xC7145D79U)}, PosC = new Vector3() { x = RawToFloat(0xC717AE00U), y = RawToFloat(0x00000000U), z = RawToFloat(0xACFAF5D4U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 48523, PosA = new Vector3() { x = RawToFloat(0x473D8800U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2D71CBB9U)}, PosB = new Vector3() { x = RawToFloat(0xC73D8800U), y = RawToFloat(0x00000000U), z = RawToFloat(0xAD1CCB2AU)}, PosC = new Vector3() { x = RawToFloat(0xC72D2539U), y = RawToFloat(0x00000000U), z = RawToFloat(0x469A2DB9U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 58724, PosA = new Vector3() { x = RawToFloat(0x47656000U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2D925038U)}, PosB = new Vector3() { x = RawToFloat(0xC7656000U), y = RawToFloat(0x00000000U), z = RawToFloat(0xAD3DC153U)}, PosC = new Vector3() { x = RawToFloat(0xC7518B63U), y = RawToFloat(0x00000000U), z = RawToFloat(0x46BA9727U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 69389, PosA = new Vector3() { x = RawToFloat(0x47878200U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2DACE001U)}, PosB = new Vector3() { x = RawToFloat(0xC7878200U), y = RawToFloat(0x00000000U), z = RawToFloat(0xAD603407U)}, PosC = new Vector3() { x = RawToFloat(0xC7078200U), y = RawToFloat(0x00000000U), z = RawToFloat(0x476AB4D7U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 80481, PosA = new Vector3() { x = RawToFloat(0x479D3000U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2DC88874U)}, PosB = new Vector3() { x = RawToFloat(0xC79D3000U), y = RawToFloat(0x00000000U), z = RawToFloat(0xAD82095EU)}, PosC = new Vector3() { x = RawToFloat(0xC71D3000U), y = RawToFloat(0x00000000U), z = RawToFloat(0x478820DDU)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 91970, PosA = new Vector3() { x = RawToFloat(0x47B2A01EU), y = RawToFloat(0x00000000U), z = RawToFloat(0x461631C0U)}, PosB = new Vector3() { x = RawToFloat(0x47B39C00U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2DE5234DU)}, PosC = new Vector3() { x = RawToFloat(0xC7B39C00U), y = RawToFloat(0x00000000U), z = RawToFloat(0xAD9495E6U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 103831, PosA = new Vector3() { x = RawToFloat(0x476E65BEU), y = RawToFloat(0x00000000U), z = RawToFloat(0x47A4101EU)}, PosB = new Vector3() { x = RawToFloat(0x47CACB00U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2E015B75U)}, PosC = new Vector3() { x = RawToFloat(0xC7CACB00U), y = RawToFloat(0x00000000U), z = RawToFloat(0xADA7C3C0U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 116040, PosA = new Vector3() { x = RawToFloat(0x47E29F00U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2E108E84U)}, PosB = new Vector3() { x = RawToFloat(0xC7E29F00U), y = RawToFloat(0x00000000U), z = RawToFloat(0xADBB7A19U)}, PosC = new Vector3() { x = RawToFloat(0xC70C0F3EU), y = RawToFloat(0x00000000U), z = RawToFloat(0x47D7878CU)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 128580, PosA = new Vector3() { x = RawToFloat(0x00000000U), y = RawToFloat(0x00000000U), z = RawToFloat(0x47FB1D00U)}, PosB = new Vector3() { x = RawToFloat(0x47A80710U), y = RawToFloat(0x00000000U), z = RawToFloat(0x47BA9D10U)}, PosC = new Vector3() { x = RawToFloat(0x2EA02E04U), y = RawToFloat(0x00000000U), z = RawToFloat(0xC7FB1D00U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 141433, PosA = new Vector3() { x = RawToFloat(0x00000000U), y = RawToFloat(0x00000000U), z = RawToFloat(0x480A1D80U)}, PosB = new Vector3() { x = RawToFloat(0x47A25D3CU), y = RawToFloat(0x00000000U), z = RawToFloat(0x47DF79A3U)}, PosC = new Vector3() { x = RawToFloat(0x2EB03393U), y = RawToFloat(0x00000000U), z = RawToFloat(0xC80A1D80U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 154586, PosA = new Vector3() { x = RawToFloat(0x00000000U), y = RawToFloat(0x00000000U), z = RawToFloat(0x4816F500U)}, PosB = new Vector3() { x = RawToFloat(0x47B175ECU), y = RawToFloat(0x00000000U), z = RawToFloat(0x47F440EDU)}, PosC = new Vector3() { x = RawToFloat(0x2EC0959FU), y = RawToFloat(0x00000000U), z = RawToFloat(0xC816F500U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 168025, PosA = new Vector3() { x = RawToFloat(0x00000000U), y = RawToFloat(0x00000000U), z = RawToFloat(0x48241500U)}, PosB = new Vector3() { x = RawToFloat(0x48241500U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2E51542AU)}, PosC = new Vector3() { x = RawToFloat(0xC8241500U), y = RawToFloat(0x00000000U), z = RawToFloat(0xAE07BD7FU)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 181738, PosA = new Vector3() { x = RawToFloat(0x00000000U), y = RawToFloat(0x00000000U), z = RawToFloat(0x48317880U)}, PosB = new Vector3() { x = RawToFloat(0x48317880U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2E6268D3U)}, PosC = new Vector3() { x = RawToFloat(0xC8317880U), y = RawToFloat(0x00000000U), z = RawToFloat(0xAE12D0F8U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 195715, PosA = new Vector3() { x = RawToFloat(0x469FD288U), y = RawToFloat(0x00000000U), z = RawToFloat(0x483E1379U)}, PosB = new Vector3() { x = RawToFloat(0x483F1F80U), y = RawToFloat(0x00000000U), z = RawToFloat(0x2E73D398U)}, PosC = new Vector3() { x = RawToFloat(0xC83F1F80U), y = RawToFloat(0x00000000U), z = RawToFloat(0xAE1E1C47U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 209946, PosA = new Vector3() { x = RawToFloat(0x00000000U), y = RawToFloat(0x00000000U), z = RawToFloat(0x484D0500U)}, PosB = new Vector3() { x = RawToFloat(0x48092F52U), y = RawToFloat(0x00000000U), z = RawToFloat(0x48185BF5U)}, PosC = new Vector3() { x = RawToFloat(0x2F02C70CU), y = RawToFloat(0x00000000U), z = RawToFloat(0xC84D0500U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 224422, PosA = new Vector3() { x = RawToFloat(0x00000000U), y = RawToFloat(0x00000000U), z = RawToFloat(0x485B2900U)}, PosB = new Vector3() { x = RawToFloat(0x4812A593U), y = RawToFloat(0x00000000U), z = RawToFloat(0x4822DE24U)}, PosC = new Vector3() { x = RawToFloat(0x2F0BCC2BU), y = RawToFloat(0x00000000U), z = RawToFloat(0xC85B2900U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 239136, PosA = new Vector3() { x = RawToFloat(0x00000000U), y = RawToFloat(0x00000000U), z = RawToFloat(0x48698680U)}, PosB = new Vector3() { x = RawToFloat(0x481C424DU), y = RawToFloat(0x00000000U), z = RawToFloat(0x482D8B0EU)}, PosC = new Vector3() { x = RawToFloat(0x2F14F5F7U), y = RawToFloat(0x00000000U), z = RawToFloat(0xC8698680U)} },
|
||||
new PrecalculatedTriangle() { MaxOrbitRadius = 250000, PosA = new Vector3() { x = RawToFloat(0x00000000U), y = RawToFloat(0x00000000U), z = RawToFloat(0x48742180U)}, PosB = new Vector3() { x = RawToFloat(0x48235AFEU), y = RawToFloat(0x00000000U), z = RawToFloat(0x48356CB1U)}, PosC = new Vector3() { x = RawToFloat(0x2F1BB9CEU), y = RawToFloat(0x00000000U), z = RawToFloat(0xC8742180U)} },
|
||||
];
|
||||
|
||||
struct PrecalculatedTriangle
|
||||
{
|
||||
public int MaxOrbitRadius;
|
||||
public Vector3 PosA;
|
||||
public Vector3 PosB;
|
||||
public Vector3 PosC;
|
||||
}
|
||||
|
||||
private static double RawToDouble(ulong value)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
return *(double*)&value;
|
||||
}
|
||||
}
|
||||
|
||||
private static float RawToFloat(uint value)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
return *(float*)&value;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
I18N.Add("You are not in any system.", "You are not in any system.", "你不在任何星系中");
|
||||
I18N.Add("There is no Dyson Sphere shell on \"{0}\".", "There is no Dyson Sphere shell on \"{0}\".", "“{0}”上没有可建造的戴森壳");
|
||||
I18N.Add("There is no Dyson Sphere data on \"{0}\".", "There is no Dyson Sphere data on \"{0}\".", "“{0}”上没有戴森球数据");
|
||||
I18N.Add("This will complete all Dyson Sphere shells on \"{0}\" instantly. Are you sure?", "This will complete all Dyson Sphere shells on \"{0}\" instantly. Are you sure?", "这将立即完成“{0}”上的所有戴森壳。你确定吗?");
|
||||
I18N.Add("No precalculated shell found for radius {0}.", "No precalculated shell found for radius {0}.", "没有找到适合半径 {0} 的预计算壳面");
|
||||
}
|
||||
|
||||
public static void CompleteShellsInstantly()
|
||||
@@ -250,23 +308,21 @@ public static class DysonSphereFunctions
|
||||
}
|
||||
|
||||
private static readonly ThreadLocal<Dictionary<int, Vector3>> _vmap = new(() => new(16384));
|
||||
private static int CalculateTriangleVertCount(VectorLF3[] polygon)
|
||||
private static int CalculateTriangleVertCount(Vector3[] pos)
|
||||
{
|
||||
if (polygon.Length != 3) return -1;
|
||||
if (pos.Length != 3) return -1;
|
||||
VectorLF3[] polygon = [pos[0], pos[1], pos[2]];
|
||||
VectorLF3 sum = VectorLF3.zero;
|
||||
double num = 0.0;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
var nodeApos = polygon[i];
|
||||
var nodeBpos = polygon[(i + 1) % 3];
|
||||
float num2 = Vector3.Distance(nodeApos, nodeBpos);
|
||||
VectorLF3 vectorLF2 = (VectorLF3)(nodeApos + nodeBpos) * 0.5;
|
||||
sum += vectorLF2 * (double)num2;
|
||||
num += (double)num2;
|
||||
double num2 = Vector3.Distance(pos[i], pos[(i + 1) % 3]);
|
||||
VectorLF3 vectorLF2 = ((VectorLF3)pos[i] + (VectorLF3)pos[(i + 1) % 3]) * 0.5;
|
||||
sum += vectorLF2 * num2;
|
||||
num += num2;
|
||||
}
|
||||
var radius = polygon[0].magnitude;
|
||||
radius = Math.Round(radius * 10.0) / 10.0;
|
||||
for (int j = 0; j < 3; j++)
|
||||
var radius = Math.Round(polygon[0].magnitude * 10.0) / 10.0;
|
||||
for (int j = 0; j < polygon.Length; j++)
|
||||
{
|
||||
polygon[j] = polygon[j].normalized * radius;
|
||||
}
|
||||
@@ -282,36 +338,34 @@ public static class DysonSphereFunctions
|
||||
}
|
||||
var gridScale = (int)(Math.Pow(radius / 4000.0, 0.75) + 0.5);
|
||||
gridScale = ((gridScale < 1) ? 1 : gridScale);
|
||||
var gridSize = (float)gridScale * 80f;
|
||||
var gridSize = gridScale * 80f;
|
||||
var gridSizeDouble = (double)gridSize;
|
||||
var cpPerVertex = gridScale * gridScale * 2;
|
||||
|
||||
var num5 = (int)((double)num3 / 0.8660254037844386 / (double)gridSize + 2.5);
|
||||
var num5 = (int)((double)num3 / factor3 / gridSizeDouble + 2.5);
|
||||
var xaxis = VectorLF3.Cross(center, Vector3.up).normalized;
|
||||
if (xaxis.magnitude < 0.1)
|
||||
{
|
||||
xaxis = new VectorLF3(0f, 0f, 1f);
|
||||
}
|
||||
var yaxis = VectorLF3.Cross(xaxis, center).normalized;
|
||||
var raydir = xaxis * 0.915662593339561 + yaxis * 0.40194777665596015;
|
||||
var w1axis = xaxis * (0.5 * (double)gridSize) - yaxis * (0.8660254037844386 * (double)gridSize);
|
||||
var w2axis = xaxis * (0.5 * (double)gridSize) + yaxis * (0.8660254037844386 * (double)gridSize);
|
||||
var w0axis = xaxis * (double)gridSize;
|
||||
double num6 = 0.5773502691896258;
|
||||
var t1axis = yaxis * ((double)gridSize * num6 * 0.5) - xaxis * ((double)gridSize * 0.5);
|
||||
var t2axis = yaxis * ((double)gridSize * num6 * 0.5) + xaxis * ((double)gridSize * 0.5);
|
||||
var t0axis = yaxis * ((double)gridSize / 0.8660254037844386 * 0.5);
|
||||
var raydir = xaxis * factor0 + yaxis * factor1;
|
||||
var w1axis = xaxis * (0.5 * gridSizeDouble) - yaxis * (factor3 * gridSizeDouble);
|
||||
var w2axis = xaxis * (0.5 * gridSizeDouble) + yaxis * (factor3 * gridSizeDouble);
|
||||
var w0axis = xaxis * gridSizeDouble;
|
||||
var t1axis = yaxis * (gridSizeDouble * factor2 * 0.5) - xaxis * (gridSizeDouble * 0.5);
|
||||
var t2axis = yaxis * (gridSizeDouble * factor2 * 0.5) + xaxis * (gridSizeDouble * 0.5);
|
||||
var t0axis = yaxis * (gridSizeDouble / factor3 * 0.5);
|
||||
var polyn = new VectorLF3[3];
|
||||
var polynu = new double[3];
|
||||
for (int l = 0; l < 3; l++)
|
||||
{
|
||||
Vector3 vector = polygon[l];
|
||||
Vector3 vector2 = polygon[(l + 1) % 3];
|
||||
polyn[l] = VectorLF3.Cross(vector, vector2).normalized;
|
||||
polyn[l] = VectorLF3.Cross(polygon[l], polygon[(l + 1) % 3]).normalized;
|
||||
polynu[l] = polyn[l].x * raydir.x + polyn[l].y * raydir.y + polyn[l].z * raydir.z;
|
||||
}
|
||||
var vmap = _vmap.Value;
|
||||
vmap.Clear();
|
||||
double num7 = (double)gridSize * 0.5;
|
||||
double num7 = gridSizeDouble * 0.5;
|
||||
for (int m = -num5; m <= num5; m++)
|
||||
{
|
||||
for (int n = -num5; n <= num5; n++)
|
||||
@@ -319,13 +373,11 @@ public static class DysonSphereFunctions
|
||||
if (m - n <= num5 && m - n >= -num5)
|
||||
{
|
||||
VectorLF3 vectorLF3;
|
||||
vectorLF3.x = center.x + w0axis.x * (double)m - w1axis.x * (double)n;
|
||||
vectorLF3.y = center.y + w0axis.y * (double)m - w1axis.y * (double)n;
|
||||
vectorLF3.z = center.z + w0axis.z * (double)m - w1axis.z * (double)n;
|
||||
double num8 = radius / Math.Sqrt(vectorLF3.x * vectorLF3.x + vectorLF3.y * vectorLF3.y + vectorLF3.z * vectorLF3.z);
|
||||
vectorLF3.x *= num8;
|
||||
vectorLF3.y *= num8;
|
||||
vectorLF3.z *= num8;
|
||||
vectorLF3.x = center.x + w0axis.x * m - w1axis.x * n;
|
||||
vectorLF3.y = center.y + w0axis.y * m - w1axis.y * n;
|
||||
vectorLF3.z = center.z + w0axis.z * m - w1axis.z * n;
|
||||
double num8 = radius / vectorLF3.magnitude;
|
||||
vectorLF3 *= num8;
|
||||
int num9 = 0;
|
||||
for (int num10 = 0; num10 < 3; num10++)
|
||||
{
|
||||
@@ -333,9 +385,7 @@ public static class DysonSphereFunctions
|
||||
if (num11 >= 0.0)
|
||||
{
|
||||
VectorLF3 normalized2 = new VectorLF3(vectorLF3.x + num11 * raydir.x, vectorLF3.y + num11 * raydir.y, vectorLF3.z + num11 * raydir.z).normalized;
|
||||
normalized2.x *= radius;
|
||||
normalized2.y *= radius;
|
||||
normalized2.z *= radius;
|
||||
normalized2 *= radius;
|
||||
VectorLF3 vectorLF4 = polygon[num10] - normalized2;
|
||||
VectorLF3 vectorLF5 = polygon[(num10 + 1) % 3] - normalized2;
|
||||
double num12 = vectorLF4.x * vectorLF5.x + vectorLF4.y * vectorLF5.y + vectorLF4.z * vectorLF5.z;
|
||||
@@ -402,13 +452,12 @@ public static class DysonSphereFunctions
|
||||
double num = 0.0;
|
||||
for (int i = 0; i < shell.frames.Count; i++)
|
||||
{
|
||||
float num2 = Vector3.Distance(shell.frames[i].nodeA.pos, shell.frames[i].nodeB.pos);
|
||||
VectorLF3 vectorLF2 = (VectorLF3)(shell.frames[i].nodeA.pos + shell.frames[i].nodeB.pos) * 0.5;
|
||||
sum += vectorLF2 * (double)num2;
|
||||
num += (double)num2;
|
||||
double num2 = Vector3.Distance(shell.frames[i].nodeA.pos, shell.frames[i].nodeB.pos);
|
||||
VectorLF3 vectorLF2 = ((VectorLF3)shell.frames[i].nodeA.pos + (VectorLF3)shell.frames[i].nodeB.pos) * 0.5;
|
||||
sum += vectorLF2 * num2;
|
||||
num += num2;
|
||||
}
|
||||
shell.radius = shell.polygon[0].magnitude;
|
||||
shell.radius = Math.Round(shell.radius * 10.0) / 10.0;
|
||||
shell.radius = Math.Round(shell.polygon[0].magnitude * 10.0) / 10.0;
|
||||
for (int j = 0; j < shell.polygon.Count; j++)
|
||||
{
|
||||
shell.polygon[j] = shell.polygon[j].normalized * shell.radius;
|
||||
@@ -426,37 +475,35 @@ public static class DysonSphereFunctions
|
||||
}
|
||||
shell.gridScale = (int)(Math.Pow(shell.radius / 4000.0, 0.75) + 0.5);
|
||||
shell.gridScale = ((shell.gridScale < 1) ? 1 : shell.gridScale);
|
||||
shell.gridSize = (float)shell.gridScale * 80f;
|
||||
shell.gridSize = shell.gridScale * 80f;
|
||||
var gridSizeDouble = (double)shell.gridSize;
|
||||
shell.cpPerVertex = shell.gridScale * shell.gridScale * 2;
|
||||
int num5 = (int)((double)num3 / 0.8660254037844386 / (double)shell.gridSize + 2.5);
|
||||
int num5 = (int)((double)num3 / factor3 / gridSizeDouble + 2.5);
|
||||
shell.xaxis = VectorLF3.Cross(normalized, Vector3.up).normalized;
|
||||
if (shell.xaxis.magnitude < 0.1)
|
||||
{
|
||||
shell.xaxis = new VectorLF3(0f, 0f, 1f);
|
||||
}
|
||||
shell.yaxis = VectorLF3.Cross(shell.xaxis, normalized).normalized;
|
||||
shell.raydir = shell.xaxis * 0.915662593339561 + shell.yaxis * 0.40194777665596015;
|
||||
shell.w1axis = shell.xaxis * (0.5 * (double)shell.gridSize) - shell.yaxis * (0.8660254037844386 * (double)shell.gridSize);
|
||||
shell.w2axis = shell.xaxis * (0.5 * (double)shell.gridSize) + shell.yaxis * (0.8660254037844386 * (double)shell.gridSize);
|
||||
shell.w0axis = shell.xaxis * (double)shell.gridSize;
|
||||
double num6 = 0.5773502691896258;
|
||||
shell.t1axis = shell.yaxis * ((double)shell.gridSize * num6 * 0.5) - shell.xaxis * ((double)shell.gridSize * 0.5);
|
||||
shell.t2axis = shell.yaxis * ((double)shell.gridSize * num6 * 0.5) + shell.xaxis * ((double)shell.gridSize * 0.5);
|
||||
shell.t0axis = shell.yaxis * ((double)shell.gridSize / 0.8660254037844386 * 0.5);
|
||||
shell.raydir = shell.xaxis * factor0 + shell.yaxis * factor1;
|
||||
shell.w1axis = shell.xaxis * (0.5 * gridSizeDouble) - shell.yaxis * (factor3 * gridSizeDouble);
|
||||
shell.w2axis = shell.xaxis * (0.5 * gridSizeDouble) + shell.yaxis * (factor3 * gridSizeDouble);
|
||||
shell.w0axis = shell.xaxis * gridSizeDouble;
|
||||
shell.t1axis = shell.yaxis * (gridSizeDouble * factor2 * 0.5) - shell.xaxis * (gridSizeDouble * 0.5);
|
||||
shell.t2axis = shell.yaxis * (gridSizeDouble * factor2 * 0.5) + shell.xaxis * (gridSizeDouble * 0.5);
|
||||
shell.t0axis = shell.yaxis * (gridSizeDouble / factor3 * 0.5);
|
||||
int count = shell.polygon.Count;
|
||||
shell.polyn = new VectorLF3[count];
|
||||
shell.polynu = new double[count];
|
||||
for (int l = 0; l < count; l++)
|
||||
{
|
||||
Vector3 vector = shell.polygon[l];
|
||||
Vector3 vector2 = shell.polygon[(l + 1) % count];
|
||||
shell.polyn[l] = VectorLF3.Cross(vector, vector2).normalized;
|
||||
shell.polyn[l] = VectorLF3.Cross(shell.polygon[l], shell.polygon[(l + 1) % count]).normalized;
|
||||
shell.polynu[l] = shell.polyn[l].x * shell.raydir.x + shell.polyn[l].y * shell.raydir.y + shell.polyn[l].z * shell.raydir.z;
|
||||
}
|
||||
DysonShell.s_vmap.Clear();
|
||||
DysonShell.s_outvmap.Clear();
|
||||
DysonShell.s_ivmap.Clear();
|
||||
double num7 = (double)shell.gridSize * 0.5;
|
||||
double num7 = gridSizeDouble * 0.5;
|
||||
for (int m = -num5; m <= num5; m++)
|
||||
{
|
||||
for (int n = -num5; n <= num5; n++)
|
||||
@@ -464,13 +511,11 @@ public static class DysonSphereFunctions
|
||||
if (m - n <= num5 && m - n >= -num5)
|
||||
{
|
||||
VectorLF3 vectorLF3;
|
||||
vectorLF3.x = shell.center.x + shell.w0axis.x * (double)m - shell.w1axis.x * (double)n;
|
||||
vectorLF3.y = shell.center.y + shell.w0axis.y * (double)m - shell.w1axis.y * (double)n;
|
||||
vectorLF3.z = shell.center.z + shell.w0axis.z * (double)m - shell.w1axis.z * (double)n;
|
||||
double num8 = shell.radius / Math.Sqrt(vectorLF3.x * vectorLF3.x + vectorLF3.y * vectorLF3.y + vectorLF3.z * vectorLF3.z);
|
||||
vectorLF3.x *= num8;
|
||||
vectorLF3.y *= num8;
|
||||
vectorLF3.z *= num8;
|
||||
vectorLF3.x = shell.center.x + shell.w0axis.x * m - shell.w1axis.x * n;
|
||||
vectorLF3.y = shell.center.y + shell.w0axis.y * m - shell.w1axis.y * n;
|
||||
vectorLF3.z = shell.center.z + shell.w0axis.z * m - shell.w1axis.z * n;
|
||||
double num8 = shell.radius / vectorLF3.magnitude;
|
||||
vectorLF3 *= num8;
|
||||
int num9 = 0;
|
||||
for (int num10 = 0; num10 < count; num10++)
|
||||
{
|
||||
@@ -478,9 +523,7 @@ public static class DysonSphereFunctions
|
||||
if (num11 >= 0.0)
|
||||
{
|
||||
VectorLF3 normalized2 = new VectorLF3(vectorLF3.x + num11 * shell.raydir.x, vectorLF3.y + num11 * shell.raydir.y, vectorLF3.z + num11 * shell.raydir.z).normalized;
|
||||
normalized2.x *= shell.radius;
|
||||
normalized2.y *= shell.radius;
|
||||
normalized2.z *= shell.radius;
|
||||
normalized2 *= shell.radius;
|
||||
VectorLF3 vectorLF4 = shell.polygon[num10] - normalized2;
|
||||
VectorLF3 vectorLF5 = shell.polygon[(num10 + 1) % count] - normalized2;
|
||||
double num12 = vectorLF4.x * vectorLF5.x + vectorLF4.y * vectorLF5.y + vectorLF4.z * vectorLF5.z;
|
||||
@@ -560,7 +603,7 @@ public static class DysonSphereFunctions
|
||||
Vector3 value = keyValuePair.Value;
|
||||
DysonShell.s_ivmap[keyValuePair.Key] = num21;
|
||||
shell.verts[num21] = value;
|
||||
shell.uv2s[num21].x = (float)(DysonShell.s_outvmap.ContainsKey(keyValuePair.Key) ? 0 : 1);
|
||||
shell.uv2s[num21].x = DysonShell.s_outvmap.ContainsKey(keyValuePair.Key) ? 0 : 1;
|
||||
shell.vkeys[num21] = keyValuePair.Key;
|
||||
num21++;
|
||||
}
|
||||
@@ -631,7 +674,7 @@ public static class DysonSphereFunctions
|
||||
num33 = num34;
|
||||
}
|
||||
}
|
||||
shell.uv2s[num31].y = (float)num33;
|
||||
shell.uv2s[num31].y = num33;
|
||||
if (num29 + num30 < 49 && shell._is_point_in_shell(vectorLF14))
|
||||
{
|
||||
double num39 = VectorLF3.Dot(vectorLF14 - shell.polygon[num33], shell.polyn[num33]);
|
||||
@@ -677,7 +720,7 @@ public static class DysonSphereFunctions
|
||||
num47 = count3 - num47;
|
||||
}
|
||||
double num48 = (double)(vector3 - shell.nodes[num46].pos).sqrMagnitude;
|
||||
num48 += (double)num47;
|
||||
num48 += num47;
|
||||
if (num48 < num42)
|
||||
{
|
||||
num42 = num48;
|
||||
@@ -740,8 +783,8 @@ public static class DysonSphereFunctions
|
||||
}
|
||||
shell.vertsq[num58++] = (short)num61;
|
||||
num60 += 1.0;
|
||||
shell.uvs[num61].x = (float)num53;
|
||||
shell.uvs[num61].y = (float)(num60 / (double)num59);
|
||||
shell.uvs[num61].x = num53;
|
||||
shell.uvs[num61].y = (float)(num60 / num59);
|
||||
if (num58 == shell.vertsqOffset[num53 + 1])
|
||||
{
|
||||
goto Block_57;
|
||||
@@ -756,8 +799,8 @@ public static class DysonSphereFunctions
|
||||
{
|
||||
shell.vertsq[num58++] = (short)num62;
|
||||
num60 += 1.0;
|
||||
shell.uvs[num62].x = (float)num53;
|
||||
shell.uvs[num62].y = (float)(num60 / (double)num59);
|
||||
shell.uvs[num62].x = num53;
|
||||
shell.uvs[num62].y = (float)(num60 / num59);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -842,7 +885,10 @@ public static class DysonSphereFunctions
|
||||
layer.shellRecycle[recycleIndex] = shellId;
|
||||
return 0;
|
||||
}
|
||||
CheatEnabler.Logger.LogDebug($"Shell {shellId} VertCount: {DysonShell.s_vmap.Count}");
|
||||
// CheatEnabler.Logger.LogDebug($"Shell {shellId} My VertCount: {DysonShell.s_vmap.Count}");
|
||||
// shell.GenerateGeometry();
|
||||
// CheatEnabler.Logger.LogDebug($"Shell {shellId} Orig VertCount: {DysonShell.s_vmap.Count}");
|
||||
// CheatEnabler.Logger.LogDebug($"Shell {shellId} Calc VertCount: {CalculateTriangleVertCount2([shell.nodes[0].pos, shell.nodes[1].pos, shell.nodes[2].pos])}");
|
||||
for (int j = 0; j < shell.nodes.Count; j++)
|
||||
{
|
||||
shell.nodes[j].shells.Add(shell);
|
||||
@@ -1112,6 +1158,104 @@ public static class DysonSphereFunctions
|
||||
dysonSphere.modelRenderer.RebuildModels();
|
||||
}
|
||||
|
||||
public static void CreateIllegalDysonShellQuickly(int triangleCount)
|
||||
{
|
||||
StarData star = null;
|
||||
var dysonEditor = UIRoot.instance?.uiGame?.dysonEditor;
|
||||
if (dysonEditor != null && dysonEditor.gameObject.activeSelf)
|
||||
{
|
||||
star = dysonEditor.selection.viewStar;
|
||||
}
|
||||
if (star == null)
|
||||
{
|
||||
star = GameMain.data?.localStar;
|
||||
if (star == null)
|
||||
{
|
||||
UIMessageBox.Show("CheatEnabler".Translate(), "You are not in any system.".Translate(), "确定".Translate(), UIMessageBox.ERROR, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var dysonSphere = GameMain.data?.dysonSpheres[star.index];
|
||||
if (dysonSphere == null)
|
||||
{
|
||||
UIMessageBox.Show("CheatEnabler".Translate(), string.Format("There is no Dyson Sphere data on \"{0}\".".Translate(), star.displayName), "确定".Translate(), UIMessageBox.ERROR, null);
|
||||
return;
|
||||
}
|
||||
|
||||
DysonShell.s_vmap ??= new Dictionary<int, Vector3>(16384);
|
||||
DysonShell.s_outvmap ??= new Dictionary<int, Vector3>(16384);
|
||||
DysonShell.s_ivmap ??= new Dictionary<int, int>(16384);
|
||||
|
||||
for (int i = 1; i <= 10; i++)
|
||||
{
|
||||
var layer = dysonSphere.layersIdBased[i];
|
||||
if (layer != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var radius = dysonSphere.maxOrbitRadius;
|
||||
for (; radius > 4000; radius -= 10)
|
||||
{
|
||||
if (dysonSphere.CheckLayerRadius(radius) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
PrecalculatedTriangle triangle;
|
||||
try
|
||||
{
|
||||
triangle = PrecalculatedTriangles.First(t => t.MaxOrbitRadius > radius);
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
UIMessageBox.Show("CheatEnabler".Translate(), string.Format("No precalculated triangle found for radius {0}.".Translate(), radius), "确定".Translate(), UIMessageBox.ERROR, null);
|
||||
return;
|
||||
}
|
||||
layer = dysonSphere.AddLayerOnId(i, radius, Quaternion.Euler(0f, 0f, 0f), Mathf.Sqrt(dysonSphere.gravity / radius) / radius * 57.2957802f);
|
||||
if (layer == null) return;
|
||||
Vector3[] nodePos = [triangle.PosA.normalized * radius, triangle.PosB.normalized * radius, triangle.PosC.normalized * radius];
|
||||
DysonNode[] nodes = [layer.QuickAddDysonNode(0, nodePos[0]), layer.QuickAddDysonNode(0, nodePos[1]), layer.QuickAddDysonNode(0, nodePos[2])];
|
||||
DysonFrame[] frames = [layer.QuickAddDysonFrame(0, nodes[0], nodes[1], false), layer.QuickAddDysonFrame(0, nodes[1], nodes[2], false), layer.QuickAddDysonFrame(0, nodes[2], nodes[0], false)];
|
||||
var shellId = layer.QuickAddDysonShell(0, nodes, frames, false);
|
||||
if (shellId == 0) return;
|
||||
var shell = layer.shellPool[shellId];
|
||||
long[] cpMax = [.. nodes.Select(node => node.totalCpMax)];
|
||||
long[] totalCpMax = [.. cpMax];
|
||||
var dirtyFrames = new HashSet<int>();
|
||||
for (var j = 1; j < triangleCount; j++)
|
||||
{
|
||||
dirtyFrames.Clear();
|
||||
for (var k = 0; k < 3; k++)
|
||||
{
|
||||
totalCpMax[k] += cpMax[k];
|
||||
if (totalCpMax[k] > int.MaxValue)
|
||||
{
|
||||
totalCpMax[k] = cpMax[k];
|
||||
dirtyFrames.Add(k > 0 ? k - 1 : 2);
|
||||
dirtyFrames.Add(k);
|
||||
nodes[k] = layer.QuickAddDysonNode(0, nodePos[k]);
|
||||
}
|
||||
}
|
||||
foreach (var frameId in dirtyFrames)
|
||||
{
|
||||
frames[frameId] = layer.QuickAddDysonFrame(0, nodes[frameId], nodes[(frameId + 1) % 3], false);
|
||||
}
|
||||
layer.QuickAddDysonShell(0, nodes, frames, false);
|
||||
}
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
node.RecalcSpReq();
|
||||
node.RecalcCpReq();
|
||||
}
|
||||
dysonSphere.CheckAutoNodes();
|
||||
if (dysonSphere.autoNodeCount <= 0) dysonSphere.PickAutoNode();
|
||||
dysonSphere.modelRenderer.RebuildModels();
|
||||
GameMain.gameScenario.NotifyOnPlanDysonShell();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static void CreateIllegalDysonShellWithMaxOutput()
|
||||
{
|
||||
StarData star = null;
|
||||
@@ -1153,10 +1297,10 @@ public static class DysonSphereFunctions
|
||||
if (layer == null) return;
|
||||
|
||||
var supposedShells = new List<SupposedShell>(60 * 59 * 58);
|
||||
VectorLF3[] nodePos = new VectorLF3[60];
|
||||
Vector3[] nodePos = new Vector3[60];
|
||||
for (var i = 0; i < 60; i++)
|
||||
{
|
||||
nodePos[i] = new VectorLF3(Math.Sin(Math.PI * 2 * i / 60), 0, Math.Cos(Math.PI * 2 * i / 60)) * layer.orbitRadius;
|
||||
nodePos[i] = new Vector3((float)Math.Sin(Math.PI * 2 * i / 60), 0, (float)Math.Cos(Math.PI * 2 * i / 60)) * layer.orbitRadius;
|
||||
}
|
||||
for (var i = 0; i < 58; i++)
|
||||
{
|
||||
@@ -1246,6 +1390,169 @@ public static class DysonSphereFunctions
|
||||
dysonSphere.inGameRenderMaskL = 0;
|
||||
}
|
||||
|
||||
public static void CreateIllegalDysonShellsSpecially()
|
||||
{
|
||||
var lastGridScale = 0;
|
||||
var radiusList = new List<int>();
|
||||
for (var r = 4000; r <= 250000; r++)
|
||||
{
|
||||
var gridScale = (int)(Math.Pow(r / 4000.0, 0.75) + 0.5);
|
||||
gridScale = (gridScale < 1) ? 1 : gridScale;
|
||||
if (gridScale == lastGridScale) continue;
|
||||
lastGridScale = gridScale;
|
||||
radiusList.Add(r);
|
||||
CheatEnabler.Logger.LogDebug($"Grid Scale: {gridScale} from {r}");
|
||||
}
|
||||
radiusList.Add(250000);
|
||||
|
||||
StarData star = null;
|
||||
var dysonEditor = UIRoot.instance?.uiGame?.dysonEditor;
|
||||
if (dysonEditor != null && dysonEditor.gameObject.activeSelf)
|
||||
{
|
||||
star = dysonEditor.selection.viewStar;
|
||||
}
|
||||
if (star == null)
|
||||
{
|
||||
star = GameMain.data?.localStar;
|
||||
if (star == null)
|
||||
{
|
||||
UIMessageBox.Show("CheatEnabler".Translate(), "You are not in any system.".Translate(), "确定".Translate(), UIMessageBox.ERROR, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
UXAssist.Functions.DysonSphereFunctions.InitCurrentDysonLayer(star, 0);
|
||||
var dysonSphere = GameMain.data?.dysonSpheres[star.index];
|
||||
if (dysonSphere == null)
|
||||
{
|
||||
UIMessageBox.Show("CheatEnabler".Translate(), string.Format("There is no Dyson Sphere data on \"{0}\".".Translate(), star.displayName), "确定".Translate(), UIMessageBox.ERROR, null);
|
||||
return;
|
||||
}
|
||||
DysonShell.s_vmap ??= new Dictionary<int, Vector3>(16384);
|
||||
DysonShell.s_outvmap ??= new Dictionary<int, Vector3>(16384);
|
||||
DysonShell.s_ivmap ??= new Dictionary<int, int>(16384);
|
||||
var shellsChanged = false;
|
||||
var mutex = new object();
|
||||
|
||||
for (var idx = 1; idx <= 2; idx++)
|
||||
{
|
||||
Dictionary<(int, int), int> availableFrames = [];
|
||||
HashSet<int> unusedFrameIds = [];
|
||||
var layer = dysonSphere.layersIdBased[idx];
|
||||
if (layer != null)
|
||||
{
|
||||
dysonSphere.RemoveLayer(idx);
|
||||
}
|
||||
var orbitRadius = (radiusList[idx] - 1) / 10 * 10f;
|
||||
layer = dysonSphere.AddLayerOnId(idx, orbitRadius, Quaternion.Euler(0f, 0f, 0f), Mathf.Sqrt(dysonSphere.gravity / orbitRadius) / orbitRadius * 57.2957802f);
|
||||
if (layer == null) return;
|
||||
|
||||
var supposedShells = new List<SupposedShell>(60 * 59 * 58);
|
||||
Vector3[] nodePos = new Vector3[60];
|
||||
for (var i = 0; i < 60; i++)
|
||||
{
|
||||
nodePos[i] = new Vector3((float)Math.Sin(Math.PI * 2 * i / 60), 0, (float)Math.Cos(Math.PI * 2 * i / 60));
|
||||
}
|
||||
for (var i = 0; i < 58; i++)
|
||||
{
|
||||
for (var j = i + 1; j < 59; j++)
|
||||
{
|
||||
for (var k = j + 1; k < 60; k++)
|
||||
{
|
||||
var area = Vector3.Cross(nodePos[j] - nodePos[i], nodePos[k] - nodePos[i]).sqrMagnitude;
|
||||
supposedShells.Add(new SupposedShell { posA = nodePos[i], posB = nodePos[j], posC = nodePos[k], area = area });
|
||||
}
|
||||
}
|
||||
}
|
||||
supposedShells.Sort((a, b) => b.area.CompareTo(a.area));
|
||||
|
||||
var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount - 1 };
|
||||
|
||||
var gridScale = (int)(Math.Pow(orbitRadius / 4000.0, 0.75) + 0.5);
|
||||
gridScale = (gridScale < 1) ? 1 : gridScale;
|
||||
var cpPerVertex = gridScale * gridScale * 2;
|
||||
var barrier = 0x7FFFFFFF / cpPerVertex;
|
||||
if (barrier > 30000) barrier = 30000;
|
||||
|
||||
Parallel.For(0, supposedShells.Count, options, (j, _) =>
|
||||
{
|
||||
var sshell = supposedShells[j];
|
||||
var vertCount = CalculateTriangleVertCount([sshell.posA * orbitRadius, sshell.posB * orbitRadius, sshell.posC * orbitRadius]);
|
||||
if (vertCount > barrier)
|
||||
{
|
||||
sshell.vertCount = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sshell.vertCount = vertCount;
|
||||
}
|
||||
});
|
||||
supposedShells.Sort((a, b) => b.vertCount.CompareTo(a.vertCount));
|
||||
for (var j = 0; j < supposedShells.Count && supposedShells[j].vertCount > 0; j++)
|
||||
{
|
||||
var sshell = supposedShells[j];
|
||||
CheatEnabler.Logger.LogDebug($"Checking Triangle {j}[{orbitRadius}] with {sshell.vertCount} vertices");
|
||||
var result = Parallel.For((radiusList[idx - 1] + 9) / 10, (radiusList[idx] + 9) / 10, options, (k, loopState) =>
|
||||
{
|
||||
var orbitRadius = k * 10f;
|
||||
var gridScale = (int)(Math.Pow(orbitRadius / 4000.0, 0.75) + 0.5);
|
||||
gridScale = (gridScale < 1) ? 1 : gridScale;
|
||||
var cpPerVertex = gridScale * gridScale * 2;
|
||||
var barrier = 0x7FFFFFFF / cpPerVertex;
|
||||
if (barrier > 31000) barrier = 31000;
|
||||
if (loopState.ShouldExitCurrentIteration) return;
|
||||
var vertCount = CalculateTriangleVertCount([sshell.posA * orbitRadius, sshell.posB * orbitRadius, sshell.posC * orbitRadius]);
|
||||
lock (mutex)
|
||||
{
|
||||
if (loopState.ShouldExitCurrentIteration) return;
|
||||
if (vertCount > barrier)
|
||||
{
|
||||
CheatEnabler.Logger.LogDebug($"EXCEEDED: Triangle {j}[{orbitRadius}] has {vertCount} vertices");
|
||||
loopState.Stop();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!result.IsCompleted)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
layer.nodePool = new DysonNode[64];
|
||||
layer.nodeRecycle = new int[64];
|
||||
layer.nodeRecycleCursor = 0;
|
||||
layer.nodeCapacity = 64;
|
||||
layer.nodeCursor = 1;
|
||||
layer.framePool = new DysonFrame[64];
|
||||
layer.frameRecycle = new int[64];
|
||||
layer.frameRecycleCursor = 0;
|
||||
layer.frameCapacity = 64;
|
||||
layer.frameCursor = 1;
|
||||
layer.shellPool = new DysonShell[64];
|
||||
layer.shellRecycle = new int[64];
|
||||
layer.shellRecycleCursor = 0;
|
||||
layer.shellCapacity = 64;
|
||||
layer.shellCursor = 1;
|
||||
DysonNode[] newNodes = [layer.QuickAddDysonNode(0, sshell.posA * orbitRadius), layer.QuickAddDysonNode(0, sshell.posB * orbitRadius), layer.QuickAddDysonNode(0, sshell.posC * orbitRadius)];
|
||||
DysonFrame[] newFrames = [layer.QuickAddDysonFrame(0, newNodes[0], newNodes[1], false), layer.QuickAddDysonFrame(0, newNodes[1], newNodes[2], false), layer.QuickAddDysonFrame(0, newNodes[2], newNodes[0], false)];
|
||||
layer.QuickAddDysonShell(0, newNodes, newFrames, false);
|
||||
foreach (var node in newNodes)
|
||||
{
|
||||
node.RecalcSpReq();
|
||||
node.RecalcCpReq();
|
||||
}
|
||||
shellsChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dysonSphere.CheckAutoNodes();
|
||||
if (dysonSphere.autoNodeCount <= 0) dysonSphere.PickAutoNode();
|
||||
dysonSphere.modelRenderer.RebuildModels();
|
||||
if (shellsChanged) GameMain.gameScenario.NotifyOnPlanDysonShell();
|
||||
dysonSphere.inEditorRenderMaskS = 0;
|
||||
dysonSphere.inEditorRenderMaskL = 0;
|
||||
dysonSphere.inGameRenderMaskS = 0;
|
||||
dysonSphere.inGameRenderMaskL = 0;
|
||||
}
|
||||
|
||||
private static int AlignUpToPowerOfTwo(int value)
|
||||
{
|
||||
value--;
|
||||
@@ -1259,10 +1566,11 @@ public static class DysonSphereFunctions
|
||||
|
||||
private class SupposedShell
|
||||
{
|
||||
public VectorLF3 posA;
|
||||
public VectorLF3 posB;
|
||||
public VectorLF3 posC;
|
||||
public Vector3 posA;
|
||||
public Vector3 posB;
|
||||
public Vector3 posC;
|
||||
|
||||
public float area;
|
||||
public int vertCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public static class CombatPatch
|
||||
MechaInvincible.Enable(false);
|
||||
}
|
||||
|
||||
private class MechaInvincible: PatchImpl<MechaInvincible>
|
||||
private class MechaInvincible : PatchImpl<MechaInvincible>
|
||||
{
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(Player), nameof(Player.invincible), MethodType.Getter)]
|
||||
@@ -65,7 +65,7 @@ public static class CombatPatch
|
||||
}
|
||||
}
|
||||
|
||||
private class BuildingsInvincible: PatchImpl<BuildingsInvincible>
|
||||
private class BuildingsInvincible : PatchImpl<BuildingsInvincible>
|
||||
{
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(SkillSystem), nameof(SkillSystem.DamageGroundObjectByLocalCaster))]
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -59,6 +59,13 @@ public class DysonSpherePatch : PatchImpl<DysonSpherePatch>
|
||||
UnlockMaxOrbitRadius.Enable(false);
|
||||
}
|
||||
|
||||
// [HarmonyPostfix]
|
||||
// [HarmonyPatch(typeof(DysonShell), nameof(DysonShell.ImportFromBlueprint))]
|
||||
// private static void DysonShell_ImportFromBlueprint_Postfix(DysonShell __instance)
|
||||
// {
|
||||
// CheatEnabler.Logger.LogDebug($"[DysonShell.ImportFromBlueprint] vertCount={__instance.vertexCount}, cpPerVertex={__instance.cpPerVertex}, cpMax={__instance.cellPointMax}");
|
||||
// }
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(DysonNode), nameof(DysonNode.OrderConstructCp))]
|
||||
private static IEnumerable<CodeInstruction> DysonNode_OrderConstructCp_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
@@ -127,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()
|
||||
@@ -289,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,25 +1123,18 @@ 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 = new();
|
||||
private static readonly Dictionary<int, ItemSource> ItemSources = [];
|
||||
private static bool _itemSourcesInitialized;
|
||||
|
||||
private class ItemSource
|
||||
@@ -1212,7 +1205,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
if (ItemSources.ContainsKey(res[i])) continue;
|
||||
var rs = new ItemSource { Count = rescnt[i], From = new Dictionary<int, float>() };
|
||||
var rs = new ItemSource { Count = rescnt[i], From = [], Extra = null };
|
||||
var it = recipe.Items;
|
||||
var itcnt = recipe.ItemCounts;
|
||||
var len2 = it.Length;
|
||||
@@ -1223,7 +1216,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
|
||||
if (len > 1)
|
||||
{
|
||||
rs.Extra = new Dictionary<int, float>();
|
||||
rs.Extra = [];
|
||||
for (var k = 0; k < len; k++)
|
||||
{
|
||||
if (i != k)
|
||||
|
||||
@@ -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;
|
||||
@@ -187,7 +187,7 @@ public static class GamePatch
|
||||
}
|
||||
}
|
||||
|
||||
public class UnlockTech: PatchImpl<UnlockTech>
|
||||
public class UnlockTech : PatchImpl<UnlockTech>
|
||||
{
|
||||
private static void UnlockTechRecursive(GameHistoryData history, [NotNull] TechProto techProto, int maxLevel = 10000)
|
||||
{
|
||||
@@ -282,7 +282,7 @@ public static class GamePatch
|
||||
}
|
||||
}
|
||||
|
||||
history.VarifyTechQueue();
|
||||
history.VerifyTechQueue();
|
||||
if (history.currentTech != history.techQueue[0])
|
||||
{
|
||||
history.currentTech = history.techQueue[0];
|
||||
|
||||
@@ -29,7 +29,7 @@ public static class PlanetPatch
|
||||
TerraformAnyway.Enable(false);
|
||||
}
|
||||
|
||||
private class WaterPumperPatch: PatchImpl<WaterPumperPatch>
|
||||
private class WaterPumperPatch : PatchImpl<WaterPumperPatch>
|
||||
{
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(BuildTool_BlueprintPaste), nameof(BuildTool_BlueprintPaste.CheckBuildConditions))]
|
||||
@@ -51,7 +51,7 @@ public static class PlanetPatch
|
||||
}
|
||||
}
|
||||
|
||||
private class TerraformAnyway: PatchImpl<TerraformAnyway>
|
||||
private class TerraformAnyway : PatchImpl<TerraformAnyway>
|
||||
{
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(BuildTool_Reform), nameof(BuildTool_Reform.ReformAction))]
|
||||
|
||||
@@ -33,7 +33,7 @@ public static class PlayerPatch
|
||||
WarpWithoutSpaceWarpers.Enable(false);
|
||||
}
|
||||
|
||||
private class InstantHandCraft: PatchImpl<InstantHandCraft>
|
||||
private class InstantHandCraft : PatchImpl<InstantHandCraft>
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(ForgeTask), MethodType.Constructor, typeof(int), typeof(int))]
|
||||
@@ -43,7 +43,7 @@ public static class PlayerPatch
|
||||
}
|
||||
}
|
||||
|
||||
private class InstantTeleport: PatchImpl<InstantTeleport>
|
||||
private class InstantTeleport : PatchImpl<InstantTeleport>
|
||||
{
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(UIGlobemap), nameof(UIGlobemap._OnUpdate))]
|
||||
@@ -66,7 +66,7 @@ public static class PlayerPatch
|
||||
}
|
||||
}
|
||||
|
||||
private class WarpWithoutSpaceWarpers: PatchImpl<WarpWithoutSpaceWarpers>
|
||||
private class WarpWithoutSpaceWarpers : PatchImpl<WarpWithoutSpaceWarpers>
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(Mecha), nameof(Mecha.HasWarper))]
|
||||
@@ -75,7 +75,7 @@ public static class PlayerPatch
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(Mecha), nameof(Mecha.UseWarper))]
|
||||
private static void Mecha_UseWarper_Postfix(ref bool __result)
|
||||
|
||||
@@ -29,12 +29,12 @@ public static class ResourcePatch
|
||||
FastMining.Enable(false);
|
||||
}
|
||||
|
||||
private class InfiniteResource: PatchImpl<InfiniteResource>
|
||||
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,48 +42,81 @@ public static class ResourcePatch
|
||||
[HarmonyPatch(typeof(UIControlPanelVeinCollectorPanel), nameof(UIControlPanelVeinCollectorPanel._OnUpdate))]
|
||||
[HarmonyPatch(typeof(UIMinerWindow), nameof(UIMinerWindow._OnUpdate))]
|
||||
[HarmonyPatch(typeof(UIMiningUpgradeLabel), nameof(UIMiningUpgradeLabel.Update))]
|
||||
[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(ci => (ci.opcode == OpCodes.Ldfld || ci.opcode == OpCodes.Ldflda) && ci.OperandIs(AccessTools.Field(typeof(GameHistoryData), nameof(GameHistoryData.miningCostRate))))
|
||||
).Repeat(codeMatcher =>
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
private class FastMining : PatchImpl<FastMining>
|
||||
{
|
||||
static private readonly float FastMiningSpeed = 2400f;
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[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.miningCostRate)))
|
||||
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, 0f)
|
||||
)
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
}
|
||||
|
||||
private class FastMining: PatchImpl<FastMining>
|
||||
{
|
||||
[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")]
|
||||
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)))
|
||||
).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`才能看到后面两个按钮
|
||||
* 生成单层仙术戴森壳
|
||||
* 保留发电量最高的戴森壳并移除其他戴森壳
|
||||
* 从发电量最高的壳复制戴森壳
|
||||
|
||||
@@ -71,6 +71,8 @@ public static class UIConfigWindow
|
||||
I18N.Add("Generate illegal dyson shell", "Generate an illegal dyson shell (!!All shells will be removed first!!)", "生成单层仙术戴森壳(!!会先删除全部的壳!!)");
|
||||
I18N.Add("Keep max production shells and remove others", "Keep max production shells and remove others", "保留发电量最高的戴森壳并移除其他戴森壳");
|
||||
I18N.Add("Duplicate shells from that with highest production", "Duplicate shells from that with highest production", "从发电量最高的壳复制戴森壳");
|
||||
I18N.Add("Generate illegal dyson shell quickly", "Generate illegal dyson shell quickly", "快速生成仙术戴森壳");
|
||||
I18N.Add("Shells count", "Shells count", "壳面数量");
|
||||
I18N.Add("WARNING: This operation can be very slow, continue?", "WARNING: This operation can be very slow, continue?", "警告:此操作可能非常慢,继续吗?");
|
||||
I18N.Add("WARNING: This operation is DANGEROUS, continue?", "WARNING: This operation is DANGEROUS, continue?", "警告:此操作非常危险,继续吗?");
|
||||
I18N.Add("Terraform without enough soil piles", "Terraform without enough soil piles", "沙土不够时依然可以整改地形");
|
||||
@@ -301,22 +303,37 @@ public static class UIConfigWindow
|
||||
wnd.AddButton(x, y, 300f, tab4, "Complete Dyson Sphere shells instantly", 16, "button-complete-dyson-sphere-shells-instantly", DysonSphereFunctions.CompleteShellsInstantly);
|
||||
{
|
||||
y += 72f;
|
||||
var btn1 = wnd.AddButton(x, y, 300f, tab4, "Generate illegal dyson shell", 16, "button-generate-illegal-dyson-shells", () => {
|
||||
var originalY = y;
|
||||
var btn1 = wnd.AddButton(x, y, 300f, tab4, "Generate illegal dyson shell", 16, "button-generate-illegal-dyson-shells", () =>
|
||||
{
|
||||
UIMessageBox.Show("Generate illegal dyson shell".Translate(), "WARNING: This operation can be very slow, continue?".Translate(), "取消".Translate(), "确定".Translate(), UIMessageBox.WARNING, null,
|
||||
() => { DysonSphereFunctions.CreateIllegalDysonShellWithMaxOutput(); });
|
||||
});
|
||||
y += 36f;
|
||||
var btn2 = wnd.AddButton(x, y, 300f, tab4, "Keep max production shells and remove others", 16, "button-keep-max-production-shells", () => {
|
||||
var btn2 = wnd.AddButton(x, y, 300f, tab4, "Keep max production shells and remove others", 16, "button-keep-max-production-shells", () =>
|
||||
{
|
||||
UIMessageBox.Show("Keep max production shells and remove others".Translate(), "WARNING: This operation is DANGEROUS, continue?".Translate(), "取消".Translate(), "确定".Translate(), UIMessageBox.WARNING, null,
|
||||
() => { DysonSphereFunctions.KeepMaxProductionShells(); });
|
||||
});
|
||||
y += 36f;
|
||||
var btn3 = wnd.AddButton(x, y, 300f, tab4, "Duplicate shells from that with highest production", 16, "button-duplicate-shells-from-the-highest-production", () => {
|
||||
var btn3 = wnd.AddButton(x, y, 300f, tab4, "Duplicate shells from that with highest production", 16, "button-duplicate-shells-from-the-highest-production", () =>
|
||||
{
|
||||
UIMessageBox.Show("Duplicate shells from that with highest production".Translate(), "WARNING: This operation can be very slow, continue?".Translate(), "取消".Translate(), "确定".Translate(), UIMessageBox.WARNING, null,
|
||||
() => { DysonSphereFunctions.DuplicateShellsWithHighestProduction(); });
|
||||
});
|
||||
y += 30f;
|
||||
var slider1 = wnd.AddSlider(x + 20f, y, tab4, DysonSphereFunctions.ShellsCountForFunctions, new ShellsCountMapper());
|
||||
|
||||
y = originalY;
|
||||
var btn4 = wnd.AddButton(x, y, 300f, tab4, "Generate illegal dyson shell quickly", 16, "button-generate-illegal-dyson-shells-quickly", () =>
|
||||
{
|
||||
UIMessageBox.Show("Generate illegal dyson shell".Translate(), "WARNING: This operation can be very slow, continue?".Translate(), "取消".Translate(), "确定".Translate(), UIMessageBox.WARNING, null,
|
||||
() => { DysonSphereFunctions.CreateIllegalDysonShellQuickly(DysonSphereFunctions.ShellsCountForFunctions.Value); });
|
||||
});
|
||||
y += 30f;
|
||||
var txt2 = wnd.AddText2(x, y, tab4, "Shells count", 15, "text-shells-count");
|
||||
var slider2 = wnd.AddSlider(x + txt2.preferredWidth + 5f, y + 6f, tab4, DysonSphereFunctions.ShellsCountForFunctions, new ShellsCountMapper());
|
||||
|
||||
Functions.DysonSphereFunctions.IllegalDysonShellFunctionsEnabled.SettingChanged += onIllegalDysonShellFunctionsChanged;
|
||||
wnd.OnFree += () => { Functions.DysonSphereFunctions.IllegalDysonShellFunctionsEnabled.SettingChanged -= onIllegalDysonShellFunctionsChanged; };
|
||||
onIllegalDysonShellFunctionsChanged(null, null);
|
||||
@@ -327,6 +344,10 @@ public static class UIConfigWindow
|
||||
btn2.gameObject.SetActive(enabled);
|
||||
btn3.gameObject.SetActive(enabled);
|
||||
slider1.gameObject.SetActive(enabled);
|
||||
|
||||
btn4.gameObject.SetActive(!enabled);
|
||||
txt2.gameObject.SetActive(!enabled);
|
||||
slider2.gameObject.SetActive(!enabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
|
||||
+7
-7
@@ -1,8 +1,10 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UXAssist", "UXAssist\UXAssist.csproj", "{9C048229-6A50-4642-BC5E-02CD39D3869A}"
|
||||
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
|
||||
@@ -28,8 +30,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DustbinPreloader", "Dustbin
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoolOpt", "PoolOpt\PoolOpt.csproj", "{8BE61246-2C9D-4088-AA33-5AFF22C5046E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UXAssist", "UXAssist\UXAssist.csproj", "{9C048229-6A50-4642-BC5E-02CD39D3869A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserCloak", "UserCloak\UserCloak.csproj", "{096D2E4B-D1CE-424D-9954-C36A23E9E279}"
|
||||
EndProject
|
||||
Global
|
||||
@@ -38,6 +38,10 @@ Global
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{9C048229-6A50-4642-BC5E-02CD39D3869A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9C048229-6A50-4642-BC5E-02CD39D3869A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9C048229-6A50-4642-BC5E-02CD39D3869A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9C048229-6A50-4642-BC5E-02CD39D3869A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F9F16B62-D1D3-466B-BE22-E64B9EA957C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F9F16B62-D1D3-466B-BE22-E64B9EA957C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F9F16B62-D1D3-466B-BE22-E64B9EA957C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -82,10 +86,6 @@ Global
|
||||
{8BE61246-2C9D-4088-AA33-5AFF22C5046E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8BE61246-2C9D-4088-AA33-5AFF22C5046E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8BE61246-2C9D-4088-AA33-5AFF22C5046E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9C048229-6A50-4642-BC5E-02CD39D3869A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9C048229-6A50-4642-BC5E-02CD39D3869A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9C048229-6A50-4642-BC5E-02CD39D3869A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9C048229-6A50-4642-BC5E-02CD39D3869A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{096D2E4B-D1CE-424D-9954-C36A23E9E279}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{096D2E4B-D1CE-424D-9954-C36A23E9E279}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{096D2E4B-D1CE-424D-9954-C36A23E9E279}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
||||
@@ -52,7 +52,7 @@ public static class BeltSignal
|
||||
tex.LoadImage(fileData);
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
||||
private static Sprite LoadEmbeddedSprite(string path, Assembly assembly = null)
|
||||
{
|
||||
var tex = LoadEmbeddedTexture(path, assembly);
|
||||
|
||||
@@ -61,19 +61,19 @@ namespace Dustbin.NebulaSupport
|
||||
NebulaModAPI.MultiplayerSession.Network.SendPacket(new SyncPlanetData(Dustbin.ExportData(factory)));
|
||||
return;
|
||||
case < 0:
|
||||
{
|
||||
var tankPool = factory.factoryStorage.tankPool;
|
||||
tankPool[-storageId].IsDustbin = packet.Enable;
|
||||
TankPatch.Reset();
|
||||
return;
|
||||
}
|
||||
{
|
||||
var tankPool = factory.factoryStorage.tankPool;
|
||||
tankPool[-storageId].IsDustbin = packet.Enable;
|
||||
TankPatch.Reset();
|
||||
return;
|
||||
}
|
||||
case > 0:
|
||||
{
|
||||
var storagePool = factory.factoryStorage.storagePool;
|
||||
storagePool[storageId].IsDustbin = packet.Enable;
|
||||
StoragePatch.Reset();
|
||||
return;
|
||||
}
|
||||
{
|
||||
var storagePool = factory.factoryStorage.storagePool;
|
||||
storagePool[storageId].IsDustbin = packet.Enable;
|
||||
StoragePatch.Reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ public static class StoragePatch
|
||||
private static UI.MyCheckBox _storageDustbinCheckBox;
|
||||
private static int _lastStorageId;
|
||||
private static Harmony _patch;
|
||||
|
||||
|
||||
public static void Enable(bool on)
|
||||
{
|
||||
if (on)
|
||||
@@ -138,7 +138,7 @@ public static class StoragePatch
|
||||
_storageDustbinCheckBox.rectTrans.anchoredPosition3D = new Vector3(190, 57 - rectTrans.sizeDelta.y, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Adopt fix from starfi5h's NebulaCompatiblilityAssist */
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(UIStorageGrid), nameof(UIStorageGrid.OnStorageSizeChanged))]
|
||||
|
||||
@@ -11,7 +11,7 @@ public static class TankPatch
|
||||
private static UI.MyCheckBox _tankDustbinCheckBox;
|
||||
private static int _lastTankId;
|
||||
private static Harmony _patch;
|
||||
|
||||
|
||||
public static void Enable(bool on)
|
||||
{
|
||||
if (on)
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace DustbinPreloader;
|
||||
|
||||
public static class Preloader
|
||||
{
|
||||
private static readonly ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource("Dustbin Preloader");
|
||||
private static readonly ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource("Dustbin Preloader");
|
||||
public static IEnumerable<string> TargetDLLs { get; } = new[] { "Assembly-CSharp.dll" };
|
||||
|
||||
public static void Patch(AssemblyDefinition assembly)
|
||||
|
||||
@@ -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;
|
||||
|
||||
+67
-67
@@ -410,30 +410,30 @@ public static class LabOptPatchFunctions
|
||||
public static void SetFunctionInternal(ref LabComponent lab, bool researchMode, int recpId, int techId, SignData[] signPool, LabComponent[] labPool)
|
||||
{
|
||||
// LabOptPatch.Logger.LogDebug($"SetFunctionInternal: id={lab.id} root={(int)RootLabIdField.GetValue(lab)} research={researchMode} recp={recpId} tech={techId}");
|
||||
lab.replicating = false;
|
||||
lab.time = 0;
|
||||
lab.hashBytes = 0;
|
||||
lab.extraHashBytes = 0;
|
||||
lab.extraTime = 0;
|
||||
lab.extraSpeed = 0;
|
||||
lab.extraPowerRatio = 0;
|
||||
lab.productive = false;
|
||||
if (researchMode)
|
||||
{
|
||||
lab.forceAccMode = false;
|
||||
lab.researchMode = true;
|
||||
lab.recipeId = 0;
|
||||
lab.techId = 0;
|
||||
lab.timeSpend = 0;
|
||||
lab.extraTimeSpend = 0;
|
||||
lab.requires = null;
|
||||
lab.requireCounts = null;
|
||||
lab.served = null;
|
||||
lab.incServed = null;
|
||||
lab.products = null;
|
||||
lab.productCounts = null;
|
||||
lab.produced = null;
|
||||
lab.productive = true;
|
||||
lab.replicating = false;
|
||||
lab.time = 0;
|
||||
lab.hashBytes = 0;
|
||||
lab.extraHashBytes = 0;
|
||||
lab.extraTime = 0;
|
||||
lab.extraSpeed = 0;
|
||||
lab.extraPowerRatio = 0;
|
||||
lab.productive = false;
|
||||
if (researchMode)
|
||||
{
|
||||
lab.forceAccMode = false;
|
||||
lab.researchMode = true;
|
||||
lab.recipeId = 0;
|
||||
lab.techId = 0;
|
||||
lab.timeSpend = 0;
|
||||
lab.extraTimeSpend = 0;
|
||||
lab.requires = null;
|
||||
lab.requireCounts = null;
|
||||
lab.served = null;
|
||||
lab.incServed = null;
|
||||
lab.products = null;
|
||||
lab.productCounts = null;
|
||||
lab.produced = null;
|
||||
lab.productive = true;
|
||||
var rootLabId = lab.pcId;
|
||||
if (rootLabId > 0)
|
||||
{
|
||||
@@ -480,29 +480,29 @@ public static class LabOptPatchFunctions
|
||||
}
|
||||
}
|
||||
signPool[lab.entityId].iconId0 = (uint)lab.techId;
|
||||
signPool[lab.entityId].iconType = lab.techId == 0 ? 0U : 3U;
|
||||
return;
|
||||
}
|
||||
lab.researchMode = false;
|
||||
lab.recipeId = 0;
|
||||
lab.techId = 0;
|
||||
lab.matrixPoints = null;
|
||||
lab.matrixServed = null;
|
||||
lab.matrixIncServed = null;
|
||||
RecipeProto recipeProto = null;
|
||||
if (recpId > 0)
|
||||
{
|
||||
recipeProto = LDB.recipes.Select(recpId);
|
||||
}
|
||||
if (recipeProto != null && recipeProto.Type == ERecipeType.Research)
|
||||
{
|
||||
lab.recipeId = recipeProto.ID;
|
||||
lab.speed = 10000;
|
||||
lab.speedOverride = lab.speed;
|
||||
lab.timeSpend = recipeProto.TimeSpend * 10000;
|
||||
lab.extraTimeSpend = recipeProto.TimeSpend * 100000;
|
||||
lab.productive = recipeProto.productive;
|
||||
lab.forceAccMode &= lab.productive;
|
||||
signPool[lab.entityId].iconType = lab.techId == 0 ? 0U : 3U;
|
||||
return;
|
||||
}
|
||||
lab.researchMode = false;
|
||||
lab.recipeId = 0;
|
||||
lab.techId = 0;
|
||||
lab.matrixPoints = null;
|
||||
lab.matrixServed = null;
|
||||
lab.matrixIncServed = null;
|
||||
RecipeProto recipeProto = null;
|
||||
if (recpId > 0)
|
||||
{
|
||||
recipeProto = LDB.recipes.Select(recpId);
|
||||
}
|
||||
if (recipeProto != null && recipeProto.Type == ERecipeType.Research)
|
||||
{
|
||||
lab.recipeId = recipeProto.ID;
|
||||
lab.speed = 10000;
|
||||
lab.speedOverride = lab.speed;
|
||||
lab.timeSpend = recipeProto.TimeSpend * 10000;
|
||||
lab.extraTimeSpend = recipeProto.TimeSpend * 100000;
|
||||
lab.productive = recipeProto.productive;
|
||||
lab.forceAccMode &= lab.productive;
|
||||
var rootLabId = lab.pcId;
|
||||
if (rootLabId > 0)
|
||||
{
|
||||
@@ -544,26 +544,26 @@ public static class LabOptPatchFunctions
|
||||
Array.Clear(lab.produced, 0, lab.produced.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lab.forceAccMode = false;
|
||||
lab.recipeId = 0;
|
||||
lab.speed = 0;
|
||||
lab.speedOverride = 0;
|
||||
lab.timeSpend = 0;
|
||||
lab.extraTimeSpend = 0;
|
||||
lab.requires = null;
|
||||
lab.requireCounts = null;
|
||||
lab.served = null;
|
||||
lab.incServed = null;
|
||||
lab.needs = null;
|
||||
lab.products = null;
|
||||
lab.productCounts = null;
|
||||
lab.produced = null;
|
||||
}
|
||||
signPool[lab.entityId].iconId0 = (uint)lab.recipeId;
|
||||
signPool[lab.entityId].iconType = lab.recipeId == 0 ? 0U : 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
lab.forceAccMode = false;
|
||||
lab.recipeId = 0;
|
||||
lab.speed = 0;
|
||||
lab.speedOverride = 0;
|
||||
lab.timeSpend = 0;
|
||||
lab.extraTimeSpend = 0;
|
||||
lab.requires = null;
|
||||
lab.requireCounts = null;
|
||||
lab.served = null;
|
||||
lab.incServed = null;
|
||||
lab.needs = null;
|
||||
lab.products = null;
|
||||
lab.productCounts = null;
|
||||
lab.produced = null;
|
||||
}
|
||||
signPool[lab.entityId].iconId0 = (uint)lab.recipeId;
|
||||
signPool[lab.entityId].iconType = lab.recipeId == 0 ? 0U : 2U;
|
||||
}
|
||||
|
||||
public static int InsertIntoLab(PlanetFactory factory, int labId, int itemId, byte itemCount, byte itemInc, ref byte remainInc, int[] needs)
|
||||
{
|
||||
|
||||
+3
-3
@@ -18,7 +18,7 @@ public class LabOptPatch : BaseUnityPlugin
|
||||
{
|
||||
Harmony.CreateAndPatchAll(typeof(LabOptPatch));
|
||||
}
|
||||
|
||||
|
||||
// Patch LabComponent.Export() to save zero value if rootLabId > 0.
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(LabComponent), nameof(LabComponent.Export))]
|
||||
@@ -274,7 +274,7 @@ public class LabOptPatch : BaseUnityPlugin
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
|
||||
// Change locks on PlanetFactory.InsertInto(), by calling LabOptPatchFunctions.InsertIntoLab()
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(PlanetFactory), nameof(PlanetFactory.InsertInto))]
|
||||
@@ -332,7 +332,7 @@ public class LabOptPatch : BaseUnityPlugin
|
||||
{
|
||||
LabOptPatchFunctions.SetRootId(ref __instance, 0);
|
||||
}
|
||||
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(LabOptPatchFunctions), nameof(LabOptPatchFunctions.SetRootId))]
|
||||
[HarmonyPatch(typeof(LabOptPatchFunctions), nameof(LabOptPatchFunctions.SetRootLabIdForStacking))]
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace LabOptPreloader;
|
||||
|
||||
public static class Preloader
|
||||
{
|
||||
private static readonly ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource("LabOpt Preloader");
|
||||
private static readonly ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource("LabOpt Preloader");
|
||||
public static IEnumerable<string> TargetDLLs { get; } = new[] { "Assembly-CSharp.dll" };
|
||||
|
||||
public static void Patch(AssemblyDefinition assembly)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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,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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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则关闭燃料补充能量功能。
|
||||
@@ -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)
|
||||
|
||||
|
||||
+544
-500
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ using HarmonyLib;
|
||||
|
||||
namespace UXAssist.Common;
|
||||
|
||||
public class GameLogic: PatchImpl<GameLogic>
|
||||
public class GameLogic : PatchImpl<GameLogic>
|
||||
{
|
||||
public static Action OnDataLoaded;
|
||||
public static Action OnGameBegin;
|
||||
|
||||
@@ -122,14 +122,14 @@ public static class I18N
|
||||
_initialized = true;
|
||||
Apply();
|
||||
}
|
||||
|
||||
|
||||
[HarmonyPostfix, HarmonyPriority(Priority.Last), HarmonyPatch(typeof(Localization), nameof(Localization.LoadLanguage))]
|
||||
private static void Localization_LoadLanguage_Postfix(int index)
|
||||
{
|
||||
if (!_initialized) return;
|
||||
ApplyLanguage(index);
|
||||
}
|
||||
|
||||
|
||||
[HarmonyPostfix, HarmonyPriority(Priority.Last), HarmonyPatch(typeof(Localization), nameof(Localization.NotifyLanguageChange))]
|
||||
private static void Localization_NotifyLanguageChange_Postfix()
|
||||
{
|
||||
|
||||
@@ -36,13 +36,13 @@ public static class Util
|
||||
tex.LoadImage(fileData);
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
||||
public static Sprite LoadSprite(string path)
|
||||
{
|
||||
var tex = LoadTexture(path);
|
||||
return Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
|
||||
}
|
||||
|
||||
|
||||
public static Texture2D LoadEmbeddedTexture(string path, Assembly assembly = null)
|
||||
{
|
||||
var fileData = LoadEmbeddedResource(path, assembly);
|
||||
@@ -50,12 +50,12 @@ public static class Util
|
||||
tex.LoadImage(fileData);
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
||||
public static Sprite LoadEmbeddedSprite(string path, Assembly assembly = null)
|
||||
{
|
||||
var tex = LoadEmbeddedTexture(path, assembly);
|
||||
return Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
|
||||
}
|
||||
|
||||
|
||||
public static string PluginFolder(Assembly assembly = null) => Path.GetDirectoryName((assembly == null ? Assembly.GetCallingAssembly() : assembly).Location);
|
||||
}
|
||||
|
||||
+1
-129
@@ -127,13 +127,10 @@ public static class WinApi
|
||||
|
||||
[DllImport("user32", ExactSpelling = true)]
|
||||
public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool bRepaint);
|
||||
|
||||
|
||||
[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
|
||||
}
|
||||
@@ -13,7 +13,8 @@ public static class FactoryFunctions
|
||||
// Clear entity connection
|
||||
var factory = cargoTraffic.factory;
|
||||
factory.ReadObjectConn(belt.entityId, 0, out var isOutput, out var otherObjId, out var otherSlot);
|
||||
if (isOutput && factory.entityPool[otherObjId].beltId == belt.outputId) {
|
||||
if (isOutput && factory.entityPool[otherObjId].beltId == belt.outputId)
|
||||
{
|
||||
factory.ClearObjectConnDirect(belt.entityId, 0);
|
||||
factory.ClearObjectConnDirect(otherObjId, otherSlot);
|
||||
}
|
||||
@@ -194,7 +195,7 @@ public static class FactoryFunctions
|
||||
bpBuildings.Add(new BPBuildingData { building = building, itemType = itemType, offset = offset });
|
||||
}
|
||||
}
|
||||
var beltsWithInput = bpBelts.Select(pair => pair.Value.building.outputObj).ToHashSet();
|
||||
HashSet<BlueprintBuilding> beltsWithInput = [.. bpBelts.Select(pair => pair.Value.building.outputObj)];
|
||||
var beltHeads = bpBelts.Where(pair => !beltsWithInput.Contains(pair.Value.building)).ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||
// Sort belt buildings
|
||||
List<BlueprintBuilding> sortedBpBelts = [];
|
||||
|
||||
@@ -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();
|
||||
@@ -173,7 +173,8 @@ public static class PlanetFunctions
|
||||
{
|
||||
ref var warning = ref warningPool[i];
|
||||
if (warning.id != i) continue;
|
||||
switch (warning.factoryId) {
|
||||
switch (warning.factoryId)
|
||||
{
|
||||
case -4:
|
||||
if (warning.astroId == planetId)
|
||||
warningSystem.RemoveWarningData(i);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,11 +5,11 @@ using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using UnityEngine.UI;
|
||||
using UXAssist.Common;
|
||||
using GameLogic = UXAssist.Common.GameLogic;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace UXAssist.Patches;
|
||||
|
||||
public class DysonSpherePatch: PatchImpl<DysonSpherePatch>
|
||||
public class DysonSpherePatch : PatchImpl<DysonSpherePatch>
|
||||
{
|
||||
public static ConfigEntry<bool> StopEjectOnNodeCompleteEnabled;
|
||||
public static ConfigEntry<bool> OnlyConstructNodesEnabled;
|
||||
@@ -261,7 +261,7 @@ public class DysonSpherePatch: PatchImpl<DysonSpherePatch>
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
private class StopEjectOnNodeComplete: PatchImpl<StopEjectOnNodeComplete>
|
||||
private class StopEjectOnNodeComplete : PatchImpl<StopEjectOnNodeComplete>
|
||||
{
|
||||
private static HashSet<int>[] _nodeForAbsorb;
|
||||
private static bool _initialized;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -492,7 +492,7 @@ public class DysonSpherePatch: PatchImpl<DysonSpherePatch>
|
||||
}
|
||||
|
||||
[PatchSetCallbackFlag(PatchCallbackFlag.CallOnDisableAfterUnpatch)]
|
||||
private class OnlyConstructNodes: PatchImpl<OnlyConstructNodes>
|
||||
private class OnlyConstructNodes : PatchImpl<OnlyConstructNodes>
|
||||
{
|
||||
protected override void OnEnable()
|
||||
{
|
||||
|
||||
+109
-107
@@ -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;
|
||||
@@ -80,17 +78,13 @@ public class GamePatch : PatchImpl<GamePatch>
|
||||
I18N.Add("Logical frame rate: {0}x", "[UXA] Logical frame rate: {0}x", "[UXA] 逻辑帧速率: {0}x");
|
||||
|
||||
EnableWindowResizeEnabled.SettingChanged += (_, _) => EnableWindowResize.Enable(EnableWindowResizeEnabled.Value);
|
||||
LoadLastWindowRectEnabled.SettingChanged += (_, _) => {
|
||||
LoadLastWindowRectEnabled.SettingChanged += (_, _) =>
|
||||
{
|
||||
if (LoadLastWindowRectEnabled.Value)
|
||||
{
|
||||
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();
|
||||
@@ -122,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);
|
||||
@@ -135,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);
|
||||
}
|
||||
@@ -159,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;
|
||||
@@ -230,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;
|
||||
@@ -257,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;
|
||||
@@ -281,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;
|
||||
@@ -600,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);
|
||||
@@ -298,7 +298,8 @@ public static class LogisticsPatch
|
||||
new CodeMatch(OpCodes.Ldc_I4_1),
|
||||
new CodeMatch(OpCodes.Call, AccessTools.PropertyGetter(typeof(GameMain), nameof(GameMain.mainPlayer)))
|
||||
);
|
||||
if (matcher.IsValid) {
|
||||
if (matcher.IsValid)
|
||||
{
|
||||
matcher.RemoveInstructions(7).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldc_I4_0)
|
||||
);
|
||||
@@ -718,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;
|
||||
@@ -726,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;
|
||||
@@ -768,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)
|
||||
@@ -787,7 +796,9 @@ public static class LogisticsPatch
|
||||
|
||||
public static void OnGameBegin()
|
||||
{
|
||||
_lastPlanet = null;
|
||||
RecycleStationTips();
|
||||
_lastPlanetId = 0;
|
||||
_stationTipsRoot?.SetActive(false);
|
||||
}
|
||||
|
||||
public static void OnDataLoaded()
|
||||
@@ -841,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>();
|
||||
@@ -992,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()
|
||||
@@ -1011,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)
|
||||
@@ -1032,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)
|
||||
@@ -1055,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;
|
||||
@@ -1087,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;
|
||||
@@ -1134,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
|
||||
@@ -1164,7 +1192,6 @@ public static class LogisticsPatch
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class StationTip : MonoBehaviour
|
||||
{
|
||||
[FormerlySerializedAs("RectTransform")]
|
||||
@@ -1208,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,
|
||||
@@ -1391,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;
|
||||
@@ -1410,8 +1431,13 @@ public static class LogisticsPatch
|
||||
);
|
||||
_sliderCurrent[i].gameObject.SetActive(true);
|
||||
}
|
||||
barPositionChanged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (itemCount > itemLimit) itemCount = itemLimit;
|
||||
}
|
||||
|
||||
if (barEnabled)
|
||||
{
|
||||
@@ -1419,6 +1445,10 @@ public static class LogisticsPatch
|
||||
if (storageState.ItemOrdered != itemOrdered)
|
||||
{
|
||||
storageState.ItemOrdered = itemOrdered;
|
||||
barPositionChanged = true;
|
||||
}
|
||||
if (barPositionChanged)
|
||||
{
|
||||
switch (itemOrdered)
|
||||
{
|
||||
case > 0:
|
||||
@@ -1433,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;
|
||||
@@ -1458,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))]
|
||||
|
||||
@@ -24,7 +24,7 @@ public static class PlanetPatch
|
||||
PlayerActionsInGlobeView.Enable(false);
|
||||
}
|
||||
|
||||
public class PlayerActionsInGlobeView: PatchImpl<PlayerActionsInGlobeView>
|
||||
public class PlayerActionsInGlobeView : PatchImpl<PlayerActionsInGlobeView>
|
||||
{
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(VFInput), nameof(VFInput.UpdateGameStates))]
|
||||
@@ -48,7 +48,7 @@ public static class PlanetPatch
|
||||
});
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(PlayerController), nameof(PlayerController.GetInput))]
|
||||
private static IEnumerable<CodeInstruction> PlayerController_GetInput_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -287,7 +287,7 @@ public static class TechPatch
|
||||
}
|
||||
}
|
||||
|
||||
private class BatchBuyoutTech: PatchImpl<BatchBuyoutTech>
|
||||
private class BatchBuyoutTech : PatchImpl<BatchBuyoutTech>
|
||||
{
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(UITechNode), nameof(UITechNode.UpdateInfoDynamic))]
|
||||
|
||||
+318
-2
@@ -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 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
|
||||
|
||||
+18
-18
@@ -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>
|
||||
|
||||
@@ -17,12 +17,12 @@ public class MyCheckButton : MonoBehaviour
|
||||
|
||||
private static GameObject _baseObject;
|
||||
|
||||
private static Color openMouseOverColor;
|
||||
private static Color openPressColor;
|
||||
private static Color openNormalColor;
|
||||
private static Color closeMouseOverColor;
|
||||
private static Color closePressColor;
|
||||
private static Color closeNormalColor;
|
||||
private static Color openMouseOverColor;
|
||||
private static Color openPressColor;
|
||||
private static Color openNormalColor;
|
||||
private static Color closeMouseOverColor;
|
||||
private static Color closePressColor;
|
||||
private static Color closeNormalColor;
|
||||
|
||||
public static void InitBaseObject()
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ public class MyFlatButton : MonoBehaviour
|
||||
var panel = UIRoot.instance.uiGame.dysonEditor.controlPanel.hierarchy.layerPanel;
|
||||
var go = Instantiate(panel.layerButtons[0].gameObject);
|
||||
var btn = go.GetComponent<UIButton>();
|
||||
go.GetComponent<Image>().sprite = panel.buttonDefaultSprite;
|
||||
btn.gameObject.name = "my-flatbutton";
|
||||
btn.highlighted = false;
|
||||
var img = btn.GetComponent<Image>();
|
||||
|
||||
@@ -228,7 +228,7 @@ public class MyWindow : ManualBehaviour
|
||||
return comboBox;
|
||||
}
|
||||
|
||||
#region Slider
|
||||
#region Slider
|
||||
public class ValueMapper<T>
|
||||
{
|
||||
public virtual int Min => 1;
|
||||
@@ -402,7 +402,7 @@ public class MyWindow : ManualBehaviour
|
||||
{
|
||||
return AddSideSlider(x, y, parent, config, new ArrayMapper<T>(valueList), format, width);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
public InputField AddInputField(float x, float y, RectTransform parent, string text = "", int fontSize = 16, string objName = "input", UnityAction<string> onChanged = null,
|
||||
UnityAction<string> onEditEnd = null)
|
||||
@@ -475,8 +475,11 @@ public class MyWindowWithTabs : MyWindow
|
||||
var swarmPanel = UIRoot.instance.uiGame.dysonEditor.controlPanel.hierarchy.swarmPanel;
|
||||
var src = swarmPanel.orbitButtons[0];
|
||||
var btn = Instantiate(src);
|
||||
var btnRect = Util.NormalizeRectWithTopLeft(btn, Margin, y, parent);
|
||||
btn.gameObject.GetComponent<Image>().sprite = swarmPanel.buttonDefaultSprite;
|
||||
btn.name = "tab-btn-" + index;
|
||||
btn.highlighted = false;
|
||||
|
||||
var btnRect = Util.NormalizeRectWithTopLeft(btn, Margin, y, parent);
|
||||
btnRect.sizeDelta = new Vector2(TabWidth, TabHeight);
|
||||
btn.transform.Find("frame").gameObject.SetActive(false);
|
||||
if (btn.transitions.Length >= 3)
|
||||
@@ -590,7 +593,7 @@ public abstract class MyWindowManager
|
||||
}
|
||||
*/
|
||||
|
||||
public class Patch: PatchImpl<Patch>
|
||||
public class Patch : PatchImpl<Patch>
|
||||
{
|
||||
protected override void OnEnable()
|
||||
{
|
||||
@@ -610,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()
|
||||
{
|
||||
}
|
||||
@@ -635,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");
|
||||
|
||||
+13
-16
@@ -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
|
||||
* (再次)修复新建游戏或加载存档时宇宙设置没有应用的问题
|
||||
* 进入宇宙创建界面时重置星系间距/扁平度设置
|
||||
|
||||
@@ -75,7 +75,7 @@ public static class EpicDifficulty
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public static int OilMultipliersCount()
|
||||
{
|
||||
return OilMultipliers.Length;
|
||||
@@ -111,7 +111,7 @@ public static class EpicDifficulty
|
||||
__instance.UpdateParametersUIDisplay();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(UIGalaxySelect), nameof(UIGalaxySelect.UpdateParametersUIDisplay))]
|
||||
private static bool UIGalaxySelect_UpdateParametersUIDisplay_Prefix(UIGalaxySelect __instance)
|
||||
@@ -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]
|
||||
|
||||
@@ -19,15 +19,15 @@ public class UniverseGenTweaks : BaseUnityPlugin, IModCanSave
|
||||
MoreSettings.Enabled = Config.Bind("MoreSettings", "Enabled", true, "Enable more settings on Universe Generation");
|
||||
MoreSettings.MaxStarCount = Config.Bind("MoreSettings", "MaxStarCount", 128,
|
||||
new ConfigDescription("(32 ~ 1024)\nMaximum star count for Universe Generation, enable MoreSettings.Enabled to take effect",
|
||||
new AcceptableValueRange<int>(32, 1024), new {}));
|
||||
new AcceptableValueRange<int>(32, 1024), new { }));
|
||||
|
||||
EpicDifficulty.Enabled = Config.Bind("EpicDifficulty", "Enabled", true, "Enable Epic difficulty");
|
||||
EpicDifficulty.ResourceMultiplier = Config.Bind("EpicDifficulty", "ResourceMultiplier", 0.01f,
|
||||
new ConfigDescription("Resource multiplier for Epic difficulty",
|
||||
new AcceptableValueRange<float>(0.0001f, 0.05f), new {}));
|
||||
new AcceptableValueRange<float>(0.0001f, 0.05f), new { }));
|
||||
EpicDifficulty.OilMultiplier = Config.Bind("EpicDifficulty", "OilMultiplier", 0.5f,
|
||||
new ConfigDescription("Oil multiplier for Epic difficulty relative to the Very-Hard difficulty",
|
||||
new AcceptableValueRange<float>(0.1f, 1f), new {}));
|
||||
new AcceptableValueRange<float>(0.1f, 1f), new { }));
|
||||
|
||||
BirthPlanetPatch.SitiVeinsOnBirthPlanet = Config.Bind("Birth", "SiTiVeinsOnBirthPlanet", false,
|
||||
"Silicon/Titanium on birth planet");
|
||||
|
||||
@@ -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": [
|
||||
|
||||
@@ -8,7 +8,7 @@ using Random = UnityEngine.Random;
|
||||
namespace UserCloak;
|
||||
|
||||
[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)]
|
||||
public class UserCloak: BaseUnityPlugin
|
||||
public class UserCloak : BaseUnityPlugin
|
||||
{
|
||||
private static Harmony _patch;
|
||||
private static ConfigEntry<int> _mode;
|
||||
|
||||
Reference in New Issue
Block a user