1
0
mirror of https://github.com/soarqin/DSP_Mods.git synced 2025-12-08 22:53:33 +08:00
This commit is contained in:
2023-09-11 02:39:18 +08:00
parent 07a32f7fd0
commit 9c5523fb37
7 changed files with 466 additions and 29 deletions

View File

@@ -31,6 +31,7 @@ public static class BirthPlanetPatch
_rareVeins = theme.RareVeins.Clone() as int[];
_rareSettings = theme.RareSettings.Clone() as float[];
_specifyBirthStarMass = StarGen.specifyBirthStarMass;
_specifyBirthStarAge = StarGen.specifyBirthStarAge;
_inited = true;
}
@@ -44,6 +45,7 @@ public static class BirthPlanetPatch
theme.RareVeins = _rareVeins.Clone() as int[];
theme.RareSettings = _rareSettings.Clone() as float[];
StarGen.specifyBirthStarMass = _specifyBirthStarMass;
StarGen.specifyBirthStarAge = _specifyBirthStarAge;
}
private bool _inited;
@@ -54,6 +56,7 @@ public static class BirthPlanetPatch
private int[] _rareVeins;
private float[] _rareSettings;
private float _specifyBirthStarMass;
private float _specifyBirthStarAge;
}
public static void Init()
@@ -164,7 +167,8 @@ public static class BirthPlanetPatch
if (HighLuminosityBirthStar.Value)
{
StarGen.specifyBirthStarMass = 100f;
StarGen.specifyBirthStarMass = 53.81f;
StarGen.specifyBirthStarAge = 0.01f;
}
_initialized = true;

View File

@@ -16,8 +16,8 @@ public class CheatEnabler : BaseUnityPlugin
public new static readonly BepInEx.Logging.ManualLogSource Logger =
BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME);
public static ConfigEntry<KeyboardShortcut> Hotkey;
private static bool _configWinInitialized = false;
private static KeyboardShortcut _shortcut = KeyboardShortcut.Deserialize("H + LeftControl");
private static UIConfigWindow _configWin;
private static string _unlockTechToMaximumLevel = "";
private static readonly List<int> TechToUnlock = new();
@@ -29,7 +29,8 @@ public class CheatEnabler : BaseUnityPlugin
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,
"disable all abnormal checks");
BuildPatch.ImmediateEnabled = Config.Bind("Build", "ImmediateBuild", false,
@@ -76,8 +77,8 @@ public class CheatEnabler : BaseUnityPlugin
"Birth planet is solid flat (no water at all)");
BirthPlanetPatch.HighLuminosityBirthStar = Config.Bind("Birth", "HighLuminosityBirthStar", false,
"Birth star has high luminosity");
_unlockTechToMaximumLevel = Config.Bind("General", "UnlockTechToMaxLevel", _unlockTechToMaximumLevel,
"Unlock listed tech to MaxLevel").Value;
// _unlockTechToMaximumLevel = Config.Bind("General", "UnlockTechToMaxLevel", _unlockTechToMaximumLevel,
// "Unlock listed tech to MaxLevel").Value;
I18N.Init();
I18N.Add("CheatEnabler Config", "CheatEnabler Config", "CheatEnabler设置");
@@ -95,17 +96,17 @@ public class CheatEnabler : BaseUnityPlugin
TerraformPatch.Init();
DysonSpherePatch.Init();
BirthPlanetPatch.Init();
foreach (var idstr in _unlockTechToMaximumLevel.Split(','))
{
if (int.TryParse(idstr, out var id))
{
TechToUnlock.Add(id);
}
}
if (TechToUnlock.Count > 0)
{
Harmony.CreateAndPatchAll(typeof(UnlockTechOnGameStart));
}
// foreach (var idstr in _unlockTechToMaximumLevel.Split(','))
// {
// if (int.TryParse(idstr, out var id))
// {
// TechToUnlock.Add(id);
// }
// }
// if (TechToUnlock.Count > 0)
// {
// Harmony.CreateAndPatchAll(typeof(UnlockTechOnGameStart));
// }
}
public void OnDestroy()
@@ -129,8 +130,8 @@ public class CheatEnabler : BaseUnityPlugin
return;
}
if (_shortcut.IsDown())
ShowConfigWindow();
if (Hotkey.Value.IsDown())
ToggleConfigWindow();
}
[HarmonyPostfix, HarmonyPatch(typeof(UIRoot), nameof(UIRoot.OpenMainMenuUI))]
@@ -157,7 +158,7 @@ public class CheatEnabler : BaseUnityPlugin
var transform1 = (RectTransform)btn.transform;
transform1.anchoredPosition3D = new Vector3(vec.x, vec.y + (vec.y - vec2.y) * 2, vec.z);
btn.button.onClick.RemoveAllListeners();
btn.button.onClick.AddListener(ShowConfigWindow);
btn.button.onClick.AddListener(ToggleConfigWindow);
}
{
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.anchoredPosition3D = new Vector3(128f, -105f, 0f);
b.onClick.RemoveAllListeners();
btn.onClick += (_) => { ShowConfigWindow(); };
btn.onClick += (_) => { ToggleConfigWindow(); };
btn.tips.tipTitle = "CheatEnabler Config";
I18N.OnInitialized += () => { btn.tips.tipTitle = "CheatEnabler Config".Translate(); };
btn.tips.tipText = null;
@@ -191,7 +192,26 @@ public class CheatEnabler : BaseUnityPlugin
_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)
{
@@ -210,6 +230,7 @@ public class CheatEnabler : BaseUnityPlugin
}
}
/*
private class UnlockTechOnGameStart
{
[HarmonyPostfix]
@@ -296,5 +317,6 @@ public class CheatEnabler : BaseUnityPlugin
techStates[currentTech] = value;
}
}
*/
}

View File

@@ -4,7 +4,7 @@
<TargetFramework>net472</TargetFramework>
<BepInExPluginGuid>org.soardev.cheatenabler</BepInExPluginGuid>
<Description>DSP MOD - CheatEnabler</Description>
<Version>1.0.0</Version>
<Version>2.0.0</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<PackageId>CheatEnabler</PackageId>
@@ -22,6 +22,7 @@
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="del /F /Q package\$(ProjectName)-$(Version).zip&#xA;zip -9 -j package/$(ProjectName)-$(Version).zip $(TargetPath) package/icon.png package/manifest.json README.md" />
</Target>

View File

@@ -1,8 +1,8 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Reflection.Emit;
using BepInEx.Configuration;
using HarmonyLib;
using PowerNetworkStructures;
namespace CheatEnabler;
@@ -62,6 +62,9 @@ public static class DysonSpherePatch
_skipBulletPatch.UnpatchSelf();
_skipBulletPatch = null;
}
SkipBulletPatch.UpdateSailLifeTime();
SkipBulletPatch.UpdateSailsCacheForThisGame();
_skipBulletPatch = Harmony.CreateAndPatchAll(typeof(SkipBulletPatch));
}
else if (_skipBulletPatch != null)
@@ -127,13 +130,148 @@ public static class DysonSpherePatch
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]
[HarmonyPatch(typeof(EjectorComponent), nameof(EjectorComponent.InternalUpdate))]
private static IEnumerable<CodeInstruction> EjectorComponent_InternalUpdate_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator 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();
}
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
@@ -188,17 +326,49 @@ public static class DysonSpherePatch
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]
[HarmonyPatch(typeof(DysonSphereLayer), nameof(DysonSphereLayer.GameTick))]
private static IEnumerable<CodeInstruction> DysonSphereLayer_GameTick_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
var matcher = new CodeMatcher(instructions, generator);
/* Remove `dysonNode.id % 120 == num` */
matcher.MatchForward(false,
new CodeMatch(OpCodes.Ldc_I4_S, 120)
).Advance(-2).RemoveInstructions(6);
matcher.Start().InsertAndAdvance(
new CodeInstruction(OpCodes.Ldarg_0),
new CodeInstruction(OpCodes.Ldarg_1),
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();
}
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

View 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();
}
}

View File

@@ -11,6 +11,7 @@ public class UIConfigWindow : UI.MyWindowWithTabs
I18N.Add("General", "General", "常规");
I18N.Add("Enable Dev Shortcuts", "Enable Dev Shortcuts", "启用开发模式快捷键");
I18N.Add("Disable Abnormal Checks", "Disable Abnormal Checks", "关闭数据异常检查");
I18N.Add("Hotkey", "Hotkey", "快捷键");
I18N.Add("Build", "Build", "建造");
I18N.Add("Finish build immediately", "Finish build immediately", "建造秒完成");
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());
y += 36f;
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());
x = 0f;

View File

@@ -1,6 +1,6 @@
{
"name": "CheatEnabler",
"version_number": "1.0.0",
"version_number": "2.0.0",
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/CheatEnabler",
"description": "Add various cheat functions while disabling abnormal determinants / 添加一些作弊功能,同时屏蔽异常检测",
"dependencies": [