mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2026-02-04 19:42:17 +08:00
Compare commits
7 Commits
6eb9161af1
...
logistic_h
| Author | SHA1 | Date | |
|---|---|---|---|
| 09cdaf3a12 | |||
| 8d5bb140e1 | |||
| c99c59a117 | |||
| 61811f9a8c | |||
| cf3117e0da | |||
| dfd34601cf | |||
| 6934607fca |
@@ -20,6 +20,10 @@
|
||||
<!-- <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>
|
||||
@@ -29,16 +33,11 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\UXAssist\UXAssist.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<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 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>
|
||||
|
||||
@@ -78,7 +78,6 @@ public static class DysonSphereFunctions
|
||||
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("This will remove all frames on \"{0}\". Are you sure?", "This will remove all frames on \"{0}\". Are you sure?", "这将移除“{0}”上的所有框架。你确定吗?");
|
||||
I18N.Add("No precalculated shell found for radius {0}.", "No precalculated shell found for radius {0}.", "没有找到适合半径 {0} 的预计算壳面");
|
||||
}
|
||||
|
||||
@@ -220,70 +219,6 @@ public static class DysonSphereFunctions
|
||||
});
|
||||
}
|
||||
|
||||
public static void RemoveAllFrames()
|
||||
{
|
||||
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 || dysonSphere.layerCount == 0)
|
||||
{
|
||||
UIMessageBox.Show("CheatEnabler".Translate(), string.Format("There is no Dyson Sphere shell on \"{0}\".".Translate(), star.displayName), "确定".Translate(), UIMessageBox.ERROR, null);
|
||||
return;
|
||||
}
|
||||
|
||||
UIMessageBox.Show("CheatEnabler".Translate(), string.Format("This will remove all frames on \"{0}\". Are you sure?".Translate(), star.displayName), "取消".Translate(), "确定".Translate(), UIMessageBox.QUESTION, null, () =>
|
||||
{
|
||||
var totalFrameSpInfo = AccessTools.Field(typeof(DysonSphereLayer), "totalFrameSP");
|
||||
|
||||
foreach (var dysonSphereLayer in dysonSphere.layersIdBased)
|
||||
{
|
||||
if (dysonSphereLayer == null) continue;
|
||||
for (var i = dysonSphereLayer.nodeCursor - 1; i >= 0; i--)
|
||||
{
|
||||
var dysonNode = dysonSphereLayer.nodePool[i];
|
||||
if (dysonNode == null || dysonNode.id != i) continue;
|
||||
if (dysonNode.frames.Count > 0)
|
||||
dysonNode.frames.Clear();
|
||||
dysonNode.RecalcSpReq();
|
||||
}
|
||||
for (var i = dysonSphereLayer.shellCursor - 1; i >= 0; i--)
|
||||
{
|
||||
var dysonShell = dysonSphereLayer.shellPool[i];
|
||||
if (dysonShell == null || dysonShell.id != i) continue;
|
||||
if (dysonShell.frames.Count > 0)
|
||||
dysonShell.frames.Clear();
|
||||
}
|
||||
for (var i = dysonSphereLayer.frameCursor - 1; i >= 0; i--)
|
||||
{
|
||||
var dysonFrame = dysonSphereLayer.framePool[i];
|
||||
if (dysonFrame == null || dysonFrame.id != i) continue;
|
||||
dysonFrame.Free();
|
||||
dysonSphereLayer.framePool[i] = null;
|
||||
}
|
||||
dysonSphereLayer.frameCursor = 1;
|
||||
dysonSphereLayer.frameRecycleCursor = 0;
|
||||
dysonSphereLayer.SetFrameCapacity(64);
|
||||
totalFrameSpInfo?.SetValue(dysonSphereLayer, 0);
|
||||
}
|
||||
dysonSphere.CheckAutoNodes();
|
||||
dysonSphere.PickAutoNode();
|
||||
dysonSphere.modelRenderer.RebuildModels();
|
||||
});
|
||||
}
|
||||
|
||||
private static DysonNode QuickAddDysonNode(this DysonSphereLayer layer, int protoId, Vector3 pos)
|
||||
{
|
||||
int nodeId;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace CheatEnabler.Functions;
|
||||
|
||||
public static class PlanetFunctions
|
||||
{
|
||||
public static void BuryAllVeins(bool bury)
|
||||
|
||||
@@ -134,12 +134,12 @@ public class DysonSpherePatch : PatchImpl<DysonSpherePatch>
|
||||
{
|
||||
UpdateSailLifeTime();
|
||||
UpdateSailsCacheForThisGame();
|
||||
GameLogicProc.OnGameBegin += OnGameBegin;
|
||||
GameLogicProc.OnGameBegin += GameMain_Begin_Postfix;
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin;
|
||||
GameLogicProc.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
}
|
||||
|
||||
private static void UpdateSailLifeTime()
|
||||
@@ -172,7 +172,7 @@ public class DysonSpherePatch : PatchImpl<DysonSpherePatch>
|
||||
_sailsCacheCapacity[index] = capacity;
|
||||
}
|
||||
|
||||
private static void OnGameBegin()
|
||||
private static void GameMain_Begin_Postfix()
|
||||
{
|
||||
UpdateSailsCacheForThisGame();
|
||||
UpdateSailLifeTime();
|
||||
|
||||
@@ -94,14 +94,14 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
ControlPanelRemoteLogistics.Enable(ControlPanelRemoteLogisticsEnabled.Value);
|
||||
Enable(true);
|
||||
CargoTrafficPatch.Enable(true);
|
||||
GameLogicProc.OnGameBegin += OnGameBegin_For_ImmBuild;
|
||||
GameLogicProc.OnGameBegin += GameMain_Begin_Postfix_For_ImmBuild;
|
||||
GameLogicProc.OnDataLoaded += OnDataLoaded;
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
{
|
||||
GameLogicProc.OnDataLoaded -= OnDataLoaded;
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin_For_ImmBuild;
|
||||
GameLogicProc.OnGameBegin -= GameMain_Begin_Postfix_For_ImmBuild;
|
||||
CargoTrafficPatch.Enable(false);
|
||||
Enable(false);
|
||||
ImmediateBuild.Enable(false);
|
||||
@@ -292,7 +292,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnGameBegin_For_ImmBuild()
|
||||
private static void GameMain_Begin_Postfix_For_ImmBuild()
|
||||
{
|
||||
if (DSPGame.IsMenuDemo) return;
|
||||
var factory = GameMain.mainPlayer?.factory;
|
||||
@@ -629,12 +629,12 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
protected override void OnEnable()
|
||||
{
|
||||
InitSignalBelts();
|
||||
GameLogicProc.OnGameBegin += OnGameBegin;
|
||||
GameLogicProc.OnGameBegin += GameMain_Begin_Postfix;
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin;
|
||||
GameLogicProc.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
_initialized = false;
|
||||
_signalBelts = null;
|
||||
_signalBeltsCapacity = 0;
|
||||
@@ -675,12 +675,11 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
|
||||
private static void InitSignalBelts()
|
||||
{
|
||||
if (DSPGame.IsMenuDemo) return;
|
||||
InitItemSources();
|
||||
if (!GameMain.isRunning) return;
|
||||
_signalBelts = new Dictionary<int, BeltSignal>[64];
|
||||
_signalBeltsCapacity = 64;
|
||||
_portalFrom = [];
|
||||
_portalTo = [];
|
||||
_portalFrom = new Dictionary<long, int>();
|
||||
_portalTo = new Dictionary<int, HashSet<long>>();
|
||||
|
||||
var factories = GameMain.data?.factories;
|
||||
if (factories == null) return;
|
||||
@@ -736,7 +735,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
if (obj != null) return obj;
|
||||
}
|
||||
|
||||
obj = [];
|
||||
obj = new Dictionary<int, BeltSignal>();
|
||||
_signalBelts[index] = obj;
|
||||
return obj;
|
||||
}
|
||||
@@ -866,10 +865,11 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
set.Remove(v);
|
||||
}
|
||||
|
||||
private static void OnGameBegin()
|
||||
private static void GameMain_Begin_Postfix()
|
||||
{
|
||||
if (DSPGame.IsMenuDemo) return;
|
||||
if (BeltSignalGeneratorEnabled.Value) InitSignalBelts();
|
||||
InitItemSources();
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
@@ -1171,7 +1171,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 = [] };
|
||||
var rs = new ItemSource { Count = rescnt[i], From = new Dictionary<int, float>() };
|
||||
var it = recipe.Items;
|
||||
var itcnt = recipe.ItemCounts;
|
||||
var len2 = it.Length;
|
||||
@@ -1182,7 +1182,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
|
||||
if (len > 1)
|
||||
{
|
||||
rs.Extra = [];
|
||||
rs.Extra = new Dictionary<int, float>();
|
||||
for (var k = 0; k < len; k++)
|
||||
{
|
||||
if (i != k)
|
||||
@@ -1258,38 +1258,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
if (itemSource.From == null) return;
|
||||
foreach (var p in itemSource.From)
|
||||
{
|
||||
var value = p.Value * times;
|
||||
if (extra.TryGetValue(p.Key, out var rcount))
|
||||
{
|
||||
if (value <= rcount)
|
||||
{
|
||||
if (value == rcount)
|
||||
{
|
||||
extra.Remove(p.Key);
|
||||
}
|
||||
else
|
||||
{
|
||||
extra[p.Key] = rcount - value;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
extra.Remove(p.Key);
|
||||
value -= rcount;
|
||||
}
|
||||
if (result.TryGetValue(p.Key, out rcount))
|
||||
{
|
||||
rcount -= value;
|
||||
if (rcount <= 0)
|
||||
{
|
||||
result.Remove(p.Key);
|
||||
}
|
||||
else
|
||||
{
|
||||
result[p.Key] = rcount;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
CalculateAllProductions(result, extra, p.Key, value);
|
||||
CalculateAllProductions(result, extra, p.Key, times * p.Value);
|
||||
}
|
||||
}
|
||||
/* END: Item sources calculation */
|
||||
|
||||
@@ -48,7 +48,7 @@ public static class GamePatch
|
||||
p.Value.OnUnregEvent();
|
||||
}
|
||||
|
||||
abnormalLogic.determinators = [];
|
||||
abnormalLogic.determinators = new Dictionary<int, AbnormalityDeterminator>();
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
@@ -81,7 +81,7 @@ public static class GamePatch
|
||||
{
|
||||
_savedDeterminators = __instance.determinators;
|
||||
if (!AbnormalDisablerEnabled.Value) return;
|
||||
__instance.determinators = [];
|
||||
__instance.determinators = new Dictionary<int, AbnormalityDeterminator>();
|
||||
foreach (var p in _savedDeterminators)
|
||||
{
|
||||
p.Value.OnUnregEvent();
|
||||
@@ -140,7 +140,7 @@ public static class GamePatch
|
||||
var pos = matcher.Pos;
|
||||
/* Remove Shift+F4 part of the method */
|
||||
matcher.Start().RemoveInstructions(pos).MatchForward(false,
|
||||
new CodeMatch(OpCodes.Call, AccessTools.PropertyGetter(typeof(GameMain), nameof(GameMain.sandboxToolsEnabled))),
|
||||
new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(GameMain), "get_sandboxToolsEnabled")),
|
||||
new CodeMatch(OpCodes.Ldc_I4_0),
|
||||
new CodeMatch(OpCodes.Ceq)
|
||||
);
|
||||
@@ -297,7 +297,7 @@ public static class GamePatch
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldarg_0),
|
||||
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UITechNode), nameof(UITechNode.tree))),
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(UITechTree), nameof(UITechTree.selected)))
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(UITechTree), "get_selected"))
|
||||
);
|
||||
var labels = matcher.Labels;
|
||||
matcher.Labels = null;
|
||||
|
||||
@@ -6,7 +6,6 @@ using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
|
||||
namespace CheatEnabler.Patches;
|
||||
|
||||
public static class PlanetPatch
|
||||
{
|
||||
public static ConfigEntry<bool> WaterPumpAnywhereEnabled;
|
||||
@@ -54,92 +53,6 @@ public static class PlanetPatch
|
||||
|
||||
private class TerraformAnyway : PatchImpl<TerraformAnyway>
|
||||
{
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(BuildTool_BlueprintPaste), nameof(BuildTool_BlueprintPaste.DetermineReforms))]
|
||||
private static IEnumerable<CodeInstruction> BuildTool_BlueprintPaste_DetermineReforms_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldarg_0),
|
||||
new CodeMatch(OpCodes.Call, AccessTools.PropertyGetter(typeof(BuildTool), nameof(BuildTool.player))),
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Player), nameof(Player.sandCount))),
|
||||
new CodeMatch(ci => ci.IsStloc())
|
||||
).Advance(4).MatchForward(false,
|
||||
new CodeMatch(ci => ci.IsLdloc()),
|
||||
new CodeMatch(ci => ci.IsLdloc()),
|
||||
new CodeMatch(OpCodes.Conv_I8),
|
||||
new CodeMatch(ci => ci.opcode == OpCodes.Bge || ci.opcode == OpCodes.Bge_S)
|
||||
);
|
||||
var labels = matcher.Labels;
|
||||
matcher.Labels = null;
|
||||
matcher.RemoveInstructions(3);
|
||||
matcher.Labels.AddRange(labels);
|
||||
matcher.Opcode = OpCodes.Br;
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(BuildTool_Reform), nameof(BuildTool_Reform.RemoveBasePit))]
|
||||
private static IEnumerable<CodeInstruction> BuildTool_Reform_RemoveBasePit_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldarg_0),
|
||||
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(BuildTool_Reform), nameof(BuildTool_Reform.circlePointCount))),
|
||||
new CodeMatch(ci => ci.opcode == OpCodes.Blt || ci.opcode == OpCodes.Blt_S)
|
||||
).RemoveInstructions(2).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldc_I4_0)
|
||||
).MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldarg_0),
|
||||
new CodeMatch(OpCodes.Call, AccessTools.PropertyGetter(typeof(BuildTool), nameof(BuildTool.player))),
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Player), nameof(Player.sandCount))),
|
||||
new CodeMatch(ci => ci.IsLdloc()),
|
||||
new CodeMatch(OpCodes.Conv_I8),
|
||||
new CodeMatch(OpCodes.Sub)
|
||||
).Advance(6).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldc_I8, 0L),
|
||||
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Math), nameof(Math.Max), [typeof(long), typeof(long)]))
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(UIRemoveBasePitButton), nameof(UIRemoveBasePitButton.OnRemoveButtonClick))]
|
||||
[HarmonyPatch(typeof(UIRemoveBasePitButton), nameof(UIRemoveBasePitButton._OnUpdate))]
|
||||
private static IEnumerable<CodeInstruction> UIRemoveBasePitButton_OnRemoveButtonClick_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldarg_0),
|
||||
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIRemoveBasePitButton), nameof(UIRemoveBasePitButton.pointCount))),
|
||||
new CodeMatch(OpCodes.Sub),
|
||||
new CodeMatch(OpCodes.Ldc_I4_0),
|
||||
new CodeMatch(OpCodes.Clt)
|
||||
);
|
||||
if (matcher.IsValid)
|
||||
{
|
||||
matcher.RemoveInstructions(2).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldc_I4_0)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
matcher.Start();
|
||||
}
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldarg_0),
|
||||
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIRemoveBasePitButton), nameof(UIRemoveBasePitButton.player))),
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Player), nameof(Player.sandCount))),
|
||||
new CodeMatch(ci => ci.IsLdloc()),
|
||||
new CodeMatch(OpCodes.Conv_I8),
|
||||
new CodeMatch(OpCodes.Sub)
|
||||
).Advance(6).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldc_I8, 0L),
|
||||
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Math), nameof(Math.Max), [typeof(long), typeof(long)]))
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(BuildTool_Reform), nameof(BuildTool_Reform.ReformAction))]
|
||||
private static IEnumerable<CodeInstruction> BuildTool_Reform_ReformAction_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
@@ -152,13 +65,13 @@ public static class PlanetPatch
|
||||
).RemoveInstructions(2).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldc_I4_0)
|
||||
).MatchForward(false,
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Player), nameof(Player.sandCount)))
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(Player), "get_sandCount"))
|
||||
).Advance(1).MatchForward(false,
|
||||
new CodeMatch(OpCodes.Conv_I8),
|
||||
new CodeMatch(OpCodes.Sub)
|
||||
new CodeMatch(OpCodes.Conv_I8),
|
||||
new CodeMatch(OpCodes.Sub)
|
||||
).Advance(2).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldc_I8, 0L),
|
||||
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Math), nameof(Math.Max), [typeof(long), typeof(long)]))
|
||||
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Math), "Max", [typeof(long), typeof(long)]))
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
@@ -68,8 +68,7 @@ public static class UIConfigWindow
|
||||
I18N.Add("Overclock Silos", "Overclock Silos (10x)", "高速发射井(10倍射速)");
|
||||
I18N.Add("Unlock Dyson Sphere max orbit radius", "Unlock Dyson Sphere max orbit radius", "解锁戴森球最大轨道半径");
|
||||
I18N.Add("Complete Dyson Sphere shells instantly", "Complete Dyson Sphere shells instantly", "立即完成戴森壳建造");
|
||||
I18N.Add("Remove all frames on Dyson Sphere", "Remove all frames on Dyson Sphere", "移除戴森球上的所有框架");
|
||||
I18N.Add("Generate illegal dyson shell", "Generate an illegal dyson shell (!!1st shell layer will be replaced!!)", "生成单层仙术戴森壳(!!会先删除第一层戴森壳!!)");
|
||||
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", "快速生成仙术戴森壳");
|
||||
@@ -302,8 +301,6 @@ public static class UIConfigWindow
|
||||
x = 300f;
|
||||
y = 10f;
|
||||
wnd.AddButton(x, y, 300f, tab4, "Complete Dyson Sphere shells instantly", 16, "button-complete-dyson-sphere-shells-instantly", DysonSphereFunctions.CompleteShellsInstantly);
|
||||
y += 36f;
|
||||
wnd.AddButton(x, y, 300f, tab4, "Remove all frames on Dyson Sphere", 16, "button-remove-all-frames-on-dyson-sphere", DysonSphereFunctions.RemoveAllFrames);
|
||||
{
|
||||
y += 72f;
|
||||
var originalY = y;
|
||||
@@ -330,7 +327,7 @@ public static class UIConfigWindow
|
||||
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 quickly".Translate(), "WARNING: This operation can be very slow, continue?".Translate(), "取消".Translate(), "确定".Translate(), UIMessageBox.WARNING, null,
|
||||
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;
|
||||
|
||||
23
DSP_Mods.sln
23
DSP_Mods.sln
@@ -4,7 +4,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UXAssist", "UXAssist\UXAssi
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CheatEnabler", "CheatEnabler\CheatEnabler.csproj", "{F9F16B62-D1D3-466B-BE22-E64B9EA957C2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogisticMiner", "LogisticMiner\LogisticMiner.csproj", "{7149D717-C913-4153-9425-38CB9D087F83}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogisticHub", "LogisticHub\LogisticHub.csproj", "{7149D717-C913-4153-9425-38CB9D087F83}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HideTips", "HideTips\HideTips.csproj", "{4EABD71D-477F-448B-801B-48F8745A3FA7}"
|
||||
EndProject
|
||||
@@ -19,14 +19,19 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OverclockEverything", "Over
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MechaDronesTweaks", "MechaDronesTweaks\MechaDronesTweaks.csproj", "{15B8BC2E-93E0-4454-8F8F-BF1FA8DC90F4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LabOpt", "LabOpt\LabOpt.csproj", "{DD76B77C-68D8-4A4C-B98E-CBEECEDC49FB}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{F2D5EBE8-7D9D-4572-9A3E-4DD1114FD99F} = {F2D5EBE8-7D9D-4572-9A3E-4DD1114FD99F}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LabOptPreloader", "LabOptPreloader\LabOptPreloader.csproj", "{F2D5EBE8-7D9D-4572-9A3E-4DD1114FD99F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DustbinPreloader", "DustbinPreloader\DustbinPreloader.csproj", "{B8EB3D8D-5613-42F0-9040-EAA11A38C6AC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoolOpt", "PoolOpt\PoolOpt.csproj", "{8BE61246-2C9D-4088-AA33-5AFF22C5046E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserCloak", "UserCloak\UserCloak.csproj", "{096D2E4B-D1CE-424D-9954-C36A23E9E279}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuaScriptEngine", "LuaScriptEngine\LuaScriptEngine.csproj", "{E9375F0E-26DC-4CEC-80DC-9C48F23340BC}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -65,6 +70,14 @@ Global
|
||||
{15B8BC2E-93E0-4454-8F8F-BF1FA8DC90F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{15B8BC2E-93E0-4454-8F8F-BF1FA8DC90F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{15B8BC2E-93E0-4454-8F8F-BF1FA8DC90F4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DD76B77C-68D8-4A4C-B98E-CBEECEDC49FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DD76B77C-68D8-4A4C-B98E-CBEECEDC49FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DD76B77C-68D8-4A4C-B98E-CBEECEDC49FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DD76B77C-68D8-4A4C-B98E-CBEECEDC49FB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F2D5EBE8-7D9D-4572-9A3E-4DD1114FD99F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F2D5EBE8-7D9D-4572-9A3E-4DD1114FD99F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F2D5EBE8-7D9D-4572-9A3E-4DD1114FD99F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F2D5EBE8-7D9D-4572-9A3E-4DD1114FD99F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B8EB3D8D-5613-42F0-9040-EAA11A38C6AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B8EB3D8D-5613-42F0-9040-EAA11A38C6AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B8EB3D8D-5613-42F0-9040-EAA11A38C6AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -77,9 +90,5 @@ Global
|
||||
{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
|
||||
{096D2E4B-D1CE-424D-9954-C36A23E9E279}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E9375F0E-26DC-4CEC-80DC-9C48F23340BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E9375F0E-26DC-4CEC-80DC-9C48F23340BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E9375F0E-26DC-4CEC-80DC-9C48F23340BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E9375F0E-26DC-4CEC-80DC-9C48F23340BC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -16,21 +16,11 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BepInEx.Core" Version="5.*" />
|
||||
<PackageReference Include="BepInEx.PluginInfoProps" Version="1.*" />
|
||||
<!-- <PackageReference Include="DysonSphereProgram.GameLibs" Version="0.10.32.*-r.*" /> -->
|
||||
<PackageReference Include="DysonSphereProgram.GameLibs" Version="0.10.32.*-r.*" />
|
||||
<PackageReference Include="DysonSphereProgram.Modding.DSPModSave" Version="1.*" />
|
||||
<PackageReference Include="DysonSphereProgram.Modding.NebulaMultiplayerModApi" Version="2.0.0" />
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2022.3.53" IncludeAssets="compile" />
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2018.4.12" IncludeAssets="compile" />
|
||||
</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>
|
||||
<EmbeddedResource Include="assets/icon/signal-410.png" />
|
||||
</ItemGroup>
|
||||
@@ -39,8 +29,13 @@
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>GameAssembly\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Exec Command="del /F /Q package\$(ProjectName)-$(Version).zip
|
||||
IF NOT EXIST package\plugins (mkdir package\plugins)
copy /y $(TargetPath) package\plugins\
cd package
powershell Compress-Archive -Force -DestinationPath '$(ProjectName)-$(Version).zip' -Path patchers, plugins, icon.png, manifest.json, ../README.md, ../CHANGELOG.md" />
|
||||
<Exec Command="del /F /Q package\$(ProjectName)-$(Version).zip
IF NOT EXIST package\plugins (mkdir package\plugins)
copy /y $(TargetPath) package\plugins\
cd package
powershell Compress-Archive -Force -DestinationPath '$(ProjectName)-$(Version).zip' -Path patchers, plugins, icon.png, manifest.json, ../README.md, ../CHANGELOG.md" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -14,17 +14,8 @@
|
||||
<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="2022.3.53" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\AssemblyFromGame\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>..\AssemblyFromGame\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<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'">
|
||||
|
||||
@@ -15,17 +15,8 @@
|
||||
<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="2022.3.53" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\AssemblyFromGame\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>..\AssemblyFromGame\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<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'">
|
||||
@@ -33,6 +24,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Exec Command="powershell Compress-Archive -Force -DestinationPath 'package/$(ProjectName)-$(Version).zip' -Path '$(TargetPath)', package/icon.png, package/manifest.json, README.md" />
|
||||
<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" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -15,17 +15,8 @@
|
||||
<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="2022.3.53" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\AssemblyFromGame\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>..\AssemblyFromGame\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<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'">
|
||||
@@ -33,6 +24,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Exec Command="IF NOT EXIST package\plugins (mkdir package\plugins)
copy /y $(TargetPath) package\plugins\
cd package
powershell Compress-Archive -Force -DestinationPath '$(ProjectName)-$(Version).zip' -Path patchers, plugins, icon.png, manifest.json, ../README.md" />
|
||||
<Exec Command="del /F /Q package\$(ProjectName)-$(Version).zip
IF NOT EXIST package\plugins (mkdir package\plugins)
copy /y $(TargetPath) package\plugins\
cd package
powershell Compress-Archive -Force -DestinationPath '$(ProjectName)-$(Version).zip' -Path patchers, plugins, icon.png, manifest.json, ../README.md" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -14,17 +14,8 @@
|
||||
<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="2022.3.53" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\AssemblyFromGame\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>..\AssemblyFromGame\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<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'">
|
||||
|
||||
57
LogisticHub/LogisticHub.cs
Normal file
57
LogisticHub/LogisticHub.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using BepInEx;
|
||||
using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
|
||||
namespace LogisticHub;
|
||||
|
||||
[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)]
|
||||
public class LogisticHub : BaseUnityPlugin
|
||||
{
|
||||
public new static readonly BepInEx.Logging.ManualLogSource Logger =
|
||||
BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME);
|
||||
|
||||
private Type[] _modules;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Module.Miner.Enabled = Config.Bind("Miner", "Enabled", true, "enable/disable this plugin");
|
||||
Module.Miner.OreEnergyConsume = Config.Bind("Miner", "EnergyConsumptionForOre", 2000000L,
|
||||
"Energy consumption for each ore vein group(in W)");
|
||||
Module.Miner.OreMiningMultiplier = Config.Bind("Miner", "OreMiningMultiplier", 3,
|
||||
new ConfigDescription("Mining multiplier for ore veins, multiplies to the number of veins in the group", new AcceptableValueRange<int>(1, 100)));
|
||||
Module.Miner.OreMiningScale = Config.Bind("Miner", "OreMiningScale", 100,
|
||||
"""
|
||||
0 for Auto(which means having researched advanced mining machine makes mining scale 300, otherwise 100).
|
||||
Mining scale(in percents) for slots below half of slot limits, and the scale reduces to 100% smoothly till reach full.
|
||||
Please note that the power consumption increases by the square of the scale which is the same as Advanced Mining Machine.
|
||||
""");
|
||||
Module.Miner.OilEnergyConsume = Config.Bind("Miner", "EnergyConsumptionForOil", 1800000L,
|
||||
"Energy consumption for each oil seep(in W)");
|
||||
Module.Miner.WaterEnergyConsume = Config.Bind("Miner", "EnergyConsumptionForWater", 2000000L,
|
||||
"Energy consumption for water slot(in W)");
|
||||
Module.Miner.WaterSpeed = Config.Bind("Miner", "WaterMiningSpeed", 10,
|
||||
"Water mining speed (count per second)");
|
||||
Module.Miner.FuelIlsSlot = Config.Bind("Miner", "ILSFuelSlot", 4,
|
||||
new ConfigDescription("Fuel slot for ILS, set 0 to disable.", new AcceptableValueRange<int>(0, 5)));
|
||||
Module.Miner.FuelPlsSlot = Config.Bind("Miner", "PLSFuelSlot", 4,
|
||||
new ConfigDescription("Fuel slot for PLS, set 0 to disable.", new AcceptableValueRange<int>(0, 4)));
|
||||
|
||||
_modules = Util.GetTypesFiltered(Assembly.GetExecutingAssembly(),
|
||||
t => string.Equals(t.Namespace, "LogisticHub.Module", StringComparison.Ordinal));
|
||||
_modules?.Do(type => type.GetMethod("Init")?.Invoke(null, null));
|
||||
Harmony.CreateAndPatchAll(typeof(LogisticHub));
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_modules?.Do(type => type.GetMethod("Start")?.Invoke(null, null));
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
_modules?.Do(type => type.GetMethod("Uninit")?.Invoke(null, null));
|
||||
}
|
||||
}
|
||||
@@ -3,20 +3,21 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>LogisticMiner</AssemblyName>
|
||||
<BepInExPluginGuid>org.soardev.logisticminer</BepInExPluginGuid>
|
||||
<Description>DSP MOD - LogisticMiner</Description>
|
||||
<Version>0.2.0</Version>
|
||||
<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="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.*" /> -->
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -28,6 +29,10 @@
|
||||
</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>
|
||||
33
LogisticHub/Module/AuxData.cs
Normal file
33
LogisticHub/Module/AuxData.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace LogisticHub.Module;
|
||||
|
||||
using UXAssist.Common;
|
||||
|
||||
public static class AuxData
|
||||
{
|
||||
public static (long, bool)[] Fuels;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
GameLogic.OnDataLoaded += () =>
|
||||
{
|
||||
var maxId = LDB.items.dataArray.Select(data => data.ID).Prepend(0).Max();
|
||||
Fuels = new (long, bool)[maxId + 1];
|
||||
foreach (var data in LDB.items.dataArray)
|
||||
Fuels[data.ID] = (data.HeatValue, data.Productive);
|
||||
};
|
||||
}
|
||||
|
||||
public static int AlignUpToPowerOf2(int n)
|
||||
{
|
||||
if (n < 16) return 16;
|
||||
n--;
|
||||
n |= n >> 1;
|
||||
n |= n >> 2;
|
||||
n |= n >> 4;
|
||||
n |= n >> 8;
|
||||
n |= n >> 16;
|
||||
return n + 1;
|
||||
}
|
||||
}
|
||||
0
LogisticHub/Module/Ejector.cs
Normal file
0
LogisticHub/Module/Ejector.cs
Normal file
345
LogisticHub/Module/Miner.cs
Normal file
345
LogisticHub/Module/Miner.cs
Normal file
@@ -0,0 +1,345 @@
|
||||
using System;
|
||||
using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
using Random = UnityEngine.Random;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace LogisticHub.Module;
|
||||
|
||||
public class Miner : PatchImpl<Miner>
|
||||
{
|
||||
public static ConfigEntry<bool> Enabled;
|
||||
public static ConfigEntry<long> OreEnergyConsume;
|
||||
public static ConfigEntry<int> OreMiningScale;
|
||||
public static ConfigEntry<int> OreMiningMultiplier;
|
||||
public static ConfigEntry<long> OilEnergyConsume;
|
||||
public static ConfigEntry<long> WaterEnergyConsume;
|
||||
public static ConfigEntry<int> WaterSpeed;
|
||||
public static ConfigEntry<int> FuelIlsSlot;
|
||||
public static ConfigEntry<int> FuelPlsSlot;
|
||||
|
||||
private static long _frame;
|
||||
private static float _miningCostRateByTech;
|
||||
private static long _miningFrames;
|
||||
private static long _miningSpeedScaleLong;
|
||||
private static bool _advancedMiningMachineUnlocked;
|
||||
private static int _miningMultiplier = 3;
|
||||
private static int _miningScale = 100;
|
||||
private static uint _miningCostBarrier;
|
||||
private static uint _miningCostBarrierOil;
|
||||
private static int[] _mineIndex;
|
||||
|
||||
private static uint _miningSeed = (uint)Random.Range(0, int.MaxValue);
|
||||
|
||||
private static readonly (int, int)[] VeinList =
|
||||
[
|
||||
(0, 1000),
|
||||
(1, 1001),
|
||||
(2, 1002),
|
||||
(3, 1003),
|
||||
(4, 1004),
|
||||
(5, 1005),
|
||||
(6, 1006),
|
||||
(7, 1007),
|
||||
(11, 1011),
|
||||
(12, 1012),
|
||||
(13, 1013),
|
||||
(14, 1014),
|
||||
(15, 1015),
|
||||
(16, 1016)
|
||||
];
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
Enabled.SettingChanged += (_, _) => { Enable(Enabled.Value); };
|
||||
|
||||
Enable(Enabled.Value);
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
{
|
||||
Enable(false);
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
GameLogicProc.OnGameBegin += OnGameBegin;
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin;
|
||||
}
|
||||
|
||||
private static void OnGameBegin()
|
||||
{
|
||||
_frame = 0L;
|
||||
UpdateMiningCostRate();
|
||||
UpdateSpeedScale();
|
||||
CheckRecipes();
|
||||
}
|
||||
|
||||
private static int SplitIncLevel(ref int n, ref int m, int p)
|
||||
{
|
||||
var level = m / n;
|
||||
var left = m - level * n;
|
||||
n -= p;
|
||||
left -= n;
|
||||
m -= left > 0 ? level * p + left : level * p;
|
||||
return level;
|
||||
}
|
||||
|
||||
private static void CheckRecipes()
|
||||
{
|
||||
_advancedMiningMachineUnlocked = GameMain.history.recipeUnlocked.Contains(119);
|
||||
_miningMultiplier = OreMiningMultiplier.Value;
|
||||
if (OreMiningScale.Value == 0)
|
||||
{
|
||||
_miningScale = _advancedMiningMachineUnlocked ? 300 : 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
_miningScale = OreMiningScale.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateMiningCostRate()
|
||||
{
|
||||
_miningCostRateByTech = GameMain.history.miningCostRate;
|
||||
_miningCostBarrier = (uint)(int)Math.Ceiling(2147483646.0 * _miningCostRateByTech);
|
||||
_miningCostBarrierOil = (uint)(int)Math.Ceiling(2147483646.0 * _miningCostRateByTech * 0.401116669f / Math.Max(DSPGame.GameDesc.resourceMultiplier, 0.416666657f));
|
||||
}
|
||||
|
||||
private static void UpdateSpeedScale()
|
||||
{
|
||||
_miningSpeedScaleLong = (long)Math.Round(GameMain.history.miningSpeedScale * 100f);
|
||||
_miningFrames = _miningSpeedScaleLong * 6000L;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.UnlockTechFunction))]
|
||||
private static void OnUnlockTech(int func)
|
||||
{
|
||||
switch (func)
|
||||
{
|
||||
case 20:
|
||||
UpdateMiningCostRate();
|
||||
break;
|
||||
case 21:
|
||||
UpdateSpeedScale();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(GameLogic), nameof(GameLogic.OnFactoryFrameBegin))]
|
||||
private static void GameLogic_OnFactoryFrameBegin_Prefix()
|
||||
{
|
||||
var main = GameMain.instance;
|
||||
if (main.isMenuDemo) return;
|
||||
if (_miningSpeedScaleLong <= 0L) return;
|
||||
|
||||
if (main.timei % 60 != 0) return;
|
||||
_frame += _miningFrames;
|
||||
var frameCounter = _frame / 1200000L;
|
||||
if (frameCounter <= 0) return;
|
||||
_frame -= frameCounter * 1200000L;
|
||||
|
||||
DeepProfiler.BeginSample(DPEntry.Miner);
|
||||
var data = GameMain.data;
|
||||
if (_mineIndex == null || data.factoryCount > _mineIndex.Length)
|
||||
Array.Resize(ref _mineIndex, data.factoryCount);
|
||||
var factoryStatPool = GameMain.statistics.production.factoryStatPool;
|
||||
for (var factoryIndex = data.factoryCount - 1; factoryIndex >= 0; factoryIndex--)
|
||||
{
|
||||
var factory = data.factories[factoryIndex];
|
||||
var veins = VeinManager.GetVeins(factoryIndex);
|
||||
if (veins == null) continue;
|
||||
var stations = StationManager.GetStations(factoryIndex);
|
||||
var planetTransport = factory.transport;
|
||||
var productRegister = factoryStatPool[factoryIndex]?.productRegister;
|
||||
var demands = stations.StorageIndices[1];
|
||||
if (demands == null) continue;
|
||||
foreach (var (itemIndex, itemId) in VeinList)
|
||||
{
|
||||
if (itemIndex >= demands.Length) continue;
|
||||
var demandList = demands[itemIndex];
|
||||
if (demandList == null) continue;
|
||||
foreach (var storageIndex in demandList)
|
||||
{
|
||||
var station = planetTransport.stationPool[storageIndex / 100];
|
||||
if (station == null)
|
||||
continue;
|
||||
ref var storage = ref station.storage[storageIndex % 100];
|
||||
if (storage.count >= storage.max) continue;
|
||||
int amount;
|
||||
long energyConsume;
|
||||
var miningScale = _miningScale;
|
||||
if (miningScale > 100 && storage.count * 2 > storage.max)
|
||||
{
|
||||
miningScale = 100 + ((miningScale - 100) * (storage.max - storage.count) * 2 + storage.max - 1) / storage.max;
|
||||
}
|
||||
|
||||
if (itemIndex > 0)
|
||||
{
|
||||
(amount, energyConsume) = Mine(factory, veins, itemId, miningScale, (int)frameCounter, _miningMultiplier, station.energy);
|
||||
if (amount < 0) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
energyConsume = (WaterEnergyConsume.Value * frameCounter * miningScale * miningScale + 9999L) / 10000L;
|
||||
if (station.energy < energyConsume) continue;
|
||||
amount = WaterSpeed.Value * miningScale / 100;
|
||||
}
|
||||
|
||||
if (amount <= 0) continue;
|
||||
storage.count += amount;
|
||||
if (productRegister != null)
|
||||
productRegister[itemId] += amount;
|
||||
station.energy -= energyConsume;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = planetTransport.stationCursor - 1; i > 0; i--)
|
||||
{
|
||||
var stationComponent = planetTransport.stationPool[i];
|
||||
if (stationComponent == null || stationComponent.isCollector || stationComponent.isVeinCollector || stationComponent.energy * 2 >= stationComponent.energyMax) continue;
|
||||
var index = (stationComponent.isStellar ? FuelIlsSlot.Value : FuelPlsSlot.Value) - 1;
|
||||
var storage = stationComponent.storage;
|
||||
if (index < 0 || index >= storage.Length)
|
||||
continue;
|
||||
var fuelCount = storage[index].count;
|
||||
if (fuelCount == 0) continue;
|
||||
var (heat, prod) = AuxData.Fuels[storage[index].itemId];
|
||||
if (heat <= 0)
|
||||
continue;
|
||||
/* Sprayed fuels */
|
||||
int pretendIncLevel;
|
||||
if (prod && (pretendIncLevel = storage[index].inc / storage[index].count) > 0)
|
||||
{
|
||||
var count = (int)((stationComponent.energyMax - stationComponent.energy) * 1000L / Cargo.incTable[pretendIncLevel] / 7L);
|
||||
if (count > fuelCount)
|
||||
count = fuelCount;
|
||||
var incLevel = SplitIncLevel(ref storage[index].count, ref storage[index].inc, count);
|
||||
if (incLevel > 10)
|
||||
incLevel = 10;
|
||||
stationComponent.energy += heat * count * (1000L + Cargo.incTable[incLevel]) / 1000L;
|
||||
}
|
||||
else
|
||||
{
|
||||
var count = (int)((stationComponent.energyMax - stationComponent.energy) / heat);
|
||||
if (count > fuelCount)
|
||||
count = fuelCount;
|
||||
SplitIncLevel(ref storage[index].count, ref storage[index].inc, count);
|
||||
stationComponent.energy += heat * count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeepProfiler.EndSample(DPEntry.Miner);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.UnlockRecipe))]
|
||||
private static void OnUnlockRecipe(int recipeId)
|
||||
{
|
||||
if (recipeId == 119)
|
||||
{
|
||||
CheckRecipes();
|
||||
}
|
||||
}
|
||||
|
||||
private static (int, long) Mine(PlanetFactory factory, ProductVeinData[] allVeins, int productId, int percent, int counter, int multiplier, long energyMax)
|
||||
{
|
||||
var veins = allVeins[productId - 1000];
|
||||
if (veins == null)
|
||||
return (-1, -1L);
|
||||
|
||||
var veinIndices = veins.VeinIndices;
|
||||
uint barrier;
|
||||
int limit;
|
||||
int count;
|
||||
long energy;
|
||||
var length = veinIndices.Count - 1;
|
||||
/* if is Oil */
|
||||
if (productId == 1007)
|
||||
{
|
||||
energy = OilEnergyConsume.Value * length;
|
||||
if (energy > energyMax)
|
||||
return (-1, -1L);
|
||||
var countf = 0f;
|
||||
var veinsPool = factory.veinPool;
|
||||
for (var i = length; i > 0; i--)
|
||||
{
|
||||
countf += veinsPool[veinIndices[i]].amount * 4 * VeinData.oilSpeedMultiplier;
|
||||
}
|
||||
count = (int)(countf * (counter * percent) / 100f);
|
||||
if (count == 0)
|
||||
return (-1, -1L);
|
||||
barrier = _miningCostBarrierOil;
|
||||
limit = 2500;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = (length * multiplier * counter * percent + 99) / 100;
|
||||
if (count == 0)
|
||||
return (-1, -1L);
|
||||
energy = (OreEnergyConsume.Value * veins.GroupCount * percent * percent + 9999L) / 10000L;
|
||||
if (energy > energyMax)
|
||||
return (-1, -1L);
|
||||
barrier = _miningCostBarrier;
|
||||
limit = 0;
|
||||
}
|
||||
|
||||
var veinsData = factory.veinPool;
|
||||
var total = 0;
|
||||
var factoryIndex = factory.index;
|
||||
var mineIndex = _mineIndex[factoryIndex];
|
||||
for (; count > 0; count--)
|
||||
{
|
||||
mineIndex = mineIndex % length + 1;
|
||||
var index = veinIndices[mineIndex];
|
||||
ref var vd = ref veinsData[index];
|
||||
int groupIndex;
|
||||
|
||||
if (vd.amount <= 0)
|
||||
{
|
||||
groupIndex = vd.groupIndex;
|
||||
factory.veinGroups[groupIndex].count--;
|
||||
factory.RemoveVeinWithComponents(index);
|
||||
factory.RecalculateVeinGroup(groupIndex);
|
||||
length = veinIndices.Count - 1;
|
||||
if (length <= 0) break;
|
||||
continue;
|
||||
}
|
||||
|
||||
total++;
|
||||
|
||||
if (vd.amount <= limit) continue;
|
||||
var consume = true;
|
||||
if (barrier < 2147483646u)
|
||||
{
|
||||
_miningSeed = (uint)((int)((ulong)((_miningSeed % 2147483646u + 1) * 48271L) % 2147483647uL) - 1);
|
||||
consume = _miningSeed < barrier;
|
||||
}
|
||||
|
||||
if (!consume) continue;
|
||||
|
||||
vd.amount--;
|
||||
groupIndex = vd.groupIndex;
|
||||
factory.veinGroups[groupIndex].amount--;
|
||||
|
||||
if (vd.amount > 0) continue;
|
||||
factory.veinGroups[groupIndex].count--;
|
||||
factory.RemoveVeinWithComponents(index);
|
||||
factory.RecalculateVeinGroup(groupIndex);
|
||||
length = veinIndices.Count - 1;
|
||||
if (length <= 0) break;
|
||||
}
|
||||
|
||||
_mineIndex[factoryIndex] = mineIndex;
|
||||
|
||||
return (total, energy);
|
||||
}
|
||||
}
|
||||
325
LogisticHub/Module/StationManager.cs
Normal file
325
LogisticHub/Module/StationManager.cs
Normal file
@@ -0,0 +1,325 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace LogisticHub.Module;
|
||||
|
||||
public class PlanetStations
|
||||
{
|
||||
public readonly List<int>[][] StorageIndices = [null, null];
|
||||
|
||||
public void AddStationStorage(bool demand, int id, int stationId, int storageIdx)
|
||||
{
|
||||
LogisticHub.Logger.LogDebug($"AddStationStorage: demand={demand}, id={id}, stationId={stationId}, storageIdx={storageIdx}");
|
||||
var stations = StorageIndices[demand ? 1 : 0];
|
||||
if (stations == null || id >= stations.Length)
|
||||
{
|
||||
Array.Resize(ref stations, AuxData.AlignUpToPowerOf2(id + 1));
|
||||
StorageIndices[demand ? 1 : 0] = stations;
|
||||
}
|
||||
|
||||
var list = stations[id];
|
||||
if (list == null)
|
||||
{
|
||||
list = [];
|
||||
stations[id] = list;
|
||||
}
|
||||
|
||||
var value = stationId * 100 + storageIdx;
|
||||
var index = list.BinarySearch(value);
|
||||
if (index < 0)
|
||||
list.Insert(~index, value);
|
||||
}
|
||||
|
||||
public void RemoveStationStorage(bool demand, int id, int stationId, int storageIdx)
|
||||
{
|
||||
var stations = StorageIndices[demand ? 1 : 0];
|
||||
if (stations == null || id >= stations.Length)
|
||||
return;
|
||||
var list = stations[id];
|
||||
if (list == null)
|
||||
return;
|
||||
|
||||
var value = stationId * 100 + storageIdx;
|
||||
var index = list.BinarySearch(value);
|
||||
if (index >= 0)
|
||||
list.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
public class StationManager : PatchImpl<StationManager>
|
||||
{
|
||||
private static PlanetStations[] _stations;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
GameLogicProc.OnGameBegin += OnGameBegin;
|
||||
Enable(true);
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
{
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin;
|
||||
Enable(false);
|
||||
}
|
||||
|
||||
private static void OnGameBegin()
|
||||
{
|
||||
_stations = null;
|
||||
var data = GameMain.data;
|
||||
for (var index = data.factoryCount - 1; index >= 0; index--)
|
||||
{
|
||||
var factory = data.factories[index];
|
||||
if (factory == null || factory.index != index) continue;
|
||||
var planetIndex = factory.index;
|
||||
var stations = StationsByPlanet(planetIndex);
|
||||
var transport = factory.transport;
|
||||
var pool = transport.stationPool;
|
||||
for (var i = transport.stationCursor - 1; i > 0; i--)
|
||||
{
|
||||
var station = pool[i];
|
||||
if (station == null || station.id != i || station.isCollector || station.isVeinCollector) continue;
|
||||
UpdateStationInfo(stations, station);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int ItemIdToIndex(int itemId)
|
||||
{
|
||||
return itemId switch
|
||||
{
|
||||
>= 1000 and < 2000 => itemId - 1000,
|
||||
>= 5000 and < 5050 => itemId - 5000 + 900,
|
||||
>= 6000 and < 6050 => itemId - 6000 + 950,
|
||||
_ => -1
|
||||
};
|
||||
}
|
||||
|
||||
public static int IndexToItemId(int index)
|
||||
{
|
||||
return index switch
|
||||
{
|
||||
< 900 => index + 1000,
|
||||
< 950 => index - 900 + 5000,
|
||||
< 1000 => index - 950 + 6000,
|
||||
_ => -1
|
||||
};
|
||||
}
|
||||
|
||||
public static PlanetStations GetStations(int planetIndex)
|
||||
{
|
||||
return _stations != null && planetIndex < _stations.Length ? _stations[planetIndex] : null;
|
||||
}
|
||||
|
||||
private static PlanetStations StationsByPlanet(int planetIndex)
|
||||
{
|
||||
if (_stations == null || _stations.Length <= planetIndex)
|
||||
Array.Resize(ref _stations, AuxData.AlignUpToPowerOf2(planetIndex + 1));
|
||||
var stations = _stations[planetIndex];
|
||||
if (stations != null) return stations;
|
||||
stations = new PlanetStations();
|
||||
_stations[planetIndex] = stations;
|
||||
return stations;
|
||||
}
|
||||
|
||||
private static void DebugLog()
|
||||
{
|
||||
for (var idx = 0; idx < _stations.Length; idx++)
|
||||
{
|
||||
var stations = _stations[idx];
|
||||
if (stations == null) continue;
|
||||
LogisticHub.Logger.LogDebug($"Planet {idx}:");
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
var storage = stations.StorageIndices[i];
|
||||
if (storage == null) continue;
|
||||
LogisticHub.Logger.LogDebug(i == 1 ? " Demand:" : " Supply:");
|
||||
for (var j = 0; j < storage.Length; j++)
|
||||
{
|
||||
var list = storage[j];
|
||||
if (list == null) continue;
|
||||
var count = list.Count;
|
||||
if (count <= 0) continue;
|
||||
var itemId = IndexToItemId(j);
|
||||
LogisticHub.Logger.LogDebug($" {itemId}: {string.Join(", ", list)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateStationInfo(PlanetStations stations, StationComponent station, int storageIdx = -1)
|
||||
{
|
||||
var storage = station.storage;
|
||||
var stationId = station.id;
|
||||
if (storageIdx >= 0)
|
||||
{
|
||||
if (storageIdx >= storage.Length) return;
|
||||
var itemId = ItemIdToIndex(storage[storageIdx].itemId);
|
||||
if (itemId <= 0) return;
|
||||
var logic = storage[storageIdx].localLogic;
|
||||
switch (logic)
|
||||
{
|
||||
case ELogisticStorage.Demand:
|
||||
stations.AddStationStorage(true, itemId, stationId, storageIdx);
|
||||
break;
|
||||
case ELogisticStorage.Supply:
|
||||
stations.AddStationStorage(false, itemId, stationId, storageIdx);
|
||||
break;
|
||||
case ELogisticStorage.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = storage.Length - 1; i >= 0; i--)
|
||||
{
|
||||
var itemId = ItemIdToIndex(storage[i].itemId);
|
||||
if (itemId <= 0) continue;
|
||||
var logic = storage[i].localLogic;
|
||||
switch (logic)
|
||||
{
|
||||
case ELogisticStorage.Demand:
|
||||
stations.AddStationStorage(true, itemId, stationId, i);
|
||||
break;
|
||||
case ELogisticStorage.Supply:
|
||||
stations.AddStationStorage(false, itemId, stationId, i);
|
||||
break;
|
||||
case ELogisticStorage.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RemoveStationInfo(PlanetStations stations, StationComponent station, int storageIdx = -1)
|
||||
{
|
||||
var storage = station.storage;
|
||||
var stationId = station.id;
|
||||
if (storageIdx >= 0)
|
||||
{
|
||||
var itemId = ItemIdToIndex(storage[storageIdx].itemId);
|
||||
if (itemId <= 0) return;
|
||||
var logic = storage[storageIdx].localLogic;
|
||||
switch (logic)
|
||||
{
|
||||
case ELogisticStorage.Demand:
|
||||
stations.RemoveStationStorage(true, itemId, stationId, storageIdx);
|
||||
break;
|
||||
case ELogisticStorage.Supply:
|
||||
stations.RemoveStationStorage(false, itemId, stationId, storageIdx);
|
||||
break;
|
||||
case ELogisticStorage.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = storage.Length - 1; i >= 0; i--)
|
||||
{
|
||||
var itemId = ItemIdToIndex(storage[i].itemId);
|
||||
if (itemId <= 0) continue;
|
||||
var logic = storage[i].localLogic;
|
||||
switch (logic)
|
||||
{
|
||||
case ELogisticStorage.Demand:
|
||||
stations.RemoveStationStorage(true, itemId, stationId, i);
|
||||
break;
|
||||
case ELogisticStorage.Supply:
|
||||
stations.RemoveStationStorage(false, itemId, stationId, i);
|
||||
break;
|
||||
case ELogisticStorage.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.Init))]
|
||||
private static void PlanetTransport_Init_Postfix(PlanetTransport __instance)
|
||||
{
|
||||
var factory = __instance.factory;
|
||||
var planetIndex = factory.index;
|
||||
|
||||
if (_stations == null || _stations.Length <= planetIndex)
|
||||
Array.Resize(ref _stations, AuxData.AlignUpToPowerOf2(planetIndex + 1));
|
||||
var stations = new PlanetStations();
|
||||
_stations[planetIndex] = stations;
|
||||
|
||||
var pool = __instance.stationPool;
|
||||
for (var i = __instance.stationCursor - 1; i > 0; i--)
|
||||
{
|
||||
var station = pool[i];
|
||||
if (station == null || station.id != i || station.isCollector || station.isVeinCollector) continue;
|
||||
UpdateStationInfo(stations, station);
|
||||
}
|
||||
// DebugLog();
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(BuildingParameters), nameof(BuildingParameters.ApplyPrebuildParametersToEntity))]
|
||||
private static void BuildingParameters_ApplyPrebuildParametersToEntity_Postfix(int entityId, PlanetFactory factory)
|
||||
{
|
||||
if (entityId <= 0) return;
|
||||
ref var entity = ref factory.entityPool[entityId];
|
||||
var stationId = entity.stationId;
|
||||
if (stationId <= 0) return;
|
||||
var station = factory.transport.stationPool[stationId];
|
||||
if (station == null || station.id != stationId || station.isCollector || station.isVeinCollector) return;
|
||||
UpdateStationInfo(StationsByPlanet(factory.index), station);
|
||||
// DebugLog();
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.RemoveStationComponent))]
|
||||
private static void PlanetTransport_RemoveStationComponent_Prefix(PlanetTransport __instance, int id)
|
||||
{
|
||||
if (id <= 0) return;
|
||||
var station = __instance.stationPool[id];
|
||||
if (station == null || station.id != id || station.isCollector || station.isVeinCollector) return;
|
||||
RemoveStationInfo(StationsByPlanet(__instance.factory.index), station);
|
||||
// DebugLog();
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.SetStationStorage))]
|
||||
private static void PlanetTransport_SetStationStorage_Prefix(PlanetTransport __instance, int stationId, int storageIdx, int itemId, ELogisticStorage localLogic, out bool __state)
|
||||
{
|
||||
var station = __instance.stationPool[stationId];
|
||||
if (station == null || station.id != stationId || station.isCollector || station.isVeinCollector || storageIdx < 0 || storageIdx >= station.storage.Length)
|
||||
{
|
||||
__state = false;
|
||||
return;
|
||||
}
|
||||
|
||||
ref var storage = ref station.storage[storageIdx];
|
||||
var oldItemId = storage.itemId;
|
||||
var oldLocalLogic = storage.localLogic;
|
||||
if (localLogic == oldLocalLogic && itemId == oldItemId)
|
||||
{
|
||||
__state = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (oldItemId > 0 && oldLocalLogic != ELogisticStorage.None)
|
||||
RemoveStationInfo(StationsByPlanet(__instance.factory.index), station, storageIdx);
|
||||
__state = localLogic != ELogisticStorage.None;
|
||||
// if (!__state) DebugLog();
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.SetStationStorage))]
|
||||
private static void PlanetTransport_SetStationStorage_Postfix(PlanetTransport __instance, int stationId, int storageIdx, bool __state)
|
||||
{
|
||||
if (!__state) return;
|
||||
var station = __instance.stationPool[stationId];
|
||||
UpdateStationInfo(StationsByPlanet(__instance.factory.index), station, storageIdx);
|
||||
// DebugLog();
|
||||
}
|
||||
}
|
||||
123
LogisticHub/Module/VeinManager.cs
Normal file
123
LogisticHub/Module/VeinManager.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace LogisticHub.Module;
|
||||
|
||||
public class ProductVeinData
|
||||
{
|
||||
public readonly List<int> VeinIndices = [];
|
||||
public readonly HashSet<int> GroupIndices = [];
|
||||
public int GroupCount = 0;
|
||||
}
|
||||
|
||||
public class VeinManager : PatchImpl<VeinManager>
|
||||
{
|
||||
private static ProductVeinData[][] _veins;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
Enable(true);
|
||||
GameLogicProc.OnGameBegin += OnGameBegin;
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
{
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin;
|
||||
Enable(false);
|
||||
}
|
||||
|
||||
private static void OnGameBegin()
|
||||
{
|
||||
_veins = null;
|
||||
var data = GameMain.data;
|
||||
for (var index = data.factoryCount - 1; index >= 0; index--)
|
||||
{
|
||||
var factory = data.factories[index];
|
||||
if (factory == null || factory.index != index) continue;
|
||||
RecalcVeins(factory);
|
||||
}
|
||||
}
|
||||
|
||||
public static ProductVeinData[] GetVeins(int planetIndex)
|
||||
{
|
||||
if (_veins == null || _veins.Length <= planetIndex)
|
||||
return null;
|
||||
return _veins[planetIndex];
|
||||
}
|
||||
|
||||
private static ProductVeinData[] GetOrCreateVeins(int planetIndex)
|
||||
{
|
||||
if (_veins == null || _veins.Length <= planetIndex)
|
||||
Array.Resize(ref _veins, AuxData.AlignUpToPowerOf2(planetIndex + 1));
|
||||
var veins = _veins[planetIndex];
|
||||
if (veins != null) return veins;
|
||||
veins = new ProductVeinData[20];
|
||||
_veins[planetIndex] = veins;
|
||||
return veins;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlanetFactory), nameof(PlanetFactory.Init))]
|
||||
[HarmonyPatch(typeof(PlanetFactory), nameof(PlanetFactory.RecalculateVeinGroup))]
|
||||
[HarmonyPatch(typeof(PlanetFactory), nameof(PlanetFactory.RecalculateAllVeinGroups))]
|
||||
private static void PlanetFactory_RecalculateAllVeinGroups_Postfix(PlanetFactory __instance)
|
||||
{
|
||||
RecalcVeins(__instance);
|
||||
}
|
||||
|
||||
private static void DebugLog()
|
||||
{
|
||||
foreach (var veins in _veins)
|
||||
{
|
||||
if (veins == null) continue;
|
||||
for (var i = 0; i < veins.Length; i++)
|
||||
{
|
||||
var pvd = veins[i];
|
||||
if (pvd == null) continue;
|
||||
LogisticHub.Logger.LogInfo($"Product {i} VeinTypeCount={pvd.VeinIndices.Count} GroupCount={pvd.GroupCount}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RecalcVeins(PlanetFactory factory)
|
||||
{
|
||||
var planetIndex = factory.index;
|
||||
var veins = GetOrCreateVeins(planetIndex);
|
||||
var veinPool = factory.veinPool;
|
||||
|
||||
foreach (var pvd in veins)
|
||||
{
|
||||
if (pvd == null) continue;
|
||||
pvd.VeinIndices.Clear();
|
||||
pvd.GroupIndices.Clear();
|
||||
pvd.GroupCount = 0;
|
||||
}
|
||||
|
||||
for (var i = factory.veinCursor - 1; i > 0; i--)
|
||||
{
|
||||
if (veinPool[i].id != i || veinPool[i].amount <= 0 || veinPool[i].type == EVeinType.None) continue;
|
||||
var productId = veinPool[i].productId - 1000;
|
||||
if (productId is < 0 or >= 20) continue;
|
||||
var pvd = veins[productId];
|
||||
if (pvd == null)
|
||||
{
|
||||
pvd = new ProductVeinData();
|
||||
veins[productId] = pvd;
|
||||
}
|
||||
|
||||
pvd.VeinIndices.Add(i);
|
||||
pvd.GroupIndices.Add(veinPool[i].groupIndex);
|
||||
}
|
||||
|
||||
foreach (var pvd in veins)
|
||||
{
|
||||
if (pvd == null) continue;
|
||||
pvd.GroupCount = pvd.GroupIndices.Count;
|
||||
}
|
||||
|
||||
// DebugLog();
|
||||
}
|
||||
}
|
||||
47
LogisticHub/README.md
Normal file
47
LogisticHub/README.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# LogisticHub
|
||||
|
||||
#### Cheat functions for Logistic Storages, make them mine resources on the planet and exchange items from certain buildings
|
||||
#### 物流塔作弊功能,使其可以在星球上采矿并与特定建筑物交换物品
|
||||
|
||||
## Usage
|
||||
|
||||
* Miner(and fuel burning) functions
|
||||
+ Inspired by [PlanetMiner](https://dsp.thunderstore.io/package/blacksnipebiu/PlanetMiner)([github](https://github.com/blacksnipebiu/PlanetMiner))
|
||||
But it is heavily optimized to resolve performance, accuracy and other issues in PlanetMiner.
|
||||
+ (Optimization to PlanetMiner) Only recalculate count of veins when vein chunks are changed (added/removed by foundations/Sandbox-Mode, or exhausted), so this removes Dictionary allocation on each planet for every frame.
|
||||
+ (Optimization to PlanetMiner) More accurate frame counting by use float number.
|
||||
+ (Optimization to PlanetMiner) Does not increase power consumptions on `Veins Utilization` upgrades.
|
||||
+ (Optimization to PlanetMiner) Separate power consumptions for veins, oil seeps and water.
|
||||
+ (Optimization to PlanetMiner) Power consumptions are counted by groups of veins and count of oil seeps, which is more sensible.
|
||||
+ Can burn fuels in certain slot when energy below half of max.
|
||||
- (Optimization to PlanetMiner) Sprayed fuels generates extra energy as normal.
|
||||
+ (Optimization to PlanetMiner) All used parameters are configurable:
|
||||
- LogisticHub has the same speed as normal Mining Machine for normal ores by default.
|
||||
But you can set mining scale in configuration, which makes LogisticHub working like Advance Mining Machines:
|
||||
power consumption increases by the square of the scale, and gradually decrease mining speed over half of the maximum count.
|
||||
This applies to all of veins, oils and water.
|
||||
Mining scale can be set to 0(by default), which means it is automatically set by tech unlocks, set to 300 when you reaches Advanced Mining Machine, otherwise 100.
|
||||
- 100/s for water by default.
|
||||
- Energy costs: 1MW/vein-group & 10MW/water-slot & 1.8MW/oil-seep(configurable)
|
||||
- Fuels burning slot. Default: 4th for ILS and PLS. Set to 0 to disable it.
|
||||
|
||||
## 使用说明
|
||||
|
||||
* 采矿(和燃料燃烧)功能
|
||||
+ 创意来自 [PlanetMiner](https://dsp.thunderstore.io/package/blacksnipebiu/PlanetMiner)([github](https://github.com/blacksnipebiu/PlanetMiner))
|
||||
对性能重度优化,并解决了PlanetMiner的精度等问题。
|
||||
+ (对PlanetMiner的优化) 仅当矿堆发生变化(填埋/恢复/采完)时重新计算矿堆数据,解决每行星每计算帧要重建字典的性能问题。
|
||||
+ (对PlanetMiner的优化) 用浮点数保证更精确的帧计算。
|
||||
+ (对PlanetMiner的优化) 升级`矿物利用`不会提升能耗。
|
||||
+ (对PlanetMiner的优化) 分开矿物,油井和水的采集能耗。
|
||||
+ (对PlanetMiner的优化) 采集能耗以矿物组,油井为单位,相对更加合理。
|
||||
+ 剩余电量少于一半时可以燃烧指定格子的燃料补充。
|
||||
- (对PlanetMiner的优化) 喷涂了增产剂的燃料按照正常的计算方式提供更多的能量(除了原本就不增加能量输出的反物质燃料棒)。
|
||||
+ (对PlanetMiner的优化) 所有参数都可以在设置文件内配置:
|
||||
- 物流塔枢纽和普通矿机采矿速度一样(等同于同时采集所有对应矿物)。
|
||||
你可以设置采矿倍率改变物流塔枢纽采矿速度,和高级采矿机相同地,能耗和倍率的平方成正比,并且在存储矿物量多于一半时逐渐降低采矿倍率。
|
||||
此倍率对各种矿物,油井和水的采集都生效。
|
||||
倍率可以设置为0(默认),此时倍率会随科技解锁而变化,默认是100%,解锁高级采矿机后变为300%。
|
||||
- 水的采集速度默认为100/s。
|
||||
- 能耗:每矿物组 1MW,单格水 10MW,每油井 1.8MW。
|
||||
- 燃料格位置。默认:星际物流塔和行星内物流塔第4格。设为0则关闭燃料补充能量功能。
|
||||
10
LogisticHub/package/manifest.json
Normal file
10
LogisticHub/package/manifest.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "LogisticHub",
|
||||
"version_number": "0.1.0",
|
||||
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/LogisticHub",
|
||||
"description": "Cheat functions to Logistic Storages which make them miner and items hub / 物流塔作弊功能,使其成为矿机和物品枢纽",
|
||||
"dependencies": [
|
||||
"xiaoye97-BepInEx-5.4.17",
|
||||
"soarqin-UXAssist-1.2.0"
|
||||
]
|
||||
}
|
||||
@@ -1,484 +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 = 2000000;
|
||||
private static int _waterSpeed = 10;
|
||||
private static int _miningScale;
|
||||
private static int _fuelIlsSlot = 3;
|
||||
private static int _fuelPlsSlot = 3;
|
||||
|
||||
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 = [];
|
||||
private static readonly Dictionary<int, (long, bool)> Fuels = [];
|
||||
|
||||
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), []))
|
||||
.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), []))
|
||||
.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), nameof(DSPGame.StartGame), typeof(GameDesc))]
|
||||
[HarmonyPatch(typeof(DSPGame), nameof(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), nameof(GameMain.Start))]
|
||||
private static void OnGameLoaded()
|
||||
{
|
||||
_frame = 0f;
|
||||
|
||||
UpdateMiningCostRate();
|
||||
UpdateSpeedScale();
|
||||
CheckRecipes();
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.UnlockTechFunction))]
|
||||
private static void OnUnlockTech(int func)
|
||||
{
|
||||
switch (func)
|
||||
{
|
||||
case 20:
|
||||
UpdateMiningCostRate();
|
||||
break;
|
||||
case 21:
|
||||
UpdateSpeedScale();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameLogic), nameof(GameLogic.OnFactoryFrameBegin))]
|
||||
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), nameof(GameHistoryData.UnlockRecipe))]
|
||||
private static void OnUnlockRecipe(int recipeId)
|
||||
{
|
||||
if (recipeId == 119)
|
||||
{
|
||||
CheckRecipes();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlanetFactory), nameof(PlanetFactory.Init))]
|
||||
[HarmonyPatch(typeof(PlanetFactory), nameof(PlanetFactory.RecalculateVeinGroup))]
|
||||
[HarmonyPatch(typeof(PlanetFactory), nameof(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(PlanetFactory), nameof(PlanetFactory.BeforeGameTick))]
|
||||
private static void FactorySystemLogisticMiner(PlanetFactory __instance)
|
||||
{
|
||||
if (_miningSpeedScaleLong <= 0)
|
||||
return;
|
||||
var planetId = __instance.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.transport;
|
||||
var factoryProductionStat =
|
||||
GameMain.statistics.production.factoryStatPool[__instance.index];
|
||||
var productRegister = factoryProductionStat?.productRegister;
|
||||
DeepProfiler.BeginSample(DPEntry.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(__instance, 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);
|
||||
|
||||
DeepProfiler.EndSample(DPEntry.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 = [];
|
||||
private int _mineIndex = -1;
|
||||
|
||||
public bool HasVein(int productId)
|
||||
{
|
||||
return _veins.ContainsKey(productId);
|
||||
}
|
||||
|
||||
public void GenVeins(PlanetFactory factory)
|
||||
{
|
||||
_veins = [];
|
||||
var veinPool = factory.veinPool;
|
||||
Dictionary<int, HashSet<int>> vg = [];
|
||||
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,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, 4th 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格,行星内物流塔第4格。设为0则关闭燃料补充能量功能。
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"name": "LogisticMiner",
|
||||
"version_number": "0.2.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"
|
||||
]
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
## Changlog
|
||||
* 1.0.0
|
||||
+ Initial release
|
||||
|
||||
## 更新日志
|
||||
* 1.0.0
|
||||
+ 初始版本
|
||||
@@ -1,232 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using BepInEx;
|
||||
using BepInEx.Logging;
|
||||
using HarmonyLib;
|
||||
using NLua;
|
||||
|
||||
namespace LuaScriptEngine;
|
||||
|
||||
[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)]
|
||||
public class LuaScriptEngine : BaseUnityPlugin
|
||||
{
|
||||
private class Timer(LuaFunction func, long startInterval, long repeatInterval = 0L)
|
||||
{
|
||||
public bool Check(long gameTick)
|
||||
{
|
||||
if (gameTick < _nextTick) return false;
|
||||
try
|
||||
{
|
||||
_func.Call();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError($"Error in Lua script: {e}");
|
||||
}
|
||||
|
||||
if (_repeatInterval <= 0L) return true;
|
||||
_nextTick += _repeatInterval;
|
||||
if (_nextTick < gameTick)
|
||||
_nextTick = gameTick + 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Reset(long gameTick)
|
||||
{
|
||||
if (_repeatInterval <= 0L) return true;
|
||||
_nextTick = gameTick + _repeatInterval;
|
||||
return false;
|
||||
}
|
||||
|
||||
private readonly LuaFunction _func = func;
|
||||
private readonly long _repeatInterval = repeatInterval;
|
||||
private long _nextTick = GameMain.gameTick + startInterval;
|
||||
}
|
||||
public new static readonly ManualLogSource Logger =
|
||||
BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME);
|
||||
|
||||
private Harmony _harmony;
|
||||
|
||||
private static readonly Lua LuaState = new();
|
||||
private static readonly List<LuaFunction> PostDataLoadedFuncs = [];
|
||||
private static readonly List<LuaFunction> PreUpdateFuncs = [];
|
||||
private static readonly List<LuaFunction> PostUpdateFuncs = [];
|
||||
private static readonly List<LuaFunction> PreGameBeginFuncs = [];
|
||||
private static readonly List<LuaFunction> PostGameBeginFuncs = [];
|
||||
private static readonly List<LuaFunction> PreGameEndFuncs = [];
|
||||
private static readonly List<LuaFunction> PostGameEndFuncs = [];
|
||||
private static readonly HashSet<Timer> Timers = [];
|
||||
private static readonly List<Timer> TimersToRemove = [];
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
LuaState.State.Encoding = Encoding.UTF8;
|
||||
LuaState.LoadCLRPackage();
|
||||
LuaState.DoString("import('Assembly-CSharp')");
|
||||
LuaState["register_callback"] = (string tp, LuaFunction action) =>
|
||||
{
|
||||
switch (tp)
|
||||
{
|
||||
case "data_loaded":
|
||||
PostDataLoadedFuncs.Add(action);
|
||||
break;
|
||||
case "pre_update":
|
||||
PreUpdateFuncs.Add(action);
|
||||
break;
|
||||
case "post_update":
|
||||
PostUpdateFuncs.Add(action);
|
||||
break;
|
||||
case "pre_game_begin":
|
||||
PreGameBeginFuncs.Add(action);
|
||||
break;
|
||||
case "post_game_begin":
|
||||
PostGameBeginFuncs.Add(action);
|
||||
break;
|
||||
case "pre_game_end":
|
||||
PreGameEndFuncs.Add(action);
|
||||
break;
|
||||
case "post_game_end":
|
||||
PostGameEndFuncs.Add(action);
|
||||
break;
|
||||
}
|
||||
};
|
||||
LuaState["add_timer"] = Timer(LuaFunction func, long firstInterval, long repeatInterval) =>
|
||||
{
|
||||
var timer = new Timer(func, firstInterval, repeatInterval);
|
||||
Timers.Add(timer);
|
||||
return timer;
|
||||
};
|
||||
LuaState["remove_timer"] = void (Timer timer) =>
|
||||
{
|
||||
Timers.Remove(timer);
|
||||
};
|
||||
var assemblyPath = System.IO.Path.Combine(
|
||||
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)!,
|
||||
"scripts"
|
||||
);
|
||||
LuaState.DoString($"package.path = '{assemblyPath.Replace('\\', '/')}/?.lua'");
|
||||
|
||||
foreach (var file in System.IO.Directory.GetFiles(assemblyPath, "*.lua"))
|
||||
{
|
||||
Logger.LogInfo($"Loading Lua script: {file}");
|
||||
LuaState.DoFile(file);
|
||||
}
|
||||
_harmony = Harmony.CreateAndPatchAll(typeof(Patches));
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
Timers.Clear();
|
||||
PreUpdateFuncs.Clear();
|
||||
PostUpdateFuncs.Clear();
|
||||
PreGameBeginFuncs.Clear();
|
||||
PostGameBeginFuncs.Clear();
|
||||
PreGameEndFuncs.Clear();
|
||||
PostGameEndFuncs.Clear();
|
||||
|
||||
_harmony?.UnpatchSelf();
|
||||
LuaState.Dispose();
|
||||
}
|
||||
|
||||
private static class Patches
|
||||
{
|
||||
private static void LoopCall(List<LuaFunction> funcs)
|
||||
{
|
||||
foreach (var func in funcs)
|
||||
{
|
||||
try
|
||||
{
|
||||
func.Call();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError($"Error in Lua script: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(VFPreload), nameof(VFPreload.InvokeOnLoadWorkEnded))]
|
||||
private static void VFPreload_InvokeOnLoadWorkEnded_Postfix()
|
||||
{
|
||||
LoopCall(PostDataLoadedFuncs);
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(GameMain), nameof(GameMain.FixedUpdate))]
|
||||
private static void GameMain_FixedUpdate_Prefix()
|
||||
{
|
||||
if (Timers.Count > 0)
|
||||
{
|
||||
var gameTick = GameMain.gameTick;
|
||||
foreach (var timer in Timers)
|
||||
{
|
||||
if (timer == null || !timer.Check(gameTick)) continue;
|
||||
TimersToRemove.Add(timer);
|
||||
}
|
||||
if (TimersToRemove.Count > 0)
|
||||
{
|
||||
foreach (var timer in TimersToRemove)
|
||||
{
|
||||
Timers.Remove(timer);
|
||||
}
|
||||
TimersToRemove.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
LoopCall(PreUpdateFuncs);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameMain), nameof(GameMain.FixedUpdate))]
|
||||
private static void GameMain_FixedUpdate_Postfix()
|
||||
{
|
||||
LoopCall(PostUpdateFuncs);
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))]
|
||||
private static void GameMain_Begin_Prefix()
|
||||
{
|
||||
var tick = GameMain.gameTick;
|
||||
foreach (var timer in Timers)
|
||||
{
|
||||
if (timer.Reset(tick))
|
||||
{
|
||||
TimersToRemove.Add(timer);
|
||||
}
|
||||
}
|
||||
if (TimersToRemove.Count > 0)
|
||||
{
|
||||
foreach (var timer in TimersToRemove)
|
||||
{
|
||||
Timers.Remove(timer);
|
||||
}
|
||||
TimersToRemove.Clear();
|
||||
}
|
||||
LoopCall(PreGameBeginFuncs);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))]
|
||||
private static void GameMain_Begin_Postfix()
|
||||
{
|
||||
LoopCall(PostGameBeginFuncs);
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(GameMain), nameof(GameMain.End))]
|
||||
private static void GameMain_End_Prefix()
|
||||
{
|
||||
LoopCall(PreGameEndFuncs);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameMain), nameof(GameMain.End))]
|
||||
private static void GameMain_End_Postfix()
|
||||
{
|
||||
LoopCall(PostGameEndFuncs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>LuaScriptEngine</AssemblyName>
|
||||
<BepInExPluginGuid>org.soardev.luascriptengine</BepInExPluginGuid>
|
||||
<Description>DSP MOD - LuaScriptEngine</Description>
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<RestoreAdditionalProjectSources>https://nuget.bepinex.dev/v3/index.json</RestoreAdditionalProjectSources>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLua" Version="1.*" />
|
||||
<PackageReference Include="BepInEx.Core" Version="5.*" />
|
||||
<PackageReference Include="BepInEx.PluginInfoProps" Version="1.*" />
|
||||
<!-- <PackageReference Include="DysonSphereProgram.GameLibs" Version="*-r.*" /> -->
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2022.3.53" IncludeAssets="compile" />
|
||||
</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 Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Exec Command="del /F /Q package\$(ProjectName)-$(Version).zip
|
||||
powershell Compress-Archive -Force -DestinationPath 'package/$(ProjectName)-$(Version).zip' -Path '$(TargetPath)', '$(TargetDir)/KeraLua.dll', '$(TargetDir)/lua54.dll', '$(TargetDir)/NLua.dll', package/icon.png, package/manifest.json, README.md" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,8 +0,0 @@
|
||||
# LuaScriptEngine
|
||||
|
||||
#### Write mod functions in lua scripts
|
||||
#### 用lua脚本编写mod功能
|
||||
|
||||
## Usage
|
||||
|
||||
## 使用说明
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 50 KiB |
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"name": "LuaScriptEngine",
|
||||
"version_number": "1.0.0",
|
||||
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/LuaScriptEngine",
|
||||
"description": "Write mod functions in lua scripts / 用lua脚本编写mod功能",
|
||||
"dependencies": [
|
||||
"xiaoye97-BepInEx-5.4.17"
|
||||
]
|
||||
}
|
||||
@@ -15,17 +15,8 @@
|
||||
<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="2022.3.53" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\AssemblyFromGame\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>..\AssemblyFromGame\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<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'">
|
||||
@@ -33,6 +24,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Exec Command="powershell Compress-Archive -Force -DestinationPath 'package/$(ProjectName)-$(Version).zip' -Path '$(TargetPath)', package/icon.png, package/manifest.json, README.md" />
|
||||
<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" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -16,18 +16,9 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BepInEx.Core" Version="5.*" />
|
||||
<PackageReference Include="BepInEx.PluginInfoProps" Version="1.*" />
|
||||
<!-- <PackageReference Include="DysonSphereProgram.GameLibs" Version="0.10.32.*-r.*" /> -->
|
||||
<PackageReference Include="DysonSphereProgram.GameLibs" Version="0.10.32.*-r.*" />
|
||||
<PackageReference Include="DysonSphereProgram.Modding.DSPModSave" Version="1.*" />
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2022.3.53" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\AssemblyFromGame\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>..\AssemblyFromGame\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<PackageReference Include="UnityEngine.Modules" Version="2018.4.12" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
|
||||
@@ -35,6 +26,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Exec Command="powershell Compress-Archive -Force -DestinationPath 'package/$(ProjectName)-$(Version).zip' -Path '$(TargetPath)', package/icon.png, package/manifest.json, README.md" />
|
||||
<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" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -15,17 +15,8 @@
|
||||
<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="2022.3.53" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\AssemblyFromGame\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>..\AssemblyFromGame\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<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'">
|
||||
@@ -33,6 +24,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Exec Command="powershell Compress-Archive -Force -DestinationPath 'package/$(ProjectName)-$(Version).zip' -Path '$(TargetPath)', package/icon.png, package/manifest.json, README.md" />
|
||||
<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" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
50
README.md
50
README.md
@@ -9,16 +9,36 @@ Add various cheat functions while disabling abnormal determinants
|
||||
|
||||
Moved [to another repo](https://github.com/soarqin/DSP_Mods_TO/tree/master/CompressSave)
|
||||
|
||||
## [Dustbin](Dustbin)
|
||||
## [LogisticHub](LogisticHub)
|
||||
|
||||
Can turn Storages and Tanks into Dustbin(Destroy incoming items)
|
||||
储物仓和储液罐可以转变为垃圾桶(销毁送进的物品)
|
||||
Cheat functions for Logistic Storages, make them mine resources on the planet and exchange items from certain buildings
|
||||
物流塔作弊功能,使其可以在星球上采矿并与特定建筑物交换物品
|
||||
|
||||
## [HideTips](HideTips)
|
||||
|
||||
Hide/Disable various tutorial tips/messages
|
||||
隐藏/屏蔽各种引导提示/消息
|
||||
|
||||
## [Dustbin](Dustbin)
|
||||
|
||||
Can turn Storages and Tanks into Dustbin(Destroy incoming items)
|
||||
储物仓和储液罐可以转变为垃圾桶(销毁送进的物品)
|
||||
|
||||
## [OverclockEverything](OverclockEverything)
|
||||
|
||||
Boost nearly all structures
|
||||
加速几乎所有建筑功能
|
||||
|
||||
## [UniverseGenTweaks](UniverseGenTweaks)
|
||||
|
||||
Universe Generator Tweak
|
||||
宇宙生成参数调节
|
||||
|
||||
## [MechaDronesTweaks](MechaDronesTweaks)
|
||||
|
||||
Some tweaks for mecha drones and build functions(Successor to FastDrones MOD)
|
||||
机甲建设机和建设功能调整(FastDrones MOD的后继者)
|
||||
|
||||
## [LabOpt](LabOpt)
|
||||
|
||||
Performance optimizations for Matrix Labs
|
||||
@@ -26,35 +46,11 @@ Marked as obsoleted temporarily, needs more investigation about LabComponent's m
|
||||
优化研究站性能
|
||||
暂时标识为过期,需要更多关于LabComponent机制的研究
|
||||
|
||||
## [LogisticMiner](LogisticMiner)
|
||||
|
||||
Logistic Storages can mine all ores/water on current planet
|
||||
物流塔可以采集当前星球的全部矿产(以及水)
|
||||
|
||||
## [LuaScriptEngine](LuaScriptEngine)
|
||||
Write mod functions in lua scripts
|
||||
用lua脚本编写mod功能
|
||||
|
||||
## [MechaDronesTweaks](MechaDronesTweaks)
|
||||
|
||||
Some tweaks for mecha drones and build functions(Successor to FastDrones MOD)
|
||||
机甲建设机和建设功能调整(FastDrones MOD的后继者)
|
||||
|
||||
## [OverclockEverything](OverclockEverything)
|
||||
|
||||
Boost nearly all structures
|
||||
加速几乎所有建筑功能
|
||||
|
||||
## [PoolOpt](PoolOpt)
|
||||
|
||||
Optimize memory pools on loading gamesaves
|
||||
加载游戏存档时优化内存池的使用
|
||||
|
||||
## [UniverseGenTweaks](UniverseGenTweaks)
|
||||
|
||||
Universe Generator Tweak
|
||||
宇宙生成参数调节
|
||||
|
||||
## [UserCloak](UserCloak)
|
||||
|
||||
Cloak(Fake) user account info
|
||||
|
||||
@@ -3,16 +3,6 @@
|
||||
|
||||
## Changlog
|
||||
|
||||
* 1.4.5
|
||||
* New feature: `Ctrl+Shift+Click to pick items from whole belts`, with 2 suboptions: `Include branches of belts` and `Include connected inserters`
|
||||
* Patch [BlueprintTweaks](https://thunderstore.io/c/dyson-sphere-program/p/kremnev8/BlueprintTweaks/) temporarily to fix `Drag Remove` functions (And wait for limoka to merge the [Pull Request](https://github.com/limoka/DSP-Mods/pull/133)):
|
||||
* Ground rendering is correct now.
|
||||
* Dismantle logic follows offcial's implementation to avoid possible crashes.
|
||||
* Fixed CommonAPI patch to make shortcut key settings saved as expect now, sorry for wrong implementation in last version.
|
||||
* 1.4.4
|
||||
* `Remember window position and size on last exit`: Fix compatiblity for game patch 0.10.33
|
||||
* `Real-time logistic stations info panel`: Try to fix a display issue.
|
||||
* Patch [CommonAPI](https://thunderstore.io/c/dyson-sphere-program/p/CommonAPI/CommonAPI/) temporarily to fix a known issue that shortcut key settings are not saved to config, while its [PR](https://github.com/limoka/CommonAPI/pull/14) is not merged yet.
|
||||
* 1.4.3
|
||||
* `Build Tesla Tower and Wireless Power Tower alternately`:
|
||||
* Fix wrong implementation for latest game patch.
|
||||
@@ -356,16 +346,6 @@
|
||||
|
||||
## 更新日志
|
||||
|
||||
* 1.4.5
|
||||
* 新功能:`按住Ctrl+Shift点击从整条传送带抓取物品`,包含两个子选项:`包含传送带分支` 和 `包含连接的分拣器`
|
||||
* 临时修复 [BlueprintTweaks](https://thunderstore.io/c/dyson-sphere-program/p/kremnev8/BlueprintTweaks/) 的 `拖拽拆除` 功能(等待 limoka 合并 [Pull Request](https://github.com/limoka/DSP-Mods/pull/133)):
|
||||
* 地面绘制现在已正确
|
||||
* 拆除逻辑遵循官方实现,避免潜在崩溃可能
|
||||
* 修正了 CommonAPI 的补丁,现在快捷键设置可以如预期保存了,不好意思上一版本实现有误
|
||||
* 1.4.4
|
||||
* `记住上次退出时的窗口位置和大小`:修复对游戏补丁0.10.33的兼容性
|
||||
* `物流站实时信息面板`:尝试修复一个显示问题
|
||||
* 对[CommonAPI](https://thunderstore.io/c/dyson-sphere-program/p/CommonAPI/CommonAPI/)临时打补丁,修复快捷键设置未能保存到配置文件的已知问题(其[PR](https://github.com/limoka/CommonAPI/pull/14)仍未合并)
|
||||
* 1.4.3
|
||||
* `交替建造电力感应塔和无线输电塔`:
|
||||
* 修复了在最新游戏补丁中的错误实现
|
||||
|
||||
@@ -24,13 +24,6 @@ public static class FactoryFunctions
|
||||
cargoTraffic.AlterBeltConnections(beltId, 0, i0, i1, i2);
|
||||
}
|
||||
|
||||
public static bool ObjectIsBeltOrInserter(PlanetFactory factory, int objId)
|
||||
{
|
||||
if (objId == 0) return false;
|
||||
ItemProto proto = LDB.items.Select(objId > 0 ? factory.entityPool[objId].protoId : factory.prebuildPool[-objId].protoId);
|
||||
return proto != null && (proto.prefabDesc.isBelt || proto.prefabDesc.isInserter);
|
||||
}
|
||||
|
||||
public static void DismantleBlueprintSelectedBuildings()
|
||||
{
|
||||
var player = GameMain.mainPlayer;
|
||||
@@ -57,7 +50,7 @@ public static class FactoryFunctions
|
||||
for (var j = 0; j < 2; j++)
|
||||
{
|
||||
factory.ReadObjectConn(objId, j, out _, out var connObjId, out _);
|
||||
if (connObjId == 0 || ObjectIsBeltOrInserter(factory, connObjId)) continue;
|
||||
if (connObjId == 0 || factory.ObjectIsBelt(connObjId) || blueprintCopyTool.ObjectIsInserter(connObjId)) continue;
|
||||
needCheck = true;
|
||||
break;
|
||||
}
|
||||
@@ -66,7 +59,7 @@ public static class FactoryFunctions
|
||||
for (var k = 0; k < 16; k++)
|
||||
{
|
||||
factory.ReadObjectConn(objId, k, out _, out var connObjId, out _);
|
||||
if (connObjId != 0 && (index = buildPreviewsToRemove.BinarySearch(connObjId)) < 0 && ObjectIsBeltOrInserter(factory, connObjId))
|
||||
if (connObjId != 0 && (index = buildPreviewsToRemove.BinarySearch(connObjId)) < 0 && (factory.ObjectIsBelt(connObjId) || blueprintCopyTool.ObjectIsInserter(connObjId)))
|
||||
buildPreviewsToRemove.Insert(~index, connObjId);
|
||||
}
|
||||
}
|
||||
@@ -77,7 +70,7 @@ public static class FactoryFunctions
|
||||
for (var j = 0; j < 2; j++)
|
||||
{
|
||||
factory.ReadObjectConn(connObjId, j, out _, out var connObjId2, out _);
|
||||
if (connObjId2 == 0 || (index = buildPreviewsToRemove.BinarySearch(connObjId2)) >= 0 || ObjectIsBeltOrInserter(factory, connObjId2)) continue;
|
||||
if (connObjId2 == 0 || (index = buildPreviewsToRemove.BinarySearch(connObjId2)) >= 0 || factory.ObjectIsBelt(connObjId2) || blueprintCopyTool.ObjectIsInserter(connObjId2)) continue;
|
||||
buildPreviewsToRemove.Insert(~index, connObjId);
|
||||
break;
|
||||
}
|
||||
@@ -88,7 +81,7 @@ public static class FactoryFunctions
|
||||
for (var j = 0; j < 16; j++)
|
||||
{
|
||||
factory.ReadObjectConn(objId, j, out _, out var connObjId, out _);
|
||||
if (connObjId != 0 && (index = buildPreviewsToRemove.BinarySearch(connObjId)) < 0 && ObjectIsBeltOrInserter(factory, connObjId))
|
||||
if (connObjId != 0 && (index = buildPreviewsToRemove.BinarySearch(connObjId)) < 0 && (factory.ObjectIsBelt(connObjId) || blueprintCopyTool.ObjectIsInserter(connObjId)))
|
||||
buildPreviewsToRemove.Insert(~index, connObjId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ public static class PlanetFunctions
|
||||
uiGame.ShutAllFullScreens();
|
||||
}
|
||||
player.controller.actionBuild.Close();
|
||||
|
||||
var groundCombatModule = player.mecha.groundCombatModule;
|
||||
for (var i = 0; i < groundCombatModule.moduleFleets.Length; i++)
|
||||
{
|
||||
@@ -68,42 +67,6 @@ public static class PlanetFunctions
|
||||
entry.fleetEnabled = false;
|
||||
groundCombatModule.RemoveFleetDirectly(i);
|
||||
}
|
||||
var constructionSystem = factory.constructionSystem;
|
||||
var constructionModule = player.mecha.constructionModule;
|
||||
for (var i = 0; i < constructionSystem.drones.cursor; i++)
|
||||
{
|
||||
ref var drone = ref constructionSystem.drones.buffer[i];
|
||||
if (drone.id <= 0) continue;
|
||||
var owner = drone.owner;
|
||||
constructionSystem.ResetDroneTargets(ref drone);
|
||||
if (owner == 0)
|
||||
{
|
||||
factory.RemoveCraftWithComponents(drone.craftId);
|
||||
constructionModule.droneIdleCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
drone.movement = factory.gameData.history.constructionDroneMovement;
|
||||
factory.craftPool[drone.craftId].pos = constructionSystem.constructionModules[owner].baseEjectPos;
|
||||
constructionSystem.constructionModules[owner].droneIdleCount++;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < constructionSystem.constructStats.cursor; i++)
|
||||
{
|
||||
ref var constructStat = ref constructionSystem.constructStats.buffer[i];
|
||||
if (constructStat.id <= 0) continue;
|
||||
constructionSystem.RemoveConstructStat(constructStat.id);
|
||||
}
|
||||
constructionModule.autoReconstructTargetTotalCount = 0;
|
||||
constructionModule.buildTargetTotalCount = 0;
|
||||
constructionModule.repairTargetTotalCount = 0;
|
||||
constructionModule.autoReconstructTargets = null;
|
||||
constructionModule.buildTargets = null;
|
||||
constructionModule.repairTargets = null;
|
||||
constructionModule.tmpTargets = null;
|
||||
constructionModule.tmpTargetsHash = null;
|
||||
constructionModule.checkItemCursor = 0;
|
||||
|
||||
//planet.data = new PlanetRawData(planet.precision);
|
||||
//planet.data.CalcVerts();
|
||||
for (var id = factory.entityCursor - 1; id > 0; id--)
|
||||
@@ -130,20 +93,6 @@ public static class PlanetFunctions
|
||||
planet.audio?.RemoveAudioData(ed.audioId);
|
||||
}
|
||||
|
||||
for (var id = factory.prebuildCursor - 1; id > 0; id--)
|
||||
{
|
||||
ref var pb = ref factory.prebuildPool[id];
|
||||
if (pb.id != id) continue;
|
||||
if (pb.colliderId != 0)
|
||||
{
|
||||
planet.physics.RemoveLinkedColliderData(pb.colliderId);
|
||||
}
|
||||
if (pb.modelId != 0)
|
||||
{
|
||||
GameMain.gpuiManager.RemovePrebuildModel(pb.modelIndex, pb.modelId);
|
||||
}
|
||||
}
|
||||
|
||||
var hives = GameMain.spaceSector?.dfHives;
|
||||
if (hives != null)
|
||||
{
|
||||
@@ -166,18 +115,18 @@ public static class PlanetFunctions
|
||||
}
|
||||
}
|
||||
|
||||
if (factory.enemyPool != null)
|
||||
if (planet.factory.enemyPool != null)
|
||||
{
|
||||
for (var i = factory.enemyCursor - 1; i > 0; i--)
|
||||
for (var i = planet.factory.enemyCursor - 1; i > 0; i--)
|
||||
{
|
||||
ref var enemyData = ref factory.enemyPool[i];
|
||||
ref var enemyData = ref planet.factory.enemyPool[i];
|
||||
if (enemyData.id != i) continue;
|
||||
var combatStatId = enemyData.combatStatId;
|
||||
factory.skillSystem.OnRemovingSkillTarget(combatStatId, factory.skillSystem.combatStats.buffer[combatStatId].originAstroId, ETargetType.CombatStat);
|
||||
factory.skillSystem.combatStats.Remove(combatStatId);
|
||||
factory.KillEnemyFinally(i, ref CombatStat.empty);
|
||||
planet.factory.skillSystem.OnRemovingSkillTarget(combatStatId, planet.factory.skillSystem.combatStats.buffer[combatStatId].originAstroId, ETargetType.CombatStat);
|
||||
planet.factory.skillSystem.combatStats.Remove(combatStatId);
|
||||
planet.factory.KillEnemyFinally(i, ref CombatStat.empty);
|
||||
}
|
||||
factory.enemySystem.Free();
|
||||
planet.factory.enemySystem.Free();
|
||||
UIRoot.instance.uiGame.dfAssaultTip.ClearAllSpots();
|
||||
}
|
||||
|
||||
@@ -216,7 +165,7 @@ public static class PlanetFunctions
|
||||
factory.PlanetReformRevert();
|
||||
}
|
||||
|
||||
GameMain.data.LeavePlanet();
|
||||
planet.UnloadFactory();
|
||||
var index = factory.index;
|
||||
var warningSystem = GameMain.data.warningSystem;
|
||||
var warningPool = warningSystem.warningPool;
|
||||
@@ -263,19 +212,6 @@ public static class PlanetFunctions
|
||||
factory.factoryStorage = new FactoryStorage(planet);
|
||||
factory.powerSystem = new PowerSystem(planet);
|
||||
factory.constructionSystem = new ConstructionSystem(planet);
|
||||
if (factory.veinPool != null)
|
||||
{
|
||||
for (var i = 0; i < factory.veinPool.Length; i++)
|
||||
{
|
||||
ref var vein = ref factory.veinPool[i];
|
||||
if (vein.id != i) continue;
|
||||
vein.minerCount = 0;
|
||||
vein.minerId0 = 0;
|
||||
vein.minerId1 = 0;
|
||||
vein.minerId2 = 0;
|
||||
vein.minerId3 = 0;
|
||||
}
|
||||
}
|
||||
factory.InitVeinHashAddress();
|
||||
factory.RecalculateAllVeinGroups();
|
||||
factory.InitVegeHashAddress();
|
||||
@@ -302,7 +238,12 @@ public static class PlanetFunctions
|
||||
factory.digitalSystem = new DigitalSystem(planet);
|
||||
|
||||
//GameMain.data.statistics.production.CreateFactoryStat(index);
|
||||
GameMain.data.ArrivePlanet(planet);
|
||||
planet.LoadFactory();
|
||||
while (!planet.factoryLoaded)
|
||||
{
|
||||
PlanetModelingManager.Update();
|
||||
Thread.Sleep(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static void BuildOrbitalCollectors()
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using CommonAPI.Systems;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using CommonAPI.Systems;
|
||||
using UXAssist.Common;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UXAssist.UI;
|
||||
using UXAssist.Common;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace UXAssist.Functions;
|
||||
@@ -41,8 +39,6 @@ public static class UIFunctions
|
||||
I18N.Add("Show distance", "Show distance", "显示距离");
|
||||
I18N.Add("Show planet count", "Show planet count", "显示行星数");
|
||||
I18N.Add("Show all information", "Show all information", "显示全部信息");
|
||||
I18N.Add("Show top players", "Show top players", "显示玩家排行榜");
|
||||
I18N.Add("Hide top players", "Hide top players", "隐藏玩家排行榜");
|
||||
I18N.OnInitialized += RecreateConfigWindow;
|
||||
}
|
||||
|
||||
@@ -723,268 +719,4 @@ public static class UIFunctions
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region MilkyWayClusterUploadResult
|
||||
|
||||
const int ClusterUploadResultKeepCount = 100;
|
||||
private static readonly ClusterUploadResult[] _clusterUploadResults = new ClusterUploadResult[ClusterUploadResultKeepCount];
|
||||
private static readonly object _clusterUploadResultsLock = new();
|
||||
private static int _clusterUploadResultsHead = 0;
|
||||
private static int _clusterUploadResultsCount = 0;
|
||||
|
||||
private struct ClusterUploadResult
|
||||
{
|
||||
public DateTime UploadTime;
|
||||
public int Result;
|
||||
public float RequestTime;
|
||||
}
|
||||
|
||||
public static void AddClusterUploadResult(int result, float requestTime)
|
||||
{
|
||||
lock (_clusterUploadResultsLock)
|
||||
{
|
||||
if (_clusterUploadResultsCount >= ClusterUploadResultKeepCount)
|
||||
{
|
||||
_clusterUploadResults[_clusterUploadResultsHead] = new ClusterUploadResult { UploadTime = DateTime.Now, Result = result, RequestTime = requestTime };
|
||||
_clusterUploadResultsHead = (_clusterUploadResultsHead + 1) % ClusterUploadResultKeepCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
_clusterUploadResults[(_clusterUploadResultsHead + _clusterUploadResultsCount) % ClusterUploadResultKeepCount] = new ClusterUploadResult { UploadTime = DateTime.Now, Result = result, RequestTime = requestTime };
|
||||
_clusterUploadResultsCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void ExportClusterUploadResults(BinaryWriter w)
|
||||
{
|
||||
lock (_clusterUploadResultsLock)
|
||||
{
|
||||
w.Write(_clusterUploadResultsCount);
|
||||
w.Write(_clusterUploadResultsHead);
|
||||
for (var i = 0; i < _clusterUploadResultsCount; i++)
|
||||
{
|
||||
ref var result = ref _clusterUploadResults[(i + _clusterUploadResultsHead) % ClusterUploadResultKeepCount];
|
||||
w.Write(result.UploadTime.ToBinary());
|
||||
w.Write(result.Result);
|
||||
w.Write(result.RequestTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ImportClusterUploadResults(BinaryReader r)
|
||||
{
|
||||
lock (_clusterUploadResultsLock)
|
||||
{
|
||||
_clusterUploadResultsCount = r.ReadInt32();
|
||||
_clusterUploadResultsHead = r.ReadInt32();
|
||||
for (var i = 0; i < _clusterUploadResultsCount; i++)
|
||||
{
|
||||
ref var result = ref _clusterUploadResults[(i + _clusterUploadResultsHead) % ClusterUploadResultKeepCount];
|
||||
result.UploadTime = DateTime.FromBinary(r.ReadInt64());
|
||||
result.Result = r.ReadInt32();
|
||||
result.RequestTime = r.ReadSingle();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region MilkyWayTopTenPlayers
|
||||
private static ClusterPlayerData[] _topTenPlayerData = null;
|
||||
private static readonly StringBuilder _sb = new(" ", 12);
|
||||
|
||||
public static UI.MyCheckButton MilkyWayTopTenPlayersToggler;
|
||||
public static event Action OnMilkyWayTopTenPlayersUpdated;
|
||||
|
||||
public static void SetTopPlayerCount(int count)
|
||||
{
|
||||
_topTenPlayerData = new ClusterPlayerData[count];
|
||||
}
|
||||
|
||||
public static void SetTopPlayerData(int index, ref ClusterPlayerData playerData)
|
||||
{
|
||||
if (index < 0 || index >= _topTenPlayerData.Length) return;
|
||||
_topTenPlayerData[index] = playerData;
|
||||
}
|
||||
|
||||
public static void UpdateMilkyWayTopTenPlayers()
|
||||
{
|
||||
if (_topTenPlayerData == null) return;
|
||||
OnMilkyWayTopTenPlayersUpdated?.Invoke();
|
||||
}
|
||||
|
||||
public static void InitMilkyWayTopTenPlayers()
|
||||
{
|
||||
var uiRoot = UIRoot.instance;
|
||||
if (!uiRoot) return;
|
||||
|
||||
var rect = uiRoot.uiMilkyWay.transform as RectTransform;
|
||||
var panel = new GameObject("uxassist-milkyway-top-ten-players-panel");
|
||||
var rtrans = panel.AddComponent<RectTransform>();
|
||||
rtrans.SetParent(rect);
|
||||
rtrans.sizeDelta = new Vector2(0f, 0f);
|
||||
rtrans.localScale = new Vector3(1f, 1f, 1f);
|
||||
rtrans.anchorMax = new Vector2(1f, 1f);
|
||||
rtrans.anchorMin = new Vector2(0f, 0f);
|
||||
rtrans.pivot = new Vector2(0f, 1f);
|
||||
rtrans.anchoredPosition3D = new Vector3(0, 0, 0f);
|
||||
|
||||
MyFlatButton[] buttons = [];
|
||||
Text[] textFields = [];
|
||||
|
||||
MilkyWayTopTenPlayersToggler = UI.MyCheckButton.CreateCheckButton(0, 0, rtrans, false, "Show top players".Translate()).WithSize(100f, 24f);
|
||||
MilkyWayTopTenPlayersToggler.OnChecked += UpdateButtons;
|
||||
MilkyWayTopTenPlayersToggler.Checked = false;
|
||||
UpdateButtons();
|
||||
OnMilkyWayTopTenPlayersUpdated += UpdateButtons;
|
||||
|
||||
Text CreateTextField(RectTransform parent)
|
||||
{
|
||||
var txt = UnityEngine.Object.Instantiate(UIRoot.instance.uiGame.assemblerWindow.stateText, parent);
|
||||
txt.gameObject.name = "uxassist-milkyway-top-ten-players-text-field";
|
||||
txt.text = "";
|
||||
txt.color = new Color(1f, 1f, 1f, 0.4f);
|
||||
txt.alignment = TextAnchor.MiddleLeft;
|
||||
txt.fontSize = 15;
|
||||
txt.rectTransform.sizeDelta = new Vector2(0, 18);
|
||||
return txt;
|
||||
}
|
||||
|
||||
void UpdateButtons()
|
||||
{
|
||||
var chk = MilkyWayTopTenPlayersToggler.Checked;
|
||||
if (_topTenPlayerData == null)
|
||||
{
|
||||
MilkyWayTopTenPlayersToggler.gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
var count = _topTenPlayerData.Length;
|
||||
MilkyWayTopTenPlayersToggler.gameObject.SetActive(count > 0);
|
||||
if (count != buttons.Length)
|
||||
{
|
||||
for (var i = count; i < buttons.Length; i++)
|
||||
{
|
||||
UnityEngine.Object.Destroy(buttons[i].gameObject);
|
||||
UnityEngine.Object.Destroy(textFields[i * 4].gameObject);
|
||||
UnityEngine.Object.Destroy(textFields[i * 4 + 1].gameObject);
|
||||
UnityEngine.Object.Destroy(textFields[i * 4 + 2].gameObject);
|
||||
UnityEngine.Object.Destroy(textFields[i * 4 + 3].gameObject);
|
||||
}
|
||||
Array.Resize(ref buttons, count);
|
||||
Array.Resize(ref textFields, count * 4);
|
||||
}
|
||||
float maxWidth0 = 0f;
|
||||
float maxWidth1 = 0f;
|
||||
float maxWidth2 = 0f;
|
||||
float maxWidth3 = 0f;
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var button = buttons[i];
|
||||
if (chk)
|
||||
{
|
||||
if (button == null)
|
||||
{
|
||||
button = MyFlatButton.CreateFlatButton(0f, 20f * i + 24f, rtrans, "").WithSize(20f, 18f);
|
||||
buttons[i] = button;
|
||||
button.uiButton.data = i;
|
||||
button.uiButton.onClick += data =>
|
||||
{
|
||||
if (data < 0 || data >= _topTenPlayerData.Length) return;
|
||||
ref var playerData = ref _topTenPlayerData[data];
|
||||
var seed = playerData.seedKey;
|
||||
int combatValue = (int)(seed % 1000L);
|
||||
int resourceMultiplier = (int)(seed / 1000L % 100L);
|
||||
int starCount = (int)(seed / 100000L % 1000L);
|
||||
int gameSeed = (int)(seed / 100000000L);
|
||||
var uiMilkyWaySearchPanel = UIRoot.instance.uiMilkyWay.uiSearchPanel;
|
||||
uiMilkyWaySearchPanel.selectSeed = gameSeed;
|
||||
uiMilkyWaySearchPanel.selectStarCnt = starCount;
|
||||
uiMilkyWaySearchPanel.selectResMulti = resourceMultiplier;
|
||||
if (combatValue / 100 > 0)
|
||||
{
|
||||
uiMilkyWaySearchPanel.selectMode = 1;
|
||||
uiMilkyWaySearchPanel.selectCombatDiff = combatValue % 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
uiMilkyWaySearchPanel.selectMode = 0;
|
||||
uiMilkyWaySearchPanel.selectCombatDiff = 0;
|
||||
}
|
||||
uiMilkyWaySearchPanel.RefreshInputText();
|
||||
uiMilkyWaySearchPanel.OnSearchButtonClick(0);
|
||||
};
|
||||
textFields[i * 4] = CreateTextField(rtrans);
|
||||
textFields[i * 4].alignment = TextAnchor.MiddleRight;
|
||||
textFields[i * 4 + 1] = CreateTextField(rtrans);
|
||||
textFields[i * 4 + 2] = CreateTextField(rtrans);
|
||||
textFields[i * 4 + 3] = CreateTextField(rtrans);
|
||||
textFields[i * 4 + 3].alignment = TextAnchor.MiddleRight;
|
||||
}
|
||||
button.SetLabelText(">>");
|
||||
textFields[i * 4].text = (i + 1).ToString();
|
||||
textFields[i * 4 + 1].text = _topTenPlayerData[i].name;
|
||||
textFields[i * 4 + 2].text = SeedToString(_topTenPlayerData[i].seedKey);
|
||||
textFields[i * 4 + 3].text = String.Format("{0}W", ToKMG(_topTenPlayerData[i].genCap * 60L));
|
||||
maxWidth0 = Math.Max(maxWidth0, textFields[i * 4].preferredWidth);
|
||||
maxWidth1 = Math.Max(maxWidth1, textFields[i * 4 + 1].preferredWidth);
|
||||
maxWidth2 = Math.Max(maxWidth2, textFields[i * 4 + 2].preferredWidth);
|
||||
maxWidth3 = Math.Max(maxWidth3, textFields[i * 4 + 3].preferredWidth);
|
||||
button.gameObject.SetActive(true);
|
||||
textFields[i * 4].gameObject.SetActive(true);
|
||||
textFields[i * 4 + 1].gameObject.SetActive(true);
|
||||
textFields[i * 4 + 2].gameObject.SetActive(true);
|
||||
textFields[i * 4 + 3].gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (button != null)
|
||||
{
|
||||
button.gameObject.SetActive(false);
|
||||
textFields[i * 4].gameObject.SetActive(false);
|
||||
textFields[i * 4 + 1].gameObject.SetActive(false);
|
||||
textFields[i * 4 + 2].gameObject.SetActive(false);
|
||||
textFields[i * 4 + 3].gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chk)
|
||||
{
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var y = 20f * i + 24f;
|
||||
UI.Util.NormalizeRectWithTopLeft(textFields[i * 4].rectTransform, 24f + maxWidth0 + 5f, y);
|
||||
UI.Util.NormalizeRectWithTopLeft(textFields[i * 4 + 1].rectTransform, 24f + maxWidth0 + 10f, y);
|
||||
UI.Util.NormalizeRectWithTopLeft(textFields[i * 4 + 2].rectTransform, 24f + maxWidth0 + 10f + maxWidth1 + 5f, y);
|
||||
UI.Util.NormalizeRectWithTopLeft(textFields[i * 4 + 3].rectTransform, 24f + maxWidth0 + 10f + maxWidth1 + 5f + maxWidth2 + 5f + maxWidth3, y);
|
||||
}
|
||||
}
|
||||
MilkyWayTopTenPlayersToggler.SetLabelText(chk ? "Hide top players".Translate() : "Show top players".Translate());
|
||||
|
||||
string ToKMG(long value)
|
||||
{
|
||||
StringBuilderUtility.WriteKMG(_sb, 8, value, true);
|
||||
return _sb.ToString();
|
||||
}
|
||||
|
||||
string SeedToString(long seed)
|
||||
{
|
||||
int combatValue = (int)(seed % 1000L);
|
||||
int resourceMultiplier = (int)(seed / 1000L % 100L);
|
||||
int starCount = (int)(seed / 100000L % 1000L);
|
||||
int gameSeed = (int)(seed / 100000000L);
|
||||
string text;
|
||||
if (combatValue / 100 > 0)
|
||||
{
|
||||
text = String.Format("{0:D8}-{1}-Z{2}-{3:00}", gameSeed, starCount, resourceMultiplier, combatValue % 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
text = String.Format("{0:D8}-{1}-A{2}", gameSeed, starCount, resourceMultiplier);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
using HarmonyLib;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using UnityEngine;
|
||||
using UXAssist.Functions;
|
||||
|
||||
namespace UXAssist.ModsCompat;
|
||||
|
||||
class BlueprintTweaks
|
||||
{
|
||||
public const string BlueprintTweaksGuid = "org.kremnev8.plugin.BlueprintTweaks";
|
||||
private static FieldInfo selectObjIdsField;
|
||||
private static Type classTypeBlueprintTweaksPlugin;
|
||||
private static Type classTypeUIBuildingGridPatch2;
|
||||
|
||||
public static bool Run(Harmony harmony)
|
||||
{
|
||||
if (!BepInEx.Bootstrap.Chainloader.PluginInfos.TryGetValue(BlueprintTweaksGuid, out var pluginInfo)) return false;
|
||||
var assembly = pluginInfo.Instance.GetType().Assembly;
|
||||
var classTypeDragRemoveBuildTool = assembly.GetType("BlueprintTweaks.DragRemoveBuildTool");
|
||||
if (classTypeDragRemoveBuildTool == null) return false;
|
||||
if (AccessTools.Method(classTypeDragRemoveBuildTool, "DetermineMorePreviews") != null) return true;
|
||||
classTypeBlueprintTweaksPlugin = assembly.GetType("BlueprintTweaks.BlueprintTweaksPlugin");
|
||||
classTypeUIBuildingGridPatch2 = assembly.GetType("BlueprintTweaks.UIBuildingGridPatch2");
|
||||
var UIBuildingGrid_Update = AccessTools.Method(typeof(UIBuildingGrid), nameof(UIBuildingGrid.Update));
|
||||
harmony.Patch(AccessTools.Method(classTypeUIBuildingGridPatch2, "UpdateGrid"), null, null, new HarmonyMethod(AccessTools.Method(typeof(BlueprintTweaks), nameof(PatchUpdateGrid))));
|
||||
selectObjIdsField = AccessTools.Field(classTypeDragRemoveBuildTool, "selectObjIds");
|
||||
harmony.Patch(AccessTools.Method(classTypeDragRemoveBuildTool, "DeterminePreviews"),
|
||||
new HarmonyMethod(AccessTools.Method(typeof(BlueprintTweaks), nameof(PatchDeterminePreviews))));
|
||||
return true;
|
||||
}
|
||||
|
||||
private static readonly int zMin = Shader.PropertyToID("_ZMin");
|
||||
private static readonly int reformMode = Shader.PropertyToID("_ReformMode");
|
||||
|
||||
private static IEnumerable<CodeInstruction> PatchUpdateGrid(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(classTypeBlueprintTweaksPlugin, "tool")),
|
||||
new CodeMatch(OpCodes.Ldfld),
|
||||
new CodeMatch(ci => ci.opcode == OpCodes.Brfalse || ci.opcode == OpCodes.Brfalse_S)
|
||||
);
|
||||
var label1 = generator.DefineLabel();
|
||||
matcher.Advance(2).Operand = label1;
|
||||
matcher.Advance(1);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldarg_0),
|
||||
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIBuildingGrid), nameof(UIBuildingGrid.blueprintMaterial))),
|
||||
new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(classTypeUIBuildingGridPatch2, "tintColor")),
|
||||
new CodeMatch(OpCodes.Call),
|
||||
new CodeMatch(OpCodes.Callvirt)
|
||||
).RemoveInstructions(5);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldarg_0),
|
||||
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIBuildingGrid), nameof(UIBuildingGrid.blueprintMaterial))),
|
||||
new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(classTypeUIBuildingGridPatch2, "cursorGratBox")),
|
||||
new CodeMatch(OpCodes.Ldsfld),
|
||||
new CodeMatch(OpCodes.Ldfld),
|
||||
new CodeMatch(OpCodes.Call),
|
||||
new CodeMatch(OpCodes.Callvirt)
|
||||
).Advance(1).Operand = AccessTools.Field(typeof(UIBuildingGrid), nameof(UIBuildingGrid.material));
|
||||
matcher.Advance(6);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldarg_0),
|
||||
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIBuildingGrid), nameof(UIBuildingGrid.blueprintMaterial))),
|
||||
new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(classTypeUIBuildingGridPatch2, "selectColor")),
|
||||
new CodeMatch(OpCodes.Ldarg_0),
|
||||
new CodeMatch(OpCodes.Ldfld),
|
||||
new CodeMatch(OpCodes.Call),
|
||||
new CodeMatch(OpCodes.Callvirt)
|
||||
).Advance(1).Operand = AccessTools.Field(typeof(UIBuildingGrid), nameof(UIBuildingGrid.material));
|
||||
matcher.Advance(1).Operand = AccessTools.Field(classTypeUIBuildingGridPatch2, "tintColor");
|
||||
matcher.Advance(5);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldarg_0),
|
||||
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIBuildingGrid), nameof(UIBuildingGrid.blueprintMaterial))),
|
||||
new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(classTypeUIBuildingGridPatch2, "showDivideLine")),
|
||||
new CodeMatch(OpCodes.Ldc_R4, 0f),
|
||||
new CodeMatch(OpCodes.Callvirt)
|
||||
).RemoveInstructions(5);
|
||||
matcher.InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_0),
|
||||
Transpilers.EmitDelegate((UIBuildingGrid grid) =>
|
||||
{
|
||||
grid.material.SetFloat(reformMode, 0f);
|
||||
grid.material.SetFloat(zMin, -0.5f);
|
||||
})
|
||||
);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldarg_0),
|
||||
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIBuildingGrid), nameof(UIBuildingGrid.blueprintGridRnd))),
|
||||
new CodeMatch(OpCodes.Ldc_I4_1),
|
||||
new CodeMatch(OpCodes.Callvirt),
|
||||
new CodeMatch(ci => ci.opcode == OpCodes.Br || ci.opcode == OpCodes.Br_S)
|
||||
).RemoveInstructions(4).Set(OpCodes.Ret, null).Labels.Add(label1);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
private static void PatchDeterminePreviews(object __instance)
|
||||
{
|
||||
var selectObjIds = (HashSet<int>)selectObjIdsField.GetValue(__instance);
|
||||
var buildTool = (BuildTool)__instance;
|
||||
var factory = buildTool.factory;
|
||||
HashSet<int> extraObjIds = [];
|
||||
foreach (var objId in selectObjIds)
|
||||
{
|
||||
var desc = buildTool.GetPrefabDesc(objId);
|
||||
var isBelt = desc.isBelt;
|
||||
var isInserter = desc.isInserter;
|
||||
if (isInserter) continue;
|
||||
if (isBelt)
|
||||
{
|
||||
var needCheck = false;
|
||||
for (var j = 0; j < 2; j++)
|
||||
{
|
||||
factory.ReadObjectConn(objId, j, out _, out var connObjId, out _);
|
||||
if (connObjId == 0 || FactoryFunctions.ObjectIsBeltOrInserter(factory, connObjId)) continue;
|
||||
needCheck = true;
|
||||
break;
|
||||
}
|
||||
if (needCheck)
|
||||
{
|
||||
for (var k = 0; k < 16; k++)
|
||||
{
|
||||
factory.ReadObjectConn(objId, k, out _, out var connObjId, out _);
|
||||
if (connObjId != 0 && !selectObjIds.Contains(connObjId) && !extraObjIds.Contains(connObjId) && FactoryFunctions.ObjectIsBeltOrInserter(factory, connObjId))
|
||||
extraObjIds.Add(connObjId);
|
||||
}
|
||||
}
|
||||
for (var m = 0; m < 4; m++)
|
||||
{
|
||||
factory.ReadObjectConn(objId, m, out _, out var connObjId, out _);
|
||||
if (connObjId == 0 || !factory.ObjectIsBelt(connObjId) || selectObjIds.Contains(connObjId) || extraObjIds.Contains(connObjId)) continue;
|
||||
for (var j = 0; j < 2; j++)
|
||||
{
|
||||
factory.ReadObjectConn(connObjId, j, out _, out var connObjId2, out _);
|
||||
if (connObjId2 == 0 || selectObjIds.Contains(connObjId2) || extraObjIds.Contains(connObjId2) || FactoryFunctions.ObjectIsBeltOrInserter(factory, connObjId2)) continue;
|
||||
extraObjIds.Add(connObjId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (desc.addonType == EAddonType.Belt) continue;
|
||||
for (var j = 0; j < 16; j++)
|
||||
{
|
||||
factory.ReadObjectConn(objId, j, out _, out var connObjId, out _);
|
||||
if (connObjId != 0 && !selectObjIds.Contains(connObjId) && !extraObjIds.Contains(connObjId) && FactoryFunctions.ObjectIsBeltOrInserter(factory, connObjId))
|
||||
extraObjIds.Add(connObjId);
|
||||
}
|
||||
}
|
||||
selectObjIds.UnionWith(extraObjIds);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using BepInEx.Bootstrap;
|
||||
using CommonAPI;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace UXAssist.ModsCompat;
|
||||
|
||||
public static class CommonAPIWrapper
|
||||
{
|
||||
public static void Run(Harmony harmony)
|
||||
{
|
||||
if (!Chainloader.PluginInfos.TryGetValue(CommonAPIPlugin.GUID, out var commonAPIPlugin) ||
|
||||
commonAPIPlugin.Metadata.Version > new System.Version(1, 6, 7, 0)) return;
|
||||
harmony.Patch(AccessTools.Method(typeof(GameOption), nameof(GameOption.InitKeys)), new HarmonyMethod(AccessTools.Method(typeof(CommonAPIWrapper), nameof(PatchInitKeys)), Priority.First));
|
||||
}
|
||||
|
||||
public static bool PatchInitKeys(GameOption __instance)
|
||||
{
|
||||
return __instance.overrideKeys == null;
|
||||
}
|
||||
}
|
||||
@@ -269,14 +269,14 @@ public class DysonSpherePatch : PatchImpl<DysonSpherePatch>
|
||||
protected override void OnEnable()
|
||||
{
|
||||
InitNodeForAbsorb();
|
||||
GameLogicProc.OnGameBegin += OnGameBegin;
|
||||
GameLogicProc.OnGameEnd += OnGameEnd;
|
||||
GameLogicProc.OnGameBegin += GameMain_Begin_Postfix;
|
||||
GameLogicProc.OnGameEnd += GameMain_End_Postfix;
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
GameLogicProc.OnGameEnd -= OnGameEnd;
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin;
|
||||
GameLogicProc.OnGameEnd -= GameMain_End_Postfix;
|
||||
GameLogicProc.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
_initialized = false;
|
||||
_nodeForAbsorb = null;
|
||||
}
|
||||
@@ -347,12 +347,12 @@ public class DysonSpherePatch : PatchImpl<DysonSpherePatch>
|
||||
return comp is { Count: > 0 };
|
||||
}
|
||||
|
||||
private static void OnGameBegin()
|
||||
private static void GameMain_Begin_Postfix()
|
||||
{
|
||||
InitNodeForAbsorb();
|
||||
}
|
||||
|
||||
private static void OnGameEnd()
|
||||
private static void GameMain_End_Postfix()
|
||||
{
|
||||
_initialized = false;
|
||||
_nodeForAbsorb = null;
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime.CompilerServices;
|
||||
using BepInEx.Configuration;
|
||||
using CommonAPI.Systems;
|
||||
using HarmonyLib;
|
||||
@@ -46,9 +45,6 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
public static ConfigEntry<int> EjectorBufferCount;
|
||||
public static ConfigEntry<int> SiloBufferCount;
|
||||
public static ConfigEntry<bool> ShortcutKeysForBlueprintCopyEnabled;
|
||||
public static ConfigEntry<bool> PressShiftToTakeWholeBeltItemsEnabled;
|
||||
public static ConfigEntry<bool> PressShiftToTakeWholeBeltItemsIncludeBranches;
|
||||
public static ConfigEntry<bool> PressShiftToTakeWholeBeltItemsIncludeInserters;
|
||||
|
||||
private static PressKeyBind _doNotRenderEntitiesKey;
|
||||
private static PressKeyBind _offgridfForPathsKey;
|
||||
@@ -135,7 +131,6 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
ReceiverBufferCount.SettingChanged += (_, _) => TweakBuildingBuffer.RefreshReceiverBufferCount();
|
||||
EjectorBufferCount.SettingChanged += (_, _) => TweakBuildingBuffer.RefreshEjectorBufferCount();
|
||||
SiloBufferCount.SettingChanged += (_, _) => TweakBuildingBuffer.RefreshSiloBufferCount();
|
||||
PressShiftToTakeWholeBeltItemsEnabled.SettingChanged += (_, _) => PressShiftToTakeWholeBeltItems.Enable(PressShiftToTakeWholeBeltItemsEnabled.Value);
|
||||
}
|
||||
|
||||
public static void Start()
|
||||
@@ -155,7 +150,6 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
BeltSignalsForBuyOut.Enable(BeltSignalsForBuyOutEnabled.Value);
|
||||
TankFastFillInAndTakeOut.Enable(TankFastFillInAndTakeOutEnabled.Value);
|
||||
TweakBuildingBuffer.Enable(TweakBuildingBufferEnabled.Value);
|
||||
PressShiftToTakeWholeBeltItems.Enable(PressShiftToTakeWholeBeltItemsEnabled.Value);
|
||||
|
||||
Enable(true);
|
||||
UpdateTankFastFillInAndTakeOutMultiplierRealValue();
|
||||
@@ -165,7 +159,6 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
{
|
||||
Enable(false);
|
||||
|
||||
PressShiftToTakeWholeBeltItems.Enable(false);
|
||||
TweakBuildingBuffer.Enable(false);
|
||||
TankFastFillInAndTakeOut.Enable(false);
|
||||
BeltSignalsForBuyOut.Enable(false);
|
||||
@@ -283,12 +276,12 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
GameLogicProc.OnGameEnd += OnGameEnd;
|
||||
GameLogicProc.OnGameEnd += GameMain_End_Postfix;
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
GameLogicProc.OnGameEnd -= OnGameEnd;
|
||||
GameLogicProc.OnGameEnd -= GameMain_End_Postfix;
|
||||
if (_sunlight)
|
||||
{
|
||||
_sunlight.transform.localEulerAngles = new Vector3(0f, 180f);
|
||||
@@ -299,7 +292,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
_nightlightInitialized = false;
|
||||
}
|
||||
|
||||
private static void OnGameEnd()
|
||||
private static void GameMain_End_Postfix()
|
||||
{
|
||||
if (_sunlight)
|
||||
{
|
||||
@@ -311,13 +304,25 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
_nightlightInitialized = false;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void UpdateSunlightAngle()
|
||||
{
|
||||
if (!_sunlight) return;
|
||||
_sunlight.transform.rotation =
|
||||
Quaternion.LookRotation(-GameMain.mainPlayer.transform.up + GameMain.mainPlayer.transform.forward * NightLightAngleX.Value / 10f +
|
||||
GameMain.mainPlayer.transform.right * NightLightAngleY.Value / 10f);
|
||||
_sunlight.transform.rotation = Quaternion.LookRotation(-GameMain.mainPlayer.transform.up + GameMain.mainPlayer.transform.forward * NightLightAngleX.Value / 10f +
|
||||
GameMain.mainPlayer.transform.right * NightLightAngleY.Value / 10f);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameData), nameof(GameData.ArriveStar))]
|
||||
public static void GameData_ArriveStar_Postfix()
|
||||
{
|
||||
_sunlight = GameMain.universeSimulator?.LocalStarSimulator()?.sunLight;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(GameData), nameof(GameData.LeaveStar))]
|
||||
public static void GameData_LeaveStar_Prefix()
|
||||
{
|
||||
_sunlight = null;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
@@ -330,6 +335,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
{
|
||||
if (!GameMain.mainPlayer.controller.model.gameObject.activeInHierarchy) return;
|
||||
if (_sail == null) _sail = GameMain.mainPlayer.animator.sails[GameMain.mainPlayer.animator.sailAnimIndex];
|
||||
_sunlight = GameMain.universeSimulator?.LocalStarSimulator()?.sunLight;
|
||||
_nightlightInitialized = true;
|
||||
}
|
||||
|
||||
@@ -350,10 +356,6 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
|
||||
if (sailing) return;
|
||||
_mechaOnEarth = true;
|
||||
if (_sunlight == null)
|
||||
{
|
||||
_sunlight = GameMain.universeSimulator?.LocalStarSimulator()?.sunLight;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
@@ -1403,16 +1405,16 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
GameLogicProc.OnGameBegin += OnGameBegin;
|
||||
GameLogicProc.OnGameEnd += OnGameEnd;
|
||||
GameLogicProc.OnGameBegin += GameMain_Begin_Postfix;
|
||||
GameLogicProc.OnGameEnd += GameMain_End_Postfix;
|
||||
FixProto();
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
UnfixProto();
|
||||
GameLogicProc.OnGameEnd -= OnGameEnd;
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin;
|
||||
GameLogicProc.OnGameEnd -= GameMain_End_Postfix;
|
||||
GameLogicProc.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
}
|
||||
|
||||
public static void AlternatelyChanged()
|
||||
@@ -1463,12 +1465,12 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
OldDragBuildDist.Clear();
|
||||
}
|
||||
|
||||
private static void OnGameBegin()
|
||||
private static void GameMain_Begin_Postfix()
|
||||
{
|
||||
FixProto();
|
||||
}
|
||||
|
||||
private static void OnGameEnd()
|
||||
private static void GameMain_End_Postfix()
|
||||
{
|
||||
UnfixProto();
|
||||
}
|
||||
@@ -1747,7 +1749,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
if (obj != null) return obj;
|
||||
}
|
||||
|
||||
obj = [];
|
||||
obj = new Dictionary<int, uint>();
|
||||
_signalBelts[index] = obj;
|
||||
return obj;
|
||||
}
|
||||
@@ -1780,12 +1782,12 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
{
|
||||
AddBeltSignalProtos();
|
||||
GameLogicProc.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
GameLogicProc.OnGameBegin += OnGameBegin;
|
||||
GameLogicProc.OnGameBegin += GameMain_Begin_Postfix;
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin;
|
||||
GameLogicProc.OnGameBegin -= GameMain_Begin_Postfix;
|
||||
GameLogicProc.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix;
|
||||
}
|
||||
|
||||
@@ -1807,7 +1809,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
RemovePlanetSignalBelts(factory.index);
|
||||
}
|
||||
|
||||
private static void OnGameBegin()
|
||||
private static void GameMain_Begin_Postfix()
|
||||
{
|
||||
_clusterSeedKey = GameMain.data.GetClusterSeedKey();
|
||||
InitSignalBelts();
|
||||
@@ -2231,237 +2233,4 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
}
|
||||
|
||||
private class PressShiftToTakeWholeBeltItems : PatchImpl<PressShiftToTakeWholeBeltItems>
|
||||
{
|
||||
private static long nextTimei = 0;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
GameLogicProc.OnGameBegin += OnGameBegin;
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
GameLogicProc.OnGameBegin -= OnGameBegin;
|
||||
}
|
||||
|
||||
private static void OnGameBegin()
|
||||
{
|
||||
nextTimei = 0;
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(VFInput), nameof(VFInput._fastTransferWithEntityDown), MethodType.Getter)]
|
||||
[HarmonyPatch(typeof(VFInput), nameof(VFInput._fastTransferWithEntityPress), MethodType.Getter)]
|
||||
private static IEnumerable<CodeInstruction> VFInput_fastTransferWithEntityDown_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.shift))),
|
||||
new CodeMatch(ci => ci.opcode == OpCodes.Brtrue || ci.opcode == OpCodes.Brtrue_S)
|
||||
);
|
||||
var lables = matcher.Labels;
|
||||
matcher.RemoveInstructions(2);
|
||||
matcher.Labels.AddRange(lables);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(PlayerAction_Inspect), nameof(PlayerAction_Inspect.GameTick))]
|
||||
private static IEnumerable<CodeInstruction> PlayerAction_Inspect_GameTick_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldc_I4_1),
|
||||
new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(PlayerAction_Inspect), nameof(PlayerAction_Inspect.fastFillIn)))
|
||||
);
|
||||
matcher.SetAndAdvance(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.shift))).Insert(
|
||||
new CodeInstruction(OpCodes.Ldc_I4_0),
|
||||
new CodeInstruction(OpCodes.Ceq)
|
||||
);
|
||||
|
||||
var label0 = generator.DefineLabel();
|
||||
var label1 = generator.DefineLabel();
|
||||
matcher.Start().MatchForward(false,
|
||||
new CodeMatch(ci => ci.IsStloc()),
|
||||
new CodeMatch(OpCodes.Ldc_I4_0),
|
||||
new CodeMatch(ci => ci.IsStloc()),
|
||||
new CodeMatch(OpCodes.Ldloc_0),
|
||||
new CodeMatch(ci => ci.IsLdloc()),
|
||||
new CodeMatch(ci => ci.IsLdloc()),
|
||||
new CodeMatch(ci => ci.IsLdloc()),
|
||||
new CodeMatch(ci => ci.IsLdloc()),
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(PlanetFactory), nameof(PlanetFactory.EntityFastTakeOut)))
|
||||
).Advance(8).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.shift))),
|
||||
new CodeInstruction(OpCodes.Brfalse_S, label0),
|
||||
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PressShiftToTakeWholeBeltItems), nameof(EntityFastTakeOutAlt))),
|
||||
new CodeInstruction(OpCodes.Br, label1)
|
||||
).Labels.Add(label0);
|
||||
matcher.Advance(1).Labels.Add(label1);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
private static void EntityFastTakeOutAlt(PlanetFactory factory, int entityId, bool toPackage, out ItemBundle itemBundle, out bool full)
|
||||
{
|
||||
if (factory._tmp_items == null)
|
||||
{
|
||||
factory._tmp_items = new ItemBundle();
|
||||
}
|
||||
else
|
||||
{
|
||||
factory._tmp_items.Clear();
|
||||
}
|
||||
itemBundle = factory._tmp_items;
|
||||
full = false;
|
||||
if (entityId == 0 || factory.entityPool[entityId].id != entityId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (GameMain.instance.timei < nextTimei) return;
|
||||
nextTimei = GameMain.instance.timei + 12;
|
||||
|
||||
ref var entityData = ref factory.entityPool[entityId];
|
||||
if (entityData.beltId <= 0) return;
|
||||
var cargoTraffic = factory.cargoTraffic;
|
||||
ref var belt = ref cargoTraffic.beltPool[entityData.beltId];
|
||||
if (belt.id != entityData.beltId) return;
|
||||
|
||||
HashSet<int> pathIds = [belt.segPathId];
|
||||
HashSet<int> inserterIds = [];
|
||||
var includeBranches = PressShiftToTakeWholeBeltItemsIncludeBranches.Value;
|
||||
var includeInserters = PressShiftToTakeWholeBeltItemsIncludeInserters.Value;
|
||||
List<int> pendingPathIds = [belt.segPathId];
|
||||
Dictionary<int, long> takeOutItems = [];
|
||||
var factorySystem = factory.factorySystem;
|
||||
while (pendingPathIds.Count > 0)
|
||||
{
|
||||
var lastIndex = pendingPathIds.Count - 1;
|
||||
var thisPathId = pendingPathIds[lastIndex];
|
||||
pendingPathIds.RemoveAt(lastIndex);
|
||||
var path = cargoTraffic.GetCargoPath(thisPathId);
|
||||
if (path == null) continue;
|
||||
if (includeInserters)
|
||||
{
|
||||
foreach (var beltId in path.belts)
|
||||
{
|
||||
ref var b = ref cargoTraffic.beltPool[beltId];
|
||||
if (b.id != beltId) return;
|
||||
// From WriteObjectConn: Only slot 4 to 11 is used for belt <-> inserter connections (method argument slot/otherSlot is -1 there)
|
||||
for (int cidx = 4; cidx < 12; cidx++)
|
||||
{
|
||||
factory.ReadObjectConn(b.entityId, cidx, out var isOutput, out var otherObjId, out var otherSlot);
|
||||
if (otherObjId <= 0) continue;
|
||||
var inserterId = factory.entityPool[otherObjId].inserterId;
|
||||
if (inserterId <= 0) continue;
|
||||
ref var inserter = ref factorySystem.inserterPool[inserterId];
|
||||
if (inserter.id != inserterId) continue;
|
||||
inserterIds.Add(inserterId);
|
||||
if (includeBranches)
|
||||
{
|
||||
var pickTargetId = inserter.pickTarget;
|
||||
if (pickTargetId > 0)
|
||||
{
|
||||
ref var pickTarget = ref factory.entityPool[pickTargetId];
|
||||
if (pickTarget.id == pickTargetId && pickTarget.beltId > 0)
|
||||
{
|
||||
ref var pickTargetBelt = ref cargoTraffic.beltPool[pickTarget.beltId];
|
||||
if (pickTargetBelt.id == pickTarget.beltId && !pathIds.Contains(pickTargetBelt.segPathId))
|
||||
{
|
||||
pathIds.Add(pickTargetBelt.segPathId);
|
||||
pendingPathIds.Add(pickTargetBelt.segPathId);
|
||||
}
|
||||
}
|
||||
}
|
||||
var insertTargetId = inserter.insertTarget;
|
||||
if (insertTargetId > 0)
|
||||
{
|
||||
ref var insertTarget = ref factory.entityPool[insertTargetId];
|
||||
if (insertTarget.id == insertTargetId && insertTarget.beltId > 0)
|
||||
{
|
||||
ref var insertTargetBelt = ref cargoTraffic.beltPool[insertTarget.beltId];
|
||||
if (insertTargetBelt.id == insertTarget.beltId && !pathIds.Contains(insertTargetBelt.segPathId))
|
||||
{
|
||||
pathIds.Add(insertTargetBelt.segPathId);
|
||||
pendingPathIds.Add(insertTargetBelt.segPathId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!includeBranches) continue;
|
||||
foreach (var inputPathId in path.inputPaths)
|
||||
{
|
||||
if (pathIds.Contains(inputPathId)) continue;
|
||||
pathIds.Add(inputPathId);
|
||||
pendingPathIds.Add(inputPathId);
|
||||
}
|
||||
if (path.outputPath == null) continue;
|
||||
var outputPathId = path.outputPath.id;
|
||||
if (pathIds.Contains(outputPathId)) continue;
|
||||
pathIds.Add(outputPathId);
|
||||
pendingPathIds.Add(outputPathId);
|
||||
}
|
||||
|
||||
var mainPlayer = factory.gameData.mainPlayer;
|
||||
foreach (var pathId in pathIds)
|
||||
{
|
||||
var cargoPath = cargoTraffic.GetCargoPath(pathId);
|
||||
if (cargoPath == null) continue;
|
||||
var end = cargoPath.bufferLength - 5;
|
||||
var buffer = cargoPath.buffer;
|
||||
for (var i = 0; i <= end;)
|
||||
{
|
||||
if (buffer[i] >= 246)
|
||||
{
|
||||
i += 250 - buffer[i];
|
||||
var index = buffer[i + 1] - 1 + (buffer[i + 2] - 1) * 100 + (buffer[i + 3] - 1) * 10000 + (buffer[i + 4] - 1) * 1000000;
|
||||
ref var cargo = ref cargoPath.cargoContainer.cargoPool[index];
|
||||
var item = cargo.item;
|
||||
var stack = cargo.stack;
|
||||
var inc = cargo.inc;
|
||||
takeOutItems[item] = (takeOutItems.TryGetValue(item, out var value) ? value : 0)
|
||||
+ ((long)stack | ((long)inc << 32));
|
||||
Array.Clear(buffer, i - 4, 10);
|
||||
i += 6;
|
||||
if (cargoPath.updateLen < i) cargoPath.updateLen = i;
|
||||
i += 4;
|
||||
cargoPath.cargoContainer.RemoveCargo(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
i += 5;
|
||||
if (i > end && i < end + 5)
|
||||
{
|
||||
i = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var inserterId in inserterIds)
|
||||
{
|
||||
ref var inserter = ref factorySystem.inserterPool[inserterId];
|
||||
if (inserter.itemId > 0 && inserter.stackCount > 0)
|
||||
{
|
||||
takeOutItems[inserter.itemId] = (takeOutItems.TryGetValue(inserter.itemId, out var value) ? value : 0)
|
||||
+ ((long)inserter.itemCount | ((long)inserter.itemInc << 32));
|
||||
inserter.itemId = 0;
|
||||
inserter.stackCount = 0;
|
||||
inserter.itemCount = 0;
|
||||
inserter.itemInc = 0;
|
||||
}
|
||||
}
|
||||
foreach (var kvp in takeOutItems)
|
||||
{
|
||||
var added = mainPlayer.TryAddItemToPackage(kvp.Key, (int)(kvp.Value & 0xFFFFFFFF), (int)(kvp.Value >> 32), true, entityId);
|
||||
if (added > 0)
|
||||
{
|
||||
UIItemup.Up(kvp.Key, added);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,8 +312,7 @@ public static class LogisticsPatch
|
||||
{
|
||||
private static KeyCode _lastKey = KeyCode.None;
|
||||
private static long _nextKeyTick;
|
||||
private static bool _skipNextUIStationStorageEvent;
|
||||
private static bool _skipNextUIControlPanelStationStorageEvent;
|
||||
private static bool _skipNextEvent;
|
||||
|
||||
private static bool UpdateKeyPressed(KeyCode code)
|
||||
{
|
||||
@@ -389,26 +388,10 @@ public static class LogisticsPatch
|
||||
EventSystem.current.RaycastAll(new PointerEventData(EventSystem.current) { position = Input.mousePosition }, targets);
|
||||
foreach (var target in targets)
|
||||
{
|
||||
StationComponent station = null;
|
||||
int index = -1;
|
||||
PlanetFactory planetFactory = null;
|
||||
var stationStorage = target.gameObject.GetComponentInParent<UIStationStorage>();
|
||||
bool isControlPanelStationStorage = false;
|
||||
if (stationStorage != null)
|
||||
{
|
||||
station = stationStorage.station;
|
||||
index = stationStorage.index;
|
||||
planetFactory = stationStorage.stationWindow?.factory;
|
||||
} else {
|
||||
var controlPanelStationStorage = target.gameObject.GetComponentInParent<UIControlPanelStationStorage>();
|
||||
if (controlPanelStationStorage == null) continue;
|
||||
station = controlPanelStationStorage.station;
|
||||
index = controlPanelStationStorage.index;
|
||||
planetFactory = controlPanelStationStorage.factory;
|
||||
isControlPanelStationStorage = true;
|
||||
}
|
||||
var station = stationStorage?.station;
|
||||
if (station?.storage is null) continue;
|
||||
ref var storage = ref station.storage[index];
|
||||
ref var storage = ref station.storage[stationStorage.index];
|
||||
var oldMax = storage.max;
|
||||
var newMax = oldMax + delta;
|
||||
if (newMax < 0)
|
||||
@@ -424,10 +407,11 @@ public static class LogisticsPatch
|
||||
}
|
||||
else
|
||||
{
|
||||
if (planetFactory == null || station.entityId <= 0 || station.entityId >= planetFactory.entityCursor) continue;
|
||||
var modelProto = LDB.models.Select(planetFactory.entityPool[station.entityId].modelIndex);
|
||||
var factory = stationStorage.stationWindow?.factory;
|
||||
if (factory == null || station.entityId <= 0 || station.entityId >= factory.entityCursor) continue;
|
||||
var modelProto = LDB.models.Select(factory.entityPool[station.entityId].modelIndex);
|
||||
itemCountMax = modelProto == null ? 0 : modelProto.prefabDesc.stationMaxItemCount;
|
||||
itemCountMax += station.isStellar && !station.isCollector ? GameMain.history.remoteStationExtraStorage : GameMain.history.localStationExtraStorage;
|
||||
itemCountMax += station.isStellar ? GameMain.history.remoteStationExtraStorage : GameMain.history.localStationExtraStorage;
|
||||
}
|
||||
|
||||
if (newMax > itemCountMax)
|
||||
@@ -437,14 +421,7 @@ public static class LogisticsPatch
|
||||
}
|
||||
|
||||
storage.max = newMax;
|
||||
if (isControlPanelStationStorage)
|
||||
{
|
||||
_skipNextUIControlPanelStationStorageEvent = oldMax / 100 != newMax / 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
_skipNextUIStationStorageEvent = oldMax / 100 != newMax / 100;
|
||||
}
|
||||
_skipNextEvent = oldMax / 100 != newMax / 100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -453,17 +430,8 @@ public static class LogisticsPatch
|
||||
[HarmonyPatch(typeof(UIStationStorage), nameof(UIStationStorage.OnMaxSliderValueChange))]
|
||||
private static bool UIStationStorage_OnMaxSliderValueChange_Prefix()
|
||||
{
|
||||
if (!_skipNextUIStationStorageEvent) return true;
|
||||
_skipNextUIStationStorageEvent = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(UIControlPanelStationStorage), nameof(UIControlPanelStationStorage.OnMaxSliderValueChange))]
|
||||
private static bool UIControlPanelStationStorage_OnMaxSliderValueChange_Prefix()
|
||||
{
|
||||
if (!_skipNextUIControlPanelStationStorageEvent) return true;
|
||||
_skipNextUIControlPanelStationStorageEvent = false;
|
||||
if (!_skipNextEvent) return true;
|
||||
_skipNextEvent = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1254,7 +1222,7 @@ public static class LogisticsPatch
|
||||
private float _pixelPerItem;
|
||||
|
||||
private StorageItemData[] _storageItems;
|
||||
private static readonly Dictionary<int, Sprite> ItemSprites = [];
|
||||
private static readonly Dictionary<int, Sprite> ItemSprites = new();
|
||||
private static readonly Color[] StateColor = [Color.gray, SupplyColor, DemandColor];
|
||||
|
||||
private struct StorageItemData
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection.Emit;
|
||||
using HarmonyLib;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using UXAssist.Common;
|
||||
|
||||
namespace UXAssist.Patches;
|
||||
@@ -171,102 +169,4 @@ public class PersistPatch : PatchImpl<PersistPatch>
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#region Cluster Upload Result
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(MilkyWayWebClient), nameof(MilkyWayWebClient.OnUploadLoginErrored))]
|
||||
private static void MilkyWayWebClient_OnUploadLoginErrored_Postfix(MilkyWayWebClient __instance, DSPWeb.HTTP_ERROR_TYPE errorType, string errorInfo, int errorCode)
|
||||
{
|
||||
switch (errorType)
|
||||
{
|
||||
case DSPWeb.HTTP_ERROR_TYPE.NETWORK_ERROR:
|
||||
Functions.UIFunctions.AddClusterUploadResult(-10001, (float)__instance.uploadRequest.reqTime);
|
||||
break;
|
||||
case DSPWeb.HTTP_ERROR_TYPE.HTTP_ERROR:
|
||||
Functions.UIFunctions.AddClusterUploadResult(-10010 - errorCode, (float)__instance.uploadRequest.reqTime);
|
||||
break;
|
||||
case DSPWeb.HTTP_ERROR_TYPE.USER_ABORT:
|
||||
Functions.UIFunctions.AddClusterUploadResult(-10003, (float)__instance.uploadRequest.reqTime);
|
||||
break;
|
||||
case DSPWeb.HTTP_ERROR_TYPE.UNEXPECTED_ERROR:
|
||||
Functions.UIFunctions.AddClusterUploadResult(-10004, (float)__instance.uploadRequest.reqTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(MilkyWayWebClient), nameof(MilkyWayWebClient.OnUploadErrored))]
|
||||
private static void MilkyWayWebClient_OnUploadErrored_Postfix(MilkyWayWebClient __instance, DSPWeb.HTTP_ERROR_TYPE errorType, string errorInfo, int errorCode)
|
||||
{
|
||||
switch (errorType)
|
||||
{
|
||||
case DSPWeb.HTTP_ERROR_TYPE.NETWORK_ERROR:
|
||||
Functions.UIFunctions.AddClusterUploadResult(-101, (float)__instance.uploadRequest.reqTime);
|
||||
break;
|
||||
case DSPWeb.HTTP_ERROR_TYPE.HTTP_ERROR:
|
||||
Functions.UIFunctions.AddClusterUploadResult(-110 - errorCode, (float)__instance.uploadRequest.reqTime);
|
||||
break;
|
||||
case DSPWeb.HTTP_ERROR_TYPE.USER_ABORT:
|
||||
Functions.UIFunctions.AddClusterUploadResult(-103, (float)__instance.uploadRequest.reqTime);
|
||||
break;
|
||||
case DSPWeb.HTTP_ERROR_TYPE.UNEXPECTED_ERROR:
|
||||
Functions.UIFunctions.AddClusterUploadResult(-104, (float)__instance.uploadRequest.reqTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(MilkyWayWebClient), nameof(MilkyWayWebClient.OnUploadSucceed))]
|
||||
private static void MilkyWayWebClient_OnUploadSucceed_Postfix(MilkyWayWebClient __instance, DownloadHandler handler)
|
||||
{
|
||||
if (!int.TryParse(handler.text, out var rcode))
|
||||
rcode = -1;
|
||||
Functions.UIFunctions.AddClusterUploadResult(rcode, (float)__instance.uploadRequest.reqTime);
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(MilkyWayCache), nameof(MilkyWayCache.LoadTopTenPlayerData))]
|
||||
private static IEnumerable<CodeInstruction> MilkyWayCache_LoadTopTenPlayerData_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldarg_1),
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(BinaryReader), nameof(BinaryReader.ReadInt32))),
|
||||
new CodeMatch(ci => ci.IsStloc())
|
||||
).Advance(2).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Dup),
|
||||
Transpilers.EmitDelegate(Functions.UIFunctions.SetTopPlayerCount)
|
||||
);
|
||||
|
||||
matcher.MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldloca_S),
|
||||
new CodeMatch(OpCodes.Ldarg_1),
|
||||
new CodeMatch(OpCodes.Callvirt),
|
||||
new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(ClusterPlayerData), nameof(ClusterPlayerData.isAnon)))
|
||||
);
|
||||
var objloc = matcher.Operand;
|
||||
matcher.Advance(4);
|
||||
var iinstr = matcher.Instruction.Clone();
|
||||
matcher.InsertAndAdvance(
|
||||
iinstr,
|
||||
new CodeInstruction(OpCodes.Ldloca_S, objloc),
|
||||
Transpilers.EmitDelegate((int index, ref ClusterPlayerData playerData) =>
|
||||
{
|
||||
Functions.UIFunctions.SetTopPlayerData(index, ref playerData);
|
||||
})
|
||||
);
|
||||
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(MilkyWayCache), nameof(MilkyWayCache.LoadTopTenPlayerData))]
|
||||
private static void MilkyWayCache_LoadTopTenPlayerData_Postfix(MilkyWayCache __instance)
|
||||
{
|
||||
Functions.UIFunctions.UpdateMilkyWayTopTenPlayers();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
|
||||
namespace UXAssist.Patches;
|
||||
|
||||
public static class PlanetPatch
|
||||
{
|
||||
public static ConfigEntry<bool> PlayerActionsInGlobeViewEnabled;
|
||||
|
||||
@@ -24,7 +24,6 @@ public class UIPatch : PatchImpl<UIPatch>
|
||||
GameLogicProc.OnGameBegin += PlanetVeinUtilization.OnGameBegin;
|
||||
Enable(true);
|
||||
Functions.UIFunctions.InitMenuButtons();
|
||||
Functions.UIFunctions.InitMilkyWayTopTenPlayers();
|
||||
PlanetVeinUtilization.Enable(PlanetVeinUtilizationEnabled.Value);
|
||||
}
|
||||
|
||||
@@ -122,7 +121,6 @@ public class UIPatch : PatchImpl<UIPatch>
|
||||
#region Helper functions
|
||||
private static void ProcessVeinData(VeinTypeInfo[] veinCount, VeinData[] veinPool)
|
||||
{
|
||||
if (veinPool == null) return;
|
||||
lock (veinPool)
|
||||
{
|
||||
foreach (VeinData veinData in veinPool)
|
||||
@@ -273,19 +271,21 @@ public class UIPatch : PatchImpl<UIPatch>
|
||||
}
|
||||
foreach (PlanetData planet in __instance.star.planets)
|
||||
{
|
||||
if (planet.runtimeVeinGroups == null) { continue; }
|
||||
PlanetFactory factory = planet.factory;
|
||||
if (factory != null)
|
||||
{
|
||||
ProcessVeinData(starVeinCount, factory.veinPool);
|
||||
continue;
|
||||
}
|
||||
VeinGroup[] veinGroups = planet.veinGroups;
|
||||
if (veinGroups == null) continue;
|
||||
lock (planet.veinGroupsLock)
|
||||
else
|
||||
{
|
||||
for (int i = 1; i < veinGroups.Length; i++)
|
||||
VeinGroup[] veinGroups = planet.runtimeVeinGroups;
|
||||
lock (planet.veinGroupsLock)
|
||||
{
|
||||
starVeinCount[(int)veinGroups[i].type].numVeinGroups++;
|
||||
for (int i = 1; i < veinGroups.Length; i++)
|
||||
{
|
||||
starVeinCount[(int)veinGroups[i].type].numVeinGroups++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,9 +71,6 @@ public static class UIConfigWindow
|
||||
I18N.Add("Drag building power poles in maximum connection range", "Drag building power poles in maximum connection range", "拖动建造电线杆时自动使用最大连接距离间隔");
|
||||
I18N.Add("Build Tesla Tower and Wireless Power Tower alternately", "Build Tesla Tower and Wireless Power Tower alternately", "交替建造电力感应塔和无线输电塔");
|
||||
I18N.Add("Belt signals for buy out dark fog items automatically", "Belt signals for buy out dark fog items automatically", "用于自动购买黑雾物品的传送带信号");
|
||||
I18N.Add("Ctrl+Shift+Click to pick items from whole belts", "Ctrl+Shift+Click to pick items from whole belts", "按住Ctrl+Shift点击从整条传送带抓取物品");
|
||||
I18N.Add("Include branches of belts", "Include branches of belts", "包含传送带分支");
|
||||
I18N.Add("Include connected inserters", "Include connected inserters (and their connected belts if above is checked)", "包含连接的分拣器(若勾选上面的选项则包含分拣器连接的传送带)");
|
||||
I18N.Add("Auto-config logistic stations", "Auto-config logistic stations", "自动配置物流设施");
|
||||
I18N.Add("Limit auto-replenish count to values below", "Limit auto-replenish count to values below", "限制自动补充数量为下面配置的值");
|
||||
I18N.Add("Dispenser", "Logistics Distributor", "物流配送器");
|
||||
@@ -407,24 +404,6 @@ public static class UIConfigWindow
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
y += 36f;
|
||||
wnd.AddCheckBox(x, y, tab2, FactoryPatch.PressShiftToTakeWholeBeltItemsEnabled, "Ctrl+Shift+Click to pick items from whole belts");
|
||||
y += 27f;
|
||||
var includeBranches = wnd.AddCheckBox(x + 10, y, tab2, FactoryPatch.PressShiftToTakeWholeBeltItemsIncludeBranches, "Include branches of belts", 13);
|
||||
y += 27f;
|
||||
var includeInserters = wnd.AddCheckBox(x + 10, y, tab2, FactoryPatch.PressShiftToTakeWholeBeltItemsIncludeInserters, "Include connected inserters", 13);
|
||||
FactoryPatch.PressShiftToTakeWholeBeltItemsEnabled.SettingChanged += PressShiftToTakeWholeBeltItemsEnabledChanged;
|
||||
wnd.OnFree += () => { FactoryPatch.PressShiftToTakeWholeBeltItemsEnabled.SettingChanged -= PressShiftToTakeWholeBeltItemsEnabledChanged; };
|
||||
PressShiftToTakeWholeBeltItemsEnabledChanged(null, null);
|
||||
|
||||
void PressShiftToTakeWholeBeltItemsEnabledChanged(object o, EventArgs e)
|
||||
{
|
||||
includeBranches.SetEnable(FactoryPatch.PressShiftToTakeWholeBeltItemsEnabled.Value);
|
||||
includeInserters.SetEnable(FactoryPatch.PressShiftToTakeWholeBeltItemsEnabled.Value);
|
||||
}
|
||||
}
|
||||
|
||||
x = 400f;
|
||||
y = 10f;
|
||||
wnd.AddButton(x, y, tab2, "Initialize This Planet", 16, "button-init-planet", () =>
|
||||
@@ -491,6 +470,7 @@ public static class UIConfigWindow
|
||||
FactoryPatch.TweakBuildingBufferEnabled.SettingChanged += TweakBuildingBufferChanged;
|
||||
wnd.OnFree += () => { FactoryPatch.TweakBuildingBufferEnabled.SettingChanged -= TweakBuildingBufferChanged; };
|
||||
TweakBuildingBufferChanged(null, null);
|
||||
|
||||
void TweakBuildingBufferChanged(object o, EventArgs e)
|
||||
{
|
||||
assemblerBufferTimeMultiplierSlider.SetEnable(FactoryPatch.TweakBuildingBufferEnabled.Value);
|
||||
@@ -626,7 +606,7 @@ public static class UIConfigWindow
|
||||
textForMeasureTextWidth = wnd.AddText2(x, y, tab3, "Min. Piler Value", 13, "text-amm-min-piler-value");
|
||||
maxWidth = Mathf.Max(maxWidth, textForMeasureTextWidth.preferredWidth);
|
||||
y = oy + 1;
|
||||
var nx = x + maxWidth + 5f + 10f;
|
||||
var nx = x + maxWidth + 5f;
|
||||
wnd.AddSideSlider(nx, y, tab3, LogisticsPatch.AutoConfigDispenserChargePower, new AutoConfigDispenserChargePowerMapper(), "G", 150f, -100f).WithFontSize(13);
|
||||
y += 18f;
|
||||
wnd.AddSideSlider(nx, y, tab3, LogisticsPatch.AutoConfigDispenserCourierCount, new MyWindow.RangeValueMapper<int>(0, 10), "G", 150f, -100f).WithFontSize(13);
|
||||
|
||||
@@ -33,13 +33,12 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
private readonly Harmony _harmony = new(PluginInfo.PLUGIN_GUID);
|
||||
|
||||
#region IModCanSave
|
||||
private const ushort ModSaveVersion = 2;
|
||||
private const ushort ModSaveVersion = 1;
|
||||
|
||||
public void Export(BinaryWriter w)
|
||||
{
|
||||
w.Write(ModSaveVersion);
|
||||
FactoryPatch.Export(w);
|
||||
UIFunctions.ExportClusterUploadResults(w);
|
||||
}
|
||||
|
||||
public void Import(BinaryReader r)
|
||||
@@ -47,10 +46,6 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
var version = r.ReadUInt16();
|
||||
if (version <= 0) return;
|
||||
FactoryPatch.Import(r);
|
||||
if (version > 1)
|
||||
{
|
||||
UIFunctions.ImportClusterUploadResults(r);
|
||||
}
|
||||
}
|
||||
|
||||
public void IntoOtherSave()
|
||||
@@ -61,8 +56,6 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
UXAssist()
|
||||
{
|
||||
ModsCompat.PlanetVeinUtilization.Run(_harmony);
|
||||
ModsCompat.BlueprintTweaks.Run(_harmony);
|
||||
ModsCompat.CommonAPIWrapper.Run(_harmony);
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
@@ -145,12 +138,6 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
FactoryPatch.SiloBufferCount = Config.Bind("Factory", "SiloBufferCount", 1, new ConfigDescription("Silo buffer count", new AcceptableValueRange<int>(1, 40)));
|
||||
FactoryPatch.ShortcutKeysForBlueprintCopyEnabled = Config.Bind("Factory", "DismantleBlueprintSelection", false,
|
||||
"Dismantle blueprint selected buildings");
|
||||
FactoryPatch.PressShiftToTakeWholeBeltItemsEnabled = Config.Bind("Factory", "PressShiftToTakeWholeBeltItems", false,
|
||||
"Ctrl+Shift+Click to pick items from whole belts");
|
||||
FactoryPatch.PressShiftToTakeWholeBeltItemsIncludeBranches = Config.Bind("Factory", "PressShiftToTakeWholeBeltItemsIncludeBranches", false,
|
||||
"Include branches of belts");
|
||||
FactoryPatch.PressShiftToTakeWholeBeltItemsIncludeInserters = Config.Bind("Factory", "PressShiftToTakeWholeBeltItemsIncludeInserters", false,
|
||||
"Include connected inserters");
|
||||
LogisticsPatch.AutoConfigLogisticsEnabled = Config.Bind("Factory", "AutoConfigLogistics", false,
|
||||
"Auto-config logistic stations");
|
||||
LogisticsPatch.AutoConfigLimitAutoReplenishCount = Config.Bind("Factory", "AutoConfigLimitAutoReplenishCount", false,
|
||||
@@ -230,8 +217,7 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
t => string.Equals(t.Namespace, "UXAssist.Patches", StringComparison.Ordinal) || string.Equals(t.Namespace, "UXAssist.Functions", StringComparison.Ordinal));
|
||||
_patches?.Do(type => type.GetMethod("Init")?.Invoke(null, null));
|
||||
_compats = Util.GetTypesInNamespace(Assembly.GetExecutingAssembly(), "UXAssist.ModsCompat");
|
||||
object[] parameters = [_harmony];
|
||||
_compats?.Do(type => type.GetMethod("Init")?.Invoke(null, parameters));
|
||||
_compats?.Do(type => type.GetMethod("Init")?.Invoke(null, null));
|
||||
|
||||
I18N.Apply();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<BepInExPluginGuid>org.soardev.uxassist</BepInExPluginGuid>
|
||||
<Description>DSP MOD - UXAssist</Description>
|
||||
<Version>1.4.5</Version>
|
||||
<Version>1.4.3</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<PackageId>UXAssist</PackageId>
|
||||
@@ -17,7 +17,7 @@
|
||||
<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.*" /> -->
|
||||
<PackageReference Include="DysonSphereProgram.Modding.CommonAPI" Version="1.*" />
|
||||
<PackageReference Include="DysonSphereProgram.Modding.CommonAPI" Version="1.6.5" />
|
||||
<PackageReference Include="DysonSphereProgram.Modding.DSPModSave" Version="1.*" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -61,8 +61,7 @@
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<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 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.4.5",
|
||||
"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": [
|
||||
|
||||
@@ -4,7 +4,6 @@ using HarmonyLib;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace UniverseGenTweaks;
|
||||
|
||||
public static class BirthPlanetPatch
|
||||
{
|
||||
public static ConfigEntry<bool> SitiVeinsOnBirthPlanet;
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
<PackageReference Include="DysonSphereProgram.Modding.DSPModSave" Version="1.*" />
|
||||
</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>
|
||||
@@ -29,15 +33,11 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\UXAssist\UXAssist.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Exec Command="powershell Compress-Archive -Force -DestinationPath 'package/$(ProjectName)-$(Version).zip' -Path '$(TargetPath)', package/icon.png, package/manifest.json, README.md, CHANGELOG.md" />
|
||||
<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,17 +15,8 @@
|
||||
<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="2022.3.53" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>..\AssemblyFromGame\Assembly-CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>..\AssemblyFromGame\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<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'">
|
||||
@@ -33,6 +24,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Exec Command="powershell Compress-Archive -Force -DestinationPath 'package/$(ProjectName)-$(Version).zip' -Path '$(TargetPath)', package/icon.png, package/manifest.json, README.md" />
|
||||
<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" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user