mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2025-12-09 08:53:34 +08:00
WIP
This commit is contained in:
@@ -31,6 +31,7 @@ public static class BirthPlanetPatch
|
|||||||
_rareVeins = theme.RareVeins.Clone() as int[];
|
_rareVeins = theme.RareVeins.Clone() as int[];
|
||||||
_rareSettings = theme.RareSettings.Clone() as float[];
|
_rareSettings = theme.RareSettings.Clone() as float[];
|
||||||
_specifyBirthStarMass = StarGen.specifyBirthStarMass;
|
_specifyBirthStarMass = StarGen.specifyBirthStarMass;
|
||||||
|
_specifyBirthStarAge = StarGen.specifyBirthStarAge;
|
||||||
_inited = true;
|
_inited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@ public static class BirthPlanetPatch
|
|||||||
theme.RareVeins = _rareVeins.Clone() as int[];
|
theme.RareVeins = _rareVeins.Clone() as int[];
|
||||||
theme.RareSettings = _rareSettings.Clone() as float[];
|
theme.RareSettings = _rareSettings.Clone() as float[];
|
||||||
StarGen.specifyBirthStarMass = _specifyBirthStarMass;
|
StarGen.specifyBirthStarMass = _specifyBirthStarMass;
|
||||||
|
StarGen.specifyBirthStarAge = _specifyBirthStarAge;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _inited;
|
private bool _inited;
|
||||||
@@ -54,6 +56,7 @@ public static class BirthPlanetPatch
|
|||||||
private int[] _rareVeins;
|
private int[] _rareVeins;
|
||||||
private float[] _rareSettings;
|
private float[] _rareSettings;
|
||||||
private float _specifyBirthStarMass;
|
private float _specifyBirthStarMass;
|
||||||
|
private float _specifyBirthStarAge;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
@@ -164,7 +167,8 @@ public static class BirthPlanetPatch
|
|||||||
|
|
||||||
if (HighLuminosityBirthStar.Value)
|
if (HighLuminosityBirthStar.Value)
|
||||||
{
|
{
|
||||||
StarGen.specifyBirthStarMass = 100f;
|
StarGen.specifyBirthStarMass = 53.81f;
|
||||||
|
StarGen.specifyBirthStarAge = 0.01f;
|
||||||
}
|
}
|
||||||
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ public class CheatEnabler : BaseUnityPlugin
|
|||||||
public new static readonly BepInEx.Logging.ManualLogSource Logger =
|
public new static readonly BepInEx.Logging.ManualLogSource Logger =
|
||||||
BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME);
|
BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME);
|
||||||
|
|
||||||
|
public static ConfigEntry<KeyboardShortcut> Hotkey;
|
||||||
private static bool _configWinInitialized = false;
|
private static bool _configWinInitialized = false;
|
||||||
private static KeyboardShortcut _shortcut = KeyboardShortcut.Deserialize("H + LeftControl");
|
|
||||||
private static UIConfigWindow _configWin;
|
private static UIConfigWindow _configWin;
|
||||||
private static string _unlockTechToMaximumLevel = "";
|
private static string _unlockTechToMaximumLevel = "";
|
||||||
private static readonly List<int> TechToUnlock = new();
|
private static readonly List<int> TechToUnlock = new();
|
||||||
@@ -29,7 +29,8 @@ public class CheatEnabler : BaseUnityPlugin
|
|||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
DevShortcuts.Enabled = Config.Bind("General", "DevShortcuts", true, "enable DevMode shortcuts");
|
Hotkey = Config.Bind("General", "Shortcut", KeyboardShortcut.Deserialize("BackQuote + LeftAlt"), "Shortcut to open config window");
|
||||||
|
DevShortcuts.Enabled = Config.Bind("General", "DevShortcuts", true, "Enable DevMode shortcuts");
|
||||||
AbnormalDisabler.Enabled = Config.Bind("General", "DisableAbnormalChecks", false,
|
AbnormalDisabler.Enabled = Config.Bind("General", "DisableAbnormalChecks", false,
|
||||||
"disable all abnormal checks");
|
"disable all abnormal checks");
|
||||||
BuildPatch.ImmediateEnabled = Config.Bind("Build", "ImmediateBuild", false,
|
BuildPatch.ImmediateEnabled = Config.Bind("Build", "ImmediateBuild", false,
|
||||||
@@ -76,8 +77,8 @@ public class CheatEnabler : BaseUnityPlugin
|
|||||||
"Birth planet is solid flat (no water at all)");
|
"Birth planet is solid flat (no water at all)");
|
||||||
BirthPlanetPatch.HighLuminosityBirthStar = Config.Bind("Birth", "HighLuminosityBirthStar", false,
|
BirthPlanetPatch.HighLuminosityBirthStar = Config.Bind("Birth", "HighLuminosityBirthStar", false,
|
||||||
"Birth star has high luminosity");
|
"Birth star has high luminosity");
|
||||||
_unlockTechToMaximumLevel = Config.Bind("General", "UnlockTechToMaxLevel", _unlockTechToMaximumLevel,
|
// _unlockTechToMaximumLevel = Config.Bind("General", "UnlockTechToMaxLevel", _unlockTechToMaximumLevel,
|
||||||
"Unlock listed tech to MaxLevel").Value;
|
// "Unlock listed tech to MaxLevel").Value;
|
||||||
|
|
||||||
I18N.Init();
|
I18N.Init();
|
||||||
I18N.Add("CheatEnabler Config", "CheatEnabler Config", "CheatEnabler设置");
|
I18N.Add("CheatEnabler Config", "CheatEnabler Config", "CheatEnabler设置");
|
||||||
@@ -95,17 +96,17 @@ public class CheatEnabler : BaseUnityPlugin
|
|||||||
TerraformPatch.Init();
|
TerraformPatch.Init();
|
||||||
DysonSpherePatch.Init();
|
DysonSpherePatch.Init();
|
||||||
BirthPlanetPatch.Init();
|
BirthPlanetPatch.Init();
|
||||||
foreach (var idstr in _unlockTechToMaximumLevel.Split(','))
|
// foreach (var idstr in _unlockTechToMaximumLevel.Split(','))
|
||||||
{
|
// {
|
||||||
if (int.TryParse(idstr, out var id))
|
// if (int.TryParse(idstr, out var id))
|
||||||
{
|
// {
|
||||||
TechToUnlock.Add(id);
|
// TechToUnlock.Add(id);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (TechToUnlock.Count > 0)
|
// if (TechToUnlock.Count > 0)
|
||||||
{
|
// {
|
||||||
Harmony.CreateAndPatchAll(typeof(UnlockTechOnGameStart));
|
// Harmony.CreateAndPatchAll(typeof(UnlockTechOnGameStart));
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnDestroy()
|
public void OnDestroy()
|
||||||
@@ -129,8 +130,8 @@ public class CheatEnabler : BaseUnityPlugin
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_shortcut.IsDown())
|
if (Hotkey.Value.IsDown())
|
||||||
ShowConfigWindow();
|
ToggleConfigWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPostfix, HarmonyPatch(typeof(UIRoot), nameof(UIRoot.OpenMainMenuUI))]
|
[HarmonyPostfix, HarmonyPatch(typeof(UIRoot), nameof(UIRoot.OpenMainMenuUI))]
|
||||||
@@ -157,7 +158,7 @@ public class CheatEnabler : BaseUnityPlugin
|
|||||||
var transform1 = (RectTransform)btn.transform;
|
var transform1 = (RectTransform)btn.transform;
|
||||||
transform1.anchoredPosition3D = new Vector3(vec.x, vec.y + (vec.y - vec2.y) * 2, vec.z);
|
transform1.anchoredPosition3D = new Vector3(vec.x, vec.y + (vec.y - vec2.y) * 2, vec.z);
|
||||||
btn.button.onClick.RemoveAllListeners();
|
btn.button.onClick.RemoveAllListeners();
|
||||||
btn.button.onClick.AddListener(ShowConfigWindow);
|
btn.button.onClick.AddListener(ToggleConfigWindow);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var panel = UIRoot.instance.uiGame.planetGlobe;
|
var panel = UIRoot.instance.uiGame.planetGlobe;
|
||||||
@@ -179,7 +180,7 @@ public class CheatEnabler : BaseUnityPlugin
|
|||||||
rect.localScale = new Vector3(0.5f, 0.5f, 0.5f);
|
rect.localScale = new Vector3(0.5f, 0.5f, 0.5f);
|
||||||
rect.anchoredPosition3D = new Vector3(128f, -105f, 0f);
|
rect.anchoredPosition3D = new Vector3(128f, -105f, 0f);
|
||||||
b.onClick.RemoveAllListeners();
|
b.onClick.RemoveAllListeners();
|
||||||
btn.onClick += (_) => { ShowConfigWindow(); };
|
btn.onClick += (_) => { ToggleConfigWindow(); };
|
||||||
btn.tips.tipTitle = "CheatEnabler Config";
|
btn.tips.tipTitle = "CheatEnabler Config";
|
||||||
I18N.OnInitialized += () => { btn.tips.tipTitle = "CheatEnabler Config".Translate(); };
|
I18N.OnInitialized += () => { btn.tips.tipTitle = "CheatEnabler Config".Translate(); };
|
||||||
btn.tips.tipText = null;
|
btn.tips.tipText = null;
|
||||||
@@ -191,7 +192,26 @@ public class CheatEnabler : BaseUnityPlugin
|
|||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ShowConfigWindow()
|
[HarmonyTranspiler]
|
||||||
|
[HarmonyPatch(typeof(UIBuildMenu), nameof(UIBuildMenu._OnUpdate))]
|
||||||
|
private static IEnumerable<CodeInstruction> UIBuildMenu__OnUpdate_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.inScreen)))
|
||||||
|
);
|
||||||
|
matcher.Repeat(codeMatcher =>
|
||||||
|
{
|
||||||
|
var jumpPos = codeMatcher.Advance(1).Operand;
|
||||||
|
codeMatcher.Advance(-1).InsertAndAdvance(
|
||||||
|
new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.noModifier))),
|
||||||
|
new CodeInstruction(OpCodes.Brfalse_S, jumpPos)
|
||||||
|
).Advance(2);
|
||||||
|
});
|
||||||
|
return matcher.InstructionEnumeration();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ToggleConfigWindow()
|
||||||
{
|
{
|
||||||
if (!_configWinInitialized)
|
if (!_configWinInitialized)
|
||||||
{
|
{
|
||||||
@@ -210,6 +230,7 @@ public class CheatEnabler : BaseUnityPlugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
private class UnlockTechOnGameStart
|
private class UnlockTechOnGameStart
|
||||||
{
|
{
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
@@ -296,5 +317,6 @@ public class CheatEnabler : BaseUnityPlugin
|
|||||||
techStates[currentTech] = value;
|
techStates[currentTech] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<TargetFramework>net472</TargetFramework>
|
<TargetFramework>net472</TargetFramework>
|
||||||
<BepInExPluginGuid>org.soardev.cheatenabler</BepInExPluginGuid>
|
<BepInExPluginGuid>org.soardev.cheatenabler</BepInExPluginGuid>
|
||||||
<Description>DSP MOD - CheatEnabler</Description>
|
<Description>DSP MOD - CheatEnabler</Description>
|
||||||
<Version>1.0.0</Version>
|
<Version>2.0.0</Version>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<PackageId>CheatEnabler</PackageId>
|
<PackageId>CheatEnabler</PackageId>
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
<Exec Command="del /F /Q package\$(ProjectName)-$(Version).zip
zip -9 -j package/$(ProjectName)-$(Version).zip $(TargetPath) package/icon.png package/manifest.json README.md" />
|
<Exec Command="del /F /Q package\$(ProjectName)-$(Version).zip
zip -9 -j package/$(ProjectName)-$(Version).zip $(TargetPath) package/icon.png package/manifest.json README.md" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
using BepInEx.Configuration;
|
using BepInEx.Configuration;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using PowerNetworkStructures;
|
|
||||||
|
|
||||||
namespace CheatEnabler;
|
namespace CheatEnabler;
|
||||||
|
|
||||||
@@ -62,6 +62,9 @@ public static class DysonSpherePatch
|
|||||||
_skipBulletPatch.UnpatchSelf();
|
_skipBulletPatch.UnpatchSelf();
|
||||||
_skipBulletPatch = null;
|
_skipBulletPatch = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SkipBulletPatch.UpdateSailLifeTime();
|
||||||
|
SkipBulletPatch.UpdateSailsCacheForThisGame();
|
||||||
_skipBulletPatch = Harmony.CreateAndPatchAll(typeof(SkipBulletPatch));
|
_skipBulletPatch = Harmony.CreateAndPatchAll(typeof(SkipBulletPatch));
|
||||||
}
|
}
|
||||||
else if (_skipBulletPatch != null)
|
else if (_skipBulletPatch != null)
|
||||||
@@ -127,13 +130,148 @@ public static class DysonSpherePatch
|
|||||||
|
|
||||||
private static class SkipBulletPatch
|
private static class SkipBulletPatch
|
||||||
{
|
{
|
||||||
|
private static long _sailLifeTime;
|
||||||
|
private static DysonSailCache[][] _sailsCache;
|
||||||
|
private static int[] _sailsCacheLen, _sailsCacheCapacity;
|
||||||
|
|
||||||
|
private struct DysonSailCache
|
||||||
|
{
|
||||||
|
public DysonSail Sail;
|
||||||
|
public int OrbitId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateSailLifeTime()
|
||||||
|
{
|
||||||
|
if (GameMain.history == null) return;
|
||||||
|
_sailLifeTime = (long)(GameMain.history.solarSailLife * 60f + 0.1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateSailsCacheForThisGame()
|
||||||
|
{
|
||||||
|
var galaxy = GameMain.data?.galaxy;
|
||||||
|
if (galaxy == null) return;
|
||||||
|
var starCount = GameMain.data.galaxy.starCount;
|
||||||
|
_sailsCache = new DysonSailCache[starCount][];
|
||||||
|
_sailsCacheLen = new int[starCount];
|
||||||
|
_sailsCacheCapacity = new int[starCount];
|
||||||
|
Array.Clear(_sailsCacheLen, 0, starCount);
|
||||||
|
Array.Clear(_sailsCacheCapacity, 0, starCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetSailsCacheCapacity(int index, int capacity)
|
||||||
|
{
|
||||||
|
var newCache = new DysonSailCache[capacity];
|
||||||
|
var len = _sailsCacheLen[index];
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
Array.Copy(_sailsCache[index], newCache, len);
|
||||||
|
}
|
||||||
|
_sailsCache[index] = newCache;
|
||||||
|
_sailsCacheCapacity[index] = capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(GameData), nameof(GameData.NewGame))]
|
||||||
|
[HarmonyPatch(typeof(GameData), nameof(GameData.Import))]
|
||||||
|
private static void GameData_NewGame_Postfix()
|
||||||
|
{
|
||||||
|
UpdateSailsCacheForThisGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.SetForNewGame))]
|
||||||
|
[HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.Import))]
|
||||||
|
private static void GameHistoryData_SetForNewGame_Postfix()
|
||||||
|
{
|
||||||
|
UpdateSailLifeTime();
|
||||||
|
}
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.UnlockTechFunction))]
|
||||||
|
private static void GameHistoryData_SetForNewGame_Postfix(int func)
|
||||||
|
{
|
||||||
|
if (func == 12)
|
||||||
|
{
|
||||||
|
UpdateSailLifeTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[HarmonyTranspiler]
|
[HarmonyTranspiler]
|
||||||
[HarmonyPatch(typeof(EjectorComponent), nameof(EjectorComponent.InternalUpdate))]
|
[HarmonyPatch(typeof(EjectorComponent), nameof(EjectorComponent.InternalUpdate))]
|
||||||
private static IEnumerable<CodeInstruction> EjectorComponent_InternalUpdate_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
private static IEnumerable<CodeInstruction> EjectorComponent_InternalUpdate_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||||
{
|
{
|
||||||
var matcher = new CodeMatcher(instructions, generator);
|
var matcher = new CodeMatcher(instructions, generator);
|
||||||
|
matcher.MatchForward(false,
|
||||||
|
new CodeMatch(OpCodes.Ldc_R4, 10f)
|
||||||
|
).Advance(2);
|
||||||
|
var start = matcher.Pos;
|
||||||
|
matcher.MatchForward(false,
|
||||||
|
new CodeMatch(OpCodes.Pop)
|
||||||
|
).Advance(1);
|
||||||
|
var end = matcher.Pos;
|
||||||
|
matcher.Start().Advance(start).RemoveInstructions(end - start).Insert(
|
||||||
|
new CodeInstruction(OpCodes.Ldarg_2),
|
||||||
|
new CodeInstruction(OpCodes.Ldarg_0),
|
||||||
|
new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(EjectorComponent), nameof(EjectorComponent.orbitId))),
|
||||||
|
new CodeInstruction(OpCodes.Ldloc_S, 8),
|
||||||
|
new CodeInstruction(OpCodes.Ldloc_S, 10),
|
||||||
|
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(SkipBulletPatch), nameof(SkipBulletPatch.AddDysonSail)))
|
||||||
|
);
|
||||||
return matcher.InstructionEnumeration();
|
return matcher.InstructionEnumeration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void AddDysonSail(DysonSwarm swarm, int orbitId, VectorLF3 uPos, VectorLF3 endVec)
|
||||||
|
{
|
||||||
|
var index = swarm.starData.index;
|
||||||
|
var delta1 = endVec - swarm.starData.uPosition;
|
||||||
|
var delta2 = VectorLF3.Cross(endVec - uPos, swarm.orbits[orbitId].up).normalized * Math.Sqrt(swarm.dysonSphere.gravity / swarm.orbits[orbitId].radius)
|
||||||
|
+ RandomTable.SphericNormal(ref swarm.randSeed, 0.5);
|
||||||
|
lock(swarm)
|
||||||
|
{
|
||||||
|
var cache = _sailsCache[index];
|
||||||
|
var len = _sailsCacheLen[index];
|
||||||
|
if (cache == null)
|
||||||
|
{
|
||||||
|
SetSailsCacheCapacity(index, 256);
|
||||||
|
cache = _sailsCache[index];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var capacity = _sailsCacheCapacity[index];
|
||||||
|
if (len >= capacity)
|
||||||
|
{
|
||||||
|
SetSailsCacheCapacity(index, capacity * 2);
|
||||||
|
cache = _sailsCache[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_sailsCacheLen[index] = len + 1;
|
||||||
|
ref var sailCache = ref cache[len];
|
||||||
|
ref var ss = ref sailCache.Sail;
|
||||||
|
ss.px = (float)delta1.x;
|
||||||
|
ss.py = (float)delta1.y;
|
||||||
|
ss.pz = (float)delta1.z;
|
||||||
|
ss.vx = (float)delta2.x;
|
||||||
|
ss.vy = (float)delta2.y;
|
||||||
|
ss.vz = (float)delta2.z;
|
||||||
|
ss.gs = 1f;
|
||||||
|
sailCache.OrbitId = orbitId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(DysonSwarm), "GameTick")]
|
||||||
|
public static void DysonSwarm_GameTick_Prefix(DysonSwarm __instance, long time)
|
||||||
|
{
|
||||||
|
var index = __instance.starData.index;
|
||||||
|
var len = _sailsCacheLen[index];
|
||||||
|
if (len == 0) return;
|
||||||
|
_sailsCacheLen[index] = 0;
|
||||||
|
var cache = _sailsCache[index];
|
||||||
|
var deadline = time + _sailLifeTime;
|
||||||
|
for (var i = len - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
__instance.AddSolarSail(cache[i].Sail, cache[i].OrbitId, deadline);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SkipAbsorbPatch
|
private static class SkipAbsorbPatch
|
||||||
@@ -188,17 +326,49 @@ public static class DysonSpherePatch
|
|||||||
|
|
||||||
private static class QuickAbsortPatch
|
private static class QuickAbsortPatch
|
||||||
{
|
{
|
||||||
|
// [HarmonyPrefix]
|
||||||
|
// [HarmonyPatch(typeof(DysonSphereLayer), "GameTick")]
|
||||||
|
// public static void DysonSphereLayerGameTick(ref DysonSphereLayer __instance, long gameTick)
|
||||||
|
// {
|
||||||
|
// DysonSwarm swarm = __instance.dysonSphere.swarm;
|
||||||
|
// for (int i = __instance.nodeCursor - 1; i > 0; i--)
|
||||||
|
// {
|
||||||
|
// DysonNode dysonNode = __instance.nodePool[i];
|
||||||
|
// if (dysonNode != null && dysonNode.id == i && dysonNode.sp == dysonNode.spMax)
|
||||||
|
// {
|
||||||
|
// dysonNode.OrderConstructCp(gameTick, swarm);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
[HarmonyTranspiler]
|
[HarmonyTranspiler]
|
||||||
[HarmonyPatch(typeof(DysonSphereLayer), nameof(DysonSphereLayer.GameTick))]
|
[HarmonyPatch(typeof(DysonSphereLayer), nameof(DysonSphereLayer.GameTick))]
|
||||||
private static IEnumerable<CodeInstruction> DysonSphereLayer_GameTick_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
private static IEnumerable<CodeInstruction> DysonSphereLayer_GameTick_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||||
{
|
{
|
||||||
var matcher = new CodeMatcher(instructions, generator);
|
var matcher = new CodeMatcher(instructions, generator);
|
||||||
/* Remove `dysonNode.id % 120 == num` */
|
matcher.Start().InsertAndAdvance(
|
||||||
matcher.MatchForward(false,
|
new CodeInstruction(OpCodes.Ldarg_0),
|
||||||
new CodeMatch(OpCodes.Ldc_I4_S, 120)
|
new CodeInstruction(OpCodes.Ldarg_1),
|
||||||
).Advance(-2).RemoveInstructions(6);
|
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(QuickAbsortPatch), nameof(QuickAbsortPatch.DoAbsorb)))
|
||||||
|
).MatchForward(false,
|
||||||
|
new CodeMatch(OpCodes.Ldarg_0),
|
||||||
|
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(DysonSphereLayer), nameof(DysonSphereLayer.dysonSphere))),
|
||||||
|
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(DysonSphere), nameof(DysonSphere.swarm)))
|
||||||
|
).Insert(new CodeInstruction(OpCodes.Ret));
|
||||||
return matcher.InstructionEnumeration();
|
return matcher.InstructionEnumeration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void DoAbsorb(DysonSphereLayer layer, long gameTick)
|
||||||
|
{
|
||||||
|
var swarm = layer.dysonSphere.swarm;
|
||||||
|
for (var i = layer.nodeCursor - 1; i > 0; i--)
|
||||||
|
{
|
||||||
|
var node = layer.nodePool[i];
|
||||||
|
if (node != null && node.id == i && node.sp == node.spMax)
|
||||||
|
{
|
||||||
|
node.OrderConstructCp(gameTick, swarm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class EjectAnywayPatch
|
private static class EjectAnywayPatch
|
||||||
|
|||||||
237
CheatEnabler/UI/MyKeyBinder.cs
Normal file
237
CheatEnabler/UI/MyKeyBinder.cs
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace CheatEnabler.UI;
|
||||||
|
|
||||||
|
// MyKeyBinder modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyKeyBinder.cs
|
||||||
|
public class MyKeyBinder : MonoBehaviour
|
||||||
|
{
|
||||||
|
private ConfigEntry<KeyboardShortcut> _config;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
public Text functionText;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
public Text keyText;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
public InputField setTheKeyInput;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
public Toggle setTheKeyToggle;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
public RectTransform rectTrans;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
public UIButton inputUIButton;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
public Text conflictText;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
public Text waitingText;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
public UIButton setDefaultUIButton;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
public UIButton setNoneKeyUIButton;
|
||||||
|
|
||||||
|
private bool _nextNotOn;
|
||||||
|
|
||||||
|
public static RectTransform CreateKeyBinder(float x, float y, RectTransform parent, ConfigEntry<KeyboardShortcut> config, string label = "", int fontSize = 17)
|
||||||
|
{
|
||||||
|
var optionWindow = UIRoot.instance.optionWindow;
|
||||||
|
var uikeyEntry = GameObject.Instantiate<UIKeyEntry>(optionWindow.entryPrefab);
|
||||||
|
GameObject go;
|
||||||
|
(go = uikeyEntry.gameObject).SetActive(true);
|
||||||
|
go.name = "my-keybinder";
|
||||||
|
var kb = go.AddComponent<MyKeyBinder>();
|
||||||
|
kb._config = config;
|
||||||
|
|
||||||
|
kb.functionText = uikeyEntry.functionText;
|
||||||
|
kb.keyText = uikeyEntry.keyText;
|
||||||
|
kb.setTheKeyInput = uikeyEntry.setTheKeyInput;
|
||||||
|
kb.setTheKeyToggle = uikeyEntry.setTheKeyToggle;
|
||||||
|
kb.rectTrans = uikeyEntry.rectTrans;
|
||||||
|
kb.inputUIButton = uikeyEntry.inputUIButton;
|
||||||
|
kb.conflictText = uikeyEntry.conflictText;
|
||||||
|
kb.waitingText = uikeyEntry.waitingText;
|
||||||
|
kb.setDefaultUIButton = uikeyEntry.setDefaultUIButton;
|
||||||
|
kb.setNoneKeyUIButton = uikeyEntry.setNoneKeyUIButton;
|
||||||
|
|
||||||
|
|
||||||
|
kb.functionText.text = label;
|
||||||
|
kb.functionText.fontSize = 17;
|
||||||
|
|
||||||
|
((RectTransform)kb.keyText.transform).anchoredPosition = new Vector2(20f, -27f);
|
||||||
|
//kb.keyText.alignment = TextAnchor.MiddleRight;
|
||||||
|
kb.keyText.fontSize = 17;
|
||||||
|
((RectTransform)kb.inputUIButton.transform.parent.transform).anchoredPosition = new Vector2(0f + 20f, -57f);
|
||||||
|
((RectTransform)kb.setDefaultUIButton.transform).anchoredPosition = new Vector2(140f + 20f, -57f);
|
||||||
|
((RectTransform)kb.setNoneKeyUIButton.transform).anchoredPosition = new Vector2(240f + 20f, -57f);
|
||||||
|
|
||||||
|
var rect = Util.NormalizeRectWithTopLeft(kb, x, y, parent);
|
||||||
|
kb.rectTrans = rect;
|
||||||
|
|
||||||
|
//rect.sizeDelta = new Vector2(240f, 64f);
|
||||||
|
GameObject.Destroy(uikeyEntry);
|
||||||
|
kb.setNoneKeyUIButton.gameObject.SetActive(false);
|
||||||
|
|
||||||
|
kb.SettingChanged();
|
||||||
|
config.SettingChanged += (sender, args) => {
|
||||||
|
kb.SettingChanged();
|
||||||
|
};
|
||||||
|
kb.inputUIButton.onClick += kb.OnInputUIButtonClick;
|
||||||
|
kb.setDefaultUIButton.onClick += kb.OnSetDefaultKeyClick;
|
||||||
|
//kb.setNoneKeyUIButton.onClick += kb.OnSetNoneKeyClick;
|
||||||
|
return go.transform as RectTransform;
|
||||||
|
|
||||||
|
void ResetAnchor(RectTransform theRect)
|
||||||
|
{
|
||||||
|
theRect.anchorMax = Vector2.zero;
|
||||||
|
theRect.anchorMin = Vector2.zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (!setTheKeyToggle.isOn && inputUIButton.highlighted)
|
||||||
|
{
|
||||||
|
setTheKeyToggle.isOn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!setTheKeyToggle.isOn) return;
|
||||||
|
if (!inputUIButton._isPointerEnter && Input.GetKeyDown(KeyCode.Mouse0))
|
||||||
|
{
|
||||||
|
inputUIButton.highlighted = false;
|
||||||
|
setTheKeyToggle.isOn = false;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
else if (!this.inputUIButton.highlighted)
|
||||||
|
{
|
||||||
|
setTheKeyToggle.isOn = false;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
waitingText.gameObject.SetActive(true);
|
||||||
|
if (!TrySetValue()) return;
|
||||||
|
setTheKeyToggle.isOn = false;
|
||||||
|
inputUIButton.highlighted = false;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool TrySetValue()
|
||||||
|
{
|
||||||
|
if (Input.GetKey(KeyCode.Escape))
|
||||||
|
{
|
||||||
|
VFInput.UseEscape();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (Input.GetKey(KeyCode.Mouse0) || Input.GetKey(KeyCode.Mouse1))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var anyKey = GetIunptKeys();
|
||||||
|
if (anyKey || _lastKey == KeyCode.None) return false;
|
||||||
|
var k = GetPressedKey();
|
||||||
|
if (string.IsNullOrEmpty(k))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_lastKey = KeyCode.None;
|
||||||
|
|
||||||
|
_config.Value = KeyboardShortcut.Deserialize(k);
|
||||||
|
//keyText.text = k;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyCode _lastKey;
|
||||||
|
private static readonly KeyCode[] ModKeys = { KeyCode.RightShift, KeyCode.LeftShift,
|
||||||
|
KeyCode.RightControl, KeyCode.LeftControl,
|
||||||
|
KeyCode.RightAlt, KeyCode.LeftAlt,
|
||||||
|
KeyCode.LeftCommand, KeyCode.LeftApple, KeyCode.LeftWindows,
|
||||||
|
KeyCode.RightCommand, KeyCode.RightApple, KeyCode.RightWindows };
|
||||||
|
|
||||||
|
public string GetPressedKey()
|
||||||
|
{
|
||||||
|
var key = _lastKey.ToString();
|
||||||
|
if (string.IsNullOrEmpty(key))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var mod = "";
|
||||||
|
foreach (var modKey in ModKeys)
|
||||||
|
{
|
||||||
|
if (Input.GetKey(modKey))
|
||||||
|
{
|
||||||
|
mod += "+" + modKey.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(mod))
|
||||||
|
{
|
||||||
|
key += mod;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
//通常キーが押されているかチェック _lastKey に保存
|
||||||
|
public bool GetIunptKeys()
|
||||||
|
{
|
||||||
|
var anyKey = false;
|
||||||
|
|
||||||
|
foreach (KeyCode item in Enum.GetValues(typeof(KeyCode)))
|
||||||
|
{
|
||||||
|
if (item == KeyCode.None || ModKeys.Contains(item) || !Input.GetKey(item)) continue;
|
||||||
|
_lastKey = item;
|
||||||
|
anyKey = true;
|
||||||
|
}
|
||||||
|
return anyKey;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
conflictText.gameObject.SetActive(false);
|
||||||
|
waitingText.gameObject.SetActive(false);
|
||||||
|
setDefaultUIButton.button.Select(); // InputFieldのフォーカス外す
|
||||||
|
_lastKey = KeyCode.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnInputUIButtonClick(int data)
|
||||||
|
{
|
||||||
|
inputUIButton.highlighted = true;
|
||||||
|
|
||||||
|
if (!_nextNotOn) return;
|
||||||
|
_nextNotOn = false;
|
||||||
|
inputUIButton.highlighted = false;
|
||||||
|
setTheKeyToggle.isOn = false;
|
||||||
|
waitingText.gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnSetDefaultKeyClick(int data)
|
||||||
|
{
|
||||||
|
_config.Value = (KeyboardShortcut)_config.DefaultValue;
|
||||||
|
keyText.text = _config.Value.Serialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnSetNoneKeyClick(int data)
|
||||||
|
{
|
||||||
|
_config.Value = (KeyboardShortcut)_config.DefaultValue;
|
||||||
|
keyText.text = _config.Value.Serialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SettingChanged()
|
||||||
|
{
|
||||||
|
keyText.text = _config.Value.Serialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ public class UIConfigWindow : UI.MyWindowWithTabs
|
|||||||
I18N.Add("General", "General", "常规");
|
I18N.Add("General", "General", "常规");
|
||||||
I18N.Add("Enable Dev Shortcuts", "Enable Dev Shortcuts", "启用开发模式快捷键");
|
I18N.Add("Enable Dev Shortcuts", "Enable Dev Shortcuts", "启用开发模式快捷键");
|
||||||
I18N.Add("Disable Abnormal Checks", "Disable Abnormal Checks", "关闭数据异常检查");
|
I18N.Add("Disable Abnormal Checks", "Disable Abnormal Checks", "关闭数据异常检查");
|
||||||
|
I18N.Add("Hotkey", "Hotkey", "快捷键");
|
||||||
I18N.Add("Build", "Build", "建造");
|
I18N.Add("Build", "Build", "建造");
|
||||||
I18N.Add("Finish build immediately", "Finish build immediately", "建造秒完成");
|
I18N.Add("Finish build immediately", "Finish build immediately", "建造秒完成");
|
||||||
I18N.Add("Infinite buildings", "Infinite buildings", "无限建筑");
|
I18N.Add("Infinite buildings", "Infinite buildings", "无限建筑");
|
||||||
@@ -64,6 +65,8 @@ public class UIConfigWindow : UI.MyWindowWithTabs
|
|||||||
UI.MyCheckBox.CreateCheckBox(x, y, tab1, DevShortcuts.Enabled, "Enable Dev Shortcuts".Translate());
|
UI.MyCheckBox.CreateCheckBox(x, y, tab1, DevShortcuts.Enabled, "Enable Dev Shortcuts".Translate());
|
||||||
y += 36f;
|
y += 36f;
|
||||||
UI.MyCheckBox.CreateCheckBox(x, y, tab1, AbnormalDisabler.Enabled, "Disable Abnormal Checks".Translate());
|
UI.MyCheckBox.CreateCheckBox(x, y, tab1, AbnormalDisabler.Enabled, "Disable Abnormal Checks".Translate());
|
||||||
|
y += 86f;
|
||||||
|
UI.MyKeyBinder.CreateKeyBinder(x, y, tab1, CheatEnabler.Hotkey, "Hotkey".Translate());
|
||||||
|
|
||||||
var tab2 = AddTab(136f, 1, _windowTrans, "Build".Translate());
|
var tab2 = AddTab(136f, 1, _windowTrans, "Build".Translate());
|
||||||
x = 0f;
|
x = 0f;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "CheatEnabler",
|
"name": "CheatEnabler",
|
||||||
"version_number": "1.0.0",
|
"version_number": "2.0.0",
|
||||||
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/CheatEnabler",
|
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/CheatEnabler",
|
||||||
"description": "Add various cheat functions while disabling abnormal determinants / 添加一些作弊功能,同时屏蔽异常检测",
|
"description": "Add various cheat functions while disabling abnormal determinants / 添加一些作弊功能,同时屏蔽异常检测",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
|
|||||||
Reference in New Issue
Block a user