mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2025-12-08 21:33:28 +08:00
Compare commits
7 Commits
45445f82a1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| f237789fa0 | |||
| b2c04c1dff | |||
| 29ee32b11b | |||
| 3f7c384284 | |||
| 556493b2b6 | |||
| 269cc3b801 | |||
| cacbfd6d5f |
@@ -1,6 +1,7 @@
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace CheatEnabler.Functions;
|
||||
|
||||
public static class PlanetFunctions
|
||||
{
|
||||
public static void BuryAllVeins(bool bury)
|
||||
|
||||
@@ -675,11 +675,12 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
|
||||
private static void InitSignalBelts()
|
||||
{
|
||||
if (!GameMain.isRunning) return;
|
||||
if (DSPGame.IsMenuDemo) return;
|
||||
InitItemSources();
|
||||
_signalBelts = new Dictionary<int, BeltSignal>[64];
|
||||
_signalBeltsCapacity = 64;
|
||||
_portalFrom = new Dictionary<long, int>();
|
||||
_portalTo = new Dictionary<int, HashSet<long>>();
|
||||
_portalFrom = [];
|
||||
_portalTo = [];
|
||||
|
||||
var factories = GameMain.data?.factories;
|
||||
if (factories == null) return;
|
||||
@@ -735,7 +736,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
if (obj != null) return obj;
|
||||
}
|
||||
|
||||
obj = new Dictionary<int, BeltSignal>();
|
||||
obj = [];
|
||||
_signalBelts[index] = obj;
|
||||
return obj;
|
||||
}
|
||||
@@ -869,7 +870,6 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
{
|
||||
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 = new Dictionary<int, float>() };
|
||||
var rs = new ItemSource { Count = rescnt[i], From = [] };
|
||||
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 = new Dictionary<int, float>();
|
||||
rs.Extra = [];
|
||||
for (var k = 0; k < len; k++)
|
||||
{
|
||||
if (i != k)
|
||||
@@ -1258,7 +1258,38 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
if (itemSource.From == null) return;
|
||||
foreach (var p in itemSource.From)
|
||||
{
|
||||
CalculateAllProductions(result, extra, p.Key, times * p.Value);
|
||||
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);
|
||||
}
|
||||
}
|
||||
/* END: Item sources calculation */
|
||||
|
||||
@@ -48,7 +48,7 @@ public static class GamePatch
|
||||
p.Value.OnUnregEvent();
|
||||
}
|
||||
|
||||
abnormalLogic.determinators = new Dictionary<int, AbnormalityDeterminator>();
|
||||
abnormalLogic.determinators = [];
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
@@ -81,7 +81,7 @@ public static class GamePatch
|
||||
{
|
||||
_savedDeterminators = __instance.determinators;
|
||||
if (!AbnormalDisablerEnabled.Value) return;
|
||||
__instance.determinators = new Dictionary<int, AbnormalityDeterminator>();
|
||||
__instance.determinators = [];
|
||||
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.Method(typeof(GameMain), "get_sandboxToolsEnabled")),
|
||||
new CodeMatch(OpCodes.Call, AccessTools.PropertyGetter(typeof(GameMain), nameof(GameMain.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.Method(typeof(UITechTree), "get_selected"))
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(UITechTree), nameof(UITechTree.selected)))
|
||||
);
|
||||
var labels = matcher.Labels;
|
||||
matcher.Labels = null;
|
||||
|
||||
@@ -6,6 +6,7 @@ using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
|
||||
namespace CheatEnabler.Patches;
|
||||
|
||||
public static class PlanetPatch
|
||||
{
|
||||
public static ConfigEntry<bool> WaterPumpAnywhereEnabled;
|
||||
@@ -53,6 +54,92 @@ 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)
|
||||
@@ -65,13 +152,13 @@ public static class PlanetPatch
|
||||
).RemoveInstructions(2).InsertAndAdvance(
|
||||
new CodeInstruction(OpCodes.Ldc_I4_0)
|
||||
).MatchForward(false,
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(Player), "get_sandCount"))
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Player), nameof(Player.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), "Max", [typeof(long), typeof(long)]))
|
||||
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Math), nameof(Math.Max), [typeof(long), typeof(long)]))
|
||||
);
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
|
||||
@@ -68,7 +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("Generate illegal dyson shell", "Generate an illegal dyson shell (!!All shells will be removed first!!)", "生成单层仙术戴森壳(!!会先删除全部的壳!!)");
|
||||
I18N.Add("Generate illegal dyson shell", "Generate an illegal dyson shell (!!1st shell layer will be replaced!!)", "生成单层仙术戴森壳(!!会先删除第一层戴森壳!!)");
|
||||
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", "快速生成仙术戴森壳");
|
||||
@@ -327,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".Translate(), "WARNING: This operation can be very slow, continue?".Translate(), "取消".Translate(), "确定".Translate(), UIMessageBox.WARNING, null,
|
||||
UIMessageBox.Show("Generate illegal dyson shell quickly".Translate(), "WARNING: This operation can be very slow, continue?".Translate(), "取消".Translate(), "确定".Translate(), UIMessageBox.WARNING, null,
|
||||
() => { DysonSphereFunctions.CreateIllegalDysonShellQuickly(DysonSphereFunctions.ShellsCountForFunctions.Value); });
|
||||
});
|
||||
y += 30f;
|
||||
|
||||
@@ -342,7 +342,7 @@ public class LogisticMiner : BaseUnityPlugin
|
||||
public float FrameNext;
|
||||
|
||||
/* stores list of indices to veinData, with an extra INT which indicates cout of veinGroups at last */
|
||||
private Dictionary<int, List<int>> _veins = new();
|
||||
private Dictionary<int, List<int>> _veins = [];
|
||||
private int _mineIndex = -1;
|
||||
|
||||
public bool HasVein(int productId)
|
||||
|
||||
@@ -59,6 +59,7 @@ public static class PlanetFunctions
|
||||
uiGame.ShutAllFullScreens();
|
||||
}
|
||||
player.controller.actionBuild.Close();
|
||||
|
||||
var groundCombatModule = player.mecha.groundCombatModule;
|
||||
for (var i = 0; i < groundCombatModule.moduleFleets.Length; i++)
|
||||
{
|
||||
@@ -67,6 +68,42 @@ 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--)
|
||||
@@ -93,6 +130,20 @@ 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)
|
||||
{
|
||||
@@ -115,18 +166,18 @@ public static class PlanetFunctions
|
||||
}
|
||||
}
|
||||
|
||||
if (planet.factory.enemyPool != null)
|
||||
if (factory.enemyPool != null)
|
||||
{
|
||||
for (var i = planet.factory.enemyCursor - 1; i > 0; i--)
|
||||
for (var i = factory.enemyCursor - 1; i > 0; i--)
|
||||
{
|
||||
ref var enemyData = ref planet.factory.enemyPool[i];
|
||||
ref var enemyData = ref factory.enemyPool[i];
|
||||
if (enemyData.id != i) continue;
|
||||
var combatStatId = enemyData.combatStatId;
|
||||
planet.factory.skillSystem.OnRemovingSkillTarget(combatStatId, planet.factory.skillSystem.combatStats.buffer[combatStatId].originAstroId, ETargetType.CombatStat);
|
||||
planet.factory.skillSystem.combatStats.Remove(combatStatId);
|
||||
planet.factory.KillEnemyFinally(i, ref CombatStat.empty);
|
||||
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.enemySystem.Free();
|
||||
factory.enemySystem.Free();
|
||||
UIRoot.instance.uiGame.dfAssaultTip.ClearAllSpots();
|
||||
}
|
||||
|
||||
@@ -165,7 +216,7 @@ public static class PlanetFunctions
|
||||
factory.PlanetReformRevert();
|
||||
}
|
||||
|
||||
planet.UnloadFactory();
|
||||
GameMain.data.LeavePlanet();
|
||||
var index = factory.index;
|
||||
var warningSystem = GameMain.data.warningSystem;
|
||||
var warningPool = warningSystem.warningPool;
|
||||
@@ -238,12 +289,7 @@ public static class PlanetFunctions
|
||||
factory.digitalSystem = new DigitalSystem(planet);
|
||||
|
||||
//GameMain.data.statistics.production.CreateFactoryStat(index);
|
||||
planet.LoadFactory();
|
||||
while (!planet.factoryLoaded)
|
||||
{
|
||||
PlanetModelingManager.Update();
|
||||
Thread.Sleep(0);
|
||||
}
|
||||
GameMain.data.ArrivePlanet(planet);
|
||||
}
|
||||
|
||||
public static void BuildOrbitalCollectors()
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using CommonAPI.Systems;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UXAssist.UI;
|
||||
using CommonAPI.Systems;
|
||||
using UXAssist.Common;
|
||||
using UXAssist.UI;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace UXAssist.Functions;
|
||||
@@ -719,4 +721,158 @@ 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 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 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>();
|
||||
panel.transform.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 = [];
|
||||
|
||||
MilkyWayTopTenPlayersToggler = UI.MyCheckButton.CreateCheckButton(0, 0, rtrans, false, "Show top players".Translate()).WithSize(100f, 24f);
|
||||
MilkyWayTopTenPlayersToggler.OnChecked += UpdateButtons;
|
||||
MilkyWayTopTenPlayersToggler.Checked = false;
|
||||
UpdateButtons();
|
||||
|
||||
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);
|
||||
}
|
||||
Array.Resize(ref buttons, count);
|
||||
}
|
||||
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);
|
||||
button.labelText.alignment = TextAnchor.MiddleLeft;
|
||||
buttons[i] = button;
|
||||
}
|
||||
button.SetLabelText(String.Format(">> {0:00}. {1} {2}W", i + 1, _topTenPlayerData[i].name, ToKMG(_topTenPlayerData[i].genCap * 60L)));
|
||||
button.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
button.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
MilkyWayTopTenPlayersToggler.SetLabelText(chk ? "Hide top players".Translate() : "Show top players".Translate());
|
||||
|
||||
string ToKMG(long value)
|
||||
{
|
||||
StringBuilderUtility.WriteKMG(_sb, 8, value, true);
|
||||
return _sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -82,7 +82,8 @@ class BlueprintTweaks
|
||||
new CodeMatch(OpCodes.Callvirt)
|
||||
).RemoveInstructions(5);
|
||||
matcher.InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_0),
|
||||
Transpilers.EmitDelegate((UIBuildingGrid grid) => {
|
||||
Transpilers.EmitDelegate((UIBuildingGrid grid) =>
|
||||
{
|
||||
grid.material.SetFloat(reformMode, 0f);
|
||||
grid.material.SetFloat(zMin, -0.5f);
|
||||
})
|
||||
|
||||
@@ -4,6 +4,7 @@ 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;
|
||||
@@ -310,25 +311,13 @@ 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);
|
||||
}
|
||||
|
||||
[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;
|
||||
_sunlight.transform.rotation =
|
||||
Quaternion.LookRotation(-GameMain.mainPlayer.transform.up + GameMain.mainPlayer.transform.forward * NightLightAngleX.Value / 10f +
|
||||
GameMain.mainPlayer.transform.right * NightLightAngleY.Value / 10f);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
@@ -341,7 +330,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -362,6 +350,10 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
|
||||
if (sailing) return;
|
||||
_mechaOnEarth = true;
|
||||
if (_sunlight == null)
|
||||
{
|
||||
_sunlight = GameMain.universeSimulator?.LocalStarSimulator()?.sunLight;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
@@ -1755,7 +1747,7 @@ public class FactoryPatch : PatchImpl<FactoryPatch>
|
||||
if (obj != null) return obj;
|
||||
}
|
||||
|
||||
obj = new Dictionary<int, uint>();
|
||||
obj = [];
|
||||
_signalBelts[index] = obj;
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -1222,7 +1222,7 @@ public static class LogisticsPatch
|
||||
private float _pixelPerItem;
|
||||
|
||||
private StorageItemData[] _storageItems;
|
||||
private static readonly Dictionary<int, Sprite> ItemSprites = new();
|
||||
private static readonly Dictionary<int, Sprite> ItemSprites = [];
|
||||
private static readonly Color[] StateColor = [Color.gray, SupplyColor, DemandColor];
|
||||
|
||||
private struct StorageItemData
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection.Emit;
|
||||
using HarmonyLib;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using UXAssist.Common;
|
||||
|
||||
namespace UXAssist.Patches;
|
||||
@@ -170,4 +171,95 @@ 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();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
|
||||
namespace UXAssist.Patches;
|
||||
|
||||
public static class PlanetPatch
|
||||
{
|
||||
public static ConfigEntry<bool> PlayerActionsInGlobeViewEnabled;
|
||||
|
||||
@@ -24,6 +24,7 @@ public class UIPatch : PatchImpl<UIPatch>
|
||||
GameLogicProc.OnGameBegin += PlanetVeinUtilization.OnGameBegin;
|
||||
Enable(true);
|
||||
Functions.UIFunctions.InitMenuButtons();
|
||||
Functions.UIFunctions.InitMilkyWayTopTenPlayers();
|
||||
PlanetVeinUtilization.Enable(PlanetVeinUtilizationEnabled.Value);
|
||||
}
|
||||
|
||||
|
||||
@@ -419,7 +419,7 @@ public static class UIConfigWindow
|
||||
PressShiftToTakeWholeBeltItemsEnabledChanged(null, null);
|
||||
|
||||
void PressShiftToTakeWholeBeltItemsEnabledChanged(object o, EventArgs e)
|
||||
{
|
||||
{
|
||||
includeBranches.SetEnable(FactoryPatch.PressShiftToTakeWholeBeltItemsEnabled.Value);
|
||||
includeInserters.SetEnable(FactoryPatch.PressShiftToTakeWholeBeltItemsEnabled.Value);
|
||||
}
|
||||
|
||||
@@ -33,12 +33,13 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
|
||||
private readonly Harmony _harmony = new(PluginInfo.PLUGIN_GUID);
|
||||
|
||||
#region IModCanSave
|
||||
private const ushort ModSaveVersion = 1;
|
||||
private const ushort ModSaveVersion = 2;
|
||||
|
||||
public void Export(BinaryWriter w)
|
||||
{
|
||||
w.Write(ModSaveVersion);
|
||||
FactoryPatch.Export(w);
|
||||
UIFunctions.ExportClusterUploadResults(w);
|
||||
}
|
||||
|
||||
public void Import(BinaryReader r)
|
||||
@@ -46,6 +47,10 @@ 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()
|
||||
|
||||
@@ -4,6 +4,7 @@ using HarmonyLib;
|
||||
using GameLogicProc = UXAssist.Common.GameLogic;
|
||||
|
||||
namespace UniverseGenTweaks;
|
||||
|
||||
public static class BirthPlanetPatch
|
||||
{
|
||||
public static ConfigEntry<bool> SitiVeinsOnBirthPlanet;
|
||||
|
||||
Reference in New Issue
Block a user